bool AlembicCustomAttributesEx::defineCustomAttributes(INode* node, Abc::OCompoundProperty& compoundProp, const AbcA::MetaData& metadata, unsigned int animatedTs)
{
   Modifier* pMod = FindModifier(node, (char*)this->modName.c_str());

   if(!pMod){
      return false;
   }

	ICustAttribContainer* cont = pMod->GetCustAttribContainer();
	if(!cont){
		return false;
	}

	for(int i=0; i<cont->GetNumCustAttribs(); i++)
	{
		CustAttrib* ca = cont->GetCustAttrib(i);
		std::string name = EC_MCHAR_to_UTF8( ca->GetName() );
	
		pblock = ca->GetParamBlockByID(0);
      break;
	}

   if(!pblock){
      return false;
   }


	for(int i=0, nNumParams = pblock->NumParams(); i<nNumParams; i++){

		ParamID id = pblock->IndextoID(i);
		MSTR name = pblock->GetLocalName(id, 0);

      std::stringstream propName;
      propName<<EC_MSTR_to_UTF8(name);

      ParamType2 type = pblock->GetParameterType(id);
      if(type == TYPE_STRING){
         customProps[propName.str()] = new Abc::OStringProperty(compoundProp, propName.str().c_str(), metadata, animatedTs );
      }
      else if(type == TYPE_FLOAT){
         customProps[propName.str()] = new Abc::OFloatProperty(compoundProp, propName.str().c_str(), metadata, animatedTs );
      }
      else if(type == TYPE_INT){
         customProps[propName.str()] = new Abc::OInt32Property(compoundProp, propName.str().c_str(), metadata, animatedTs );
      }
	}
   
   return true;
}
Beispiel #2
0
void ViewportLoader::ActivateEffect(MtlBase * mtl, BOOL state)
{

	ICustAttribContainer* cc = mtl->GetCustAttribContainer();
	if(!cc)
		return;
	MtlBase * mb = (MtlBase *) cc->GetOwner();
	if(!mb)
		return;

	if(state && effect)
		mb->SetMtlFlag(MTL_HW_MAT_ENABLED);
	else
		mb->ClearMtlFlag(MTL_HW_MAT_ENABLED);
	
	GetCOREInterface()->ForceCompleteRedraw();

}
Beispiel #3
0
static bool IsDxMaterialEnabled(MtlBase * map)
{
	bool enabled = false;
	ICustAttribContainer * cont = map->GetCustAttribContainer();

	if(cont)
	{
		for(int i=0; i< cont->GetNumCustAttribs(); i++)
		{
			CustAttrib * ca = cont->GetCustAttrib(i);
			if(ca->GetInterface(VIEWPORT_SHADER_MANAGER_INTERFACE2)){

				IViewportShaderManager2 * vsm = (IViewportShaderManager2*)ca->GetInterface(VIEWPORT_SHADER_MANAGER_INTERFACE2);
				return vsm->IsDxStdMtlEnabled();
			}
		}
	}
	return enabled;
}
Beispiel #4
0
bool ViewportLoader::IsLoaderActiveInMedit()
{
	MtlBase* mtl = FindOwnerMaterial();

	if ( mtl && mtl->TestMtlFlag( MTL_BEING_EDITED ) )
	{
		ICustAttribContainer * cc = mtl->GetCustAttribContainer();
		if ( cc )
		{
			for( int i = 0; i < cc->GetNumCustAttribs(); i++ )
			{
				if ( this == cc->GetCustAttrib( i ) )
					return true;
			}
		}
	}

	return false;
}
void HavokImport::HandleRagdollOnNonAccum(INode* accumChild, INode* ragdollParent)
{
	const int MaxChar = 512;
	char buffer[MaxChar];

	//Fix for nonaccumNodes

	//TSTR name(A2THelper(buffer, parent->GetName().c_str(), _countof(buffer)));
	ragdollParent->SetName(FormatText(TEXT("Ragdoll_%s"), accumChild->GetName()));

	Object *Obj = ragdollParent->GetObjectRef();

	if (Obj->SuperClassID() == GEN_DERIVOB_CLASS_ID)
	{
		while (Obj->SuperClassID() == GEN_DERIVOB_CLASS_ID) {
		
			IDerivedObject *DerObj = static_cast<IDerivedObject *> (Obj);
			const int nMods = DerObj->NumModifiers();
			for (int i = 0; i < nMods; i++)
			{
				Modifier *Mod = DerObj->GetModifier(i);
				if (Mod->ClassID() == HK_RIGIDBODY_MODIFIER_CLASS_ID)
				{
					ICustAttribContainer* cc = Mod->GetCustAttribContainer();
					if (cc)
					{
					//reset
						Mod->DeleteCustAttribContainer();

					}
					Mod->AllocCustAttribContainer();
					cc = Mod->GetCustAttribContainer();
					CustAttrib* c = (CustAttrib*)CreateInstance(CUST_ATTRIB_CLASS_ID, Class_ID(0x6e663460, 0x32682c72));
					IParamBlock2* custModParameters = c->GetParamBlock(0);
					custModParameters->SetValue(0, 0, accumChild, 0);

					cc->InsertCustAttrib(0, c);
				}
			}
			Obj = DerObj->GetObjRef();
		}
	}
}
RefResult StdDualVSImp::NotifyRefChanged(const Interval& changeInt, RefTargetHandle hTarget, PartID& partID, RefMessage message, BOOL propagate)
{
	switch (message) 
	{
		case REFMSG_TARGET_DELETED:
			{
				int i = FindNodeIndex((INode*)hTarget);
				assert(i >= 0);
				callb->DeleteRenderMeshCache(caches[i]->GetNode());
				delete caches[i];
				caches[i] = NULL;
				// NH 07|11|02 The cache is no longer dynamic - it will only grow but not shrink, 
				// so there could be null entries.  This was causing a problem in SetReference
//				caches.Delete(i,1);
//				caches.Shrink();
			}
			break;
		case REFMSG_NODE_MATERIAL_CHANGED:
			{
				int i = FindNodeIndex((INode*)hTarget);
				assert(i >= 0);
				DeleteReference(i);
			}
			break;
		case REFMSG_NODE_WSCACHE_UPDATED:
			{
				int i = FindNodeIndex((INode*)hTarget);
				//NH:06|11|02  I removed this, as in an undo situation the node reference may not be restored yet
				// as the viewport shader has not been initialised and thus not set the node.  In this case -1 is valid
//				assert(i >= 0);
				if(i >= 0)
					caches[i]->SetValid(false);
			}
			break;
		case REFMSG_SUBANIM_STRUCTURE_CHANGED:
		case REFMSG_REF_DELETED:
			{
				BOOL del = TRUE;

				int i = FindNodeIndex((INode*)hTarget);
				INode * n = (INode*)hTarget;
				Mtl * m = n->GetMtl();
				if(m)
				{
					// NH|06|11|02 check for the Viewport Manager - if the Effect is the same as the callback then keep it
					ICustAttribContainer *cont = m->GetCustAttribContainer();
					if (cont && cont->GetNumCustAttribs()) {
						IDXShaderManagerInterface *sm = GetDXShaderManager();
						if (!sm) 
						{
							break;
						}

						for (int kk = 0; kk < cont->GetNumCustAttribs(); kk++) {
							CustAttrib *ca = cont->GetCustAttrib(kk);
							IViewportShaderManager *manager = (IViewportShaderManager*)ca->GetInterface(VIEWPORT_SHADER_MANAGER_INTERFACE);
							if (manager) {

								ReferenceTarget *rt = manager->GetActiveEffect();
								if(rt == callb->GetRefTarg())
									del = FALSE;

							}
						}
					}
				}
				// Check, if there's still a reference path from the node to the MtlBase
				if(!DependsOn(hTarget,callb->GetRefTarg()) && del)
				{
					DeleteReference(i);
				}
				forceInvalid = true;
			}
	}
	return REF_SUCCEED;
}
void HavokImport::createRagdollRigidBody(INode* n, INode* parent, INode* ragdollParent, bhkRigidBodyRef rbody) {

	const int MaxChar = 512;
	char buffer[MaxChar];

	//TSTR name(A2THelper(buffer, parent->GetName().c_str(), _countof(buffer)));
	n->SetName(FormatText(TEXT("Ragdoll_%s"), parent->GetName()));

	Object *pObj = n->GetObjectRef();
	IDerivedObject *dobj = nullptr;
	if (n->SuperClassID() == GEN_DERIVOB_CLASS_ID)
		dobj = static_cast<IDerivedObject*>(pObj);
	else {
		dobj = CreateDerivedObject(pObj);
	}

	MotionSystem msys = rbody->GetMotionSystem(); //?
	MotionQuality qtype = rbody->GetQualityType();
	float mass = rbody->GetMass();
	float lindamp = rbody->GetLinearDamping();
	float angdamp = rbody->GetAngularDamping();
	float frict = rbody->GetFriction();
	float resti = rbody->GetRestitution();
	float maxlinvel = rbody->GetMaxLinearVelocity();
	float maxangvel = rbody->GetMaxAngularVelocity();
	float pendepth = rbody->GetPenetrationDepth();
	InertiaMatrix im = rbody->GetInertia();

	Modifier* rbMod = (Modifier*)CreateInstance(OSM_CLASS_ID, HK_RIGIDBODY_MODIFIER_CLASS_ID);
	if (IParamBlock2* rbParameters = rbMod->GetParamBlockByID(PB_RB_MOD_PBLOCK)) {
		//These are fundamental parameters
		rbParameters->SetValue(PA_RB_MOD_MASS, 0, mass, 0);
		rbParameters->SetValue(PA_RB_MOD_RESTITUTION, 0, resti, 0);
		rbParameters->SetValue(PA_RB_MOD_FRICTION, 0, frict, 0);
		rbParameters->SetValue(PA_RB_MOD_INERTIA_TENSOR, 0, Point3(im[0][0],im[1][1],im[2][2]), 0);

		rbParameters->SetValue(PA_RB_MOD_LINEAR_DAMPING, 0, lindamp, 0);
		rbParameters->SetValue(PA_RB_MOD_CHANGE_ANGULAR_DAMPING, 0, angdamp, 0);

		rbParameters->SetValue(PA_RB_MOD_MAX_LINEAR_VELOCITY, 0, maxlinvel, 0);
		rbParameters->SetValue(PA_RB_MOD_MAX_ANGULAR_VELOCITY, 0, maxangvel, 0);

		rbParameters->SetValue(PA_RB_MOD_ALLOWED_PENETRATION_DEPTH, 0, pendepth, 0);


		rbParameters->SetValue(PA_RB_MOD_QUALITY_TYPE, 0, QT_FIXED, 0);
		rbParameters->SetValue(PA_RB_MOD_SOLVER_DEACTIVATION, 0, SD_LOW, 0);
		rbParameters->SetValue(PA_RB_MOD_DEACTIVATOR_TYPE, 0, DT_LOW, 0);

		/*body->SetMotionSystem(MotionSystem::MO_SYS_BOX);
		body->SetDeactivatorType(DeactivatorType::DEACTIVATOR_NEVER);
		body->SetSolverDeactivation(SolverDeactivation::SOLVER_DEACTIVATION_LOW);
		body->SetQualityType(MO_QUAL_FIXED);*/


		/*switch (qtype) {
		case MO_QUAL_INVALID:
			break;
		case MO_QUAL_FIXED:
			rbParameters->SetValue(PA_RB_MOD_QUALITY_TYPE, 0, QT_FIXED, 0);
			break;
		case MO_QUAL_KEYFRAMED:
			rbParameters->SetValue(PA_RB_MOD_QUALITY_TYPE, 0, QT_KEYFRAMED, 0);
			break;
		case MO_QUAL_DEBRIS:
			rbParameters->SetValue(PA_RB_MOD_QUALITY_TYPE, 0, QT_DEBRIS, 0);
			break;
		case MO_QUAL_MOVING:
			rbParameters->SetValue(PA_RB_MOD_QUALITY_TYPE, 0, QT_MOVING, 0);
			break;
		case MO_QUAL_CRITICAL:
			rbParameters->SetValue(PA_RB_MOD_QUALITY_TYPE, 0, QT_CRITICAL, 0);
			break;
		case MO_QUAL_BULLET:
			rbParameters->SetValue(PA_RB_MOD_QUALITY_TYPE, 0, QT_BULLET, 0);
			break;
		case MO_QUAL_USER:
			break;
		case MO_QUAL_CHARACTER:
			break;
		case MO_QUAL_KEYFRAMED_REPORT:
			rbParameters->SetValue(PA_RB_MOD_QUALITY_TYPE, 0, QT_KEYFRAMED_REPORTING, 0);
			break;
		}*/


	}

	//Link Rigid Body to parent Rigid Body
	ICustAttribContainer* cc = rbMod->GetCustAttribContainer();

	if (!cc)
	{
		rbMod->AllocCustAttribContainer();
		cc = rbMod->GetCustAttribContainer();
	}
	CustAttrib* c = (CustAttrib*)CreateInstance(CUST_ATTRIB_CLASS_ID, Class_ID(0x6e663460, 0x32682c72));
	IParamBlock2* custModParameters = c->GetParamBlock(0);
	custModParameters->SetValue(0, 0, parent, 0);

	cc->InsertCustAttrib(0, c);

	Modifier* constraintMod = nullptr;

	vector< bhkSerializableRef > constraints = rbody->GetConstraints();
	//Rigid Body constraints
	if (ragdollParent) {

		for (vector< bhkSerializableRef >::iterator it = constraints.begin(); it != constraints.end(); ) {
			bhkConstraintRef constraint = bhkConstraintRef(*it);
			if (constraint->IsDerivedType(bhkLimitedHingeConstraint::TYPE)) {
				bhkLimitedHingeConstraintRef limitedHingeConstraint = bhkLimitedHingeConstraintRef(*it);
				LimitedHingeDescriptor lh = limitedHingeConstraint->GetLimitedHinge();
				constraintMod = (Modifier*)CreateInstance(OSM_CLASS_ID, HK_CONSTRAINT_HINGE_CLASS_ID);
				if (IParamBlock2* constraintParameters = constraintMod->GetParamBlockByID(PB_CONSTRAINT_MOD_COMMON_SPACES_PARAMS)) {
					constraintParameters->SetValue(PA_CONSTRAINT_MOD_PARENT_NODE, 0, ragdollParent, 0);
					constraintParameters->SetValue(PA_CONSTRAINT_MOD_PARENT_ROTATION_LOCK, 0, 0, 0);

					Point3 origin(0, 0, 0);

					Matrix3 parentRotation(TOPOINT3(lh.perp2AxleInA1), TOPOINT3(lh.perp2AxleInA2), TOPOINT3(lh.axleA), origin);
					Matrix3 childRotation(TOPOINT3(lh.perp2AxleInB1), TOPOINT3(lh.perp2AxleInB2), TOPOINT3(lh.axleB), origin);

					//Matrix3 parentRotation(true);
					//MatrixFromNormal(TOPOINT3(lh.axleA), parentRotation);
					//Matrix3 childRotation(true);
					//MatrixFromNormal(TOPOINT3(lh.axleB), childRotation);

					constraintParameters->SetValue(PA_CONSTRAINT_MOD_CHILD_SPACE_ROTATION, 0, childRotation, 0);
					constraintParameters->SetValue(PA_CONSTRAINT_MOD_PARENT_SPACE_ROTATION, 0, parentRotation, 0);
				}
				if (IParamBlock2* constraintParameters = constraintMod->GetParamBlockByID(PB_HINGE_MOD_PBLOCK)) {
					constraintParameters->SetValue(PA_HINGE_MOD_IS_LIMITED, 0, 1, 0);
					constraintParameters->SetValue(PA_HINGE_MOD_LIMIT_MIN, 0, TODEG(lh.minAngle), 0);
					constraintParameters->SetValue(PA_HINGE_MOD_LIMIT_MAX, 0, TODEG(lh.maxAngle), 0);
					constraintParameters->SetValue(PA_HINGE_MOD_MAX_FRICTION_TORQUE, 0, lh.maxFriction, 0);
					//	constraintParameters->SetValue(PA_HINGE_MOD_MOTOR_TYPE, 0, lh.motor., 0);
				}
			}
			else if (constraint->IsDerivedType(bhkRagdollConstraint::TYPE)) {
				bhkRagdollConstraintRef ragdollConstraint = bhkRagdollConstraintRef(*it);
				RagdollDescriptor rag = ragdollConstraint->GetRagdoll();
				constraintMod = (Modifier*)CreateInstance(OSM_CLASS_ID, HK_CONSTRAINT_RAGDOLL_CLASS_ID);
				if (IParamBlock2* constraintParameters = constraintMod->GetParamBlockByID(PB_CONSTRAINT_MOD_COMMON_SPACES_PARAMS)) {
					constraintParameters->SetValue(PA_CONSTRAINT_MOD_PARENT_NODE, 0, ragdollParent, 0);
					constraintParameters->SetValue(PA_CONSTRAINT_MOD_PARENT_ROTATION_LOCK, 0, 0, 0);
					
					//TOVECTOR3(rag.twistA);
					//MatrixFromNormal(TOPOINT3(rag.twistA), parentRotation);
					Point3 origin(0,0,0);
					Matrix3 parentRotation(TOPOINT3(rag.planeA),TOPOINT3(rag.motorA),TOPOINT3(rag.twistA),origin);
					
					//TOVECTOR3(rag.twistB);
					//MatrixFromNormal(TOPOINT3(rag.twistB), childRotation);
					Matrix3 childRotation(TOPOINT3(rag.planeB), TOPOINT3(rag.motorB), TOPOINT3(rag.twistB), origin);

					constraintParameters->SetValue(PA_CONSTRAINT_MOD_CHILD_SPACE_TRANSLATION, 0, TOPOINT3(rag.pivotB), 0);
					constraintParameters->SetValue(PA_CONSTRAINT_MOD_CHILD_SPACE_ROTATION, 0, childRotation, 0);
					constraintParameters->SetValue(PA_CONSTRAINT_MOD_PARENT_SPACE_TRANSLATION, 0, TOPOINT3(rag.pivotA), 0);
					constraintParameters->SetValue(PA_CONSTRAINT_MOD_PARENT_SPACE_ROTATION, 0, parentRotation, 0);
				}
				if (IParamBlock2* constraintParameters = constraintMod->GetParamBlockByID(PB_RAGDOLL_MOD_PBLOCK)) {
					constraintParameters->SetValue(PA_RAGDOLL_MOD_CONE_ANGLE, 0, TODEG(rag.coneMaxAngle), 0);
					constraintParameters->SetValue(PA_RAGDOLL_MOD_PLANE_MIN, 0, TODEG(rag.planeMinAngle), 0);
					constraintParameters->SetValue(PA_RAGDOLL_MOD_PLANE_MAX, 0, TODEG(rag.planeMaxAngle), 0);
					constraintParameters->SetValue(PA_RAGDOLL_MOD_TWIST_MIN, 0, TODEG(rag.twistMinAngle), 0);
					constraintParameters->SetValue(PA_RAGDOLL_MOD_TWIST_MAX, 0, TODEG(rag.twistMaxAngle), 0);
					constraintParameters->SetValue(PA_RAGDOLL_MOD_MAX_FRICTION_TORQUE, 0, rag.maxFriction, 0);
				}
			}
			else if (constraint->IsDerivedType(bhkMalleableConstraint::TYPE)) {
				bhkMalleableConstraintRef malleableConstraint = bhkMalleableConstraintRef(*it);
				if (malleableConstraint->GetConstraintType() == (unsigned int)2) {
					LimitedHingeDescriptor lh = malleableConstraint->GetLimitedHinge();
					constraintMod = (Modifier*)CreateInstance(OSM_CLASS_ID, HK_CONSTRAINT_HINGE_CLASS_ID);
					if (IParamBlock2* constraintParameters = constraintMod->GetParamBlockByID(PB_CONSTRAINT_MOD_COMMON_SPACES_PARAMS)) {
						constraintParameters->SetValue(PA_CONSTRAINT_MOD_PARENT_NODE, 0, ragdollParent, 0);
						constraintParameters->SetValue(PA_CONSTRAINT_MOD_PARENT_ROTATION_LOCK, 0, 0, 0);
						Point3 origin(0, 0, 0);

						Matrix3 parentRotation(TOPOINT3(lh.perp2AxleInA1), TOPOINT3(lh.perp2AxleInA2), TOPOINT3(lh.axleA), origin);
						Matrix3 childRotation(TOPOINT3(lh.perp2AxleInB1), TOPOINT3(lh.perp2AxleInB2), TOPOINT3(lh.axleB), origin);

						//Matrix3 parentRotation(true);
						//MatrixFromNormal(TOPOINT3(lh.axleA), parentRotation);
						//Matrix3 childRotation(true);
						//MatrixFromNormal(TOPOINT3(lh.axleB), childRotation);

						constraintParameters->SetValue(PA_CONSTRAINT_MOD_CHILD_SPACE_ROTATION, 0, childRotation, 0);
						constraintParameters->SetValue(PA_CONSTRAINT_MOD_PARENT_SPACE_ROTATION, 0, parentRotation, 0);
					}
					if (IParamBlock2* constraintParameters = constraintMod->GetParamBlockByID(PB_HINGE_MOD_PBLOCK)) {
						constraintParameters->SetValue(PA_HINGE_MOD_IS_LIMITED, 0, 1, 0);
						constraintParameters->SetValue(PA_HINGE_MOD_LIMIT_MIN, 0, TODEG(lh.minAngle), 0);
						constraintParameters->SetValue(PA_HINGE_MOD_LIMIT_MAX, 0, TODEG(lh.maxAngle), 0);
						constraintParameters->SetValue(PA_HINGE_MOD_MAX_FRICTION_TORQUE, 0, lh.maxFriction, 0);
						//	constraintParameters->SetValue(PA_HINGE_MOD_MOTOR_TYPE, 0, lh.motor., 0);
					}
				}
				else if (malleableConstraint->GetConstraintType() == (unsigned int)7) {
					RagdollDescriptor rag = malleableConstraint->GetRagdoll();
					constraintMod = (Modifier*)CreateInstance(OSM_CLASS_ID, HK_CONSTRAINT_RAGDOLL_CLASS_ID);
					if (IParamBlock2* constraintParameters = constraintMod->GetParamBlockByID(PB_CONSTRAINT_MOD_COMMON_SPACES_PARAMS)) {
						constraintParameters->SetValue(PA_CONSTRAINT_MOD_PARENT_NODE, 0, ragdollParent, 0);
						constraintParameters->SetValue(PA_CONSTRAINT_MOD_PARENT_ROTATION_LOCK, 0, 0, 0);
						//TOVECTOR3(rag.twistA);
						//MatrixFromNormal(TOPOINT3(rag.twistA), parentRotation);
						Point3 origin(0, 0, 0);
						Matrix3 parentRotation(TOPOINT3(rag.planeA), TOPOINT3(rag.motorA), TOPOINT3(rag.twistA), origin);

						//TOVECTOR3(rag.twistB);
						//MatrixFromNormal(TOPOINT3(rag.twistB), childRotation);
						Matrix3 childRotation(TOPOINT3(rag.planeB), TOPOINT3(rag.motorB), TOPOINT3(rag.twistB), origin);


						constraintParameters->SetValue(PA_CONSTRAINT_MOD_CHILD_SPACE_TRANSLATION, 0, TOPOINT3(rag.pivotB), 0);
						constraintParameters->SetValue(PA_CONSTRAINT_MOD_CHILD_SPACE_ROTATION, 0, childRotation, 0);
						constraintParameters->SetValue(PA_CONSTRAINT_MOD_PARENT_SPACE_TRANSLATION, 0, TOPOINT3(rag.pivotA), 0);
						constraintParameters->SetValue(PA_CONSTRAINT_MOD_PARENT_SPACE_ROTATION, 0, parentRotation, 0);
					}
					if (IParamBlock2* constraintParameters = constraintMod->GetParamBlockByID(PB_RAGDOLL_MOD_PBLOCK)) {
						constraintParameters->SetValue(PA_RAGDOLL_MOD_CONE_ANGLE, 0, TODEG(rag.coneMaxAngle), 0);
						constraintParameters->SetValue(PA_RAGDOLL_MOD_PLANE_MIN, 0, TODEG(rag.planeMinAngle), 0);
						constraintParameters->SetValue(PA_RAGDOLL_MOD_PLANE_MAX, 0, TODEG(rag.planeMaxAngle), 0);
						constraintParameters->SetValue(PA_RAGDOLL_MOD_TWIST_MIN, 0, TODEG(rag.twistMinAngle), 0);
						constraintParameters->SetValue(PA_RAGDOLL_MOD_TWIST_MAX, 0, TODEG(rag.twistMaxAngle), 0);
						constraintParameters->SetValue(PA_RAGDOLL_MOD_MAX_FRICTION_TORQUE, 0, rag.maxFriction, 0);
					}
				}
			}
			++it;
		}
	}

	dobj->SetAFlag(A_LOCK_TARGET);
	dobj->AddModifier(rbMod);
	if (constraintMod)
		dobj->AddModifier(constraintMod);
	dobj->ClearAFlag(A_LOCK_TARGET);
	n->SetObjectRef(dobj);

}
void MaxAWDExporter::ExportUserAttributes(Animatable *obj, AWDAttrElement *elem)
{
    if (!opts->ExportAttributes())
        return;

    ICustAttribContainer *attributes = obj->GetCustAttribContainer();
    if (attributes) {
        int a=0;
        int numAttribs=0;
        numAttribs = attributes->GetNumCustAttribs();
        for (a=0; a<numAttribs; a++) {
            int k=0;
            CustAttrib *attr = attributes->GetCustAttrib(a);

            for (k=0; k<attr->NumParamBlocks(); k++) {
                int p=0;
                IParamBlock2 *block = attr->GetParamBlock(k);
                if (block!=NULL){
                    char * blockName_ptr=W2A(block->GetLocalName());
                    if (ATTREQ(blockName_ptr,"AWDObjectSettingsParams") ){    }
                    // the next three should not occur yet, as we do not read Custom-properties on materials yet
                    else if (ATTREQ(blockName_ptr,"AWD_MaterialSettingsparams") ){    }
                    else if (ATTREQ(blockName_ptr,"AWD_EffectMethodsparams") ){    }
                    else if (ATTREQ(blockName_ptr,"AWDShadingParams") ){    }
                    else{
                        for (p=0; p<block->NumParams(); p++) {
                            ParamID pid = block->IndextoID(p);
                            Color col;
                            AColor acol;

                            Interval valid = FOREVER;

                            awd_uint16 len = 0;
                            AWD_field_type type = AWD_FIELD_FLOAT32;
                            AWD_field_ptr ptr;
                            ptr.v = NULL;

                            switch (block->GetParameterType(pid)) {
                                case TYPE_ANGLE:
                                case TYPE_PCNT_FRAC:
                                case TYPE_WORLD:
                                case TYPE_FLOAT:
                                    type = AWD_FIELD_FLOAT64;
                                    len = sizeof(awd_float64);
                                    ptr.v = malloc(len);
                                    *ptr.f64 = block->GetFloat(pid);
                                    break;

                                case TYPE_TIMEVALUE:
                                case TYPE_INT:
                                    type = AWD_FIELD_INT32;
                                    len = sizeof(awd_int32);
                                    ptr.v = malloc(len);
                                    *ptr.i32 = block->GetInt(pid);
                                    break;

                                case TYPE_BOOL:
                                    type = AWD_FIELD_BOOL;
                                    len = sizeof(awd_bool);
                                    ptr.v = malloc(len);
                                    *ptr.b = (0 != block->GetInt(pid));
                                    break;

                                case TYPE_FILENAME:
                                case TYPE_STRING:
                                    type = AWD_FIELD_STRING;
                                    ptr.str = (char*)block->GetStr(pid);
                                    len = strlen(ptr.str);
                                    break;

                                case TYPE_RGBA:
                                    type = AWD_FIELD_COLOR;
                                    len = sizeof(awd_color);
                                    col = block->GetColor(pid);
                                    ptr.v = malloc(len);
                                    *ptr.col = awdutil_float_color(col.r, col.g, col.b, 1.0);
                                    break;

                                case TYPE_FRGBA:
                                    type = AWD_FIELD_COLOR;
                                    len = sizeof(awd_color);
                                    acol = block->GetAColor(pid);
                                    ptr.v = malloc(len);
                                    *ptr.col = awdutil_float_color(acol.r, acol.g, acol.b, acol.a);
                                    break;
                            }

                            if (ptr.v != NULL) {
                                ParamDef def = block->GetParamDef(pid);
                                if (ns == NULL) {
                                    // Namespace has not yet been created; ns is a class
                                    // variable that will be created only once and then
                                    // reused for all user attributes.
                                    char * ns_ptr=opts->AttributeNamespace();//dont free, as this will get freed in the opts delete
                                    ns = new AWDNamespace(ns_ptr, strlen(ns_ptr));
                                    awd->add_namespace(ns);
                                }
                                char * thisName=W2A(def.int_name);
                                elem->set_attr(ns, thisName, strlen(thisName)+1, ptr, len, type);
                                free(thisName);
                            }
                        }
                    }
                    free(blockName_ptr);
                }
            }
        }
    }
}
CustomAttributes_struct MaxAWDExporter::GetCustomAWDObjectSettings(IDerivedObject * node_der,Animatable *obj)
{
    CustomAttributes_struct returnData;
    returnData.export_this=true;
    returnData.export_this_children=true;
    if(node_der!=NULL){
        int nMods = node_der->NumModifiers();
        for (int m = 0; m<nMods; m++){
            Modifier* node_mod = node_der->GetModifier(m);
            if (node_mod->IsEnabled()){
                MSTR className;
                node_mod->GetClassName(className);
                char * className_ptr=W2A(className);
                if (ATTREQ(className_ptr,"AWDObjectSettings")){
                    IParamBlock2* pb = GetParamBlock2ByIndex((ReferenceMaker*)node_mod, 0);
                    if(pb!=NULL){
                        int numBlockparams=pb->NumParams();
                        int p=0;
                        for (p=0; p<numBlockparams; p++) {
                            ParamID pid = pb->IndextoID(p);
                            ParamDef def = pb->GetParamDef(pid);
                            ParamType2 paramtype = pb->GetParameterType(pid);
                            char * paramName_ptr=W2A(def.int_name);
                            if (ATTREQ(paramName_ptr, "thisAWDID")){
                                //if (paramtype==TYPE_STRING)
                                //    skeletonMod_ptr=W2A(pb->GetStr(pid));
                            }
                            if (ATTREQ(paramName_ptr, "Export")){
                                if (paramtype==TYPE_BOOL)
                                    returnData.export_this=(0 != pb->GetInt(pid));
                            }
                            if (ATTREQ(paramName_ptr, "ExportChildren")){
                                if (paramtype==TYPE_BOOL)
                                    returnData.export_this_children=(0 != pb->GetInt(pid));
                            }
                        }
                    }
                    free (className_ptr);
                    return returnData;
                }
                free (className_ptr);
            }
        }
        Object * thisOBJ=(Object *)node_der->GetObjRef();
        if(thisOBJ!=NULL){
            if((thisOBJ->SuperClassID() == GEN_DERIVOB_CLASS_ID) || (thisOBJ->SuperClassID() == WSM_DERIVOB_CLASS_ID) || (thisOBJ->SuperClassID() == DERIVOB_CLASS_ID )){
                IDerivedObject* thisDerObj=( IDerivedObject* ) thisOBJ;
                if(thisDerObj!=NULL){
                    int nMods = thisDerObj->NumModifiers();
                    for (int m = 0; m<nMods; m++){
                        Modifier* node_mod = thisDerObj->GetModifier(m);
                        if (node_mod->IsEnabled()){
                            MSTR className;
                            node_mod->GetClassName(className);
                            char * className_ptr=W2A(className);
                            if (ATTREQ(className_ptr,"AWDObjectSettings")){
                                IParamBlock2* pb = GetParamBlock2ByIndex((ReferenceMaker*)node_mod, 0);
                                if(pb!=NULL){
                                    int numBlockparams=pb->NumParams();
                                    int p=0;
                                    for (p=0; p<numBlockparams; p++) {
                                        ParamID pid = pb->IndextoID(p);
                                        ParamDef def = pb->GetParamDef(pid);
                                        ParamType2 paramtype = pb->GetParameterType(pid);
                                        char * paramName_ptr=W2A(def.int_name);
                                        if (ATTREQ(paramName_ptr, "thisAWDID")){
                                            //if (paramtype==TYPE_STRING)
                                            //    skeletonMod_ptr=W2A(pb->GetStr(pid));
                                        }
                                        if (ATTREQ(paramName_ptr, "export")){
                                            if (paramtype==TYPE_BOOL)
                                                returnData.export_this=(0 != pb->GetInt(pid));
                                        }
                                        if (ATTREQ(paramName_ptr, "exportChildren")){
                                            if (paramtype==TYPE_BOOL)
                                                returnData.export_this_children=(0 != pb->GetInt(pid));
                                        }
                                    }
                                }
                                free (className_ptr);
                                return returnData;
                            }
                            free (className_ptr);
                        }
                    }
                }
            }
        }
    }

    while(obj->SuperClassID() != BASENODE_CLASS_ID) {
        if (obj->SuperClassID() == GEN_DERIVOB_CLASS_ID) {
          IDerivedObject *dobj = (IDerivedObject *)obj;
          obj = dobj->GetObjRef();  // Get next object down mod-stack.
        }
        else {
          break;  // Failed.
        }
    }
    ICustAttribContainer *attributes = obj->GetCustAttribContainer();

    if (attributes) {
        int a=0;
        int numAttribs=0;
        numAttribs = attributes->GetNumCustAttribs();
        for (a=0; a<numAttribs; a++) {
            int p=0;
            int t=0;
            CustAttrib *attr = attributes->GetCustAttrib(a);
            for (t=0; t<attr->NumParamBlocks(); t++) {
                IParamBlock2 *block = attr->GetParamBlock(t);
                char * localName_ptr=W2A(block->GetLocalName());
                if (ATTREQ(localName_ptr,"AWD_Export") ){
                    for (p=0; p<block->NumParams(); p++) {
                        ParamID pid = block->IndextoID(p);
                        ParamDef def = block->GetParamDef(pid);
                        char * paramName_ptr=W2A(def.int_name);
                        if (block->GetParameterType(pid)==TYPE_BOOL){
                            if (ATTREQ(paramName_ptr,"Export") )
                                returnData.export_this= (0 != block->GetInt(pid));
                            else if (ATTREQ(paramName_ptr,"ExportChildren") )
                                returnData.export_this_children= (0 != block->GetInt(pid));
                        }
                        free(paramName_ptr);
                    }
                }
                free(localName_ptr);
            }
        }
    }
    return returnData;
}
void SaveMetaData(INode* node, AlembicObject* object)
{
  if (object == NULL) {
    return;
  }
  if (object->GetNumSamples() > 0) {
    return;
  }

  Modifier* pMod = FindModifier(node, Class_ID(0xd81fc3e, 0x1e4eacf5));

  bool bReadCustAttribs = false;
  if (!pMod) {
    pMod = FindModifier(node, "Metadata");
    bReadCustAttribs = true;
  }

  if (!pMod) {
    return;
  }

  std::vector<std::string> metaData;

  if (bReadCustAttribs) {
    ICustAttribContainer* cont = pMod->GetCustAttribContainer();
    if (!cont) {
      return;
    }
    for (int i = 0; i < cont->GetNumCustAttribs(); i++) {
      CustAttrib* ca = cont->GetCustAttrib(i);
      std::string name = EC_MCHAR_to_UTF8(ca->GetName());

      IParamBlock2* pblock = ca->GetParamBlockByID(0);
      if (pblock) {
        int nNumParams = pblock->NumParams();
        for (int i = 0; i < nNumParams; i++) {
          ParamID id = pblock->IndextoID(i);
          // MSTR name = pblock->GetLocalName(id, 0);
          MSTR value = pblock->GetStr(id, 0);
          metaData.push_back(EC_MSTR_to_UTF8(value));
        }
      }
    }
  }
  else {
    IParamBlock2* pblock = pMod->GetParamBlockByID(0);
    if (pblock && pblock->NumParams() == 1) {
      ParamID id = pblock->IndextoID(0);
      MSTR name = pblock->GetLocalName(id, 0);
      int nSize = pblock->Count(id);

      for (int i = 0; i < nSize; i++) {
        MSTR value = pblock->GetStr(id, 0, i);
        metaData.push_back(EC_MSTR_to_UTF8(value));
      }
    }
  }

  if (metaData.size() > 0) {
    Abc::OStringArrayProperty metaDataProperty = Abc::OStringArrayProperty(
        object->GetCompound(), ".metadata", object->GetCompound().getMetaData(),
        object->GetCurrentJob()->GetAnimatedTs());
    Abc::StringArraySample metaDataSample(&metaData.front(), metaData.size());
    metaDataProperty.set(metaDataSample);
  }
}