- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Examples

# cgfxAttrDef.h

    //
    // Copyright (C) 2002-2003 NVIDIA
    //
    // File: cgfxAttrDef.h
    //
    // Utilities for dealing with CgFX shaders
    //
    // Author: Jim Atkinson
    //
    // Changes:
    //  12/2003  Kurt Harriman - www.octopusgraphics.com +1-415-893-1023
    //           - Added cgfxAttrDef members:  fNumericSoftMin, fNumericSoftMax,
    //             fSemantic, fTweaked, fInitOnUndo, typeName(),
    //             compoundAttrSuffixes(), attrFromNode(), initializeAttributes(),
    //             isInitialValueEqual(), setInitialValue(), purgeMObjectCache(),
    //             validateMObjectCache(), getExtraAttrSuffix()
    //           - Deleted members: fMustInit, setDefaultValues()
    //           - Changed members: fTextureId
    //           - Added cgfxAttrDefList member: findInsensitive()
    //           - Use MDGModifier instead of MDagModifier
    //           - Minimizing unnecessary #includes so other Maya tools can
    //             borrow this header without pulling in extra dependencies.
    //
    //-
    // ==========================================================================
    // 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.
    // ==========================================================================
    //+
    #ifndef _cgfxAttrDef_h_
    #define _cgfxAttrDef_h_

    // This class holds the definition of a single attribute
    // as it has been extracted from the CGeffect interface.
    // All the data has been stored in native Maya format for
    // simplicity of use.
    //

    #include <maya/MObject.h>
    #include <maya/MString.h>
    #include <maya/MMatrix.h>
    #include <maya/MImage.h>
    #include <maya/MMessage.h>
    #include <maya/MDistance.h>

    #include "cgfxRCPtr.h"

    #include <Cg/cg.h>
    #include <Cg/cgGL.h>

    class  cgfxAttrDefList;                // below
    class  cgfxEffect;                     // in "cgfxEffectDef.h"
    class  cgfxShaderNode;                 // in "cgfxShaderNode.h"
    class  cgfxTextureCacheEntry;
    class  MDGModifier;                    // in <maya/MDGModifier.h>
    class  MFnDependencyNode;              // in <maya/MFnDependencyNode.h>
    #define kNullCallback 0

    //--------------------------------------------------------------------//
    //                            cgfxAttrDef                             //
    //--------------------------------------------------------------------//
    // Hold the definition of an attribute.

    class cgfxAttrDef
    {
    public:
        enum cgfxAttrType
        {
            // Unknown.
            //
            kAttrTypeUnknown,

            // Boolean value.  Create with MFnNumericAttribute; set default
            // value
            //
            kAttrTypeBool,

            // Integer value.  Create with MFnNumericAttribute; set min,
            // max, default value
            //
            kAttrTypeInt,

            // Float value.  Create with MFnNumericAttribute; set min, max,
            // default value
            //
            kAttrTypeFloat,

            // String value.  Create with MFnTypedAttribute; set default
            // value
            //
            kAttrTypeString,

            // 2, 3, and 4 element vectors. Create with MFnNumericAttribute;
            // children are *X, *Y, *Z, and (maybe) *W; set min, max,
            // default for each child.
            //
            kAttrTypeVector2,
            kAttrTypeVector3,
            kAttrTypeVector4,

            kAttrTypeObjectDir,     // Object coordinates
            kAttrTypeFirstDir = kAttrTypeObjectDir,
            kAttrTypeWorldDir,      // World coordinates
            kAttrTypeViewDir,       // Eye coordinates
            kAttrTypeProjectionDir, // Clip coordinates
            kAttrTypeScreenDir,     // Screen coordinates
            kAttrTypeLastDir = kAttrTypeScreenDir,

            kAttrTypeObjectPos,     // Object coordinates
            kAttrTypeFirstPos = kAttrTypeObjectPos,
            kAttrTypeWorldPos,      // World coordinates
            kAttrTypeViewPos,       // Eye coordinates
            kAttrTypeProjectionPos, // Clip coordinates
            kAttrTypeScreenPos,     // Screen coordinates
            kAttrTypeLastPos = kAttrTypeScreenPos,

            // Color value.  Create with MFnCompoundAttribute; children are
            // *R, *G, *B, and (maybe) *A; set min, max, default for each
            // child.
            //
            kAttrTypeColor3,
            kAttrTypeColor4,

            // Matrix value.  Create with MFnMatrixAttribute; default is
            // identity.
            //
            kAttrTypeMatrix,
            kAttrTypeFirstMatrix = kAttrTypeMatrix,
            kAttrTypeWorldMatrix,
            kAttrTypeViewMatrix,
            kAttrTypeProjectionMatrix,
            kAttrTypeWorldViewMatrix,
            kAttrTypeWorldViewProjectionMatrix,
            kAttrTypeLastMatrix = kAttrTypeWorldViewProjectionMatrix,

            // Texture types.  Create as a color connected to a new file
            // texture node.
            //
            kAttrTypeColor1DTexture,
            kAttrTypeFirstTexture = kAttrTypeColor1DTexture,
            kAttrTypeColor2DTexture,
            kAttrTypeColor3DTexture,
            kAttrTypeColor2DRectTexture,
            kAttrTypeNormalTexture,
            kAttrTypeBumpTexture,
            kAttrTypeCubeTexture,
            kAttrTypeEnvTexture,
            kAttrTypeNormalizationTexture,
            kAttrTypeLastTexture = kAttrTypeNormalizationTexture,

    #ifdef _WIN32
            // Time
            kAttrTypeTime,
    #endif
            // Other value.  This is for attributes that have odd type or
            // dimensionality.  Create them as multi, multi, multi
            // attributes as needed; default is zero.
            //
            kAttrTypeOther,

            // Last value.
            _kAttrTypeLast
        };

        // Static methods to return useful info about a cgfxAttrType.
        static const char*  typeName( cgfxAttrType eAttrType );
        static const char** compoundAttrSuffixes( cgfxAttrType eAttrType );

        // These are hints as to what might be connected to a direction or
        // position input.
        //
        enum cgfxVectorHint
        {
            kVectorHintNone,
            kVectorHintDirLight,
            kVectorHintPointLight,
            kVectorHintSpotLight,
            kVectorHintEye,

            _kVectorHintLast
        };

        //----------------------------------------------------------------//

        MString         fName;
        cgfxAttrType    fType;
        int             fSize;          // The number of elements, not bytes.
        MObject         fAttr;          // The attribute itself
        cgfxVectorHint  fHint;

        // Vector4 or Color4 types use an extra Maya attribute to hold W or Alpha.
        MObject         fAttr2;         // An extra attribute if necessary.

        double*         fNumericMin;    // we use doubles even for int data.
        double*         fNumericMax;
        double*         fNumericSoftMin;
        double*         fNumericSoftMax;
        double*         fNumericDef;    // Numeric initial value
        MDistance::Unit fUnits;

        MString         fStringDef;     // String initial value

        MString         fDescription;   // Description (if supplied)
        MString         fSemantic;      // Semantic (if supplied)

        CGparameter     fParameterHandle;

        cgfxRCPtr<cgfxTextureCacheEntry> fTexture;
        MCallbackId     fTextureMonitor;
        MString         fTextureUVLink; // A string value for texture UV link.

        bool            fInvertMatrix;  // Matrix elements should be inverted.
        bool            fTransposeMatrix;//Matrix elements should be transposed.

        bool            fTweaked;       // true => user has changed attr value
        bool            fInitOnUndo;    // true => set attr to initial value when
        //   changing back to this effect on undo

    private:
        bool            fIsConvertedToInternal;
        // the symbol to mark if the unit is converted to internal one
        const static char fSymbol;

        //----------------------------------------------------------------//

    public:
        // Constructor
        cgfxAttrDef(CGparameter cgParameter);
        cgfxAttrDef(
            const MString&          sAttrName,
            const cgfxAttrType      eAttrType,
            const MString&          sDescription,
            const MString&          sSemantic,
            MObject                 obNode,
            MObject                 obAttr
        );

        // Destructor
        ~cgfxAttrDef();

    private:
        // Prohibited and not implemented.
        cgfxAttrDef(const cgfxAttrDef&);
        const cgfxAttrDef& operator=(const cgfxAttrDef&);

    public:
        // Release any associated resources
        void            release();
        void            releaseTexture();
        void            releaseCallback();

        // Return a string representation of fType.
        MString         typeName() const { return typeName( fType ); }

        static cgfxRCPtr<cgfxAttrDefList> attrsFromNode(MObject& node);

        static void     updateNode(
            const cgfxRCPtr<const cgfxEffect>& effect,
            cgfxShaderNode*                     pNode,
            MDGModifier*                        dgMod,
            cgfxRCPtr<cgfxAttrDefList>&         attrDefList,
            MStringArray&                       attributeList);
        static void buildAttrDefList(MObject& node);
        static void     initializeAttributes(
            MObject&                            node,
            const cgfxRCPtr<cgfxAttrDefList>&   list,
            bool                                bUndoing,
            MDGModifier*                        dgMod );
        static void     purgeMObjectCache(const cgfxRCPtr<cgfxAttrDefList>& list);
        static void     validateMObjectCache(const MObject&   obCgfxShader,
                                             const cgfxRCPtr<cgfxAttrDefList>& list);

        static cgfxAttrDef* attrFromNode(
            const MFnDependencyNode& fnNode,
            const MString&           sAttrName,
            const cgfxAttrType       eAttrType,
            const MString&           sDescription,
            const MString&           sSemantic);

        // Return suffix for Color4/Vector4 extra attribute, or NULL.
        const char*     getExtraAttrSuffix() const;

        bool            createAttribute(const MObject& oNode, MDGModifier* mod, cgfxShaderNode*   pNode);
        bool            destroyAttribute(MObject& oNode, MDGModifier* mod);

    protected:

        // setTextureType
        //
        // Description:
        //
        // Parameters:
        //      param - parameter
        //
        // Returns:
        //      None
        //
        void setTextureType(CGparameter param);

        void setSamplerType(CGparameter param);

        void setMatrixType(CGparameter param);

        // setVectorType
        //
        // Description:
        //
        // Parameters:
        //      param - parameter
        //
        // Returns:
        //      None
        //
        void

            setVectorType(CGparameter param);

        // Return true if initial value of 'this' is same as 'that'.
        bool            isInitialValueEqual( const cgfxAttrDef& that ) const;

        // Copy initial value from given attribute.
        void            setInitialValue( const cgfxAttrDef& from );

        // Set attribute flag
        void setAttributeFlags();

    public:
        // These routines all get the value of the attribute referenced by
        // this cgfxAttrDef object.
        //
        void            getValue( MObject& oNode, bool& value ) const;
        void            getValue( MObject& oNode, int& value ) const;
        void            getValue( MObject& oNode, float& value ) const;
        void            getValue( MObject& oNode, MString& value ) const;
        void            getValue( MObject& oNode, float& v1, float& v2 ) const;
        void            getValue( MObject& oNode,
            float& v1, float& v2, float& v3 ) const;
        void            getValue( MObject& oNode,
            float& v1, float& v2, float& v3, float& v4 ) const;
        void            getValue( MObject& oNode, MMatrix& value ) const;
        void            getValue( MObject& oNode, MImage& value ) const;

        // This routine finds the DG input to this attribute (e.g. texture
        // node connections)
        //
        void            getSource( MObject& oNode, MPlug& src) const;

        // These routines all set the value of the attribute referenced by
        // this cgfxAttrDef object.
        //
        void            setValue( MObject& oNode, bool value );
        void            setValue( MObject& oNode, int value );
        void            setValue( MObject& oNode, float value );
        void            setValue( MObject& oNode, const MString& value );
        void            setValue( MObject& oNode, float v1, float v2 );
        void            setValue( MObject& oNode, float v1, float v2, float v3 );
        void            setValue( MObject& oNode,
            float v1, float v2, float v3, float v4 );
        void            setValue( MObject& oNode, const MMatrix& v );
        void            setTexture( MObject& oNode, const MString& value, MDGModifier* dgMod);

        void            setUnitsToInternal(CGparameter& cgParameter);
    };

    #define VALID(ptr) (ptr == 0 || _CrtIsValidHeapPointer(ptr))

    //--------------------------------------------------------------------//
    //                          cgfxAttrDefList                           //
    //--------------------------------------------------------------------//
    // Hold a list of cgfxAttrDef* objects that can be searched by name

    class cgfxAttrDefList
    {
    protected:
        class element;
        friend class element;

    public:
        class iterator;
        friend class iterator;

    protected:
        class element
        {
        public:
            element*        prev;
            element*        next;
            cgfxAttrDef*    data;

            element()
                : prev(0)
                , next(0)
                , data(0)
            { /* nothing */ };

            ~element()
            {
    #ifdef _WIN32
                _ASSERTE(VALID(prev));
                _ASSERTE(VALID(next));
                _ASSERTE(VALID(data));
    #endif
                if (prev)
                {
                    prev->next = next;
                }
                if (next)
                {
                    next->prev = prev;
                }
                delete data;
            };
        };

        element* head;
        element* tail;
        int refcount;

    public:
        class iterator
        {
            friend class cgfxAttrDefList;

        protected:
            element*        item;

        public:
    #ifdef _WIN32
            cgfxAttrDef* operator *() { _ASSERTE(VALID(item)); _ASSERTE(VALID(item->data)); return item->data; };
            iterator& operator ++ () { _ASSERTE(VALID(item)); _ASSERTE(VALID(item->next)); item = item->next; return *this; };
    #else
            cgfxAttrDef* operator *() { return item->data; };
            iterator& operator ++  () { item = item->next; return *this; };
    #endif

            iterator operator ++ (int)
            {
                iterator tmp = *this;
    #ifdef _WIN32
                _ASSERTE(VALID(item));
                _ASSERTE(VALID(item->next));
    #endif
                item = item->next;
                return tmp;
            };

            operator bool() { return (item != 0); };

            iterator(): item(0) { /* nothing */ };
            iterator(cgfxAttrDefList& list): item(list.head)
            {
    #ifdef _WIN32
                    _ASSERTE(VALID(item));
    #endif
            };
            iterator(const cgfxRCPtr<cgfxAttrDefList>& list)
            {
    #ifdef _WIN32
                _ASSERTE(VALID(list.operator->()));
                item = list.isNull() ? 0 : list->head;
                _ASSERTE(VALID(item));
    #else
                item = list.isNull() ? 0 : list->head;
    #endif
            };
            void reset() { item = 0; };

        protected:
            iterator(element* e): item(e) { /* nothing */ };
        };

        cgfxAttrDefList()
            :   head(0)
            ,   tail(0)
            ,   refcount(0)
        { /* nothing */ };

    private:

        friend class cgfxRCPtr<cgfxAttrDefList>;

        ~cgfxAttrDefList()
        {
            clear();
        };

        void addRef()
        {
            ++refcount;
        };

        void release();

        // Prohibited and not implemented.
        cgfxAttrDefList(const cgfxAttrDefList&);
        const cgfxAttrDefList& operator=(const cgfxAttrDefList&);

    public:

        void releaseTextures();

        void clear()
        {
    #ifdef _WIN32
            _ASSERTE(VALID(head));
    #endif
            if (head)
            {
                element *tmp = new element;
                tmp->next = head;
                head->prev = tmp;

                while (tmp->next)
                {
                    delete tmp->next;
                }
                delete tmp;
            }

            head = tail = 0;
        };

        bool empty() { return (head == 0); };

        iterator find(const MString& name)
        {
            iterator it(*this);

            while (it)
            {
                if ((*it)->fName == name)
                {
                    break;
                }
                ++it;
            }

            return it;
        };

        iterator        findInsensitive( const MString& name );

        void add(cgfxAttrDef* aDef)
        {
            element * e = new element;
            e->data = aDef;
            if (tail)
            {
                tail->next = e;
                e->prev = tail;
            }
            else
            {
                head = e;
            }
            tail = e;
        }

        iterator begin()
        {
            return iterator(*this);
        };

        void dump(const char* name);
    };

    #undef VALID
    #endif /* _cgfxAttrDef_h_ */