latticeNoise.cpp

//-
// ==========================================================================
// Copyright 1995,2006,2008 Autodesk, Inc. All rights reserved.
//
// Use of this software is subject to the terms of the Autodesk
// license agreement provided at the time of installation or download,
// or which otherwise accompanies this software in either electronic
// or hard copy form.
// ==========================================================================
//+

//
//  File: latticeNoise.cc
//
//  Description:
//      plugin registration code
//

#include "latticeNoise.h"
#include <maya/MFnPlugin.h>
#include <maya/MString.h>
#include <stdlib.h>

MStatus initializePlugin( MObject obj )
{
        MStatus   status;
        MFnPlugin plugin( obj, PLUGIN_COMPANY, "3.0", "Any");

        // Register latticeNoise node
        //
        status = plugin.registerNode( "latticeNoise", latticeNoiseNode::id,
                                                                                 latticeNoiseNode::creator,
                                                                                 latticeNoiseNode::initialize);
        if (!status) {
                status.perror("registerNode");
                return status;
        }

        // Register latticeNoise command
        //
        status = plugin.registerCommand( "latticeNoise", latticeNoiseCmd::creator );
        if (!status) {
                plugin.deregisterNode( latticeNoiseNode::id );
                status.perror("registerCommand");
                return status;
        }

        return status;
}

MStatus uninitializePlugin( MObject obj)
{
        MStatus   status;
        MFnPlugin plugin( obj );

        // Deregister latticeNoise node
        //
        status = plugin.deregisterNode( latticeNoiseNode::id ); 
        if (!status) {
                status.perror("registerNode");
                return status;
        }

        // Register latticeNoise command
        //
        status = plugin.deregisterCommand( "latticeNoise" ); 
        if (!status) {
                status.perror("deregisterCommand");
                return status;
        }

        return status;
}

//
//  Class: noise
//
//  Description:
//      The noise class is used for generating pseudo-random continuous noise.
//      The noise values generated are always between 0 and 1.
//
//      The technique used is a simple lattice noise algorithm based upon one 
//      by Ken Perlin.  This particular implementation is adapted from 
//      Darwyn Peachey's (Texturing and Modeling: a Procedural Approach, S. Ebert
//      Editor, 1994).
//
#include <stdlib.h>
#include <math.h>

const int kTableMask = TABLE_SIZE - 1;



//                       PUBLIC                             //

float noise::atValue( float x )
//
//  Description:
//      Get the noise value at the given point in 1-space.
//
//  Arguments:
//      x - the point at which to calculate the noise
//
//  Return Value:
//      the noise value at the point
//
{
        int ix; 
        float fx; 

        if ( !isInitialized ) {
                initTable( 23479015 );
                isInitialized = 1;
        }

        ix = (int)floorf( x );
        fx = x - (float)ix; 
 
        return spline( fx, value( ix - 1 ),
                                       value( ix ),
                                       value( ix + 1 ),
                                       value( ix + 2 ) );
}

float noise::atPoint( float x, float y, float z )
//
//  Description:
//      Get the noise value at the given point in 3-space.
//
//  Arguments:
//      x - x component of point
//      y - x component of point
//      z - x component of point
//
//  Return Value:
//      the noise value at the point
//
{
        int ix, iy, iz;
        int i, j, k;
        float fx, fy, fz;
        float xknots[4], yknots[4], zknots[4];

        if ( !isInitialized ) {
                initTable( 23479015 );
        }

        ix = (int)floorf( x );
        fx = x - (float)ix; 

        iy = (int)floorf( y );
        fy = y - (float)iy;

        iz = (int)floorf( z );
        fz = z - (float)iz;

        for ( k = -1; k <= 2; k++ ) {
                for ( j = -1; j <= 2; j++ ) {
                        for ( i = -1; i <= 2 ; i++ ) {
                                xknots[i+1] = value( ix + i, iy + j, iz + k );
                        }
                        yknots[j+1] = spline( fx, xknots[0], xknots[1], xknots[2], xknots[3] );
                }
                zknots[k+1] = spline( fy, yknots[0], yknots[1], yknots[2], yknots[3] );
        }

        float val = spline( fz, zknots[0], zknots[1], zknots[2], zknots[3] ); 

        return val;
}

pnt noise::atPointAndTime( float x, float y, float z, float t )
//
//  Description:
//      Get three noise values at the given point in 4-space.  This is actually
//      a reasonably expensive operation.  It requires 255 simple spline 
//      interpolations.  However, the noise function is continuous. 
//
//  Arguments:
//      x - x component of point
//      y - x component of point
//      z - x component of point
//      t - t component of point (time component)
//
//  Return Value:
//      the noise value at the point
//
{
        pnt ret;
        
        int ix, iy, iz, it;
        int i, j, k, l;
        float fx, fy, fz, ft;
        float xknots[3][4], yknots[3][4], zknots[3][4], tknots[3][4];

        if ( !isInitialized ) {
                initTable( 23479015 );
        }

        ix = (int)floorf( x );
        fx = x - (float)ix; 

        iy = (int)floorf( y );
        fy = y - (float)iy;

        iz = (int)floorf( z );
        fz = z - (float)iz;

        it = (int)floorf( t);
        ft = t - (float)it;

        for ( l = -1; l <= 2; l++ ) {
                for ( k = -1; k <= 2; k++ ) {
                        for ( j = -1; j <= 2; j++ ) {
                                for ( i = -1; i <= 2 ; i++ ) {
                                        xknots[0][i+1] = value( ix + i, iy + j, iz + k, it + l,
                                                                                        valueTable1 ); 
                                        xknots[1][i+1] = value( ix + i, iy + j, iz + k, it + l,
                                                                                        valueTable2 ); 
                                        xknots[2][i+1] = value( ix + i, iy + j, iz + k, it + l,
                                                                                        valueTable3 ); 
                                }
                                yknots[0][j+1] = spline( fx, xknots[0][0], xknots[0][1], 
                                                                                 xknots[0][2], xknots[0][3] );
                                yknots[1][j+1] = spline( fx, xknots[1][0], xknots[1][1], 
                                                                                 xknots[1][2], xknots[1][3] );
                                yknots[2][j+1] = spline( fx, xknots[2][0], xknots[2][1], 
                                                                                 xknots[2][2], xknots[2][3] );
                        }
                        zknots[0][k+1] = spline( fy, yknots[0][0], yknots[0][1], 
                                                                         yknots[0][2], yknots[0][3] );
                        zknots[1][k+1] = spline( fy, yknots[1][0], yknots[1][1], 
                                                                         yknots[1][2], yknots[1][3] );
                        zknots[2][k+1] = spline( fy, yknots[2][0], yknots[2][1], 
                                                                         yknots[2][2], yknots[2][3] );
                }
                tknots[0][l+1] = spline( fz, zknots[0][0], zknots[0][1], 
                                                                 zknots[0][2], zknots[0][3] );
                tknots[1][l+1] = spline( fz, zknots[1][0], zknots[1][1], 
                                                                 zknots[1][2], zknots[1][3] );
                tknots[2][l+1] = spline( fz, zknots[2][0], zknots[2][1], 
                                                                 zknots[2][2], zknots[2][3] );
        } 
        ret.x = spline( ft, tknots[0][0], tknots[0][1], tknots[0][2], tknots[0][3] ); 
        ret.y = spline( ft, tknots[1][0], tknots[1][1], tknots[1][2], tknots[1][3] ); 
        ret.z = spline( ft, tknots[2][0], tknots[2][1], tknots[2][2], tknots[2][3] ); 

        return ret;
}
 

void  noise::initTable( long seed )
//
//  Description:
//      Initialize the table of random values with the given seed. 
//
//  Arguments:
//      seed - the new seed value 
//
{
        srand48( seed );

        for ( int i = 0; i < TABLE_SIZE; i++ ) {
                valueTable1[i] = (float)drand48();
                valueTable2[i] = (float)drand48();
                valueTable3[i] = (float)drand48();
        } 
        isInitialized = 1; 
}



//                       PRIVATE                            //
 

float noise::spline( float x, float knot0, float knot1, float knot2, float knot3 )
//
//  Description:
//      This is a simple version of a Catmull-Rom spline interpolation.  
//
//  Assumptions:
//      
//      0 < x < 1
// 
//
{
        float c0, c1, c2, c3;

        // Evaluate span of cubic at x using Horner's rule
        //
        c3 = (-0.5F * knot0 ) + ( 1.5F * knot1 ) + (-1.5F * knot2 ) + ( 0.5F * knot3 );
        c2 = ( 1.0F * knot0 ) + (-2.5F * knot1 ) + ( 2.0F * knot2 ) + (-0.5F * knot3 );
        c1 = (-0.5F * knot0 ) + ( 0.0F * knot1 ) + ( 0.5F * knot2 ) + ( 0.0F * knot3 );
        c0 = ( 0.0F * knot0 ) + ( 1.0F * knot1 ) + ( 0.0F * knot2 ) + ( 0.0F * knot3 );
                  
        return ( ( c3 * x + c2 ) * x + c1 ) * x + c0;;
}


int noise::isInitialized = 0;

int noise::permtable[256] = {
    254,    91,     242,    186,    90,     204,    85,     133,    233,
    50,     187,    49,     182,    224,    144,    166,    7,      51,
    20,     179,    36,     203,    114,    156,    195,    40,     24,
    60,     162,    84,     126,    102,    63,     194,    220,    161,
    72,     94,     193,    229,    140,    57,     3,      189,    106,
    54,     164,    198,    199,    44,     245,    235,    100,    87,
    25,     41,     62,     111,    13,     70,     27,     82,     69,
    53,     66,     247,    124,    67,     163,    125,    155,    228,
    122,    19,     113,    143,    121,    9,      1,      241,    171,
    200,    83,     244,    185,    170,    141,    115,    190,    154,
    48,     32,     178,    127,    167,    56,     134,    15,     160,
    238,    64,     6,      11,     196,    232,    26,     89,     0,
    219,    112,    68,     30,     215,    227,    75,     132,    71,
    239,    251,    92,     14,     104,    231,    29,     180,    150,
    226,    191,    47,     73,     37,     183,    88,     105,    42,
    22,     2,      38,     5,      119,    74,     249,    184,    52,
    8,      55,     118,    255,    206,    173,    165,    78,     31,
    123,    98,     212,    80,     139,    61,     138,    77,     177,
    45,     137,    145,    28,     168,    128,    95,     223,    35,
    205,    76,     211,    175,    81,     33,     207,    21,     131,
    58,     152,    16,     240,    18,     96,     210,    109,    214,
    216,    202,    148,    34,     146,    117,    176,    93,     246,
    172,    97,     159,    197,    218,    65,     147,    253,    221,
    217,    79,     101,    142,    23,     149,    99,     39,     12,
    135,    110,    234,    108,    153,    129,    4,      169,    174,
    116,    243,    130,    107,    222,    10,     43,     188,    46,
    213,    252,    86,     157,    192,    236,    158,    120,    17,
    103,    248,    225,    230,    250,    208,    181,    151,    237,
    201,    59,     136,    209 
};

float noise::valueTable1[256];
float noise::valueTable2[256];
float noise::valueTable3[256];

Autodesk® Maya® 2010 © 1997-2009 Autodesk, Inc. All rights reserved. Generated with doxygen 1.5.6