void XModifier::NotifyPostCollapse(INode *node,Object *obj, IDerivedObject *derObj, int index) { // We don't allow a stack collapse, to delete us. // We're going to apply ourselves to the collapsed object Object *bo = node->GetObjectRef(); IDerivedObject *derob = NULL; if(bo->SuperClassID() != GEN_DERIVOB_CLASS_ID) { derob = CreateDerivedObject(obj); node->SetObjectRef(derob); } else derob = (IDerivedObject*) bo; derob->AddModifier(this,NULL,derob->NumModifiers()); bModDisabled = false; }
// We want to survive a collapsed stack so we reapply ourselves here void FaceDataToColorMod::NotifyPostCollapse(INode *node,Object *obj, IDerivedObject *derObj, int index) { BOOL collapsable; mpParams->GetValue (pb_collapsable, TimeValue(0), collapsable, FOREVER); if (collapsable) return; Object *bo = node->GetObjectRef(); IDerivedObject *derob = NULL; if(bo->SuperClassID() != GEN_DERIVOB_CLASS_ID) { derob = CreateDerivedObject(obj); node->SetObjectRef(derob); } else derob = (IDerivedObject*) bo; // Add ourselves to the top of the stack derob->AddModifier(this,NULL,derob->NumModifiers()); // Reengage modification: mDisabled = false; }
// We want to survive a collapsed stack so we reapply ourselves here void EditFaceDataMod::NotifyPostCollapse(INode *node,Object *obj, IDerivedObject *derObj, int index) { if (mCollapsable) return; Object *bo = node->GetObjectRef(); IDerivedObject *derob = NULL; if(bo->SuperClassID() != GEN_DERIVOB_CLASS_ID) { derob = CreateDerivedObject(obj); node->SetObjectRef(derob); } else derob = (IDerivedObject*) bo; // Add ourselves to the top of the stack derob->AddModifier(this,NULL,derob->NumModifiers()); // Reinsert our local mod data ModContext* mc = derob->GetModContext(derob->NumModifiers()-1); mc->localData = mpModDataCollapseCache; mpModDataCollapseCache = NULL; // Reengage modification: mDisabled = false; }
// vertex coloring bool NifImporter::ImportVertexColor(INode *tnode, TriObject *o, vector<Triangle>& tris, vector<Color4> cv, int cv_offset/*=0*/) { bool hasAlpha = false; bool hasColor = false; Mesh& mesh = o->GetMesh(); if (vertexColorMode == 1) // Bake into mesh (no Modifier) { int n = cv.size(); if (n > 0) { vector<TVFace> vcFace; int nt = tris.size(); vcFace.resize(nt); mesh.setNumVCFaces(nt); for (int i=0; i<nt; ++i) { Triangle& t = tris[i]; TVFace& vcf = vcFace[i]; vcf.setTVerts(t.v1, t.v2, t.v3); mesh.vcFace[i].setTVerts(t.v1, t.v2, t.v3); } vector<VertColor> vertColors, vertAlpha; vertColors.resize(n); vertAlpha.resize(n); mesh.setNumVertCol(cv.size()); for (int i=0; i<n; i++){ Color4& c = cv[i]; hasColor |= (c.r != 1.0f && c.g != 1.0f && c.b != 1.0f); vertColors[i] = Color(c.r,c.g,c.b); hasAlpha |= (c.a != 1.0f); vertAlpha[i] = Color(c.a,c.a,c.a); } // Add the Vertex Paint Alpha modifier now if (hasAlpha) { mesh.setMapSupport(MAP_ALPHA, TRUE); mesh.setNumMapVerts(MAP_ALPHA, n, FALSE); mesh.setNumMapFaces(MAP_ALPHA, nt, FALSE); mesh.setVCDisplayData(MAP_ALPHA, 0, 0); for (int i=0; i<nt; ++i) mesh.vcFaceData[i] = vcFace[i]; for (int i=0; i<n; ++i) mesh.vertColArray[i] = vertAlpha[i]; } // Add the Vertex Paint Color modifier now if (hasAlpha || hasColor) { mesh.setMapSupport(0, TRUE); mesh.setNumMapVerts(0, n, TRUE); mesh.setNumMapFaces(0, nt, FALSE); mesh.setVCDisplayData(0, NULL, NULL); for (int i=0; i<nt; ++i) mesh.vcFaceData[i] = vcFace[i]; for (int i=0; i<n; ++i) mesh.vertColArray[i] = vertColors[i]; } } } else if (vertexColorMode == 2) { #if VERSION_3DSMAX > ((5000<<16)+(15<<8)+0) // Version 5 int n = cv.size(); if (n > 0) { vector<Color> colorMap, alphaMap; IVertexPaint::VertColorTab vertColors, vertAlpha; vertColors.SetCount(n, TRUE); vertAlpha.SetCount(n, TRUE); colorMap.resize(n); alphaMap.resize(n); mesh.setNumVertCol(cv.size()); for (int i=0; i<n; i++){ Color4& c = cv[i]; mesh.vertCol[i].Set(c.r, c.g, c.b); hasColor |= (c.r != 1.0f && c.g != 1.0f && c.b != 1.0f); colorMap[i] = Color(c.r,c.g,c.b); vertColors[i] = &colorMap[i]; hasAlpha |= (c.a != 1.0f); alphaMap[i] = Color(c.a,c.a,c.a); vertAlpha[i] = &alphaMap[i]; } // Civ4 assumes that vcFace is filled in even if only alpha is given via color modifier if (hasColor || hasAlpha) { int n = tris.size(); mesh.setNumVCFaces(n); for (int i=0; i<n; ++i) { Triangle& t = tris[i]; TVFace& vcf = mesh.vcFace[i]; vcf.setTVerts(t.v1, t.v2, t.v3); } } // Add the Vertex Paint Color modifier now if (hasColor) { IDerivedObject *dobj = CreateDerivedObject(tnode->GetObjectRef()); Modifier * mod = (Modifier*)CreateInstance(OSM_CLASS_ID, PAINTLAYERMOD_CLASS_ID); dobj->AddModifier(mod); tnode->SetObjectRef(dobj); IVertexPaint* ivertexPaint = (IVertexPaint*)mod->GetInterface(IVERTEXPAINT_INTERFACE_ID); ObjectState os = tnode->EvalWorldState(0); IAssignVertexColors::Options o; ivertexPaint->GetOptions(o); o.mapChannel = 0; o.mixVertColors = true; ivertexPaint->SetOptions(o); ivertexPaint->SetColors(tnode, vertColors); //mod->DisableModInViews(); //mod->EnableModInViews(); } // Add the Vertex Paint Alpha modifier now if (hasAlpha) { IDerivedObject *dobj = CreateDerivedObject(tnode->GetObjectRef()); Modifier * mod = (Modifier*)CreateInstance(OSM_CLASS_ID, PAINTLAYERMOD_CLASS_ID); dobj->AddModifier(mod); tnode->SetObjectRef(dobj); IVertexPaint* ivertexPaint = (IVertexPaint*)mod->GetInterface(IVERTEXPAINT_INTERFACE_ID); ObjectState os = tnode->EvalWorldState(0); IAssignVertexColors::Options o; ivertexPaint->GetOptions(o); o.mapChannel = -2; o.mixVertColors = true; ivertexPaint->SetOptions(o); ivertexPaint->SetColors(tnode, vertAlpha); //mod->DisableModInViews(); //mod->EnableModInViews(); } } #endif } return (hasAlpha || hasColor); }
void UtilTest::MakeObject() { // Create a new object through the CreateInstance() API Object *obj = (Object*)ip->CreateInstance( GEOMOBJECT_CLASS_ID, Class_ID(CYLINDER_CLASS_ID,0)); assert(obj); // Get a hold of the parameter block IParamArray *iCylParams = obj->GetParamBlock(); assert(iCylParams); // Set the value of radius, height and segs. int rad = obj->GetParamBlockIndex(CYLINDER_RADIUS); assert(rad>=0); iCylParams->SetValue(rad,TimeValue(0),30.0f); int height = obj->GetParamBlockIndex(CYLINDER_HEIGHT); assert(height>=0); iCylParams->SetValue(height,TimeValue(0),100.0f); int segs = obj->GetParamBlockIndex(CYLINDER_SEGMENTS); assert(segs>=0); iCylParams->SetValue(segs,TimeValue(0),10); // Create a derived object that references the cylinder IDerivedObject *dobj = CreateDerivedObject(obj); // Create a bend modifier Modifier *bend = (Modifier*)ip->CreateInstance( OSM_CLASS_ID, Class_ID(BENDOSM_CLASS_ID,0)); // Set the bend angle - ParamBlock2 IParamBlock2* iBendBlock = ((Animatable*)bend)->GetParamBlock(0); //only one pblock2 assert(iBendBlock); ParamID pid = BEND_ANGLE; iBendBlock->SetValue(pid,TimeValue(0),90.0f); // Add the bend modifier to the derived object. dobj->AddModifier(bend); // Create a node in the scene that references the derived object INode *node = ip->CreateObjectNode(dobj); // Name the node and make the name unique. TSTR name(_T("MyNode")); ip->MakeNameUnique(name); node->SetName(name); // Get ready to add WSMs to this node node->CreateWSMDerivedObject(); IDerivedObject *wsdobj = node->GetWSMDerivedObject(); if (wsdobj) { WSMObject *swobj = (WSMObject*)ip->CreateInstance( WSM_OBJECT_CLASS_ID, Class_ID(SINEWAVE_OBJECT_CLASS_ID,0)); int ix; IParamArray *iRipParams = swobj->GetParamBlock(); ix = swobj->GetParamBlockIndex(RWAVE_AMPLITUDE); iRipParams->SetValue(ix,TimeValue(0),10.0f); ix = swobj->GetParamBlockIndex(RWAVE_AMPLITUDE2); iRipParams->SetValue(ix,TimeValue(0),10.0f); ix = swobj->GetParamBlockIndex(RWAVE_WAVELEN); iRipParams->SetValue(ix,TimeValue(0),40.0f); ix = swobj->GetParamBlockIndex(RWAVE_CIRCLES); iRipParams->SetValue(ix,TimeValue(0),10); ix = swobj->GetParamBlockIndex(RWAVE_DIVISIONS); iRipParams->SetValue(ix,TimeValue(0),4); ix = swobj->GetParamBlockIndex(RWAVE_SEGMENTS); iRipParams->SetValue(ix,TimeValue(0),16); INode *swnode = ip->CreateObjectNode(swobj); TSTR swname(_T("RippleNode")); ip->MakeNameUnique(swname); node->SetName(swname); // Create a Space Warp Modifier Modifier *swmod = swobj->CreateWSMMod(swnode); if (swmod) { wsdobj->AddModifier(swmod); } } // Redraw the views ip->RedrawViews(ip->GetTime()); }
void Import::ApplyModifiers (dScene& scene, const MaxNodeChache& maxNodeCache) { dScene::Iterator iter (scene); for (iter.Begin(); iter; iter ++) { dScene::dTreeNode* meshNode = iter.GetNode(); dNodeInfo* info = scene.GetInfoFromNode(meshNode); if (info->IsType(dGeometryNodeInfo::GetRttiType())) { dScene::dTreeNode* skinModifierNode = NULL; for (void* ptr = scene.GetFirstChild(meshNode); ptr; ptr = scene.GetNextChild(meshNode, ptr)) { dScene::dTreeNode* node = scene.GetNodeFromLink(ptr); dNodeInfo* info = scene.GetInfoFromNode(node); if (info->GetTypeId() == dGeometryNodeSkinModifierInfo::GetRttiType()) { skinModifierNode = node; break; } } if (skinModifierNode) { //create a skin modifier and add it Modifier* skinMod = (Modifier*) CreateInstance(OSM_CLASS_ID, SKIN_CLASSID); ISkinImportData* iskinImport = (ISkinImportData*) skinMod->GetInterface(I_SKINIMPORTDATA); INode* maxNode = maxNodeCache.Find(meshNode)->GetInfo(); _ASSERTE (maxNode); IDerivedObject *derob = NULL; Object* obj = maxNode->GetObjectRef(); if(obj->SuperClassID() != GEN_DERIVOB_CLASS_ID) { derob = CreateDerivedObject(obj); maxNode->SetObjectRef(derob); } else { derob = (IDerivedObject*) obj; } derob->AddModifier(skinMod); dGeometryNodeSkinModifierInfo* skinModifier = (dGeometryNodeSkinModifierInfo*) scene.GetInfoFromNode(skinModifierNode); dMatrix matrix (skinModifier->m_shapeBindMatrix); Matrix3 bindPoseMatrix; bindPoseMatrix.SetRow (0, *((Point3*) &matrix[0])); bindPoseMatrix.SetRow (1, *((Point3*) &matrix[1])); bindPoseMatrix.SetRow (2, *((Point3*) &matrix[2])); bindPoseMatrix.SetRow (3, *((Point3*) &matrix[3])); iskinImport->SetSkinTm(maxNode, bindPoseMatrix, bindPoseMatrix); int maxNodeCount = 0; INode* maxNodes[1024]; for (void* ptr = scene.GetFirstChild(skinModifierNode); ptr; ptr = scene.GetNextChild(skinModifierNode, ptr)) { dScene::dTreeNode* boneNode = scene.GetNodeFromLink(ptr); INode* skelBone = maxNodeCache.Find(boneNode)->GetInfo(); maxNodes[maxNodeCount] = skelBone; maxNodeCount ++; skelBone->SetBoneNodeOnOff(TRUE, 0); skelBone->BoneAsLine(TRUE); skelBone->ShowBone(1); if (iskinImport->AddBoneEx(skelBone, TRUE)) { dSceneNodeInfo* sceneNode = (dSceneNodeInfo*) scene.GetInfoFromNode(boneNode); dMatrix matrix (sceneNode->GetTransform()); Matrix3 bindPoseMatrix; bindPoseMatrix.SetRow (0, *((Point3*) &matrix[0])); bindPoseMatrix.SetRow (1, *((Point3*) &matrix[1])); bindPoseMatrix.SetRow (2, *((Point3*) &matrix[2])); bindPoseMatrix.SetRow (3, *((Point3*) &matrix[3])); iskinImport->SetBoneTm(skelBone, bindPoseMatrix, bindPoseMatrix); } } // must evaluate the node after adding bones maxNode->EvalWorldState(0); for (int i = 0; i < skinModifier->m_vertexCount; i ++) { Tab<float> weightList; Tab<INode*> boneNodeList; for (int j = 0; j < 4; j ++) { if (skinModifier->m_vertexWeights[i][j] > 1.0e-5f) { int boneIndex = skinModifier->m_boneWeightIndex[i].m_index[j]; INode *skelBone = maxNodes[boneIndex]; _ASSERTE (skelBone); boneNodeList.Append (1, &skelBone); weightList.Append (1, &skinModifier->m_vertexWeights[i][j]); } } iskinImport->AddWeights(maxNode, i, boneNodeList, weightList); } } } } }
INode* HavokImport::ImportHCTCapsule(bhkCapsuleShapeRef shape, INode *parent, INode *ragdollParent, Matrix3& tm) { USES_CONVERSION; bhkShapeRef retval; if (SimpleObject *obj = (SimpleObject *)ni.gi->CreateInstance(GEOMOBJECT_CLASS_ID, HK_TAPEREDCAPSULE_CLASS_ID)) { if (IParamBlock2* pblock2 = obj->GetParamBlockByID(PB_TAPEREDCAPSULE_OBJ_PBLOCK)) { float radius = shape->GetRadius(); int mtl = GetHavokIndexFromMaterials(ni.IsSkyrim() ? -1 : shape->GetMaterial(), ni.IsSkyrim() ? shape->GetSkyrimMaterial() : -1); float radius1 = shape->GetRadius1() * ni.bhkScaleFactor; float radius2 = shape->GetRadius2(); Vector3 pt1 = shape->GetFirstPoint(); Vector3 pt2 = shape->GetSecondPoint(); float len = (pt2 - pt1).Magnitude() * ni.bhkScaleFactor; Point3 center = (TOPOINT3(pt2 + pt1) / 2.0f) * ni.bhkScaleFactor; Point3 norm = Normalize(TOPOINT3(pt2 - pt1)); Matrix3 mat; MatrixFromNormal(norm, mat); pblock2->SetValue(PA_TAPEREDCAPSULE_OBJ_RADIUS, 0, radius1, 0); pblock2->SetValue(PA_TAPEREDCAPSULE_OBJ_HEIGHT, 0, len, 0); if (INode *n = ni.CreateImportRagdollNode(A2T(shape->GetType().GetTypeName().c_str()), obj, ragdollParent)) { PosRotScale prs = prsDefault; n->SetObjOffsetPos(parent->GetObjOffsetPos() + center); n->SetObjOffsetRot(parent->GetObjOffsetRot()*mat); Point3 pos = tm.GetTrans(); Quat rot(tm); PosRotScaleNode(n, pos, rot, 1.0, prsDefault); Object *pObj = n->GetObjectRef(); IDerivedObject *dobj = nullptr; if (pObj->SuperClassID() == GEN_DERIVOB_CLASS_ID) dobj = static_cast<IDerivedObject*>(pObj); else { dobj = CreateDerivedObject(pObj); } //Havok shape Modifier* shapeMod = (Modifier*)CreateInstance(OSM_CLASS_ID, HK_SHAPE_MODIFIER_CLASS_ID); if (IParamBlock2* shapeParameters = shapeMod->GetParamBlockByID(PB_SHAPE_MOD_PBLOCK)) { shapeParameters->SetValue(PA_SHAPE_MOD_SHAPE_TYPE, 0, 2, 0); } dobj->SetAFlag(A_LOCK_TARGET); dobj->AddModifier(shapeMod); dobj->ClearAFlag(A_LOCK_TARGET); n->SetObjectRef(dobj); return n; } } } return ragdollParent; #if 0 if (SimpleObject *ob = (SimpleObject *)ni.gi->CreateInstance(GEOMOBJECT_CLASS_ID, SCUBA_CLASS_ID)) { float radius = shape->GetRadius(); float radius1 = shape->GetRadius1(); float radius2 = shape->GetRadius2(); Point3 pt1 = TOPOINT3(shape->GetFirstPoint()); Point3 pt2 = TOPOINT3(shape->GetSecondPoint()); float height = Length(pt1 - pt2); int heighttype = 1; RefTargetHandle t = ob->GetReference(0); if (IParamBlock2* pblock2 = ob->GetParamBlockByID(0)) { pblock2->SetValue(CAPSULE_RADIUS, 0, radius); pblock2->SetValue(CAPSULE_HEIGHT, 0, height); pblock2->SetValue(CAPSULE_CENTERS, 0, heighttype); } if (INode *n = ni.CreateImportNode(shape->GetType().GetTypeName().c_str(), ob, parent)) { // Need to "Affect Pivot Only" and "Center to Object" first //n->CenterPivot(0, FALSE); // Need to reposition the Capsule so that caps are rotated correctly for pts given int mtlIdx = GetHavokIndexFromMaterial(shape->GetMaterial()); int lyrIdx = GetHavokIndexFromLayer(OL_UNIDENTIFIED); CreatebhkCollisionModifier(n, bv_type_capsule, mtlIdx, lyrIdx, 0); ImportBase(body, shape, parent, n, tm); AddShape(rbody, n); return true; } } return true; #endif }
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); }
INode* HavokImport::ImportHCTSphere(bhkSphereShapeRef shape, INode * parent, INode* ragdollParent, Matrix3 & tm) { USES_CONVERSION; bhkShapeRef retval; if (SimpleObject *obj = (SimpleObject *)ni.gi->CreateInstance(GEOMOBJECT_CLASS_ID, HK_TAPEREDCAPSULE_CLASS_ID)) { if (IParamBlock2* pblock2 = obj->GetParamBlockByID(PB_TAPEREDCAPSULE_OBJ_PBLOCK)) { float radius = shape->GetRadius(); int mtl = GetHavokIndexFromMaterials(ni.IsSkyrim() ? -1 : shape->GetMaterial(), ni.IsSkyrim() ? shape->GetSkyrimMaterial() : -1); //float radius1 = shape->GetRadius1() * ni.bhkScaleFactor; //float radius2 = shape->GetRadius2(); //Vector3 pt1 = shape->GetFirstPoint(); //Vector3 pt2 = shape->GetSecondPoint(); float len = radius * ni.bhkScaleFactor; //Point3 center = (TOPOINT3(pt2 + pt1) / 2.0f) * ni.bhkScaleFactor; //Point3 norm = Normalize(TOPOINT3(len)); //Matrix3 mat; //MatrixFromNormal(norm, mat); //Matrix3 newTM = tm * mat * TransMatrix(center); pblock2->SetValue(PA_TAPEREDCAPSULE_OBJ_RADIUS, 0, len, 0); // pblock2->SetValue(PA_TAPEREDCAPSULE_OBJ_HEIGHT, 0, 1.0, 0); if (INode *n = ni.CreateImportNode(A2T(shape->GetType().GetTypeName().c_str()), obj, ragdollParent)) { // ImportBase(body, shape, parent, n, newTM); 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())); PosRotScale prs = prsDefault; //n->SetObjOffsetScale(ScaleValue(Point3(1, 1, 1))); Point3 pos = tm.GetTrans(); Quat rot(tm); PosRotScaleNode(n, pos, rot, 1.0, prsDefault); Object *pObj = n->GetObjectRef(); IDerivedObject *dobj = nullptr; if (pObj->SuperClassID() == GEN_DERIVOB_CLASS_ID) dobj = static_cast<IDerivedObject*>(pObj); else { dobj = CreateDerivedObject(pObj); } Modifier* shapeMod = (Modifier*)CreateInstance(OSM_CLASS_ID, HK_SHAPE_MODIFIER_CLASS_ID); if (IParamBlock2* shapeParameters = shapeMod->GetParamBlockByID(PB_SHAPE_MOD_PBLOCK)) { shapeParameters->SetValue(PA_SHAPE_MOD_SHAPE_TYPE, 0, 1, 0); } dobj->SetAFlag(A_LOCK_TARGET); dobj->AddModifier(shapeMod); dobj->ClearAFlag(A_LOCK_TARGET); n->SetObjectRef(dobj); //AddShape(rbody, n); return n; } } } return ragdollParent; }
void ResetXForm::ResetNodes(const INodeTab& nodesToReset) { Interface *ip = GetCOREInterface(); for (int i = 0; i < nodesToReset.Count(); i++) { INode *node = nodesToReset[i]; if (!node || node->IsGroupMember() || node->IsGroupHead()) continue; if (SelectedAncestor(node)) continue; Matrix3 ntm, ptm, rtm(1), piv(1), tm; // Get Parent and Node TMs ntm = node->GetNodeTM(ip->GetTime()); ptm = node->GetParentTM(ip->GetTime()); // Compute the relative TM ntm = ntm * Inverse(ptm); // The reset TM only inherits position rtm.SetTrans(ntm.GetTrans()); // Set the node TM to the reset TM tm = rtm*ptm; node->SetNodeTM(ip->GetTime(), tm); // Compute the pivot TM piv.SetTrans(node->GetObjOffsetPos()); PreRotateMatrix(piv,node->GetObjOffsetRot()); ApplyScaling(piv,node->GetObjOffsetScale()); // Reset the offset to 0 node->SetObjOffsetPos(Point3(0,0,0)); node->SetObjOffsetRot(IdentQuat()); node->SetObjOffsetScale(ScaleValue(Point3(1,1,1))); // Take the position out of the matrix since we don't reset position ntm.NoTrans(); // Apply the offset to the TM ntm = piv * ntm; // Apply a derived object to the node's object Object *obj = node->GetObjectRef(); IDerivedObject *dobj = CreateDerivedObject(obj); // Create an XForm mod SimpleMod *mod = (SimpleMod*)ip->CreateInstance( OSM_CLASS_ID, Class_ID(CLUSTOSM_CLASS_ID,0)); // Apply the transformation to the mod. SetXFormPacket pckt(ntm); mod->tmControl->SetValue(ip->GetTime(),&pckt); // Add the modifier to the derived object. dobj->SetAFlag(A_LOCK_TARGET); // RB 3/11/99: When the macro recorder is on the derived object will get deleted unless it is locked. dobj->AddModifier(mod); dobj->ClearAFlag(A_LOCK_TARGET); // Replace the node's object node->SetObjectRef(dobj); } // Why on earth were we clearing the undo stack? // GetSystemSetting(SYSSET_CLEAR_UNDO); ip->RedrawViews(ip->GetTime()); SetSaveRequiredFlag(TRUE); }