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; }
//------------------------------ bool MorphControllerCreator::createMorphController( const COLLADAFW::MorphController* morphController, INode* referencingINode ) { Object* sourceObject = getObjectByUniqueId( morphController->getSource() ); if ( !sourceObject ) { // TODO handle error // morph source object not present return true; } mMorphModifier = (MorphR3*) createMaxObject(OSM_CLASS_ID, MORPHER_CLASS_ID); if ( !mMorphModifier ) { // TODO handle error // morph controller could not be created return true; } if ( (sourceObject->ClassID() == derivObjClassID) || (sourceObject->ClassID() == WSMDerivObjClassID) ) { // Object is a derived object, just attach ourselves to it mDerivedObject = (IDerivedObject*) sourceObject; } else { // Create the derived object for the target and the modifier mDerivedObject = CreateDerivedObject(sourceObject); } mDerivedObject->AddModifier(mMorphModifier); mMorphModifier->cache.MakeCache(sourceObject); const COLLADAFW::FloatOrDoubleArray& morphWeights = morphController->getMorphWeights(); const COLLADAFW::UniqueIdArray& morphTargets = morphController->getMorphTargets(); // There is a maximum number of channels supported by the 3dsMax morpher: // Calculate the number of channels to process size_t colladaTargetCount = morphTargets.getCount(); int channelCount = (int) min(colladaTargetCount, mMorphModifier->chanBank.size()); const COLLADAFW::UniqueId& morphWeightsAnimationListId = morphWeights.getAnimationList(); const COLLADAFW::AnimationList* morphWeightsAnimationList = getAnimationListByUniqueId( morphWeightsAnimationListId ); for (int i = 0; i < channelCount; ++i) { const COLLADAFW::UniqueId& targetUniqueId = morphTargets[i]; Object* targetObject = getObjectByUniqueId( targetUniqueId ); if ( !targetObject ) { // TODO handle error // the target has not been created, might be missing in dae file return true; } INodeList targetINodes; getObjectINodesByUniqueId( targetUniqueId, targetINodes ); INode* targetINode = 0; if ( !targetINodes.empty() ) { // it does not seem to make a difference which INode we use, as long as it references the correct geometry targetINode = targetINodes[0]; } morphChannel* channel = &mMorphModifier->chanBank[i]; if ( targetINode ) { channel->buildFromNode(targetINode); channel->mConnection = targetINode; } else { // Manually initializes this channel initializeChannelGeometry(channel, targetObject); } if ( !morphWeightsAnimationList ) { float weight = 0; if ( morphWeights.getType() == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_FLOAT ) { weight = (*morphWeights.getFloatValues())[i]; } else if ( morphWeights.getType() == COLLADAFW::FloatOrDoubleArray::DATA_TYPE_DOUBLE ) { weight = (float)(*morphWeights.getDoubleValues())[i]; } channel->cblock->SetValue(0, 0, weight * 100); } } if ( morphWeightsAnimationList ) { const COLLADAFW::AnimationList::AnimationBindings& animationBindings = morphWeightsAnimationList->getAnimationBindings(); for ( size_t i = 0, count = animationBindings.getCount(); i < count; ++i) { const COLLADAFW::AnimationList::AnimationBinding& animationBinding = animationBindings[i]; if ( animationBinding.animationClass != COLLADAFW::AnimationList::ARRAY_ELEMENT_1D) { // this animation does not animate one element of a one dimensional array continue; } const DocumentImporter::MaxControllerList& maxControllerList = getMaxControllerListByAnimationUniqueId( animationBinding.animation ); assert(maxControllerList.size()==1); if ( maxControllerList.size() < 1 ) { // this animation does not animate one element of a one dimensional array continue; } Control* weightController = maxControllerList[0]; size_t channelNumber = animationBinding.firstIndex; if ( (int)channelNumber >= channelCount ) { // invalid channel continue; } morphChannel* channel = &mMorphModifier->chanBank[channelNumber]; if ( !channel ) { continue; } Control* scaledWeightController = cloneController( weightController, &ConversionFunctors::toPercent); //Control* scaledWeightController = cloneController( weightController); //channel->cblock->SetController(0, weightController); channel->cblock->SetController(0, scaledWeightController); } } //assign the morph controller to all INodes referencing it INodeList referencingINodes; getObjectINodesByUniqueId( morphController->getUniqueId(), referencingINodes ); for ( size_t i = 0, count = referencingINodes.size(); i < count; ++i) { INode* referencingINode = referencingINodes[i]; referencingINode->SetObjectRef(mDerivedObject); } addUniqueIdObjectPair( morphController->getUniqueId(), mDerivedObject ); return true; }
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); iBendBlock->SetValue(BEND_ANGLE,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); }