//This will set the formation void FormationBhvr::SetFormation(TimeValue t) { INode *node; Matrix3 tempMatrix; //Make sure that the leader is not part of the follower array.. RemoveLeaderFromFormation(t); INode *leader = GetLeader(t); if(leader==NULL) return; Matrix3 leaderPosition = GetCurrentMatrix(leader,t); leaderPosition.NoScale(); //kill any scale if we have it leaderPosition.Invert(); //it's inverted... int numDelegates = GetFollowerCount(t); //zero out the formation matrix that's used for saving it out. pblock->ZeroCount(follower_matrix1); pblock->ZeroCount(follower_matrix2); pblock->ZeroCount(follower_matrix3); pblock->ZeroCount(follower_matrix4); for(int i =0;i<numDelegates;i++) { node = GetFollower(t,i); if(node) { tempMatrix = GetCurrentMatrix(node,t); tempMatrix.NoScale(); Matrix3 leaderMat =tempMatrix*leaderPosition; AppendFollowerMatrix(t,leaderMat); //killed because matrix3 wasn't working ...pblock->Append(follower_matrix,1,&leaderMat); } else { //we still set up follower_matrix so that the counts //of the follower_matrix tab and the follower tab are equal. tempMatrix.IdentityMatrix(); AppendFollowerMatrix(t,tempMatrix); //pblock->Append(follower_matrix,1,&tempMat); } } }
Matrix3 Exporter::getObjectTransform(INode *node, TimeValue t, bool local) { Matrix3 tm = node->GetObjTMAfterWSM(t); if (local) { INode *parent = node->GetParentNode(); if (parent != NULL) { Matrix3 pm = parent->GetNodeTM(t); pm.Invert(); tm *= pm; } } return tm; }
bool CExporter::generateSkinBone(grp::SkinnedMeshExporter* skinnedMesh, INode* node, ISkin* skin) { Matrix3 mSkinOffset; if (!skin->GetSkinInitTM(node, mSkinOffset, true)) { setLastError("获取Skin偏移矩阵失败"); return false; } int iNumBone = skin->GetNumBones(); skinnedMesh->m_boneNames.resize(iNumBone); skinnedMesh->m_offsetMatrices.resize(iNumBone); for (int i = 0; i < iNumBone; ++i) { //mbs only INode* pBone = skin->GetBone(i); if (NULL == pBone) { setLastError("找不到skin依赖的骨骼"); return false; } if (ENUM_NODE_DUMMY == checkNodeType(pBone)) { char szError[1024]; ::StringCchPrintf(szError, sizeof(szError), "发现绑定到虚拟体[%s]的顶点", pBone->GetName()); setLastError(szError); return false; } wchar_t unicodeString[256]; mbstowcs(unicodeString, pBone->GetName(), 255); skinnedMesh->m_boneNames[i] = unicodeString; Matrix3 mBoneOffset; skin->GetBoneInitTM(pBone, mBoneOffset); mBoneOffset.Invert(); Matrix3 meshOffset = node->GetObjectTM(0); mBoneOffset = meshOffset * mBoneOffset; //mBoneOffset = mSkinOffset * mBoneOffset; grp::Matrix& mCore = skinnedMesh->m_offsetMatrices[i]; ::MatrixFromMatrix3(mCore, mBoneOffset); } return true; }
Matrix3 CActionExporter::get_bone_tm(CSkeletonExporter* pSkeleton,int boneIndex,unsigned int iMaxTime) { sMaxBoneNode_t bone = pSkeleton->m_MaxBones[boneIndex]; Matrix3 boneInitMTInv; if(G_MaxEnv().m_bUseBeforeSkeletonPose) boneInitMTInv = bone.m_SkinInitMT; else boneInitMTInv = bone.m_InitNodeTM0; boneInitMTInv.Invert(); INode* pNode = bone.m_pNode; Matrix3 BoneTM = boneInitMTInv * pNode->GetNodeTM(iMaxTime); //>GetNodeTM(iMaxTime); Point3 Trans = BoneTM.GetTrans(); BoneTM.NoTrans(); //对骨骼进行缩放 Trans.x *= pSkeleton->m_fScale; Trans.y *= pSkeleton->m_fScale; Trans.z *= pSkeleton->m_fScale; BoneTM.SetTrans(Trans); return BoneTM; }
//============================================================================================= NL3D::IShape *CExportNel::buildRemanence(INode& node, TimeValue time) { std::auto_ptr<CSegRemanenceShape> srs(new CSegRemanenceShape); uint numSlices = getScriptAppData (&node, NEL3D_APPDATA_REMANENCE_SLICE_NUMBER, 2); float samplingPeriod = getScriptAppData (&node, NEL3D_APPDATA_REMANENCE_SAMPLING_PERIOD, 0.02f); float rollupRatio = getScriptAppData (&node, NEL3D_APPDATA_REMANENCE_ROLLUP_RATIO, 1.f); if (samplingPeriod <= 0.f) samplingPeriod = 0.02f; if (numSlices <= 2) numSlices = 2; if (rollupRatio <= 0) rollupRatio = 1.f; srs->setNumSlices((uint32) numSlices); srs->setSliceTime(samplingPeriod); srs->setRollupRatio(rollupRatio); // get material from this node std::vector<NL3D::CMaterial> materials; CMaxMeshBaseBuild mmbb; buildMaterials(materials, mmbb, node, time); if (materials.size() != 1) { buildRemanenceError(this, node, "The remanent segment %s should have a single material"); return NULL; } srs->setMaterial(materials[0]); // // get geometry ObjectState os = node.EvalWorldState(_Ip->GetTime()); Object *obj = node.EvalWorldState(time).obj; if (obj->SuperClassID() != SHAPE_CLASS_ID) { buildRemanenceError(this, node, "Can't get curves from %s"); return NULL; } ShapeObject *so = (ShapeObject *) obj; if (so->NumberOfCurves() != 1 || so->NumberOfPieces(time, 0) == 0) { buildRemanenceError(this, node, "Remanence export : %s should only contain one curve with at least one segment!"); return NULL; } int numPieces = so->NumberOfPieces(time, 0); srs->setNumCorners(numPieces + 1); // build offset matrix Matrix3 invNodeTM = node.GetNodeTM(time); invNodeTM.Invert(); // Get the object matrix Matrix3 objectTM = node.GetObjectTM(time); // Compute the local to world matrix Matrix3 objectToLocal = objectTM*invNodeTM; for(uint k = 0; k <= (uint) numPieces; ++k) { Point3 pos; pos = (k == 0) ? so->InterpPiece3D(time, 0, 0, 0.f) : so->InterpPiece3D(time, 0, k - 1, 1.f); NLMISC::CVector nelPos; convertVector(nelPos, objectToLocal * pos); srs->setCorner(k, nelPos); } srs->setTextureShifting(CExportNel::getScriptAppData (&node, NEL3D_APPDATA_REMANENCE_SHIFTING_TEXTURE, 0) != 0); if (CExportNel::getScriptAppData (&node, NEL3D_APPDATA_EXPORT_ANIMATED_MATERIALS, 0) != 0) { srs->setAnimatedMaterial(mmbb.MaterialInfo[0].MaterialName); } // ******************************** // *** Export default transformation // ******************************** // Get the node matrix Matrix3 localTM; getLocalMatrix (localTM, node, time); // Get the translation, rotation, scale of the node CVector pos, scale; CQuat rot; decompMatrix (scale, rot, pos, localTM); // Set the default values srs->getDefaultPos()->setDefaultValue(pos); srs->getDefaultScale()->setDefaultValue(scale); srs->getDefaultRotQuat()->setDefaultValue(rot); return srs.release(); /*ObjectState os = node.EvalWorldState(_Ip->GetTime()); Object *obj = node.EvalWorldState(time).obj; TriObject *tri = (TriObject *) obj->ConvertToType(0, Class_ID(TRIOBJ_CLASS_ID, 0)); bool deleteIt=false; if (obj != tri) deleteIt = true; Mesh *pMesh = &tri->mesh; if (pMesh && pMesh->numVerts > 1) { Point3 v = pMesh->getVert(0); NLMISC::CVector minV, maxV; convertVector(minV, v); maxV = minV; for(uint k = 1; k < (uint) pMesh->numVerts; ++k) { NLMISC::CVector nv; v = pMesh->getVert(k); convertVector(nv, v); maxV.maxof(maxV, nv); minV.minof(minV, nv); } srs->setSeg(0, minV); srs->setSeg(1, maxV); } else { buildRemanenceError(this, node, "Can't get mesh from %s or empty mesh"); }*/ // }
//--------------------------------------------------------------- void ControllerExporter::exportSkinController( ExportNode* exportNode, SkinController* skinController, const String& controllerId, const String& skinSource ) { INode* iNode = exportNode->getINode(); if ( !skinController ) return; // We cannot use skin->GetContextInterface to get ISkinContextData if we are exporting an XRef, since we cannot access // the INode the object belongs to in the referenced file. To solve this problem, we temporarily create an INode, that references // the object and delete it immediately. ISkinInterface* skinInterface = getISkinInterface( exportNode, skinController ); if ( !skinInterface ) return; openSkin(controllerId, skinSource); Matrix3 bindShapeTransformationMatrix; skinInterface->getSkinInitTM(bindShapeTransformationMatrix, true); double bindShapeTransformationArray[4][4]; VisualSceneExporter::matrix3ToDouble4x4(bindShapeTransformationArray, bindShapeTransformationMatrix); addBindShapeTransform(bindShapeTransformationArray); int jointCount = skinInterface->getNumBones(); INodeList boneINodes; // Export joints source String jointsId = controllerId + JOINTS_SOURCE_ID_SUFFIX; COLLADASW::NameSource jointSource(mSW); jointSource.setId(jointsId); jointSource.setArrayId(jointsId + ARRAY_ID_SUFFIX); jointSource.setAccessorStride(1); jointSource.getParameterNameList().push_back("JOINT"); jointSource.setAccessorCount(jointCount); jointSource.prepareToAppendValues(); for (int i = 0; i < jointCount; ++i) { // there should not be any null bone. // the ISkin::GetBone, not GetBoneFlat, function is called here. INode* boneNode = skinInterface->getBone(i); assert(boneNode); boneINodes.push_back(boneNode); ExportNode* jointExportNode = mExportSceneGraph->getExportNode(boneNode); assert(jointExportNode); if ( !jointExportNode->hasSid() ) jointExportNode->setSid(mExportSceneGraph->createJointSid()); jointExportNode->setIsJoint(); jointSource.appendValues(jointExportNode->getSid()); } jointSource.finish(); determineReferencedJoints(exportNode, skinController); //export inverse bind matrix source String inverseBindMatrixId = controllerId + BIND_POSES_SOURCE_ID_SUFFIX; COLLADASW::Float4x4Source inverseBindMatrixSource(mSW); inverseBindMatrixSource.setId(inverseBindMatrixId); inverseBindMatrixSource.setArrayId(inverseBindMatrixId + ARRAY_ID_SUFFIX); inverseBindMatrixSource.setAccessorStride(16); inverseBindMatrixSource.getParameterNameList().push_back("TRANSFORM"); inverseBindMatrixSource.setAccessorCount(jointCount); inverseBindMatrixSource.prepareToAppendValues(); for (int i = 0; i < jointCount; ++i) { INode* boneNode = boneINodes[i]; Matrix3 bindPose; if ( !skinInterface->getBoneInitTM(boneNode, bindPose) ) { bindPose = VisualSceneExporter::getWorldTransform( boneNode, mDocumentExporter->getOptions().getAnimationStart() ); } bindPose.Invert(); double bindPoseArray[4][4]; VisualSceneExporter::matrix3ToDouble4x4(bindPoseArray, bindPose); inverseBindMatrixSource.appendValues(bindPoseArray); } inverseBindMatrixSource.finish(); int vertexCount = skinInterface->getNumVertices(); //count weights, excluding the ones equals one int weightsCount = 1; for (int i = 0; i < vertexCount; ++i) { int jointCount = skinInterface->getNumAssignedBones(i); for (int p = 0; p < jointCount; ++p) { float weight = skinInterface->getBoneWeight(i, p); if ( !COLLADASW::MathUtils::equals(weight, 1.0f) ) weightsCount++; } } //export weights source String weightsId = controllerId + WEIGHTS_SOURCE_ID_SUFFIX; COLLADASW::FloatSource weightsSource(mSW); weightsSource.setId(weightsId); weightsSource.setArrayId(weightsId + ARRAY_ID_SUFFIX); weightsSource.setAccessorStride(1); weightsSource.getParameterNameList().push_back("WEIGHT"); weightsSource.setAccessorCount(weightsCount); weightsSource.prepareToAppendValues(); weightsSource.appendValues(1.0); for (int i = 0; i < vertexCount; ++i) { int jointCount = skinInterface->getNumAssignedBones(i); for (int p = 0; p < jointCount; ++p) { float weight = skinInterface->getBoneWeight(i, p); if ( !COLLADASW::MathUtils::equals(weight, 1.0f) ) weightsSource.appendValues(weight); } } weightsSource.finish(); COLLADASW::JointsElement joints(mSW); joints.getInputList().push_back(COLLADASW::Input(COLLADASW::InputSemantic::JOINT, "#" + jointsId)); joints.getInputList().push_back(COLLADASW::Input(COLLADASW::InputSemantic::BINDMATRIX, "#" + inverseBindMatrixId)); joints.add(); COLLADASW::VertexWeightsElement vertexWeights(mSW); COLLADASW::Input weightInput(COLLADASW::InputSemantic::WEIGHT, "#" + weightsId); vertexWeights.getInputList().push_back(COLLADASW::Input(COLLADASW::InputSemantic::JOINT, "#" + jointsId, 0)); vertexWeights.getInputList().push_back(COLLADASW::Input(COLLADASW::InputSemantic::WEIGHT, "#" + weightsId, 1)); vertexWeights.setCount(vertexCount); vertexWeights.prepareToAppendVCountValues(); for (int i = 0; i < vertexCount; ++i) vertexWeights.appendValues(skinInterface->getNumAssignedBones(i)); vertexWeights.CloseVCountAndOpenVElement(); int currentIndex = 1; for (int i = 0; i < vertexCount; ++i) { int jointCount = skinInterface->getNumAssignedBones(i); for (int p = 0; p < jointCount; ++p) { vertexWeights.appendValues(skinInterface->getAssignedBone(i, p)); float weight = skinInterface->getBoneWeight(i, p); if ( !COLLADASW::MathUtils::equals(weight, 1.0f) ) { vertexWeights.appendValues(currentIndex++); } else { vertexWeights.appendValues(0); } } } vertexWeights.finish(); closeSkin(); skinInterface->releaseMe(); }
void MeshRenderer::DoRender( BufferIndex bufferIndex, const Matrix& modelViewMatrix, const Matrix& modelMatrix, const Matrix& viewMatrix, const Matrix& projectionMatrix, const Vector4& color ) { MeshInfo& meshInfo = mMeshInfo[bufferIndex]; Mesh* mesh = meshInfo.mesh; RenderMaterial& material = *(meshInfo.material); BoneTransforms& boneTransforms = meshInfo.boneTransforms; if( ! meshInfo.boneTransforms.transforms.empty() ) { ApplyViewToBoneTransforms( meshInfo.boneTransforms, viewMatrix ); } const int stride = sizeof(Dali::MeshData::Vertex); Dali::MeshData::Vertex *v = 0; mesh->UploadVertexData( *mContext, bufferIndex ); mesh->BindBuffers( *mContext ); GeometryType geometryType = GEOMETRY_TYPE_TEXTURED_MESH; if( ! material.HasTexture() ) { geometryType = GEOMETRY_TYPE_MESH; } GLsizei numBoneMatrices = (GLsizei)mesh->GetMeshData(Mesh::RENDER_THREAD).GetBoneCount(); // Select program type ShaderSubTypes shaderType = SHADER_DEFAULT; if( mShader->AreSubtypesRequired( geometryType ) ) { if( numBoneMatrices ) { if( mesh->GetMeshData(Mesh::RENDER_THREAD).HasColor() ) { shaderType = SHADER_RIGGED_AND_VERTEX_COLOR; } else if( mAffectedByLighting ) { shaderType = SHADER_RIGGED_AND_LIT; } else { shaderType = SHADER_RIGGED_AND_EVENLY_LIT; } } else { if( mesh->GetMeshData(Mesh::RENDER_THREAD).HasColor() ) { shaderType = SHADER_VERTEX_COLOR; } else if( ! mAffectedByLighting ) { shaderType = SHADER_EVENLY_LIT; } // else default } } if( geometryType != mGeometryType || shaderType != mShaderType ) { mGeometryType = geometryType; mShaderType = shaderType; ResetCustomUniforms(); } Program& program = mShader->Apply( *mContext, bufferIndex, geometryType, modelMatrix, viewMatrix, modelViewMatrix, projectionMatrix, color, mShaderType ); GLint location = Program::UNIFORM_UNKNOWN; GLint positionLoc = program.GetAttribLocation(Program::ATTRIB_POSITION); GLint texCoordLoc = Program::ATTRIB_UNKNOWN; GLint boneWeightsLoc = Program::ATTRIB_UNKNOWN; GLint boneIndicesLoc = Program::ATTRIB_UNKNOWN; GLint normalLoc = Program::ATTRIB_UNKNOWN; GLint colorLoc = Program::ATTRIB_UNKNOWN; mContext->VertexAttribPointer( positionLoc, 3, GL_FLOAT, GL_FALSE, stride, &v->x ); mContext->EnableVertexAttributeArray( positionLoc ); if( numBoneMatrices > 0 ) { location = mCustomUniform[ shaderType ][ 0 ].GetUniformLocation( program, "uBoneCount" ); if( Program::UNIFORM_UNKNOWN != location ) { program.SetUniform1i(location, numBoneMatrices); } location = mCustomUniform[ shaderType ][ 1 ].GetUniformLocation( program, "uBoneMatrices" ); if( Program::UNIFORM_UNKNOWN != location ) { program.SetUniformMatrix4fv(location, numBoneMatrices, boneTransforms.viewTransforms[0].AsFloat()); } if( mesh->GetMeshData(Mesh::RENDER_THREAD).HasNormals() ) { location = mCustomUniform[ shaderType ][ 2 ].GetUniformLocation( program, "uBoneMatricesIT" ); if( Program::UNIFORM_UNKNOWN != location ) { program.SetUniformMatrix3fv( location, numBoneMatrices, boneTransforms.inverseTransforms[0].AsFloat() ); } } boneWeightsLoc = program.GetAttribLocation( Program::ATTRIB_BONE_WEIGHTS ); if( Program::ATTRIB_UNKNOWN != boneWeightsLoc ) { mContext->VertexAttribPointer( boneWeightsLoc, 4, GL_FLOAT, GL_FALSE, stride, &v->boneWeights[0] ); mContext->EnableVertexAttributeArray( boneWeightsLoc ); } boneIndicesLoc = program.GetAttribLocation( Program::ATTRIB_BONE_INDICES ); if( Program::ATTRIB_UNKNOWN != boneIndicesLoc ) { mContext->VertexAttribPointer( boneIndicesLoc, 4, GL_UNSIGNED_BYTE, GL_FALSE, stride, &v->boneIndices[0] ); mContext->EnableVertexAttributeArray( boneIndicesLoc ); } } if( material.HasTexture() ) { material.BindTextures( program ); } // Always use UV's - may be being used for another purpose by a custom shader! texCoordLoc = program.GetAttribLocation(Program::ATTRIB_TEXCOORD); if( Program::ATTRIB_UNKNOWN != texCoordLoc ) { mContext->VertexAttribPointer( texCoordLoc, 2, GL_FLOAT, GL_FALSE, stride, &v->u ); mContext->EnableVertexAttributeArray( texCoordLoc ); } if( mesh->GetMeshData(Mesh::RENDER_THREAD).HasNormals() ) { normalLoc = program.GetAttribLocation(Program::ATTRIB_NORMAL); if( Program::ATTRIB_UNKNOWN != normalLoc ) { mContext->VertexAttribPointer( normalLoc, 3, GL_FLOAT, GL_FALSE, stride, &v->nX ); mContext->EnableVertexAttributeArray( normalLoc ); } } else if( mesh->GetMeshData(Mesh::RENDER_THREAD).HasColor() ) // Normals & color are mutually exclusive { colorLoc = program.GetAttribLocation(Program::ATTRIB_COLOR); if( Program::ATTRIB_UNKNOWN != colorLoc) { mContext->VertexAttribPointer( colorLoc, 3, GL_FLOAT, GL_FALSE, stride, &v->vertexR ); mContext->EnableVertexAttributeArray( colorLoc ); } } material.SetUniforms( mRenderMaterialUniforms, program, shaderType ); if( mAffectedByLighting ) { // Set light parameters location = mCustomUniform[ shaderType ][ 3 ].GetUniformLocation( program, "uNumberOfLights" ); if( Program::UNIFORM_UNKNOWN != location ) { program.SetUniform1i( location, mLightController->GetNumberOfLights() ); } // Model View IT matrix required for vertex normal lighting calculation location = mCustomUniform[ shaderType ][ 4 ].GetUniformLocation( program, "uModelViewIT" ); if( Program::UNIFORM_UNKNOWN != location ) { Matrix3 modelViewInverseTranspose = modelViewMatrix; modelViewInverseTranspose.Invert(); modelViewInverseTranspose.Transpose(); program.SetUniformMatrix3fv( location, 1, modelViewInverseTranspose.AsFloat() ); } // only one active light supported at the moment (due to performance) //if( numberOfLights > 0 ) { Vector2 tempVector2; Vector3 tempVector3; Node& lightNode = mLightController->GetLight( 0 ); LightAttachment& light = dynamic_cast< LightAttachment& >( lightNode.GetAttachment() ); location = mCustomUniform[ shaderType ][ 5 ].GetUniformLocation( program, "uLight0.mType" ); if( Program::UNIFORM_UNKNOWN != location ) { program.SetUniform1i( location, (GLint)light.GetType() ); } location = mCustomUniform[ shaderType ][ 6 ].GetUniformLocation( program, "uLight0.mFallOff" ); if( Program::UNIFORM_UNKNOWN != location ) { tempVector2 = light.GetFallOff(); program.SetUniform2f( location, tempVector2.x, tempVector2.y ); } location = mCustomUniform[ shaderType ][ 7 ].GetUniformLocation( program, "uLight0.mSpotAngle" ); if( Program::UNIFORM_UNKNOWN != location ) { tempVector2 = light.GetSpotAngle(); program.SetUniform2f( location, tempVector2.x, tempVector2.y ); } location = mCustomUniform[ shaderType ][ 8 ].GetUniformLocation( program, "uLight0.mLightPos" ); if( Program::UNIFORM_UNKNOWN != location ) { // light position in eyespace Vector3 tempVector3( viewMatrix * Vector4(lightNode.GetWorldPosition(bufferIndex)) ); program.SetUniform3f( location, tempVector3.x, tempVector3.y, tempVector3.z ); } location = mCustomUniform[ shaderType ][ 9 ].GetUniformLocation( program, "uLight0.mLightDir" ); if( Program::UNIFORM_UNKNOWN != location ) { tempVector3 = light.GetDirection(); tempVector3.Normalize(); program.SetUniform3f( location, tempVector3.x, tempVector3.y, tempVector3.z ); } location = mCustomUniform[ shaderType ][ 10 ].GetUniformLocation( program, "uLight0.mAmbient" ); if( Program::UNIFORM_UNKNOWN != location ) { tempVector3 = light.GetAmbientColor(); program.SetUniform3f( location, tempVector3.r, tempVector3.g, tempVector3.b ); } location = mCustomUniform[ shaderType ][ 11 ].GetUniformLocation( program, "uLight0.mDiffuse" ); if( Program::UNIFORM_UNKNOWN != location ) { tempVector3 = light.GetDiffuseColor(); program.SetUniform3f( location, tempVector3.r, tempVector3.g, tempVector3.b ); } location = mCustomUniform[ shaderType ][ 12 ].GetUniformLocation( program, "uLight0.mSpecular" ); if( Program::UNIFORM_UNKNOWN != location ) { tempVector3 = light.GetSpecularColor(); program.SetUniform3f( location, tempVector3.r, tempVector3.g, tempVector3.b ); } } } Dali::MeshData::VertexGeometryType vertexGeometry = mesh->GetMeshData(Mesh::RENDER_THREAD).GetVertexGeometryType(); switch( vertexGeometry ) { case Dali::MeshData::TRIANGLES: mContext->DrawElements(GL_TRIANGLES, mesh->GetFaceIndexCount(Mesh::RENDER_THREAD), GL_UNSIGNED_SHORT, 0); DRAW_ELEMENT_RECORD(mesh->GetFaceIndexCount()); break; case Dali::MeshData::LINES: mContext->DrawElements(GL_LINES, mesh->GetFaceIndexCount(Mesh::RENDER_THREAD), GL_UNSIGNED_SHORT, 0); DRAW_ELEMENT_RECORD(mesh->GetFaceIndexCount()); break; case Dali::MeshData::POINTS: mContext->DrawArrays(GL_POINTS, 0, mesh->GetFaceIndexCount(Mesh::RENDER_THREAD) ); DRAW_ARRAY_RECORD(mesh->GetFaceIndexCount()); } if( normalLoc != Program::ATTRIB_UNKNOWN ) { mContext->DisableVertexAttributeArray( normalLoc ); } if( colorLoc != Program::ATTRIB_UNKNOWN ) { mContext->DisableVertexAttributeArray( colorLoc ); } mContext->DisableVertexAttributeArray( positionLoc ); if( texCoordLoc != Program::ATTRIB_UNKNOWN ) { mContext->DisableVertexAttributeArray( texCoordLoc ); } if( boneWeightsLoc != Program::ATTRIB_UNKNOWN ) { mContext->DisableVertexAttributeArray( boneWeightsLoc ); } if( boneIndicesLoc != Program::ATTRIB_UNKNOWN ) { mContext->DisableVertexAttributeArray( boneIndicesLoc ); } return; }
Void SoftBody::_SetupPose( Bool bIsVolume, Bool bIsFrame ) { const Node * pNode; UInt iNodeIndex; // Update links EnumLinks(); Link * pLink = EnumNextLink(); while( pLink != NULL ) { pLink->UpdateConstants(); pLink = EnumNextLink(); } // Compute total mass Scalar fTotalMass = _ComputeMass(); Scalar fMassK = fTotalMass * 1000.0f * (Scalar)( GetNodeCount() ); EnumNodes(); pNode = EnumNextNode(); while( pNode != NULL ) { if ( pNode->InvMass == 0.0f ) fTotalMass += fMassK; pNode = EnumNextNode(); } Scalar fInvTotalMass = MathFn->Invert( fTotalMass ); // Flags m_hPose.bIsVolume = bIsVolume; m_hPose.bIsFrame = bIsFrame; // Weights m_hPose.arrWeights.Clear(); EnumNodes(); pNode = EnumNextNode(); while( pNode != NULL ) { if ( pNode->InvMass > 0.0f ) m_hPose.arrWeights.Push( pNode->Mass * fInvTotalMass ); else m_hPose.arrWeights.Push( fMassK * fInvTotalMass ); pNode = EnumNextNode(); } // COM m_hPose.vCenterOfMass = _ComputeCenterOfMass(); // Deltas m_hPose.arrDeltas.Clear(); EnumNodes(); pNode = EnumNextNode(); while( pNode != NULL ) { m_hPose.arrDeltas.Push( pNode->Position - m_hPose.vCenterOfMass ); pNode = EnumNextNode(); } // Volume m_hPose.fVolume = ( (bIsVolume) ? _ComputeVolume() : 0.0f ); // BaseScaling Matrix3 matBaseScaling; matBaseScaling.MakeNull(); Vector3 vTmpRow; EnumNodes(); pNode = EnumNextNode(); while( pNode != NULL ) { iNodeIndex = pNode->GetIndex(); const Vector3 & vDelta = m_hPose.arrDeltas[iNodeIndex]; const Vector3 & vWeightedDelta = ( vDelta * m_hPose.arrWeights[iNodeIndex] ); matBaseScaling.GetRow( vTmpRow, 0 ); matBaseScaling.SetRow( 0, vTmpRow + (vDelta * vWeightedDelta.X) ); matBaseScaling.GetRow( vTmpRow, 1 ); matBaseScaling.SetRow( 1, vTmpRow + (vDelta * vWeightedDelta.Y) ); matBaseScaling.GetRow( vTmpRow, 2 ); matBaseScaling.SetRow( 2, vTmpRow + (vDelta * vWeightedDelta.Z) ); pNode = EnumNextNode(); } matBaseScaling.Invert( m_hPose.matBaseScaling ); // Rotation & Scaling m_hPose.matRotation.MakeIdentity(); m_hPose.matScaling.MakeIdentity(); }
void CExportNel::addSkeletonBindPos (INode& skinedNode, mapBoneBindPos& boneBindPos) { // Return success uint ok=NoError; // Get the skin modifier Modifier* skin=getModifier (&skinedNode, SKIN_CLASS_ID); // Found it ? if (skin) { // Get a com_skin2 interface ISkin *comSkinInterface=(ISkin*)skin->GetInterface (SKIN_INTERFACE); // Should been controled with isSkin before. nlassert (comSkinInterface); // Found com_skin2 ? if (comSkinInterface) { // Get local data ISkinContextData *localData=comSkinInterface->GetContextInterface(&skinedNode); // Should been controled with isSkin before. nlassert (localData); // Found ? if (localData) { // Check same vertices count uint vertCount=localData->GetNumPoints(); // For each vertex for (uint vert=0; vert<vertCount; vert++) { // Get bones count for this vertex uint boneCount=localData->GetNumAssignedBones (vert); // For each bones for (uint bone=0; bone<boneCount; bone++) { // Get the bone id int boneId=localData->GetAssignedBone(vert, bone); // Get bone INode* INode *boneNode=comSkinInterface->GetBone(boneId); // Get the bind matrix of the bone Matrix3 bindPos; comSkinInterface->GetBoneInitTM(boneNode, bindPos); // Add an entry inthe map boneBindPos.insert (mapBoneBindPos::value_type (boneNode, bindPos)); } } } // Release the interface skin->ReleaseInterface (SKIN_INTERFACE, comSkinInterface); } } else { // Get the skin modifier Modifier* skin=getModifier (&skinedNode, PHYSIQUE_CLASS_ID); // Should been controled with isSkin before. nlassert (skin); // Found it ? if (skin) { // Get a com_skin2 interface IPhysiqueExport *physiqueInterface=(IPhysiqueExport *)skin->GetInterface (I_PHYINTERFACE); // Should been controled with isSkin before. nlassert (physiqueInterface); // Found com_skin2 ? if (physiqueInterface) { // Get local data IPhyContextExport *localData=physiqueInterface->GetContextInterface(&skinedNode); // Should been controled with isSkin before. nlassert (localData); // Found ? if (localData) { // Use rigid export localData->ConvertToRigid (TRUE); // Allow blending localData->AllowBlending (TRUE); // Check same vertices count uint vertCount=localData->GetNumberVertices(); // For each vertex for (uint vert=0; vert<vertCount; vert++) { if (vert==111) int toto=0; // Get a vertex interface IPhyVertexExport *vertexInterface=localData->GetVertexInterface (vert); // Check if it is a rigid vertex or a blended vertex int type=vertexInterface->GetVertexType (); if (type==RIGID_TYPE) { // this is a rigid vertex IPhyRigidVertex *rigidInterface=(IPhyRigidVertex*)vertexInterface; // Get bone INode* INode *bone=rigidInterface->GetNode(); // Get the bind matrix of the bone Matrix3 bindPos; int res=physiqueInterface->GetInitNodeTM (bone, bindPos); nlassert (res==MATRIX_RETURNED); // Add an entry inthe map if (boneBindPos.insert (mapBoneBindPos::value_type (bone, bindPos)).second) { #ifdef NL_DEBUG // *** Debug info // Bone name std::string boneName=getName (*bone); // Local matrix Matrix3 nodeTM; nodeTM=bone->GetNodeTM (0); // Offset matrix Matrix3 offsetScaleTM (TRUE); Matrix3 offsetRotTM (TRUE); Matrix3 offsetPosTM (TRUE); ApplyScaling (offsetScaleTM, bone->GetObjOffsetScale ()); offsetRotTM.SetRotate (bone->GetObjOffsetRot ()); offsetPosTM.SetTrans (bone->GetObjOffsetPos ()); Matrix3 offsetTM = offsetScaleTM * offsetRotTM * offsetPosTM; // Local + offset matrix Matrix3 nodeOffsetTM = offsetTM * nodeTM; // Init TM Matrix3 initTM; int res=physiqueInterface->GetInitNodeTM (bone, initTM); nlassert (res==MATRIX_RETURNED); // invert initTM.Invert(); Matrix3 compNode=nodeTM*initTM; Matrix3 compOffsetNode=nodeOffsetTM*initTM; Matrix3 compOffsetNode2=nodeOffsetTM*initTM; #endif // NL_DEBUG } } else { // It must be a blendable vertex nlassert (type==RIGID_BLENDED_TYPE); IPhyBlendedRigidVertex *blendedInterface=(IPhyBlendedRigidVertex*)vertexInterface; // For each bones uint boneIndex; uint count=(uint)blendedInterface->GetNumberNodes (); for (boneIndex=0; boneIndex<count; boneIndex++) { // Get the bone pointer INode *bone = blendedInterface->GetNode(boneIndex); if (bone == NULL) { nlwarning("bone == NULL; boneIndex = %i / %i", boneIndex, count); } else { // Get the bind matrix of the bone Matrix3 bindPos; int res = physiqueInterface->GetInitNodeTM (bone, bindPos); if (res != MATRIX_RETURNED) { nlwarning("res != MATRIX_RETURNED; res = %i; boneIndex = %i / %i", res, boneIndex, count); nlwarning("bone = %i", (uint32)(void *)bone); std::string boneName = getName (*bone); nlwarning("boneName = %s", boneName.c_str()); nlassert(false); } // Add an entry inthe map if (boneBindPos.insert (mapBoneBindPos::value_type (bone, bindPos)).second) { #ifdef NL_DEBUG // *** Debug info // Bone name std::string boneName=getName (*bone); // Local matrix Matrix3 nodeTM; nodeTM=bone->GetNodeTM (0); // Offset matrix Matrix3 offsetScaleTM (TRUE); Matrix3 offsetRotTM (TRUE); Matrix3 offsetPosTM (TRUE); ApplyScaling (offsetScaleTM, bone->GetObjOffsetScale ()); offsetRotTM.SetRotate (bone->GetObjOffsetRot ()); offsetPosTM.SetTrans (bone->GetObjOffsetPos ()); Matrix3 offsetTM = offsetScaleTM * offsetRotTM * offsetPosTM; // Local + offset matrix Matrix3 nodeOffsetTM = offsetTM * nodeTM; // Init TM Matrix3 initTM; int res=physiqueInterface->GetInitNodeTM (bone, initTM); nlassert (res==MATRIX_RETURNED); // invert initTM.Invert(); Matrix3 compNode=nodeTM*initTM; Matrix3 compOffsetNode=nodeOffsetTM*initTM; Matrix3 compOffsetNode2=nodeOffsetTM*initTM; #endif // NL_DEBUG } } } } // Release vertex interfaces localData->ReleaseVertexInterface (vertexInterface); } // Release locaData interface physiqueInterface->ReleaseContextInterface (localData); } // Release the interface skin->ReleaseInterface (SKIN_INTERFACE, physiqueInterface); } } } }
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); //} }