Modifier *CMaxMesh::FindPhysiqueModifier(INode *pINode) { // get the object reference of the node Object *pObject; pObject = pINode->GetObjectRef(); if(pObject == 0) return 0; // loop through all derived objects while(pObject->SuperClassID() == GEN_DERIVOB_CLASS_ID) { IDerivedObject *pDerivedObject; pDerivedObject = static_cast<IDerivedObject *>(pObject); // loop through all modifiers int stackId; for(stackId = 0; stackId < pDerivedObject->NumModifiers(); stackId++) { // get the modifier Modifier *pModifier; pModifier = pDerivedObject->GetModifier(stackId); // check if we found the physique modifier if(pModifier->ClassID() == Class_ID(PHYSIQUE_CLASS_ID_A, PHYSIQUE_CLASS_ID_B)) return pModifier; } // continue with next derived object pObject = pDerivedObject->GetObjRef(); } return 0; }
ISkin* MaxExportPlugin::FindSkinModifier(INode* node) { Object* object = node->GetObjectRef(); if (!object) return 0; while (object->SuperClassID() == GEN_DERIVOB_CLASS_ID && object) { IDerivedObject* derivedObject = (IDerivedObject*)object; int modStackId = 0; while (modStackId < derivedObject->NumModifiers()) { Modifier* mod = derivedObject->GetModifier(modStackId); //file << "MODIFIER: " << std::to_wstring(mod->ClassID().PartA()) << " " << std::to_wstring(mod->ClassID().PartB()) << "\n"; if (mod->ClassID() == SKIN_CLASS_ID) { return (ISkin*)(mod->GetInterface(I_SKIN)); } modStackId++; } object = derivedObject->GetObjRef(); } return 0; }
Modifier* SGP_MaxInterface::FindModifier(INode *pINode, Class_ID id) { // get the object reference of the node Object *pObject; pObject = pINode->GetObjectRef(); if(pObject == NULL) return NULL; // loop through all derived objects while(pObject->SuperClassID() == GEN_DERIVOB_CLASS_ID) { IDerivedObject *pDerivedObject; pDerivedObject = static_cast<IDerivedObject *>(pObject); // loop through all modifiers int stackId; for(stackId = 0; stackId < pDerivedObject->NumModifiers(); stackId++) { // get the modifier Modifier *pModifier; pModifier = pDerivedObject->GetModifier(stackId); // check if we found the modifier if(pModifier->ClassID() == id) return pModifier; } // continue with next derived object pObject = pDerivedObject->GetObjRef(); } return NULL; }
Modifier *CMaxMesh::FindSkinModifier(INode *pINode) { #if MAX_RELEASE >= 4000 // get the object reference of the node Object *pObject; pObject = pINode->GetObjectRef(); if(pObject == 0) return 0; // loop through all derived objects while(pObject->SuperClassID() == GEN_DERIVOB_CLASS_ID) { IDerivedObject *pDerivedObject; pDerivedObject = static_cast<IDerivedObject *>(pObject); // loop through all modifiers int stackId; for(stackId = 0; stackId < pDerivedObject->NumModifiers(); stackId++) { // get the modifier Modifier *pModifier; pModifier = pDerivedObject->GetModifier(stackId); // check if we found the skin modifier if(pModifier->ClassID() == SKIN_CLASSID) return pModifier; } // continue with next derived object pObject = pDerivedObject->GetObjRef(); } #endif return 0; }
//---------------------------------------------------------------------------- void SceneBuilder::CollectModifiers (INode *node, std::vector<Modifier*> &modifiers) { // 确定这个节点是否有修改器。如果有,存储起来。 // // node: // Max场景中节点指针。 // modifiers: // 存储所有修改器指针。 Object *obj = node->GetObjectRef(); if (!obj) return; while (obj->SuperClassID() == GEN_DERIVOB_CLASS_ID) { IDerivedObject* derObj = static_cast<IDerivedObject*>(obj); int modStackIndex = 0; while (modStackIndex < derObj->NumModifiers()) { Modifier *mod = derObj->GetModifier(modStackIndex); if (mod) { modifiers.push_back(mod); } modStackIndex++; } obj = derObj->GetObjRef(); } }
//// FindSkinModifier /////////////////////////////////////////////////////// // Given an INode, gets the ISkin object of that node, or nil if there is // none. Taken from the Max4 SDK, ISkin.h ISkin* plMaxNodeBase::FindSkinModifier() { int modStackIndex; // Get object from node. Abort if no object. Object *pObj = GetObjectRef(); if( pObj == nil ) return nil; // Is derived object ? while( pObj->SuperClassID() == GEN_DERIVOB_CLASS_ID ) { IDerivedObject *pDerObj = (IDerivedObject *)pObj; // Iterate over all entries of the modifier stack. for( modStackIndex = 0; modStackIndex < pDerObj->NumModifiers(); modStackIndex++ ) { // Get current modifier. Modifier *mod = pDerObj->GetModifier( modStackIndex ); // Is this Skin ? if( mod->ClassID() == SKIN_CLASSID ) { ISkin* skin = (ISkin*)mod->GetInterface(I_SKIN); if( skin->GetNumBones() > 0 ) return skin; } } pObj = pDerObj->GetObjRef(); } // Not found. return nil; }
Modifier* PhyExportUtil::findPhysiqueModifier( INode* node ) { // Get object from node. Abort if no object. ::Object* obj = node->GetObjectRef(); if ( !obj ) return 0; // Is derived object ? while ( obj->SuperClassID() == GEN_DERIVOB_CLASS_ID && obj ) { // Yes -> Cast. IDerivedObject* derivedObj = static_cast<IDerivedObject*>( obj ); // Iterate over all entries of the modifier stack. for ( int modStackIndex = 0 ; modStackIndex < derivedObj->NumModifiers() ; ++modStackIndex ) { // Get current modifier. Modifier* modPtr = derivedObj->GetModifier( modStackIndex ); // Is this Physique ? if ( modPtr->ClassID() == Class_ID(PHYSIQUE_CLASS_ID_A, PHYSIQUE_CLASS_ID_B) ) { // Yes -> Exit. return modPtr; } } obj = derivedObj->GetObjRef(); } // Not found. return 0; }
PaintDefromModData *PaintDeformTest::GetPMD(INode *pNode) { ModContext *mc = NULL; Object* pObj = pNode->GetObjectRef(); if (!pObj) return NULL; while (pObj->SuperClassID() == GEN_DERIVOB_CLASS_ID && mc == NULL) { IDerivedObject* pDerObj = (IDerivedObject *)(pObj); int Idx = 0; while (Idx < pDerObj->NumModifiers()) { // Get the modifier. Modifier* mod = pDerObj->GetModifier(Idx); if (mod->ClassID() == PAINTDEFORMTEST_CLASS_ID) { // is this the correct Physique Modifier based on index? PaintDeformTest *pmod = (PaintDeformTest*)mod; if (pmod == this) { mc = pDerObj->GetModContext(Idx); break; } } Idx++; } pObj = pDerObj->GetObjRef(); } if(!mc) return NULL; if ( !mc->localData ) return NULL; PaintDefromModData *bmd = (PaintDefromModData *) mc->localData; return bmd; }
Object *GetBaseObjectFromNode (INode *node) { Object *ob; IDerivedObject *od; SClass_ID cid; ob=node->GetObjectRef(); if (ob) cid=ob->SuperClassID(); else return (NULL); while ((cid==GEN_DERIVOB_CLASS_ID) && (ob)) { od=(IDerivedObject *)ob; ob=od->GetObjRef(); cid=ob->SuperClassID(); } return(ob); }
ISkin* CExporter::getISkinPtr(Object* object) { assert(object != NULL); while (GEN_DERIVOB_CLASS_ID == object->SuperClassID()) { IDerivedObject* pDerObj = static_cast<IDerivedObject*>(object); for (int i = 0; i < pDerObj->NumModifiers(); ++i) { Modifier* mod = pDerObj->GetModifier(i); if (SKIN_CLASSID == mod->ClassID()) { return (ISkin*)(mod->GetInterface(I_SKIN)); } } object = pDerObj->GetObjRef(); } return NULL; }
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(); } } }
Modifier *FindSkinModifier (INode *node) { Object* ObjectPtr = node->GetObjectRef(); if (!ObjectPtr) return NULL; while (ObjectPtr->SuperClassID() == GEN_DERIVOB_CLASS_ID && ObjectPtr) { IDerivedObject *DerivedObjectPtr = (IDerivedObject *)(ObjectPtr); int ModStackIndex = 0; while (ModStackIndex < DerivedObjectPtr->NumModifiers()) { Modifier* ModifierPtr = DerivedObjectPtr->GetModifier(ModStackIndex); if (ModifierPtr->ClassID() == SKIN_CLASSID) return ModifierPtr; ModStackIndex++; } ObjectPtr = DerivedObjectPtr->GetObjRef(); } return NULL; }
Modifier *CMaxMesh::FindMorpherModifier(INode *pINode) { // get the object reference of the node Object *pObject; pObject = pINode->GetObjectRef(); if(pObject == 0) return 0; // loop through all derived objects while(pObject->SuperClassID() == GEN_DERIVOB_CLASS_ID) { IDerivedObject *pDerivedObject; pDerivedObject = static_cast<IDerivedObject *>(pObject); // loop through all modifiers int stackId; for(stackId = 0; stackId < pDerivedObject->NumModifiers(); stackId++) { // get the modifier Modifier *pModifier; pModifier = pDerivedObject->GetModifier(stackId); Class_ID id = pModifier->ClassID(); char buf[512]; sprintf(buf, "node %s modifier %d class %d:%d/0x%x:0x%x\n", pINode->GetName(), stackId, id.PartA(), id.PartB(), id.PartA(), id.PartB()); ::OutputDebugStringA(buf); // check if we found the physique modifier if(pModifier->ClassID() == MR3_CLASS_ID) { ::OutputDebugStringA("that was it! the morpher I was looking for!\n"); return pModifier; } } // continue with next derived object pObject = pDerivedObject->GetObjRef(); } return 0; }
BOOL RecursePipeAndMatch(LocalPatchData *smd, Object *obj) { SClass_ID sc; IDerivedObject* dobj; Object *currentObject = obj; if ((sc = obj->SuperClassID()) == GEN_DERIVOB_CLASS_ID) { dobj = (IDerivedObject*)obj; while (sc == GEN_DERIVOB_CLASS_ID) { for (int j = 0; j < dobj->NumModifiers(); j++) { ModContext *mc = dobj->GetModContext(j); if (mc->localData == smd) { return TRUE; } } dobj = (IDerivedObject*)dobj->GetObjRef(); currentObject = (Object*) dobj; sc = dobj->SuperClassID(); } } int bct = currentObject->NumPipeBranches(FALSE); if (bct > 0) { for (int bi = 0; bi < bct; bi++) { Object* bobj = currentObject->GetPipeBranch(bi,FALSE); if (RecursePipeAndMatch(smd, bobj)) return TRUE; } } return FALSE; }
// --[ Method ]--------------------------------------------------------------- // // - Class : CStravaganzaMaxTools // // - prototype : Modifier* GetPhysiqueModifier(INode* pMaxNode) // // - Purpose : Returns the Physique modifier of a given node if present. // // ----------------------------------------------------------------------------- Modifier* CStravaganzaMaxTools::GetPhysiqueModifier(INode* pMaxNode) { Object* pMaxObject = pMaxNode->GetObjectRef(); if(!pMaxObject) { return NULL; } while(pMaxObject->SuperClassID() == GEN_DERIVOB_CLASS_ID && pMaxObject) { // Yes -> Cast. IDerivedObject* pMaxDerivedObject = (IDerivedObject *)(pMaxObject); // Iterate over all entries of the modifier stack. int nModStackIndex = 0; while(nModStackIndex < pMaxDerivedObject->NumModifiers()) { // Get current modifier. Modifier* pMaxModifier = pMaxDerivedObject->GetModifier(nModStackIndex); // Is this Physique? if(pMaxModifier->ClassID() == Class_ID(PHYSIQUE_CLASS_ID_A, PHYSIQUE_CLASS_ID_B)) { return pMaxModifier; } nModStackIndex++; } pMaxObject = pMaxDerivedObject->GetObjRef(); } // Not found. return NULL; }
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 HavokExport::makeHavokRigidBody(NiNodeRef parent, INode *ragdollParent, float scale) { this->scale = scale; Object *Obj = ragdollParent->GetObjectRef(); Modifier* rbMod = nullptr; Modifier* shapeMod = nullptr; Modifier* constraintMod = nullptr; SimpleObject* havokTaperCapsule = nullptr; //get modifiers while (Obj->SuperClassID() == GEN_DERIVOB_CLASS_ID) { IDerivedObject *DerObj = static_cast<IDerivedObject *> (Obj); const int nMods = DerObj->NumModifiers(); //it is really the last modifier on the stack, and not the total number of modifiers for (int i = 0; i < nMods; i++) { Modifier *Mod = DerObj->GetModifier(i); if (Mod->ClassID() == HK_RIGIDBODY_MODIFIER_CLASS_ID) { rbMod = Mod; } if (Mod->ClassID() == HK_SHAPE_MODIFIER_CLASS_ID) { shapeMod = Mod; } if (Mod->ClassID() == HK_CONSTRAINT_RAGDOLL_CLASS_ID || Mod->ClassID() == HK_CONSTRAINT_HINGE_CLASS_ID) { constraintMod = Mod; } } if (Obj->SuperClassID() == GEOMOBJECT_CLASS_ID) { havokTaperCapsule = (SimpleObject*)Obj; } Obj = DerObj->GetObjRef(); } if (!rbMod) { throw exception(FormatText("No havok rigid body modifier found on %s", ragdollParent->GetName())); } if (!shapeMod) { throw exception(FormatText("No havok shape modifier found on %s", ragdollParent->GetName())); } // Object* taper = ragdollParent->GetObjectRef(); IParamBlock2* taperParameters = Obj->GetParamBlockByID(PB_TAPEREDCAPSULE_OBJ_PBLOCK); float radius; enum { // GENERAL PROPERTIES ROLLOUT PA_TAPEREDCAPSULE_OBJ_RADIUS = 0, PA_TAPEREDCAPSULE_OBJ_TAPER, PA_TAPEREDCAPSULE_OBJ_HEIGHT, PA_TAPEREDCAPSULE_OBJ_VERSION_INTERNAL, }; taperParameters->GetValue(PA_TAPEREDCAPSULE_OBJ_RADIUS, 0, radius, FOREVER); int shapeType; if (IParamBlock2* shapeParameters = shapeMod->GetParamBlockByID(PB_SHAPE_MOD_PBLOCK)) { shapeParameters->GetValue(PA_SHAPE_MOD_SHAPE_TYPE,0,shapeType,FOREVER); } //Havok Shape bhkShapeRef shape; if (shapeType == 2) { // Capsule bhkCapsuleShapeRef capsule = new bhkCapsuleShape(); capsule->SetRadius(radius/scale); capsule->SetRadius1(radius/scale); capsule->SetRadius2(radius/scale); float length; taperParameters->GetValue(PA_TAPEREDCAPSULE_OBJ_HEIGHT, 0, length, FOREVER); //get the normal Matrix3 axis(true); ragdollParent->GetObjOffsetRot().MakeMatrix(axis); Point3 normalAx = axis.GetRow(2); //capsule center Point3 center = ragdollParent->GetObjOffsetPos(); //min and max points Point3 pt1 = center - normalAx*(length/2); Point3 pt2 = center + normalAx*(length/2); capsule->SetFirstPoint(TOVECTOR3(pt1)/scale); capsule->SetSecondPoint(TOVECTOR3(pt2)/scale); capsule->SetMaterial(HAV_MAT_SKIN); shape = StaticCast<bhkShape>(capsule); } else { // Sphere //CalcBoundingSphere(node, tm.GetTrans(), radius, 0); bhkSphereShapeRef sphere = new bhkSphereShape(); sphere->SetRadius(radius/scale); sphere->SetMaterial(HAV_MAT_SKIN); shape = StaticCast<bhkShape>(sphere); } bhkRigidBodyRef body; if (shape) { bhkBlendCollisionObjectRef blendObj = new bhkBlendCollisionObject(); body = new bhkRigidBody(); Matrix3 tm = ragdollParent->GetObjTMAfterWSM(0); //Calculate Object Offset Matrix Matrix3 otm(1); Point3 pos = ragdollParent->GetObjOffsetPos(); otm.PreTranslate(pos); Quat quat = ragdollParent->GetObjOffsetRot(); PreRotateMatrix(otm, quat); Matrix3 otmInvert = otm; otmInvert.Invert(); //correct object tm Matrix3 tmbhk = otmInvert * tm; //set geometric parameters body->SetRotation(TOQUATXYZW(Quat(tmbhk).Invert())); body->SetTranslation(TOVECTOR4(tmbhk.GetTrans() / scale)); body->SetCenter(TOVECTOR4(ragdollParent->GetObjOffsetPos())/scale); //set physics if (IParamBlock2* rbParameters = rbMod->GetParamBlockByID(PB_RB_MOD_PBLOCK)) { //These are fundamental parameters int lyr = NP_DEFAULT_HVK_LAYER; int mtl = NP_DEFAULT_HVK_MATERIAL; int msys = NP_DEFAULT_HVK_MOTION_SYSTEM; int qtype = NP_DEFAULT_HVK_QUALITY_TYPE; float mass = NP_DEFAULT_HVK_MASS; float lindamp = NP_DEFAULT_HVK_LINEAR_DAMPING; float angdamp = NP_DEFAULT_HVK_ANGULAR_DAMPING; float frict = NP_DEFAULT_HVK_FRICTION; float maxlinvel = NP_DEFAULT_HVK_MAX_LINEAR_VELOCITY; float maxangvel = NP_DEFAULT_HVK_MAX_ANGULAR_VELOCITY; float resti = NP_DEFAULT_HVK_RESTITUTION; float pendepth = NP_DEFAULT_HVK_PENETRATION_DEPTH; Point3 InertiaTensor; rbParameters->GetValue(PA_RB_MOD_MASS, 0, mass, FOREVER); rbParameters->GetValue(PA_RB_MOD_RESTITUTION, 0, resti, FOREVER); rbParameters->GetValue(PA_RB_MOD_FRICTION, 0, frict, FOREVER); rbParameters->GetValue(PA_RB_MOD_INERTIA_TENSOR, 0, InertiaTensor, FOREVER); rbParameters->GetValue(PA_RB_MOD_LINEAR_DAMPING, 0, lindamp, FOREVER); rbParameters->GetValue(PA_RB_MOD_CHANGE_ANGULAR_DAMPING, 0, angdamp, FOREVER); rbParameters->GetValue(PA_RB_MOD_MAX_LINEAR_VELOCITY, 0, maxlinvel, FOREVER); rbParameters->GetValue(PA_RB_MOD_MAX_ANGULAR_VELOCITY, 0, maxangvel, FOREVER); rbParameters->GetValue(PA_RB_MOD_ALLOWED_PENETRATION_DEPTH, 0, pendepth, FOREVER); rbParameters->GetValue(PA_RB_MOD_QUALITY_TYPE, 0, qtype, FOREVER); body->SetMass(mass); body->SetRestitution(resti); body->SetFriction(frict); body->SetLinearDamping(lindamp); body->SetMaxLinearVelocity(maxlinvel); body->SetMaxAngularVelocity(maxangvel); body->SetPenetrationDepth(pendepth); InertiaMatrix im; im[0][0] = InertiaTensor[0]; im[1][1] = InertiaTensor[1]; im[2][2] = InertiaTensor[2]; body->SetInertia(im); /*switch (qtype) { case QT_FIXED: body->SetQualityType(MO_QUAL_FIXED); break; case QT_KEYFRAMED: body->SetQualityType(MO_QUAL_KEYFRAMED); break; case QT_DEBRIS: body->SetQualityType(MO_QUAL_DEBRIS); break; case QT_MOVING: body->SetQualityType(MO_QUAL_MOVING); break; case QT_CRITICAL: body->SetQualityType(MO_QUAL_CRITICAL); break; case QT_BULLET: body->SetQualityType(MO_QUAL_BULLET); break; case QT_KEYFRAMED_REPORTING: body->SetQualityType(MO_QUAL_KEYFRAMED_REPORT); break; }*/ body->SetSkyrimLayer(SkyrimLayer::SKYL_BIPED); body->SetSkyrimLayerCopy(SkyrimLayer::SKYL_BIPED); body->SetMotionSystem(MotionSystem::MO_SYS_BOX); body->SetDeactivatorType(DeactivatorType::DEACTIVATOR_NEVER); body->SetSolverDeactivation(SolverDeactivation::SOLVER_DEACTIVATION_LOW); body->SetQualityType(MO_QUAL_FIXED); } if (constraintMod && ragdollParent->GetParentNode() && parent->GetParent()) { if (constraintMod->ClassID() == HK_CONSTRAINT_RAGDOLL_CLASS_ID) { bhkRagdollConstraintRef ragdollConstraint = new bhkRagdollConstraint(); //entities ragdollConstraint->AddEntity(body); NiNodeRef parentRef = parent->GetParent(); bhkRigidBodyRef nifParentRigidBody; while (parentRef) { if (parentRef->GetCollisionObject()) { nifParentRigidBody = StaticCast<bhkRigidBody>(StaticCast<bhkBlendCollisionObject>(parentRef->GetCollisionObject())->GetBody()); break; } parentRef = parentRef->GetParent(); } if (!nifParentRigidBody) throw exception(FormatText("Unable to find NIF constraint parent for ragdoll node %s", ragdollParent->GetName())); ragdollConstraint->AddEntity(nifParentRigidBody); RagdollDescriptor desc; //parameters if (IParamBlock2* constraintParameters = constraintMod->GetParamBlockByID(PB_CONSTRAINT_MOD_COMMON_SPACES_PARAMS)) { Point3 pivotA; Matrix3 parentRotation; Point3 pivotB; Matrix3 childRotation; constraintParameters->GetValue(PA_CONSTRAINT_MOD_CHILD_SPACE_TRANSLATION, 0, pivotB, FOREVER); constraintParameters->GetValue(PA_CONSTRAINT_MOD_CHILD_SPACE_ROTATION, 0, childRotation, FOREVER); constraintParameters->GetValue(PA_CONSTRAINT_MOD_PARENT_SPACE_TRANSLATION, 0, pivotA, FOREVER); constraintParameters->GetValue(PA_CONSTRAINT_MOD_PARENT_SPACE_ROTATION, 0, parentRotation, FOREVER); desc.pivotA = TOVECTOR4(pivotA); desc.pivotB = TOVECTOR4(pivotB); desc.planeA = TOVECTOR4(parentRotation.GetRow(0)); desc.motorA = TOVECTOR4(parentRotation.GetRow(1)); desc.twistA = TOVECTOR4(parentRotation.GetRow(2)); desc.planeB = TOVECTOR4(childRotation.GetRow(0)); desc.motorB = TOVECTOR4(childRotation.GetRow(1)); desc.twistB = TOVECTOR4(childRotation.GetRow(2)); } if (IParamBlock2* constraintParameters = constraintMod->GetParamBlockByID(PB_RAGDOLL_MOD_PBLOCK)) { float coneMaxAngle; float planeMinAngle; float planeMaxAngle; float coneMinAngle; float twistMinAngle; float maxFriction; constraintParameters->GetValue(PA_RAGDOLL_MOD_CONE_ANGLE, 0, coneMaxAngle, FOREVER); constraintParameters->GetValue(PA_RAGDOLL_MOD_PLANE_MIN, 0, planeMinAngle, FOREVER); constraintParameters->GetValue(PA_RAGDOLL_MOD_PLANE_MAX, 0, planeMaxAngle, FOREVER); constraintParameters->GetValue(PA_RAGDOLL_MOD_TWIST_MIN, 0, coneMinAngle, FOREVER); constraintParameters->GetValue(PA_RAGDOLL_MOD_TWIST_MAX, 0, twistMinAngle, FOREVER); constraintParameters->GetValue(PA_RAGDOLL_MOD_MAX_FRICTION_TORQUE, 0, maxFriction, FOREVER); desc.coneMaxAngle = TORAD(coneMaxAngle); desc.planeMinAngle = TORAD(planeMinAngle); desc.planeMaxAngle = TORAD(planeMaxAngle); desc.coneMaxAngle = TORAD(coneMinAngle); desc.twistMinAngle = TORAD(twistMinAngle); desc.maxFriction = maxFriction; } ragdollConstraint->SetRagdoll(desc); body->AddConstraint(ragdollConstraint); } else if (constraintMod->ClassID() == HK_CONSTRAINT_HINGE_CLASS_ID) { bhkLimitedHingeConstraintRef limitedHingeConstraint = new bhkLimitedHingeConstraint(); //entities limitedHingeConstraint->AddEntity(body); NiNodeRef parentRef = parent->GetParent(); bhkRigidBodyRef nifParentRigidBody; while (parentRef) { if (parentRef->GetCollisionObject()) { nifParentRigidBody = StaticCast<bhkRigidBody>(StaticCast<bhkBlendCollisionObject>(parentRef->GetCollisionObject())->GetBody()); break; } parentRef = parentRef->GetParent(); } if (!nifParentRigidBody) throw exception(FormatText("Unable to find NIF constraint parent for limited hinge node %s", ragdollParent->GetName())); limitedHingeConstraint->AddEntity(nifParentRigidBody); LimitedHingeDescriptor lh; if (IParamBlock2* constraintParameters = constraintMod->GetParamBlockByID(PB_CONSTRAINT_MOD_COMMON_SPACES_PARAMS)) { Matrix3 parentRotation; Matrix3 childRotation; constraintParameters->GetValue(PA_CONSTRAINT_MOD_CHILD_SPACE_ROTATION, 0, childRotation, FOREVER); constraintParameters->GetValue(PA_CONSTRAINT_MOD_PARENT_SPACE_ROTATION, 0, parentRotation, FOREVER); lh.perp2AxleInA1 = TOVECTOR4(parentRotation.GetRow(0)); lh.perp2AxleInA2 = TOVECTOR4(parentRotation.GetRow(1)); lh.axleA = TOVECTOR4(parentRotation.GetRow(2)); lh.perp2AxleInB1 = TOVECTOR4(childRotation.GetRow(0)); lh.perp2AxleInB2 = TOVECTOR4(childRotation.GetRow(1)); lh.axleB = TOVECTOR4(childRotation.GetRow(2)); } if (IParamBlock2* constraintParameters = constraintMod->GetParamBlockByID(PB_HINGE_MOD_PBLOCK)) { float minAngle; float maxAngle; float maxFriction; constraintParameters->GetValue(PA_HINGE_MOD_LIMIT_MIN, 0, minAngle, FOREVER); constraintParameters->GetValue(PA_HINGE_MOD_LIMIT_MAX, 0, maxAngle, FOREVER); constraintParameters->GetValue(PA_HINGE_MOD_MAX_FRICTION_TORQUE, 0, maxFriction, FOREVER); // constraintParameters->SetValue(PA_HINGE_MOD_MOTOR_TYPE, 0, lh.motor., 0); lh.minAngle = TORAD(minAngle); lh.maxAngle = TORAD(maxAngle); lh.maxAngle = maxFriction; } limitedHingeConstraint->SetLimitedHinge(lh); body->AddConstraint(limitedHingeConstraint); } } //InitializeRigidBody(body, node); body->SetShape(shape); blendObj->SetBody(StaticCast<NiObject>(body)); parent->SetCollisionObject(StaticCast<NiCollisionObject>(blendObj)); } ////rigid body parameters // // get data from node //int lyr = NP_DEFAULT_HVK_LAYER; //int mtl = NP_DEFAULT_HVK_MATERIAL; //int msys = NP_DEFAULT_HVK_MOTION_SYSTEM; //int qtype = NP_DEFAULT_HVK_QUALITY_TYPE; //float mass = NP_DEFAULT_HVK_MASS; //float lindamp = NP_DEFAULT_HVK_LINEAR_DAMPING; //float angdamp = NP_DEFAULT_HVK_ANGULAR_DAMPING; //float frict = NP_DEFAULT_HVK_FRICTION; //float maxlinvel = NP_DEFAULT_HVK_MAX_LINEAR_VELOCITY; //float maxangvel = NP_DEFAULT_HVK_MAX_ANGULAR_VELOCITY; //float resti = NP_DEFAULT_HVK_RESTITUTION; //float pendepth = NP_DEFAULT_HVK_PENETRATION_DEPTH; //BOOL transenable = TRUE; //if (IParamBlock2* rbParameters = rbMod->GetParamBlockByID(PB_SHAPE_MOD_PBLOCK)) //{ // //These are fundamental parameters // rbParameters->GetValue(PA_RB_MOD_MASS, 0, mass, FOREVER); // rbParameters->GetValue(PA_RB_MOD_RESTITUTION, 0, resti, FOREVER); // rbParameters->GetValue(PA_RB_MOD_FRICTION, 0, frict, FOREVER); // rbParameters->GetValue(PA_RB_MOD_LINEAR_DAMPING, 0, lindamp, FOREVER); // rbParameters->GetValue(PA_RB_MOD_CHANGE_ANGULAR_DAMPING, 0, angdamp, FOREVER); // rbParameters->GetValue(PA_RB_MOD_MAX_LINEAR_VELOCITY, 0, maxlinvel, FOREVER); // rbParameters->GetValue(PA_RB_MOD_MAX_ANGULAR_VELOCITY, 0, maxangvel, FOREVER); // rbParameters->GetValue(PA_RB_MOD_ALLOWED_PENETRATION_DEPTH, 0, pendepth, FOREVER); // rbParameters->GetValue(PA_RB_MOD_QUALITY_TYPE, 0, qtype, FOREVER); // switch (qtype) { // case MO_QUAL_INVALID: // break; // case QT_FIXED: // rbParameters->SetValue(PA_RB_MOD_QUALITY_TYPE, 0, MO_QUAL_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; // } // // setup body // bhkRigidBodyRef body = transenable ? new bhkRigidBodyT() : new bhkRigidBody(); // OblivionLayer obv_layer; SkyrimLayer sky_layer; // GetHavokLayersFromIndex(lyr, (int*)&obv_layer, (int*)&sky_layer); // body->SetLayer(obv_layer); // body->SetLayerCopy(obv_layer); // body->SetSkyrimLayer(sky_layer); // body->SetMotionSystem(MotionSystem(msys)); // body->SetQualityType(MotionQuality(qtype)); // body->SetMass(mass); // body->SetLinearDamping(lindamp); // body->SetAngularDamping(angdamp); // body->SetFriction(frict); // body->SetRestitution(resti); // body->SetMaxLinearVelocity(maxlinvel); // body->SetMaxAngularVelocity(maxangvel); // body->SetPenetrationDepth(pendepth); // body->SetCenter(center); // QuaternionXYZW q; q.x = q.y = q.z = 0; q.w = 1.0f; // body->SetRotation(q); //} }
static void extractTriangleGeometry( GmModel* gm, INode* node, Mesh* mesh, Mtl* material ) { #ifdef SGEXPORT_PHYSIQUE Modifier* phyMod = 0; IPhysiqueExport* phyExport = 0; IPhyContextExport* mcExport = 0; #endif Modifier* skinMod = 0; ISkin* skin = 0; String nodeName ( node->GetName() ); try { // vertex transform to left-handed system Matrix3 pivot = TmUtil::getPivotTransform( node ); Matrix3 vertexTM = pivot * s_convtm; bool insideOut = TmUtil::hasNegativeParity( pivot ); /*Matrix4x4 pm = TmUtil::toLH( vertexTM ); Debug::println( "Object {0} vertex local TM is", nodeName ); Debug::println( " {0,#.###} {1,#.###} {2,#.###} {3,#.###}", pm(0,0), pm(0,1), pm(0,2), pm(0,3) ); Debug::println( " {0,#.###} {1,#.###} {2,#.###} {3,#.###}", pm(1,0), pm(1,1), pm(1,2), pm(1,3) ); Debug::println( " {0,#.###} {1,#.###} {2,#.###} {3,#.###}", pm(2,0), pm(2,1), pm(2,2), pm(2,3) ); Debug::println( " {0,#.###} {1,#.###} {2,#.###} {3,#.###}", pm(3,0), pm(3,1), pm(3,2), pm(3,3) );*/ // add vertex positions int vertices = mesh->getNumVerts(); for ( int vi = 0 ; vi < vertices ; ++vi ) { Point3 v = vertexTM * mesh->verts[vi]; mb::Vertex* vert = gm->addVertex(); vert->setPosition( v.x, v.y, v.z ); } // add vertex weights (from Physique modifier) #ifdef SGEXPORT_PHYSIQUE phyMod = PhyExportUtil::findPhysiqueModifier( node ); if ( phyMod ) { Debug::println( " Found Physique modifier: {0}", gm->name ); // get (possibly shared) Physique export interface phyExport = (IPhysiqueExport*)phyMod->GetInterface( I_PHYINTERFACE ); if( !phyExport ) throw Exception( Format("No Physique modifier export interface") ); // export from initial pose? phyExport->SetInitialPose( false ); // get (unique) context dependent export inteface mcExport = (IPhyContextExport*)phyExport->GetContextInterface( node ); if( !mcExport ) throw Exception( Format("No Physique modifier context export interface") ); // convert to rigid for time independent vertex assignment mcExport->ConvertToRigid( true ); // allow blending to export multi-link assignments mcExport->AllowBlending( true ); // list bones Vector<INode*> bones( Allocator<INode*>(__FILE__,__LINE__) ); PhyExportUtil::listBones( mcExport, bones ); // add vertex weight maps for ( int i = 0 ; i < bones.size() ; ++i ) { INode* bone = bones[i]; String name = bone->GetName(); mb::VertexMap* vmap = gm->addVertexMap( 1, name, mb::VertexMapFormat::VERTEXMAP_WEIGHT ); PhyExportUtil::addWeights( vmap, bone, mcExport ); } } #endif // SGEXPORT_PHYSIQUE // add vertex weights (from Skin modifier) skinMod = SkinExportUtil::findSkinModifier( node ); if ( skinMod ) { skin = (ISkin*)skinMod->GetInterface(I_SKIN); require( skin ); ISkinContextData* skincx = skin->GetContextInterface( node ); require( skincx ); Debug::println( " Found Skin modifier: {0} ({1} bones, {2} points)", gm->name, skin->GetNumBones(), skincx->GetNumPoints() ); if ( skincx->GetNumPoints() != gm->vertices() ) throw Exception( Format("Only some vertices ({0}/{1}) of {2} are skinned", skincx->GetNumPoints(), gm->vertices(), gm->name) ); // list bones Vector<INode*> bones( Allocator<INode*>(__FILE__,__LINE__) ); SkinExportUtil::listBones( skin, bones ); // add vertex weight maps for ( int i = 0 ; i < bones.size() ; ++i ) { INode* bone = bones[i]; String name = bone->GetName(); mb::VertexMap* vmap = gm->addVertexMap( 1, name, mb::VertexMapFormat::VERTEXMAP_WEIGHT ); SkinExportUtil::addWeights( vmap, bone, skin, skincx ); //Debug::println( " Bone {0} is affecting {1} vertices", name, vmap->size() ); } // DEBUG: print skin node tm and initial object tm /*Matrix3 tm; int ok = skin->GetSkinInitTM( node, tm ); require( ok == SKIN_OK ); Debug::println( " NodeInitTM of {0}", nodeName ); TmUtil::println( tm, 4 ); ok = skin->GetSkinInitTM( node, tm, true ); require( ok == SKIN_OK ); Debug::println( " NodeObjectTM of {0}", nodeName ); TmUtil::println( tm, 4 );*/ // DEBUG: print bones /*Debug::println( " bones of {0}:", nodeName ); for ( int i = 0 ; i < bones.size() ; ++i ) { Debug::println( " bone ({0}): {1}", i, String(bones[i]->GetName()) ); skin->GetBoneInitTM( bones[i], tm ); Debug::println( " InitNodeTM:" ); TmUtil::println( tm, 6 ); skin->GetBoneInitTM( bones[i], tm, true ); Debug::println( " InitObjectTM:" ); TmUtil::println( tm, 6 ); }*/ // DEBUG: print bones used by the points /*for ( int i = 0 ; i < skincx->GetNumPoints() ; ++i ) { int bonec = skincx->GetNumAssignedBones(i); Debug::println( " point {0} has {1} bones", i, bonec ); for ( int k = 0 ; k < bonec ; ++k ) { int boneidx = skincx->GetAssignedBone( i, k ); float w = skincx->GetBoneWeight( i, k ); Debug::println( " point {0} boneidx ({1}): {2}, weight {3}", i, k, boneidx, w ); } }*/ } // ensure clockwise polygon vertex order int vx[3] = {2,1,0}; if ( insideOut ) { int tmp = vx[0]; vx[0] = vx[2]; vx[2] = tmp; } // list unique materials used by the triangles Vector<ShellMaterial> usedMaterials( Allocator<ShellMaterial>(__FILE__,__LINE__) ); if ( material ) { for ( int fi = 0 ; fi < mesh->getNumFaces() ; ++fi ) { Face& face = mesh->faces[fi]; int mergesubmaterial = -1; int originalsubmaterial = -1; for ( int j = 0; j < material->NumSubMtls(); ++j) { // Get Sub Material Slot name TSTR name = material->GetSubMtlSlotName(j); // Light maps are stored in sub material slot named "Baked Material" if ( strcmp( name, "Baked Material" ) == 0 ) mergesubmaterial = j; else originalsubmaterial = j; } if ( mergesubmaterial != -1 ) // A baked material was found, shell materials will be created { Mtl* mat = material->GetSubMtl( originalsubmaterial ); Mtl* bakedmtl = material->GetSubMtl( mergesubmaterial ); if ( mat->NumSubMtls() > 0 ) // Check for nested multi-material { for ( int j = 0; j < mat->NumSubMtls(); ++j) usedMaterials.add( ShellMaterial( mat->GetSubMtl( face.getMatID() % mat->NumSubMtls() ), bakedmtl ) ); } else usedMaterials.add( ShellMaterial( mat, bakedmtl ) ); } else if ( material->NumSubMtls() > 0 ) // Multi-material without baked material { usedMaterials.add( ShellMaterial( material->GetSubMtl( face.getMatID() % material->NumSubMtls() ), 0 ) ); } else // Single material without baked material { usedMaterials.add( ShellMaterial( material, 0 ) ); } } std::sort( usedMaterials.begin(), usedMaterials.end() ); usedMaterials.setSize( std::unique( usedMaterials.begin(), usedMaterials.end() ) - usedMaterials.begin() ); } // create used materials for ( int mi = 0 ; mi < usedMaterials.size() ; ++mi ) { ShellMaterial shellmtl = usedMaterials[mi]; gm->materials.add( GmUtil::createGmMaterial( shellmtl.original, shellmtl.baked ) ); } // add triangles for ( int fi = 0 ; fi < mesh->getNumFaces() ; ++fi ) { mb::Polygon* poly = gm->addPolygon(); // triangle indices Face& face = mesh->faces[fi]; for ( int vxi = 0 ; vxi < 3 ; ++vxi ) { int vi = face.v[ vx[vxi] ]; require( vi >= 0 && vi < gm->vertices() ); mb::Vertex* vert = gm->getVertex( vi ); poly->addVertex( vert ); } // triangle material int polyMaterialIndex = 0; if ( material ) { ShellMaterial mat( material, 0 ); int numsubmaterials = material->NumSubMtls(); if ( numsubmaterials > 0 ) { mat.original = material->GetSubMtl( face.getMatID() % material->NumSubMtls() ); for ( int j = 0; j < numsubmaterials; ++j) // Is baked material present? { TSTR name = material->GetSubMtlSlotName(j); if ( strcmp( name, "Baked Material" ) == 0 ) mat.baked = material->GetSubMtl( j ); if ( strcmp( name, "Original Material" ) == 0 ) mat.original = material->GetSubMtl( j ); } if ( mat.original->NumSubMtls() > 0 ) // Is there a nested multi-material? { mat.original = mat.original->GetSubMtl( face.getMatID() % mat.original->NumSubMtls() ); } } for ( int mi = 0 ; mi < usedMaterials.size() ; ++mi ) { if ( usedMaterials[mi] == mat ) { polyMaterialIndex = mi; break; } } } poly->setMaterial( polyMaterialIndex ); } // add vertex colors int mp = 0; if ( mesh->mapSupport(mp) && mesh->getNumMapVerts(mp) > 0 ) { mb::DiscontinuousVertexMap* vmad = gm->addDiscontinuousVertexMap( 3, "rgb", mb::VertexMapFormat::VERTEXMAP_RGB ); int tverts = mesh->getNumMapVerts( mp ); UVVert* tvert = mesh->mapVerts( mp ); TVFace* tface = mesh->mapFaces( mp ); //Debug::println( "Vertex colors:" ); for ( int fi = 0 ; fi < mesh->getNumFaces() ; ++fi ) { Face& face = mesh->faces[fi]; mb::Polygon* poly = gm->getPolygon( fi ); for ( int vxi = 0 ; vxi < 3 ; ++vxi ) { int vi = face.v[ vx[vxi] ]; mb::Vertex* vert = gm->getVertex( vi ); Point3 tc = tvert[ tface[fi].t[ vx[vxi] ] % tverts ]; float rgb[3] = {tc.x, tc.y, tc.z}; vmad->addValue( vert->index(), poly->index(), rgb, 3 ); //Debug::println( " vertex[{0}].rgb: {1} {2} {3}", vert->index(), rgb[0], rgb[1], rgb[2] ); } } } // add texcoord layers int lastCoords = MAX_MESHMAPS-2; while ( lastCoords > 0 && (!mesh->mapSupport(lastCoords) || 0 == mesh->getNumMapVerts(lastCoords)) ) --lastCoords; if ( lastCoords > 8 ) throw IOException( Format("Too many texture coordinate sets ({1}) in {0}", gm->name, lastCoords) ); for ( mp = 1 ; mp <= lastCoords ; ++mp ) { mb::DiscontinuousVertexMap* vmad = gm->addDiscontinuousVertexMap( 2, "uv", mb::VertexMapFormat::VERTEXMAP_TEXCOORD ); if ( mesh->mapSupport(mp) && mesh->getNumMapVerts(mp) > 0 ) { int tverts = mesh->getNumMapVerts( mp ); UVVert* tvert = mesh->mapVerts( mp ); TVFace* tface = mesh->mapFaces( mp ); for ( int fi = 0 ; fi < mesh->getNumFaces() ; ++fi ) { Face& face = mesh->faces[fi]; mb::Polygon* poly = gm->getPolygon( fi ); for ( int vxi = 0 ; vxi < 3 ; ++vxi ) { int vi = face.v[ vx[vxi] ]; mb::Vertex* vert = gm->getVertex( vi ); Point3 tc = tvert[ tface[fi].t[ vx[vxi] ] % tverts ]; float uv[2] = {tc.x, 1.f-tc.y}; vmad->addValue( vert->index(), poly->index(), uv, 2 ); } } } } // compute face vertex normals from smoothing groups require( mesh->getNumFaces() == gm->polygons() ); mb::DiscontinuousVertexMap* vmad = gm->addDiscontinuousVertexMap( 3, "vnormals", mb::VertexMapFormat::VERTEXMAP_NORMALS ); for ( int fi = 0 ; fi < gm->polygons() ; ++fi ) { mb::Polygon* poly = gm->getPolygon( fi ); require( poly ); require( poly->index() >= 0 && poly->index() < mesh->getNumFaces() ); Face& face = mesh->faces[ poly->index() ]; require( poly->vertices() == 3 ); for ( int j = 0 ; j < poly->vertices() ; ++j ) { Vector3 vn(0,0,0); mb::Vertex* vert = poly->getVertex( j ); // sum influencing normals for ( int k = 0 ; k < vert->polygons() ; ++k ) { mb::Polygon* vpoly = vert->getPolygon( k ); require( vpoly ); require( vpoly->index() >= 0 && vpoly->index() < mesh->getNumFaces() ); Face& vface = mesh->faces[ vpoly->index() ]; if ( 0 != (face.smGroup & vface.smGroup) || poly == vpoly ) { Vector3 vpolyn; vpoly->getNormal( &vpolyn.x, &vpolyn.y, &vpolyn.z ); vn += vpolyn; } } // normalize float lensqr = vn.lengthSquared(); if ( lensqr > Float::MIN_VALUE ) vn *= 1.f / Math::sqrt(lensqr); else vn = Vector3(0,0,0); vmad->addValue( vert->index(), poly->index(), vn.begin(), 3 ); } } // re-export mesh points in non-deformed pose if Skin modifier present // NOTE: 3ds Mesh must not be used after this, because collapsing can invalidate it if ( skin ) { // evaluate derived object before Skin modifier TimeValue time = 0; bool evalNext = false; bool evalDone = false; ::ObjectState os; ::Object* obj = node->GetObjectRef(); while ( obj->SuperClassID() == GEN_DERIVOB_CLASS_ID && !evalDone ) { IDerivedObject* derivedObj = static_cast<IDerivedObject*>(obj); for ( int modStack = 0 ; modStack < derivedObj->NumModifiers() ; ++modStack ) { if ( evalNext ) { os = derivedObj->Eval( time, modStack ); evalDone = true; break; } Modifier* mod = derivedObj->GetModifier(modStack); if ( mod->ClassID() == SKIN_CLASSID ) evalNext = true; } obj = derivedObj->GetObjRef(); } // evaluate possible non-derived object if ( evalNext && !evalDone ) { os = obj->Eval( time ); evalDone = true; } // convert to TriObject and get points if ( evalDone && os.obj->CanConvertToType( Class_ID(TRIOBJ_CLASS_ID,0) ) ) { Debug::println( " Evaluating object {0} before Skin modifier", nodeName ); // get TriObject std::auto_ptr<TriObject> triAutoDel(0); TriObject* tri = static_cast<TriObject*>( os.obj->ConvertToType( time, Class_ID(TRIOBJ_CLASS_ID,0) ) ); if ( tri != os.obj ) triAutoDel = std::auto_ptr<TriObject>( tri ); // get mesh points before Skin is applied //Debug::println( " Original collapsed mesh has {0} points, before Skin modifier {1} points", mesh->getNumVerts(), tri->mesh.getNumVerts() ); require( gm->vertices() == tri->mesh.getNumVerts() ); Mesh* mesh = &tri->mesh; int vertices = mesh->getNumVerts(); for ( int vi = 0 ; vi < vertices ; ++vi ) { Point3 v = vertexTM * mesh->verts[vi]; mb::Vertex* vert = gm->getVertex( vi ); vert->setPosition( v.x, v.y, v.z ); } } } // split vertices with discontinuous vertex map values for ( int vmi = 0 ; vmi < gm->discontinuousVertexMaps() ; ++vmi ) { mb::DiscontinuousVertexMap* vmad = gm->getDiscontinuousVertexMap( vmi ); gm->splitVertexDiscontinuities( vmad ); } // find base texcoord layer mb::DiscontinuousVertexMap* texcoords = 0; for ( int i = 0 ; i < gm->discontinuousVertexMaps() ; ++i ) { mb::DiscontinuousVertexMap* vmad = gm->getDiscontinuousVertexMap(i); if ( vmad->dimensions() == 2 && vmad->format() == mb::VertexMapFormat::VERTEXMAP_TEXCOORD ) { texcoords = vmad; break; } } if ( !texcoords ) Debug::printlnError( "Object {0} must have texture coordinates", gm->name ); // requires identification of footsteps in MySceneExport::isExportableGeometry //throw IOException( Format("Object {0} must have texture coordinates", gm->name) ); // optimize gm->removeUnusedVertices(); // cleanup export interfaces #ifdef SGEXPORT_PHYSIQUE if ( mcExport ) { require( phyExport ); phyExport->ReleaseContextInterface( mcExport ); mcExport = 0; } if ( phyExport ) { require( phyMod ); phyMod->ReleaseInterface( I_PHYINTERFACE, phyExport ); phyExport = 0; } #endif // SGEXPORT_PHYSIQUE if ( skin ) { skinMod->ReleaseInterface( I_SKIN, skin ); skin = 0; skinMod = 0; } } catch ( ... ) { // cleanup export interfaces #ifdef SGEXPORT_PHYSIQUE if ( mcExport ) { require( phyExport ); phyExport->ReleaseContextInterface( mcExport ); mcExport = 0; } if ( phyExport ) { require( phyMod ); phyMod->ReleaseInterface( I_PHYINTERFACE, phyExport ); phyExport = 0; } #endif // SGEXPORT_PHYSIQUE if ( skin ) { skinMod->ReleaseInterface( I_SKIN, skin ); skin = 0; skinMod = 0; } throw; } }
static INT_PTR CALLBACK UVStripDlgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_INITDIALOG: theUVStrip.Init(hWnd); TCHAR s[50]; _stprintf(s,GetString(IDS_OBJ_SELECTED),theUVStrip.ip->GetSelNodeCount()); SetWindowText(GetDlgItem(hWnd,IDC_SEL),s); break; case WM_DESTROY: theUVStrip.Destroy(hWnd); break; case WM_COMMAND: switch (LOWORD(wParam)) { case IDC_R1: { int cn = theUVStrip.ip->GetSelNodeCount(); Interval valid=FOREVER; if(cn>0) { for(int x=0;x<cn;x++) { // then osm stack Object* obj = theUVStrip.ip->GetSelNode(x)->GetObjectRef(); //check to make sure no modifiers on the object int ct = 0; SClass_ID sc; IDerivedObject* dobj; if ((sc = obj->SuperClassID()) == GEN_DERIVOB_CLASS_ID) { dobj = (IDerivedObject*)obj; while (sc == GEN_DERIVOB_CLASS_ID) { ct += dobj->NumModifiers(); dobj = (IDerivedObject*)dobj->GetObjRef(); sc = dobj->SuperClassID(); } } if ((dobj = theUVStrip.ip->GetSelNode(x)->GetWSMDerivedObject()) != NULL) { ct += dobj->NumModifiers(); } if (ct != 0) { //error message here TSTR buf2 = GetString(IDS_ERROR); TSTR buf1 = GetString(IDS_ERROR_MESH); MessageBox(hWnd,buf1,buf2,MB_ICONEXCLAMATION); } else { ObjectState os = theUVStrip.ip->GetSelNode(x)->EvalWorldState(theUVStrip.ip->GetTime()); if (os.obj && os.obj->SuperClassID() == GEOMOBJECT_CLASS_ID && os.obj->IsSubClassOf(triObjectClassID)) { Object *bobj = os.obj->FindBaseObject(); if (bobj->ClassID() ==Class_ID(EDITTRIOBJ_CLASS_ID,0)) { TriObject *T1 = (TriObject *)os.obj; T1->GetMesh().setNumTVerts(0); T1->GetMesh().setNumTVFaces(0); } else { //error message here TSTR buf2 = GetString(IDS_ERROR); TSTR buf1 = GetString(IDS_ERROR_MESH); MessageBox(hWnd,buf1,buf2,MB_ICONEXCLAMATION); } } else { //error message here TSTR buf2 = GetString(IDS_ERROR); TSTR buf1 = GetString(IDS_ERROR_MESH); MessageBox(hWnd,buf1,buf2,MB_ICONEXCLAMATION); } } theUVStrip.ip->ForceCompleteRedraw(); } } break; } case IDC_R2:{ int cn = theUVStrip.ip->GetSelNodeCount(); if(cn>0){ for(int x=0;x<cn;x++){ INode *tmp=theUVStrip.ip->GetSelNode(x); tmp->SetMtl(NULL); if(GetCheckBox(hWnd, IDC_BLANK)) tmp->SetWireColor(RGB(160,160,160)); } theUVStrip.ip->ForceCompleteRedraw(); } break;} } break; default: return FALSE; } return TRUE; }
//--------------------------------------------------------------- void ControllerList::resolveControllers( const ExportNode& exportNode ) { Object* object = exportNode.getINode()->GetObjectRef(); if ( !object ) return; if ( exportNode.getIsXRefObject() ) object = XRefFunctions::getXRefItemSource(object); if ( !object ) return; SClass_ID superClassId; IDerivedObject* derivedObject; Object *currentObject = object; //int modIdx = 0; superClassId = object->SuperClassID(); if (superClassId == GEN_DERIVOB_CLASS_ID || superClassId == DERIVOB_CLASS_ID || superClassId == WSM_DERIVOB_CLASS_ID) { derivedObject = (IDerivedObject*)object; while (superClassId == GEN_DERIVOB_CLASS_ID || superClassId == DERIVOB_CLASS_ID || superClassId == WSM_DERIVOB_CLASS_ID) { for (int modifierIndex = 0; modifierIndex < derivedObject->NumModifiers(); ++modifierIndex) { Modifier* modifier = derivedObject->GetModifier(modifierIndex); //no iskin support for xrefs // TODO needs further investigation... if ( SkinController::isSkinController(modifier) /*&& !exportNode.getIsXRefObject() */) { SkinController * skinController = new SkinController(derivedObject, modifierIndex, modifier->IsEnabled() != false); mControllers.push_back(skinController); } else if ( MorphController::isMorphController(modifier) ) { MorphController * morphController = new MorphController(derivedObject, modifierIndex, modifier->IsEnabled() != false); mControllers.push_back(morphController); } else return; } derivedObject = (IDerivedObject*) derivedObject->GetObjRef(); currentObject = (Object*) derivedObject; superClassId = derivedObject->SuperClassID(); } } /* int bct = currentObject->NumPipeBranches(FALSE); if (bct > 0) { for (int bi = 0; bi < bct; bi++) { Object* bobj = currentObject->GetPipeBranch(bi,FALSE); Resolve(bobj); return; } } */ }