OBB* RagDoll::CreateBoneBox(Bone* parent, Bone *bone, D3DXVECTOR3 size, D3DXQUATERNION rot) { if (bone == NULL || parent == NULL) return NULL; D3DXMATRIX &parentMat = parent->CombinedTransformationMatrix; D3DXMATRIX &boneMat = bone->CombinedTransformationMatrix; D3DXVECTOR3 parentPos(parentMat(3, 0), parentMat(3, 1), parentMat(3, 2)); D3DXVECTOR3 bonePos(boneMat(3, 0), boneMat(3, 1), boneMat(3, 2)); D3DXQUATERNION q; D3DXVECTOR3 p, s; D3DXMatrixDecompose(&s, &q, &p, &parentMat); q *= rot; D3DXQuaternionNormalize(&q, &q); p = (parentPos + bonePos) * 0.5f; OBB *obb = new OBB(p, size, q, true); physicsEngine.GetWorld()->addRigidBody(obb->m_pBody); m_boxes.push_back(obb); parent->m_pObb = obb; parent->m_pivot = obb->SetPivot(parentPos); return obb; }
void CAnimatedGrabHandler::ProcessIKLimbs (ICharacterInstance * pCharacter) { if (m_grabStats.grabId>0 && pCharacter && m_grabStats.followBoneID>-1) { Matrix34 entMtx(m_pActor->GetEntity()->GetSlotWorldTM(0)); QuatT boneQ(pCharacter->GetISkeletonPose()->GetAbsJointByID(m_grabStats.followBoneID)); Vec3 bonePos(boneQ.t ); //static float color[] = {1,1,1,1}; //gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine(entMtx* bonePos,ColorB(255,255,0,100),entMtx * (bonePos +boneMtx * m_grabStats.grabOffset),ColorB(255,255,0,100) ); m_grabStats.followBoneWPos = entMtx * bonePos; } else m_grabStats.followBoneWPos.zero(); }
Ogre::SkeletonPtr MilkshapePlugin::doExportSkeleton(msModel* pModel, Ogre::MeshPtr& mesh) { Ogre::LogManager &logMgr = Ogre::LogManager::getSingleton(); Ogre::String msg; // // choose filename // OPENFILENAME ofn; memset (&ofn, 0, sizeof (OPENFILENAME)); char szFile[MS_MAX_PATH]; char szFileTitle[MS_MAX_PATH]; char szDefExt[32] = "skeleton"; char szFilter[128] = "OGRE .skeleton Files (*.skeleton)\0*.skeleton\0All Files (*.*)\0*.*\0\0"; szFile[0] = '\0'; szFileTitle[0] = '\0'; ofn.lStructSize = sizeof (OPENFILENAME); ofn.lpstrDefExt = szDefExt; ofn.lpstrFilter = szFilter; ofn.lpstrFile = szFile; ofn.nMaxFile = MS_MAX_PATH; ofn.lpstrFileTitle = szFileTitle; ofn.nMaxFileTitle = MS_MAX_PATH; ofn.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST; ofn.lpstrTitle = "Export to OGRE Skeleton"; if (!::GetSaveFileName (&ofn)) return Ogre::SkeletonPtr(); // Strip off the path Ogre::String skelName = szFile; size_t lastSlash = skelName.find_last_of("\\"); skelName = skelName.substr(lastSlash+1); // Set up logMgr.logMessage("Trying to create Skeleton object"); Ogre::SkeletonPtr ogreskel = Ogre::SkeletonManager::getSingleton().create(skelName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME); logMgr.logMessage("Skeleton object created"); // Complete the details // Do the bones int numBones = msModel_GetBoneCount(pModel); msg = "Number of bones: " + Ogre::StringConverter::toString(numBones); logMgr.logMessage(msg); int i; // Create all the bones in turn for (i = 0; i < numBones; ++i) { msBone* bone = msModel_GetBoneAt(pModel, i); Ogre::Bone* ogrebone = ogreskel->createBone(bone->szName); msVec3 msBonePos, msBoneRot; msBone_GetPosition(bone, msBonePos); msBone_GetRotation(bone, msBoneRot); Ogre::Vector3 bonePos(msBonePos[0], msBonePos[1], msBonePos[2]); ogrebone->setPosition(bonePos); // Hmm, Milkshape has chosen a Euler angle representation of orientation which is not smart // Rotation Matrix or Quaternion would have been the smarter choice // Might we have Gimbal lock here? What order are these 3 angles supposed to be applied? // Grr, we'll try our best anyway... Ogre::Quaternion qx, qy, qz, qfinal; qx.FromAngleAxis(Ogre::Radian(msBoneRot[0]), Ogre::Vector3::UNIT_X); qy.FromAngleAxis(Ogre::Radian(msBoneRot[1]), Ogre::Vector3::UNIT_Y); qz.FromAngleAxis(Ogre::Radian(msBoneRot[2]), Ogre::Vector3::UNIT_Z); // Assume rotate by x then y then z qfinal = qz * qy * qx; ogrebone->setOrientation(qfinal); Ogre::LogManager::getSingleton().stream() << "Bone #" << i << ": " << "Name='" << bone->szName << "' " << "Position: " << bonePos << " " << "Ms3d Rotation: {" << msBoneRot[0] << ", " << msBoneRot[1] << ", " << msBoneRot[2] << "} " << "Orientation: " << qfinal; } // Now we've created all the bones, link them up logMgr.logMessage("Establishing bone hierarchy.."); for (i = 0; i < numBones; ++i) { msBone* bone = msModel_GetBoneAt(pModel, i); if (strlen(bone->szParentName) == 0) { // Root bone msg = "Root bone detected: Name='" + Ogre::String(bone->szName) + "' Index=" + Ogre::StringConverter::toString(i); logMgr.logMessage(msg); } else { Ogre::Bone* ogrechild = ogreskel->getBone(bone->szName); Ogre::Bone* ogreparent = ogreskel->getBone(bone->szParentName); if (ogrechild == 0) { msg = "Error: could not locate child bone '" + Ogre::String(bone->szName) + "'"; logMgr.logMessage(msg); continue; } if (ogreparent == 0) { msg = "Error: could not locate parent bone '" + Ogre::String(bone->szParentName) + "'"; logMgr.logMessage(msg); continue; } // Make child ogreparent->addChild(ogrechild); } } logMgr.logMessage("Bone hierarchy established."); // Create the Animation(s) doExportAnimations(pModel, ogreskel); // Create skeleton serializer & export Ogre::SkeletonSerializer serializer; msg = "Exporting skeleton to " + Ogre::String(szFile); logMgr.logMessage(msg); serializer.exportSkeleton(ogreskel.getPointer(), szFile); logMgr.logMessage("Skeleton exported"); msg = "Linking mesh to skeleton file '" + skelName + "'"; Ogre::LogManager::getSingleton().logMessage(msg); mesh->_notifySkeleton(ogreskel); return ogreskel; }