void CCharacterHitBox::UpdateNodeRadiusModels() { AIASSERT( m_pHitBoxUser, m_hObject, "Called with NULL HitBoxUser" ); AIASSERT( m_hModel, m_hObject, "Called with NULL m_hModel" ); AIASSERT( m_hObject, m_hObject, "Called with NULL m_hObject" ); // Create the models if necessary... if (!m_NodeRadiusList.GetLength()) { CreateNodeRadiusModels(); } NodeRadiusStruct** pNRS = m_NodeRadiusList.GetItem(TLIT_FIRST); while (pNRS && *pNRS && (*pNRS)->hModel) { const char* szNodeName = g_pModelsDB->GetNodeName( (*pNRS)->hNode ); LTTransform resultTransform; if ( GetNodeTransform( szNodeName, resultTransform ) != false ) { g_pLTServer->SetObjectPos((*pNRS)->hModel, resultTransform.m_vPos); float fNodeRadius = GetNodeRadius((*pNRS)->hNode); g_pLTServer->SetObjectScale((*pNRS)->hModel, fNodeRadius); } pNRS = m_NodeRadiusList.GetItem(TLIT_NEXT); } }
//----------------------------------------------------------------------------------- static void ImportSceneNode(SceneImport* import, FbxNode* node, MatrixStack4x4& matrixStack, std::map<int, FbxNode*>& nodeToJointIndex) { if (node == nullptr) { return; } Matrix4x4 nodeLocalTransform = GetNodeTransform(node); matrixStack.Push(nodeLocalTransform); //New stuff! We want to load it! int attributeCount = node->GetNodeAttributeCount(); for (int attributeIndex = 0; attributeIndex < attributeCount; ++attributeIndex) { ImportNodeAttribute(import, node->GetNodeAttributeByIndex(attributeIndex), matrixStack, nodeToJointIndex); } //Import Children int childCount = node->GetChildCount(); for (int childIndex = 0; childIndex < childCount; ++childIndex) { ImportSceneNode(import, node->GetChild(childIndex), matrixStack, nodeToJointIndex); } matrixStack.Pop(); }
//------------------------------------------------------------------------------ //! InitPhysics //! Adds body to btDynamicsWorld //! tunneling방지를 위한 ccd값은 물체의 가장 큰축으로 만든 정육면체로 설정한다. void CBulletObjectAnimator::InitPhysics() { //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (physicsParams.mass != 0.0f); // calculate inertia vector btVector3 localInertia(0,0,0); if (isDynamic) collisionShape->calculateLocalInertia(physicsParams.mass, localInertia); // calculate value for ccdThreshold core::aabbox3d<f32> box = sceneNode->getBoundingBox(); core::vector3df ext = box.getExtent(); f32 ret=0; if (ext.X>ret) ret=ext.X; if (ext.Y>ret) ret=ext.Y; if (ext.Z>ret) ret=ext.Z; physicsParams.ccdThreshold = ret/2; // evaluate start transform in terms of btTransform // and set offset of center of mass btTransform startTransform, centerOfMassOffset; GetNodeTransform(sceneNode, startTransform); centerOfMassOffset.setIdentity(); centerOfMassOffset.setOrigin(btVector3(physicsParams.centerOfMassOffset.X, physicsParams.centerOfMassOffset.Y, physicsParams.centerOfMassOffset.Z)); //using motionstate is recommended, it provides interpolation capabilities, //and only synchronizes 'active' objects motionState = new btDefaultMotionState(startTransform, centerOfMassOffset); // create body /* rigidBody = new btRigidBody( physicsParams.mass, motionState, collisionShape, localInertia, physicsParams.linearDamping, physicsParams.angularDamping, physicsParams.friction, physicsParams.restitution );*/ rigidBody = new btRigidBody( physicsParams.mass, motionState, collisionShape, localInertia); rigidBody->setDamping(physicsParams.linearDamping,physicsParams.angularDamping); rigidBody->setFriction(physicsParams.friction); rigidBody->setRestitution(physicsParams.restitution); // Only do CCD if motion in one timestep (1.f/60.f) exceeds half dims //rigidBody->setCcdMotionThreshold((btScalar)(physicsParams.ccdThreshold)); //Experimental: better estimation of CCD Time of Impact: //rigidBody->setCcdSweptSphereRadius((btScalar)(.2*physicsParams.ccdThreshold)); setCCD(0,0); }
//----------------------------------------------------------------------------------- static void ImportSkeletons(SceneImport* import, FbxNode* node, MatrixStack4x4& matrixStack, Skeleton* skeleton, int parentJointIndex, std::map<int, FbxNode*>& nodeToJointIndex) { if (nullptr == node) { return; } Matrix4x4 mat = GetNodeTransform(node); matrixStack.Push(mat); //Walk the attributes, looking for doot doots. int attributeCount = node->GetNodeAttributeCount(); for (int attributeIndex = 0; attributeIndex < attributeCount; ++attributeIndex) { FbxNodeAttribute* attribute = node->GetNodeAttributeByIndex(attributeIndex); if ((attribute != nullptr) && (attribute->GetAttributeType() == FbxNodeAttribute::eSkeleton)) { //So we have a skeleton FbxSkeleton* fbxSkele = (FbxSkeleton*)attribute; Skeleton* newSkeleton = ImportSkeleton(import, matrixStack, skeleton, parentJointIndex, fbxSkele, nodeToJointIndex); //newSkeleton will either be the same skeleton passed, or a new skeleton, or no skeleton if it was a bad node. //If we got something back- it's what we p[ass on to the next generation. if (newSkeleton != nullptr) { skeleton = newSkeleton; parentJointIndex = skeleton->GetLastAddedJointIndex(); } } } //do the rest of the tree int childCount = node->GetChildCount(); for (int childIndex = 0; childIndex < childCount; ++childIndex) { ImportSkeletons(import, node->GetChild(childIndex), matrixStack, skeleton, parentJointIndex, nodeToJointIndex); } matrixStack.Pop(); }
void CCharacterHitBox::CreateNodeRadiusModels() { AIASSERT( m_pHitBoxUser, m_hObject, "Called with NULL HitBoxUser" ); AIASSERT( m_hModel, m_hObject, "Called with NULL m_hModel" ); AIASSERT( m_hObject, m_hObject, "Called with NULL m_hObject" ); if (!m_hModel) { return; } ModelsDB::HSKELETON hModelSkeleton = m_pHitBoxUser->GetModelSkeleton(); int cNodes = g_pModelsDB->GetSkeletonNumNodes(hModelSkeleton); for (int iNode = 0; iNode < cNodes; iNode++) { ModelsDB::HNODE hCurNode = g_pModelsDB->GetSkeletonNode( hModelSkeleton, iNode ); const char* szNodeName = g_pModelsDB->GetNodeName( hCurNode ); float fNodeRadius = GetNodeRadius( hCurNode ); if (fNodeRadius <= 0.0f) { continue; } if (!szNodeName) { continue; } LTTransform transform; if ( GetNodeTransform(szNodeName, transform ) == false ) { continue; } // Create the radius model... ObjectCreateStruct theStruct; theStruct.m_Pos = transform.m_vPos; theStruct.SetFileName("Models\\sphere." RESEXT_MODEL_PACKED); theStruct.SetMaterial( 0,"Materials\\Grid." RESEXT_MATERIAL ); theStruct.m_Flags = FLAG_VISIBLE; theStruct.m_ObjectType = OT_MODEL; theStruct.m_eGroup = ePhysicsGroup_NonSolid; HCLASS hClass = g_pLTServer->GetClass("BaseClass"); LPBASECLASS pModel = g_pLTServer->CreateObject(hClass, &theStruct); LTASSERT( pModel, "Failed to create BaseClass" ); if (!pModel) { return; } // Don't eat ticks please... ::SetNextUpdate(pModel->m_hObject, UPDATE_NEVER); g_pLTServer->SetObjectScale(pModel->m_hObject, fNodeRadius); NodeRadiusStruct* pNRS = debug_new(NodeRadiusStruct); pNRS->hNode = hCurNode; pNRS->hModel = pModel->m_hObject; // Add the model to our list... m_NodeRadiusList.AddTail(pNRS); } }