CCal3dSceneNode.cpp

00001 #include "CCal3dSceneNode.h"
00002 
00003 #define DUMP_OFFLINE_ANIMATION false
00004 
00005 #include <fstream>
00006 #include <vector>
00007 
00013 CCal3DSceneNode::CCal3DSceneNode(const char* cf,
00014         irr::scene::ISceneNode* parent, 
00015         irr::scene::ISceneManager* mgr, irr::s32 id)
00016         :irr::scene::ISceneNode(parent,mgr,id), configFile(cf)
00017 {
00018         m_scale = 1.0f;
00019         m_blendTime = 0.05f;
00020         m_lodLevel = 1.0f;
00021         lastTick=0;
00022         m_bPaused=false;
00023         bInitialized=false;
00024         
00025         mediaPath=configFile.substr(0,configFile.find_last_of("/"));
00026         
00027         material.Wireframe=false;
00028         material.Lighting = true;
00029         //material.MaterialType=irr::video::EMT_TRANSPARENT_VERTEX_ALPHA;
00030         material.MaterialType=irr::video::EMT_SOLID;
00031         material.ZWriteEnable=true;
00032         material.BackfaceCulling=false;
00033 
00034         setDebugDataVisible(false);
00035 }
00036 
00037 
00038 
00040 CCal3DSceneNode::~CCal3DSceneNode()
00041 {
00042         delete m_calModel;
00043         delete m_calCoreModel;
00044 }
00045 
00046 
00047 
00049 // irrlicht rendering stuff
00051 
00052 void CCal3DSceneNode::OnPreRender()
00053 {
00054         if (bInitialized && IsVisible) 
00055         {
00056                 SceneManager->registerNodeForRendering(this);
00057         }
00058 
00059         irr::scene::ISceneNode::OnPreRender();
00060 }
00061 
00062 
00063 
00064 void CCal3DSceneNode::render()
00065 {
00066         
00067         if(bInitialized)
00068         {
00069                 irr::video::IVideoDriver* driver=SceneManager->getVideoDriver();
00070                 
00071                 
00072                 driver->setTransform(irr::video::ETS_WORLD, AbsoluteTransformation);
00073                 
00074                 
00075                 irr::video::S3DVertex tmp;
00076                 irr::scene::SMeshBuffer mb;
00077 
00078                 unsigned char meshColor[4]; // r g b a
00079 
00080 
00081                 // get the renderer of the model
00082                 CalRenderer *pCalRenderer;
00083                 pCalRenderer = m_calModel->getRenderer();
00084                 pCalRenderer->setNormalization(true);
00085 
00086                 if(this->DebugDataVisible)
00087                 {
00088                         irr::video::SMaterial mat;
00089                         mat.Wireframe=false;
00090                         mat.Lighting=false;
00091                         driver->setMaterial(mat);
00092                         driver->draw3DBox(Box);
00093 
00094                         CalSkeleton* pCalSkeleton = m_calModel->getSkeleton();
00095                         pCalSkeleton->calculateBoundingBoxes();
00096                         std::vector<CalBone*> &vectorCoreBone = pCalSkeleton->getVectorBone();
00097                         irr::core::aabbox3df b;
00098                         CalVector p[8];
00099                         Vector3 v[8];
00100                         
00101 
00102                         for(size_t boneId=0;boneId<vectorCoreBone.size();++boneId)
00103                         {
00104                                 CalBone* bone=vectorCoreBone[boneId];
00105                                 CalBoundingBox & calBoundingBox = bone->getBoundingBox();
00106                                 calBoundingBox.computePoints(p);
00107                                 
00108                                 for(int i=0;i<8;++i) v[i].set(p[i].x,p[i].y,p[i].z);
00109                                 
00110                                 driver->setMaterial(mat);
00111                                 // draw the box
00112                                 driver->draw3DLine(v[0],v[1],irr::video::SColor(255,0,0,255));
00113                                 driver->draw3DLine(v[0],v[2],irr::video::SColor(255,0,0,255));
00114                                 driver->draw3DLine(v[1],v[3],irr::video::SColor(255,0,0,255));
00115                                 driver->draw3DLine(v[2],v[3],irr::video::SColor(255,0,0,255));
00116                                 driver->draw3DLine(v[4],v[5],irr::video::SColor(255,0,0,255));
00117                                 driver->draw3DLine(v[4],v[6],irr::video::SColor(255,0,0,255));
00118                                 driver->draw3DLine(v[5],v[7],irr::video::SColor(255,0,0,255));
00119                                 driver->draw3DLine(v[6],v[7],irr::video::SColor(255,0,0,255));
00120                                 driver->draw3DLine(v[0],v[4],irr::video::SColor(255,0,0,255));
00121                                 driver->draw3DLine(v[1],v[5],irr::video::SColor(255,0,0,255));
00122                                 driver->draw3DLine(v[2],v[6],irr::video::SColor(255,0,0,255));
00123                                 driver->draw3DLine(v[3],v[7],irr::video::SColor(255,0,0,255));
00124                         }
00125                 }
00126 
00127                 // begin the rendering loop
00128                 if(pCalRenderer->beginRendering())
00129                 {
00130                         // get the number of meshes
00131                         int meshCount;
00132                         meshCount = pCalRenderer->getMeshCount();
00133 
00134                         // render all meshes of the model
00135                         int meshId;
00136                         for(meshId = 0; meshId < meshCount; meshId++)
00137                         {
00138                                 // get the number of submeshes
00139                                 int submeshCount;
00140                                 submeshCount = pCalRenderer->getSubmeshCount(meshId);
00141 
00142                                 // render all submeshes of the mesh
00143                                 int submeshId;
00144                                 for(submeshId = 0; submeshId < submeshCount; submeshId++)
00145                                 {
00146                                         // select mesh and submesh for further data access
00147                                         if(pCalRenderer->selectMeshSubmesh(meshId, submeshId))
00148                                         {
00149 
00150                                                 // set the material ambient color
00151                                                 pCalRenderer->getAmbientColor(&meshColor[0]);
00152                                                 material.AmbientColor.set(meshColor[3],meshColor[0],meshColor[1],meshColor[2]);
00153 
00154                                                 // set the material diffuse color
00155                                                 pCalRenderer->getDiffuseColor(&meshColor[0]);
00156                                                 material.DiffuseColor.set(meshColor[3],meshColor[0],meshColor[1],meshColor[2]);
00157 
00158                                                 // set the material specular color
00159                                                 pCalRenderer->getSpecularColor(&meshColor[0]);
00160                                                 material.SpecularColor.set(meshColor[3],meshColor[0],meshColor[1],meshColor[2]);
00161 
00162                                                 // set the material shininess factor
00163                                                 material.Shininess = pCalRenderer->getShininess();
00164 
00165                                                 // get the transformed vertices of the submesh
00166                                                 static float meshVertices[30000][3];
00167                                                 int vertexCount;
00168                                                 vertexCount = pCalRenderer->getVertices(&meshVertices[0][0]);
00169 
00170                                                 // get the transformed normals of the submesh
00171                                                 static float meshNormals[30000][3];
00172                                                 int normalsCount=pCalRenderer->getNormals(&meshNormals[0][0]);
00173 
00174                                                 // get the texture coordinates of the submesh
00175                                                 static float meshTextureCoordinates[30000][2];
00176                                                 int textureCoordinateCount;
00177                                                 textureCoordinateCount = pCalRenderer->getTextureCoordinates(0, &meshTextureCoordinates[0][0]);
00178 
00179                                                 // get the faces of the submesh
00180                                                 static CalIndex meshFaces[50000][3];
00181                                                 int faceCount =pCalRenderer->getFaces(&meshFaces[0][0]);
00182                                                 
00183                                                 if((pCalRenderer->getMapCount() > 0) && (textureCoordinateCount > 0))
00184                                                 {
00185                                                         irr::video::ITexture* t=static_cast<irr::video::ITexture*>(pCalRenderer->getMapUserData(0));
00186                                                         material.Texture1=t;
00187                                                 }
00188                                                 
00189                                                 mb.Vertices.clear();
00190                                                 for(int i=0;i<vertexCount;i++)
00191                                                 {
00192                                                         tmp.Pos.set(meshVertices[i][0],meshVertices[i][1],meshVertices[i][2]);
00193                                                         tmp.Normal.set(meshNormals[i][0],meshNormals[i][1],meshNormals[i][2]);
00194                                                         tmp.TCoords.set(meshTextureCoordinates[i][0],meshTextureCoordinates[i][1]);
00195                                                         tmp.Color=irr::video::SColor(255,255,255,255);
00196                                                         mb.Vertices.push_back(tmp);
00197                                                 }
00198 
00199                                                 mb.Indices.clear();
00200                                                 for(int i=0; i<faceCount; ++i){
00201                                                         mb.Indices.push_back(meshFaces[i][0]);
00202                                                         mb.Indices.push_back(meshFaces[i][1]);
00203                                                         mb.Indices.push_back(meshFaces[i][2]);
00204                                                 }
00205 
00206                                                 // draw 
00207                                                 driver->setMaterial(material);
00208 
00209                                                 driver->drawIndexedTriangleList(mb.Vertices.const_pointer(),
00210                                                         mb.Vertices.size(),mb.Indices.const_pointer(),faceCount);
00211                                                 
00212                                                 //CLog::GetSingleton().write(LOG_APP,"#Verts %d #Norm %d #Tex %d #Faces %d #Map %d",
00213                                                 //      vertexCount,normalsCount,textureCoordinateCount,faceCount, pCalRenderer->getMapCount());
00214                                         }
00215                                 }
00216                         }
00217 
00218                         // end the rendering
00219                         pCalRenderer->endRendering();
00220                         
00221                 }
00222         }
00223 }
00224 
00225 
00226 
00227 void CCal3DSceneNode::OnPostRender(irr::u32 timeMs)
00228 {
00229         // calculate the amount of elapsed seconds
00230         float elapsedSeconds;
00231         elapsedSeconds = (float)(timeMs - lastTick) / 1000.0f;
00232 
00233         // update the model if not paused
00234         if(!m_bPaused && lastTick!=0)
00235         {
00236                 // check if the time has come to blend to the next animation
00237                 if(m_calCoreModel->getCoreAnimationCount() > 1)
00238                 {
00239                         m_leftAnimationTime -= elapsedSeconds;
00240                         if(m_leftAnimationTime <= m_blendTime)
00241                         {
00242                                 // get the next animation
00243                                 m_currentAnimationId = (m_currentAnimationId + 1) % m_calCoreModel->getCoreAnimationCount();
00244 
00245                                 // fade in the new animation
00246                                 m_calModel->getMixer()->executeAction(m_currentAnimationId, m_leftAnimationTime, m_blendTime);
00247 
00248                                 // adjust the animation time left until next animation flip
00249                                 m_leftAnimationTime = m_calCoreModel->getCoreAnimation(m_currentAnimationId)->getDuration() - m_blendTime;
00250                         }
00251                 }
00252 
00253                 m_calModel->update(elapsedSeconds);
00254 
00255                 CalVector p[8];
00256                 m_calModel->getBoundingBox(true).computePoints(p);
00257                 Box.reset(p[0].x,p[0].y,p[0].z);
00258                 for(int i=0;i<8;++i) Box.addInternalPoint(p[i].x,p[i].y,p[i].z);
00259         }
00260 
00261         // update bones from special animation (physic etc.)
00262 
00263         // current tick will be last tick next round
00264         lastTick = timeMs;
00265 
00266         irr::scene::ISceneNode::OnPostRender(timeMs);
00267 }
00268 
00269 
00270 
00271 const irr::core::aabbox3df& CCal3DSceneNode::getBoundingBox() const
00272 {
00273         return Box;
00274 }
00275 
00276 
00277 
00279 // call 3d stuff
00281 
00285 bool CCal3DSceneNode::parseModelConfiguration(const std::string &cf)
00286 {
00287         std::string fn;
00288         // open the model configuration file
00289         std::ifstream file;
00290         file.open(cf.c_str(), std::ios::in | std::ios::binary);
00291         if(!file)
00292         {
00293                 //"Failed to open model configuration file '%s'." ,cf.c_str()
00294                 return false;
00295         }
00296 
00297         // create a core model instance
00298         m_calCoreModel = new CalCoreModel("dummy");
00299         if(!m_calCoreModel)
00300         {
00301                 // "CalError : %s",CalError::getLastErrorDescription().c_str()
00302                 return false;
00303         }
00304 
00305         // parse all lines from the model configuration file
00306         int line;
00307         for(line = 1; ; line++)
00308         {
00309                 // read the next model configuration line
00310                 std::string strBuffer;
00311                 std::getline(file, strBuffer);
00312 
00313                 // stop if we reached the end of file
00314                 if(file.eof()) break;
00315 
00316                 // check if an error happend while reading from the file
00317                 if(!file)
00318                 {
00319                         //"Error while reading from the model configuration file '%s'." ,cf.c_str()
00320                         return false;
00321                 }
00322 
00323                 // find the first non-whitespace character
00324                 std::string::size_type pos;
00325                 pos = strBuffer.find_first_not_of(" \t");
00326 
00327                 // check for empty lines
00328                 if((pos == std::string::npos) || (strBuffer[pos] == '\n') || (strBuffer[pos] == '\r') || (strBuffer[pos] == 0)) continue;
00329 
00330                 // check for comment lines
00331                 if(strBuffer[pos] == '#') continue;
00332 
00333                 // get the key
00334                 std::string strKey;
00335                 strKey = strBuffer.substr(pos, strBuffer.find_first_of(" =\t\n\r", pos) - pos);
00336                 pos += strKey.size();
00337 
00338                 // get the '=' character
00339                 pos = strBuffer.find_first_not_of(" \t", pos);
00340                 if((pos == std::string::npos) || (strBuffer[pos] != '='))
00341                 {
00342                         //"%s  (%d): Invalid syntax.",cf.c_str(),line
00343                         return false;
00344                 }
00345 
00346                 // find the first non-whitespace character after the '=' character
00347                 pos = strBuffer.find_first_not_of(" \t", pos + 1);
00348 
00349                 // get the data
00350                 std::string strData;
00351                 strData = strBuffer.substr(pos, strBuffer.find_first_of("\n\r", pos) - pos);
00352 
00353                 // handle the model creation
00354                 if(strKey == "scale")
00355                 {
00356                         // set rendering scale factor
00357                         m_scale = float(atof(strData.c_str()));
00358                 }
00359                 else if(strKey == "skeleton")
00360                 {
00361                         // load core skeleton
00362                         fn.clear(); fn=mediaPath+"/"+strData;
00363                         //"Loading skeleton '%s'...",fn.c_str()
00364                         if(!m_calCoreModel->loadCoreSkeleton(fn))
00365                         {
00366                                 //"CalError : %s",CalError::getLastErrorDescription().c_str()
00367                                 return false;
00368                         }
00369                 }
00370                 else if(strKey == "animation")
00371                 {
00372                         fn.clear(); fn=mediaPath+"/"+strData;
00373                         // load core animation
00374                         //"Loading animation '%s'...",fn.c_str()
00375                         if(m_calCoreModel->loadCoreAnimation(fn) == -1)
00376                         {
00377                                 //"CalError : %s",CalError::getLastErrorDescription().c_str()
00378                                 return false;
00379                         }
00380                 }
00381                 else if(strKey == "mesh")
00382                 {
00383                         fn.clear(); fn=mediaPath+"/"+strData;
00384                         // load core mesh
00385                         //"Loading mesh '%s'...",fn.c_str()
00386                         if(m_calCoreModel->loadCoreMesh(fn) == -1)
00387                         {
00388                                 //"CalError : %s",CalError::getLastErrorDescription().c_str()
00389                                 return false;
00390                         }
00391                 }
00392                 else if(strKey == "material")
00393                 {
00394                         fn.clear(); fn=mediaPath+"/"+strData;
00395                         // load core material
00396                         //"Loading material '%s'...",fn.c_str()
00397                         if(m_calCoreModel->loadCoreMaterial(fn) == -1)
00398                         {
00399                                 //"CalError : %s",CalError::getLastErrorDescription().c_str()
00400                                 return false;
00401                         }
00402                 }
00403                 else
00404                 {
00405                         // everything else triggers an error message, but is ignored
00406                         //"%s  (%d): Invalid syntax.",cf.c_str(),line
00407                 }
00408         }
00409 
00410         // explicitely close the file
00411         file.close();
00412 
00413         return true;
00414 }
00415 
00416 
00417 
00418 // load all textures
00419 bool CCal3DSceneNode::init()
00420 {
00421         bool ok=true;
00422 
00423         if(!parseModelConfiguration(configFile))
00424         {
00425                 bInitialized=false;
00426                 return false;
00427         }
00428 
00429         m_calCoreModel->scale(m_scale);
00430 
00431         // make one material thread for each material
00432         // NOTE: this is not the right way to do it, but this viewer can't do the right
00433         // mapping without further information on the model etc., so this is the only
00434         // thing we can do here.
00435         for(int materialId = 0; materialId < m_calCoreModel->getCoreMaterialCount(); materialId++)
00436         {
00437                 // create the a material thread
00438                 m_calCoreModel->createCoreMaterialThread(materialId);
00439 
00440                 // initialize the material thread
00441                 m_calCoreModel->setCoreMaterialId(materialId, 0, materialId);
00442         }
00443 
00444         m_calCoreModel->getCoreSkeleton()->calculateBoundingBoxes(m_calCoreModel);
00445 
00446         // load all textures and store the texture id in the corresponding map in the material
00447         for(int materialId = 0; materialId < m_calCoreModel->getCoreMaterialCount(); materialId++)
00448         {
00449                 // get the core material
00450                 CalCoreMaterial *pCoreMaterial;
00451                 pCoreMaterial = m_calCoreModel->getCoreMaterial(materialId);
00452 
00453                 // loop through all maps of the core material
00454                 int mapId;
00455                 for(mapId = 0; mapId < pCoreMaterial->getMapCount(); mapId++)
00456                 {
00457                         // get the filename of the texture
00458                         std::string fn=mediaPath+"/"+pCoreMaterial->getMapFilename(mapId);
00459                         
00460                         // load the texture from the file
00461                         irr::video::ITexture* texture=SceneManager->getVideoDriver()->getTexture(fn.c_str());
00462                         if(texture)
00463                         {
00464                                 // store the texture id in the user data of the map
00465                                 pCoreMaterial->setMapUserData(mapId, (Cal::UserData)texture);
00466                         }
00467                         else
00468                         {
00469                                 ok=false;
00470                                 //"Loading texture '%s' failed.",fn.c_str()
00471                         }
00472 
00473                 }
00474         }
00475 
00476         // create the model instance from the loaded core model
00477         m_calModel = new CalModel(m_calCoreModel);
00478         if(!m_calModel)
00479         {
00480                 //"CalError : %s",CalError::getLastErrorDescription().c_str()
00481                 return false;
00482         }
00483 
00484         // attach all meshes to the model
00485         int meshId;
00486         for(meshId = 0; meshId < m_calCoreModel->getCoreMeshCount(); meshId++)
00487         {
00488                 m_calModel->attachMesh(meshId);
00489         }
00490         // set the material set of the whole model
00491         m_calModel->setMaterialSet(0);
00492 
00493         // set initial animation state
00494         if(m_calCoreModel->getCoreAnimationCount() > 0)
00495         {
00496                 m_currentAnimationId = 0;
00497                 m_leftAnimationTime = m_calCoreModel->getCoreAnimation(m_currentAnimationId)->getDuration() - m_blendTime;
00498                 if(m_calCoreModel->getCoreAnimationCount() > 1)
00499                 {
00500                         m_calModel->getMixer()->executeAction(m_currentAnimationId, 0.0f, m_blendTime);
00501                 }
00502                 else
00503                 {
00504                         m_calModel->getMixer()->blendCycle(m_currentAnimationId, 1.0f, 0.0f);
00505                 }
00506         }
00507         else
00508         {
00509                 m_currentAnimationId = -1;
00510                 m_leftAnimationTime = -1.0f;
00511         }
00512 
00513         m_calModel->setLodLevel(m_lodLevel);
00514         m_calModel->update(0);
00515 
00516         // calculate the irrlicht bounding box
00517         CalVector p[8];
00518         m_calModel->getBoundingBox(true).computePoints(p);
00519         Box.reset(p[0].x,p[0].y,p[0].z);
00520         for(int i=0;i<8;++i) Box.addInternalPoint(p[i].x,p[i].y,p[i].z);
00521 
00522         //"Init done."
00523         bInitialized=ok;
00524         
00525         return ok;
00526 }
00527 
00529 // dragon stuff
00531 
00532 void CCal3DSceneNode::moveBone(int boneID, CalQuaternion& direction)
00533 {
00534         if (! DUMP_OFFLINE_ANIMATION)
00535         {
00536                 CalQuaternion oldPos;
00537                 CalQuaternion newPos;
00538                 oldPos = getCoreBoneRotation(boneID);
00539                 newPos.w = oldPos.w + direction.w;
00540                 newPos.x = oldPos.x + direction.x;
00541                 newPos.y = oldPos.y + direction.y;
00542                 newPos.z = oldPos.z + direction.z;
00543                 setBoneRotation(boneID, newPos);
00544         }
00545         else
00546         {
00547                 dumpBoneQaternion(boneID);
00548         }
00549 }
00550 
00551 CalQuaternion CCal3DSceneNode::getCoreBoneRotation(int boneID)
00552 {
00553         CalQuaternion q(0,0,0,0);
00554         q = m_calCoreModel->getCoreSkeleton()->getCoreBone(boneID)->getRotation();
00555         
00556         return q;
00557 }
00558 
00559 CalQuaternion CCal3DSceneNode::getBoneRotation(int boneID)
00560 {
00561         CalQuaternion q(0,0,0,0);
00562         q = m_calModel->getSkeleton()->getBone(boneID)->getRotation();
00563         
00564         return q;
00565 }
00566 
00567 void CCal3DSceneNode::setBoneRotation(int boneID, CalQuaternion& newRotation)
00568 {
00569         //m_calCoreModel->getCoreSkeleton()->getCoreBone(boneID)->setRotation(newRotation);
00570         m_calModel->getSkeleton()->getBone(boneID)->setRotation(newRotation);
00571         m_calModel->getSkeleton()->calculateState();
00572 }
00573 
00574 void CCal3DSceneNode::dumpBoneQaternion(int boneID)
00575 {
00576         CalQuaternion q(0,0,0,0);
00577         //q = m_calCoreModel->getCoreSkeleton()->getCoreBone(boneID)->getRotation();
00578         q = m_calModel->getSkeleton()->getBone(boneID)->getRotation();
00579         
00580         //debug:
00581         std::cout << "getBoneRotation("<<boneID<<") q: x="<<q.x<<" y="<<q.y<<" z="<<q.z<<" w="<<q.w<<std::endl;
00582 
00583 }
00584 
00585 float CCal3DSceneNode::quaternionGetMagnitude(CalQuaternion qIn)
00586 {
00587         /*
00588         How do I calculate the magnitude of a quaternion?
00589         The magnitude of a quaternion is calculated by multiplying the
00590         quaternion with its conjugate ie:
00591 
00592                                  ------------
00593                                 /       --
00594           |Qr| =  \/     Qr.Qr
00595 
00596         */
00597     return( sqrt(qIn.w*qIn.w + qIn.x*qIn.x + qIn.y*qIn.y + qIn.z*qIn.z) );
00598 
00599 }
00600 
00601 void CCal3DSceneNode::quaternionNormalize(CalQuaternion& qInOut)
00602 {
00603         /*
00604         How do I normalise a quaternion?
00605         A quaternion can be normalised in a way similar to vectors. The
00606         magnitude of the quaternion is calculated first. Then both the
00607         scalar and vector part of the quaternion are divided by this value.
00608         A unit quaternion will always have a magnitude of 1.0
00609         */
00610         float magnitude = quaternionGetMagnitude(qInOut);
00611         qInOut.x = qInOut.x / magnitude;
00612         qInOut.y = qInOut.y / magnitude;
00613         qInOut.z = qInOut.z / magnitude;
00614         qInOut.w = qInOut.w / magnitude;
00615 }
00616 
00617 void CCal3DSceneNode::quaternionToAxisAndAngle(CalQuaternion qIn, CalVector& vOut, float& aOut)
00618 {
00619     /* 
00620         How do I convert a quaternion to a rotation axis and angle?
00621         A quaternion can be converted back to a rotation axis and angle
00622         using the following algorithm:
00623  
00624         quaternion_normalise( qr );
00625 
00626     cos_angle  = qr -> qw;
00627     angle      = acos( cos_angle ) * 2 * RADIANS;
00628     sin_angle  = sqrt( 1.0 - cos_angle * cos_angle );
00629 
00630     if ( fabs( sin_angle ) < 0.0005 )
00631       sa = 1;
00632 
00633     axis -> vx = qr -> qx / sa;
00634     axis -> vy = qr -> qy / sa;
00635     axis -> vz = qr -> qz / sa;
00636         */
00637 
00638         /*
00639         quaternionNormalize(qIn);
00640 
00641         float cosAngle = qIn.w;
00642         float angle = acos(cosAngle) * 2 * ( ( 2 * 3.14159265f ) / 360 );
00643         float sinAngle = sqrt( 1.0f - cosAngle * cosAngle );
00644 
00645         if ( fabs( sinAngle ) < 0.0005 )
00646                 sinAngle = 1.0f;
00647 
00648         vOut.x = qIn.x / sinAngle;
00649         vOut.y = qIn.y / sinAngle;
00650         vOut.z = qIn.z / sinAngle;
00651         */
00652 
00653         float s = qIn.x*qIn.x + qIn.y*qIn.y + qIn.z*qIn.z;
00654         vOut.x = qIn.x / s;
00655         vOut.y = qIn.y / s;
00656         vOut.z = qIn.z / s;
00657         aOut = 2 * acos(qIn.w);
00658 }
00659 
00660 // CalQuaternion qOut will represent a vector (x,y,z) and an angel (w) of qIn
00661 void CCal3DSceneNode::quaternionToAxisAndAngle(CalQuaternion qIn, CalQuaternion& qOut)
00662 {
00663         CalVector v;
00664         float angle;
00665 
00666         quaternionToAxisAndAngle(qIn, v, angle);
00667 
00668         qOut.x = v.x;
00669         qOut.y = v.y;
00670         qOut.z = v.z;
00671         qOut.x = angle;
00672 
00673 }
00674 
00675 

Generated on Sun Dec 2 18:30:26 2007 for DrgonWings by  doxygen 1.5.4