#ifndef _cgfxAttrDef_h_
#define _cgfxAttrDef_h_
#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 <Cg/cg.h>
#include <Cg/cgGL.h>
class cgfxAttrDefList;
class cgfxShaderNode;
class MDGModifier;
class MFnDependencyNode;
#define kNullCallback 0
class cgfxAttrDef
{
public:
enum cgfxAttrType
{
kAttrTypeUnknown,
kAttrTypeBool,
kAttrTypeInt,
kAttrTypeFloat,
kAttrTypeString,
kAttrTypeVector2,
kAttrTypeVector3,
kAttrTypeVector4,
kAttrTypeObjectDir,
kAttrTypeFirstDir = kAttrTypeObjectDir,
kAttrTypeWorldDir,
kAttrTypeViewDir,
kAttrTypeProjectionDir,
kAttrTypeScreenDir,
kAttrTypeLastDir = kAttrTypeScreenDir,
kAttrTypeObjectPos,
kAttrTypeFirstPos = kAttrTypeObjectPos,
kAttrTypeWorldPos,
kAttrTypeViewPos,
kAttrTypeProjectionPos,
kAttrTypeScreenPos,
kAttrTypeLastPos = kAttrTypeScreenPos,
kAttrTypeColor3,
kAttrTypeColor4,
kAttrTypeMatrix,
kAttrTypeFirstMatrix = kAttrTypeMatrix,
kAttrTypeWorldMatrix,
kAttrTypeViewMatrix,
kAttrTypeProjectionMatrix,
kAttrTypeWorldViewMatrix,
kAttrTypeWorldViewProjectionMatrix,
kAttrTypeLastMatrix = kAttrTypeWorldViewProjectionMatrix,
kAttrTypeColor1DTexture,
kAttrTypeFirstTexture = kAttrTypeColor1DTexture,
kAttrTypeColor2DTexture,
kAttrTypeColor3DTexture,
kAttrTypeColor2DRectTexture,
kAttrTypeNormalTexture,
kAttrTypeBumpTexture,
kAttrTypeCubeTexture,
kAttrTypeEnvTexture,
kAttrTypeNormalizationTexture,
kAttrTypeLastTexture = kAttrTypeNormalizationTexture,
#ifdef _WIN32
kAttrTypeTime,
#endif
kAttrTypeOther,
_kAttrTypeLast
};
static const char* typeName( cgfxAttrType eAttrType );
static const char** compoundAttrSuffixes( cgfxAttrType eAttrType );
enum cgfxVectorHint
{
kVectorHintNone,
kVectorHintDirLight,
kVectorHintPointLight,
kVectorHintSpotLight,
kVectorHintEye,
_kVectorHintLast
};
MString fName;
cgfxAttrType fType;
int fSize;
MObject fAttr;
cgfxVectorHint fHint;
MObject fAttr2;
double* fNumericMin;
double* fNumericMax;
double* fNumericSoftMin;
double* fNumericSoftMax;
double* fNumericDef;
MDistance::Unit fUnits;
MString fStringDef;
MString fDescription;
MString fSemantic;
CGparameter fParameterHandle;
GLuint fTextureId;
MCallbackId fTextureMonitor;
bool fInvertMatrix;
bool fTransposeMatrix;
bool fTweaked;
bool fInitOnUndo;
public:
cgfxAttrDef();
~cgfxAttrDef();
void release();
void releaseTexture();
void releaseCallback();
MString typeName() const { return typeName( fType ); }
static cgfxAttrDefList* attrsFromEffect(CGeffect cgEffect, CGtechnique cgTechnique);
static cgfxAttrDefList* attrsFromNode(MObject& node);
static void updateNode(CGeffect effect,
cgfxShaderNode* pNode,
MDGModifier* dgMod,
cgfxAttrDefList*& attrDefList,
MStringArray& attributeList );
static void buildAttrDefList(MObject& node);
static void initializeAttributes( MObject& node,
cgfxAttrDefList* list,
bool bUndoing,
MDGModifier* dgMod );
static void purgeMObjectCache( cgfxAttrDefList* list );
static void validateMObjectCache( const MObject& obCgfxShader,
cgfxAttrDefList* list );
static cgfxAttrDef* attrFromNode(
const MFnDependencyNode& fnNode,
const MString& sAttrName,
const cgfxAttrType eAttrType,
const MString& sDescription,
const MString& sSemantic);
const char* getExtraAttrSuffix() const;
bool createAttribute(const MObject& oNode, MDGModifier* mod, cgfxShaderNode* pNode);
bool destroyAttribute(MObject& oNode, MDGModifier* mod);
protected:
void setTextureType(CGparameter param);
void setSamplerType(CGparameter param);
void setMatrixType(CGparameter param);
void
setVectorType(CGparameter param);
bool isInitialValueEqual( const cgfxAttrDef& that ) const;
void setInitialValue( const cgfxAttrDef& from );
void setAttributeFlags();
public:
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;
void getSource( MObject& oNode, MPlug& src) const;
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);
};
#define VALID(ptr) (ptr == 0 || _CrtIsValidHeapPointer(ptr))
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)
{ };
~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) { };
iterator(cgfxAttrDefList& list): item(list.head)
{
#ifdef _WIN32
_ASSERTE(VALID(item));
#endif
};
iterator(cgfxAttrDefList* list)
{
#ifdef _WIN32
_ASSERTE(VALID(list));
item = (list) ? list->head : 0;
_ASSERTE(VALID(item));
#else
item = (list) ? list->head : 0;
#endif
};
void reset() { item = 0; };
protected:
iterator(element* e): item(e) { };
};
cgfxAttrDefList()
: head(0)
, tail(0)
, refcount(1)
{ };
protected:
~cgfxAttrDefList()
{
clear();
};
public:
void addRef()
{
++refcount;
};
void release();
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);
};
};
#undef VALID
#endif