lugre_gfx3D.cpp

Go to the documentation of this file.
00001 #include "lugre_prefix.h"
00002 #include "lugre_game.h"
00003 #include "lugre_gfx3D.h"
00004 #include "lugre_scripting.h"
00005 #include "lugre_robstring.h"
00006 //#include "GhoulPrimitives.h"
00007 #include "lugre_robrenderable.h"
00008 #include <Ogre.h>
00009 #include <OgreTagPoint.h>
00010 #include <math.h>
00011 #include <vector>
00012 #include <list>
00013 #include <algorithm>
00014 #include <functional>
00015 #include "lugre_listener.h"
00016 #include "lugre_timer.h"
00017 #include "lugre_ogrewrapper.h"
00018 #include "lugre_meshshape.h"
00019 #include "lugre_camera.h"
00020 #include <OgreWireBoundingBox.h>
00021 #include <OgreFont.h>
00022 #include <OgreFontManager.h>
00023 #include "lugre_ogrefonthelper.h"
00024 #include "lugre_beam.h"
00025 #include "lugre_fastbatch.h"
00026 
00027 using namespace Ogre;
00028 
00029 namespace Lugre {
00030 
00031 // ***** ***** utils
00032 
00033 void EnDisableParticleSystemEmitters(Ogre::ParticleSystem *p, const bool enabled = true){
00034     int numEmitters = p->getNumEmitters();
00035     for(int x = 0; x < numEmitters; x++){
00036         ParticleEmitter* emitter = p->getEmitter(x);
00037         emitter->setEnabled(enabled);
00038     } 
00039 }
00040 
00042 typedef std::list< Ogre::ParticleSystem * > ParticleSystemList;
00043 typedef std::list< Ogre::ParticleSystem * >::iterator ParticleSystemListIterator;
00044 
00045 ParticleSystemList glUnusedParticleSystem;
00046 
00047 const bool kGfx3DReuseParticleSystem = true;
00048 
00050 void FreeOldUnusedParticleSystems(const unsigned int limit){
00051     while(glUnusedParticleSystem.size() > limit){
00052         Ogre::ParticleSystem *p = glUnusedParticleSystem.back();
00053         // printf("DEBUG remove old particle system: %d\n",p);
00054         assert(p && "ParticleSystem must be not 0");
00055         cOgreWrapper::GetSingleton().mSceneMgr->destroyParticleSystem(p); 
00056         glUnusedParticleSystem.pop_back();
00057     }
00058 }
00059 
00061 void PushUnusedParticleSystem(Ogre::ParticleSystem *p){
00062     if(kGfx3DReuseParticleSystem){
00063         // printf("DEBUG PushUnusedParticleSystem(%d) origin: %s cursize: %d\n",p,p->getOrigin().c_str(),glUnusedParticleSystem.size());
00064         EnDisableParticleSystemEmitters(p, false);
00065         p->clear();
00066         p->setBoundsAutoUpdated(false);
00067         p->setBounds(Ogre::AxisAlignedBox());
00068         
00069         glUnusedParticleSystem.push_front(p);
00070     } else {
00071         cOgreWrapper::GetSingleton().mSceneMgr->destroyParticleSystem(p); 
00072     }
00073 }
00074     
00075 void ClearUnusedParticleSystemCache () { 
00076     glUnusedParticleSystem.clear();
00077 }
00078 
00081 Ogre::ParticleSystem *PopFromUnusedParticleSystems(const Ogre::String sName){
00082     if(kGfx3DReuseParticleSystem){
00083         // printf("DEBUG PopFromUnusedParticleSystems %s size: %d\n", sName.c_str(),glUnusedParticleSystem.size());
00084         for(ParticleSystemListIterator it = glUnusedParticleSystem.begin(); it != glUnusedParticleSystem.end();){
00085             // copy to this one from list erase
00086             ParticleSystemListIterator itt = it;
00087             Ogre::ParticleSystem *p = *itt;
00088             
00089             if(p->getOrigin() == sName){
00090                 glUnusedParticleSystem.erase(itt);
00091                 p->setBoundsAutoUpdated(true, 5.0f);
00092                 EnDisableParticleSystemEmitters(p, true);
00093                 // printf("DEBUG found matching %s: %d size: %d\n", sName.c_str(), p, glUnusedParticleSystem.size());
00094                 return p;
00095             };
00096             
00097             ++it;
00098         }
00099     }
00100     return 0;
00101 }
00102     
00103 class cRadialGrid : public cListener { public :
00104     cRobSimpleRenderable    mpCircles;
00105     cRobSimpleRenderable    mpLines;
00106     class cCircle { public: 
00107                 Real mfRad; size_t miSegments; ColourValue col; 
00108         cCircle(Real mfRad, size_t miSegments, ColourValue col) : 
00109                      mfRad(mfRad), miSegments(miSegments), col(col) {} 
00110     };
00111     std::vector<cCircle>    mlCircle;
00112     
00113     cRadialGrid() { PROFILE
00114         cTimer::GetSingletonPtr()->RegisterFrameIntervalListener(this,0,0);
00115         mpCircles.setMaterial("RadialGrid");
00116         mpLines.setMaterial("RadialGrid");
00117         ColourValue primary (0.5,0.5,0.5,0.5);
00118         ColourValue sec     (0.2,0.2,0.2,0.2);
00119         Real e = 200;
00120         size_t seg = 31;
00121         mlCircle.push_back(cCircle(e*5,seg,sec));
00122         mlCircle.push_back(cCircle(e*10,seg,sec));
00123         mlCircle.push_back(cCircle(e*20,seg,sec));
00124         mlCircle.push_back(cCircle(e*30,seg,sec));
00125         mlCircle.push_back(cCircle(e*40,seg,sec));
00126         mlCircle.push_back(cCircle(e*50,seg,primary));
00127         mlCircle.push_back(cCircle(e*75,seg,sec));
00128         mlCircle.push_back(cCircle(e*100,seg,primary));
00129         mlCircle.push_back(cCircle(e*150,seg,sec));
00130         mlCircle.push_back(cCircle(e*200,seg,sec));
00131         UpdateCircles();
00132     }
00133     virtual ~cRadialGrid() {}
00134     void Listener_Notify (cListenable* pTarget,const size_t eventcode,void* param,void* userdata) { Step(); }
00135     
00136     void    UpdateCircles   () {
00137         int i,j;
00138         size_t numLines = 0;
00139         for (i=0;i<mlCircle.size();++i) numLines += mlCircle[i].miSegments;
00140         mpCircles.Begin(numLines*2,0,false,false,Ogre::RenderOperation::OT_LINE_LIST);
00141         
00142         for (i=0;i<mlCircle.size();++i) {
00143             cCircle& c = mlCircle[i];
00144             Real angstep = Real(Math::PI*2.0)/Real(c.miSegments);
00145             for (j=0;j<c.miSegments;++j) {
00146                 mpCircles.Vertex(Vector3(c.mfRad*sin(angstep*Real(j+0)),0,c.mfRad*cos(angstep*Real(j+0))),c.col);
00147                 mpCircles.Vertex(Vector3(c.mfRad*sin(angstep*Real(j+1)),0,c.mfRad*cos(angstep*Real(j+1))),c.col);
00148             }
00149         }
00150         
00151         mpCircles.End();
00152     }
00153     
00154     void Step () { PROFILE
00155         static ColourValue mid(0.0,0.0,0.0,0.0);
00156         static ColourValue out(0.2,0.2,0.2,0.2);
00157         
00158         mpLines.Begin(2,0,true,false,Ogre::RenderOperation::OT_LINE_LIST);
00159         mpLines.Vertex(Ogre::Vector3(0,0,0),out);
00160         mpLines.Vertex(Ogre::Vector3(0,1,0),mid);
00161         mpLines.End();
00162         // TODO : must be adjusted for location system
00163         /*
00164         size_t numLines = 0;
00165         
00166         cGame& game = cGame::GetSingleton();
00167         
00168         cObject* obj;
00169         for (std::map<size_t,cObject*>::iterator itor=game.mlObject.begin();itor!=game.mlObject.end();++itor) {
00170             obj = (*itor).second;
00171             if (obj && !obj->mbDead) {
00172                 numLines += 1;
00173             }
00174         }
00175         
00176         mpLines.Begin(numLines*2,0,true,false,Ogre::RenderOperation::OT_LINE_LIST);
00177         
00178         for (std::map<size_t,cObject*>::iterator itor=game.mlObject.begin();itor!=game.mlObject.end();++itor) {
00179             obj = (*itor).second;
00180             if (obj && !obj->mbDead) {
00181                 mpLines.Vertex(obj->mvPos,out);
00182                 mpLines.Vertex(Vector3(obj->mvPos.x,0,obj->mvPos.z),mid);
00183             }
00184         }
00185         
00186         mpLines.End();
00187         */
00188     }
00189 };
00190 
00191 
00192 class cRadar : public cListener { public :
00193     cRobSimpleRenderable    mpLines;
00194     cRobSimpleRenderable    mpDots;
00195     class cCircle { public: Real mfRad; size_t miSegments; cCircle(Real mfRad,size_t miSegments) : mfRad(mfRad),miSegments(miSegments) {} };
00196     std::vector<cCircle>    mlCircle;
00197     cRadar() { PROFILE
00198         cTimer::GetSingletonPtr()->RegisterFrameIntervalListener(this,0,0);
00199         mpLines.setMaterial("BaseWhiteNoLighting");
00200         mpDots.setMaterial("BaseWhiteNoLighting");
00201         //mlCircle.push_back(cCircle(10,17));
00202         //mlCircle.push_back(cCircle(20,21));
00203     }
00204     virtual ~cRadar() {}
00205     
00206     void Listener_Notify (cListenable* pTarget,const size_t eventcode,void* param,void* userdata) { Step(); }
00207     
00208     
00209     ColourValue     GetDotColor     (size_t radarclass) {
00210         if (radarclass > 8) return ColourValue(0,0,1,1);
00211         switch (radarclass) {
00212             case 1:     return ColourValue(0,1,1,1); // bullet
00213             case 2:     return ColourValue(0.5,0.5,0.5,1); // rocket
00214             case 3:     return ColourValue(0,1,0,1); // loot
00215             case 4:     return ColourValue(1,0.5,0,1); // explosion
00216             case 7:     return ColourValue(1,0,0,1); // pirate
00217             case 8:     return ColourValue(0.5,0,1,1); // trader
00218             default :   return ColourValue(1,1,1,1);
00219         };
00220         /*
00221         o.miRadarClass
00222         0 = unassigned (asteroid)
00223         1 = bullet
00224         2 = rocket
00225         3 = loot
00226         4 = explosion
00227         8+ = 8+team
00228         // o.miRadarClass = 8+team
00229         */
00230     }
00231     
00232     void Step () { PROFILE
00233         Quaternion qcam = cOgreWrapper::GetSingleton().mCamera->getDerivedOrientation();
00234         //Vector3 origin(0,-25,-10+100);
00235         Vector3 origin = qcam * Vector3(0,-20,-100);
00236         Vector3 zero = cOgreWrapper::GetSingleton().mCamera->getDerivedPosition();
00237         //Real  scale = 0.003;
00238         Real    maxrange = 20;
00239         //Real  maxrangesq = maxrange*maxrange;
00240         size_t numLines = 0;
00241         //size_t numDots = 0;
00242         unsigned int i;
00243         for (i=0;i<mlCircle.size();++i) numLines += mlCircle[i].miSegments;
00244         numLines += 2;
00245         //numDots += 5;
00246         
00247         mpDots.Begin(1,0,true,false,Ogre::RenderOperation::OT_POINT_LIST);
00248         mpDots.Vertex(origin);
00249         mpDots.End();
00250         
00251         // TODO : must be adjusted for location system
00252         /*
00253         cGame& game = cGame::GetSingleton();
00254         
00255         cObject* obj;
00256         for (std::map<size_t,cObject*>::iterator itor=game.mlObject.begin();itor!=game.mlObject.end();++itor) {
00257             obj = (*itor).second;
00258             if (obj && !obj->mbDead) {
00259                 obj->mvGFXVar1 = scale*(obj->mvPos-zero);
00260                 if (obj->mvGFXVar1.squaredLength() <= maxrangesq) {
00261                     //numLines += 1;
00262                     numDots += 1;
00263                 }
00264             }
00265         }
00266         
00267         mpDots.Begin(numDots,0,true,false,Ogre::RenderOperation::OT_POINT_LIST);
00268         
00269         
00270         
00271         for (std::map<size_t,cObject*>::iterator itor=game.mlObject.begin();itor!=game.mlObject.end();++itor) {
00272             obj = (*itor).second;
00273             if (obj && !obj->mbDead) {
00274                 if (obj->mvGFXVar1.squaredLength() <= maxrangesq) {
00275                     //numLines += 1;
00276                     mpDots.Vertex(origin + obj->mvGFXVar1,GetDotColor(obj->miRadarClass));
00277                 }
00278             }
00279         }
00280         mpDots.End();
00281         */
00282         
00283         
00284         mpLines.Begin(numLines*2,0,true,false,Ogre::RenderOperation::OT_LINE_LIST);
00285         for (i=0;i<mlCircle.size();++i) {
00286             cCircle& c = mlCircle[i];
00287             Real angstep = Real(Math::PI*2.0)/Real(c.miSegments);
00288             for (int j=0;j<c.miSegments;++j) {
00289                 mpLines.Vertex(origin + Vector3(c.mfRad*sin(angstep*Real(j+0)),0,c.mfRad*cos(angstep*Real(j+0))));
00290                 mpLines.Vertex(origin + Vector3(c.mfRad*sin(angstep*Real(j+1)),0,c.mfRad*cos(angstep*Real(j+1))));
00291             }
00292         }
00293         Real e = 1;
00294         mpLines.Vertex(origin + Vector3(0,0,-e));
00295         mpLines.Vertex(origin + Vector3(0,0,e));
00296         //mpLines.Vertex(origin + Vector3(0,-e,0));
00297         //mpLines.Vertex(origin + Vector3(0,e,0));
00298         mpLines.Vertex(origin + Vector3(-e,0,0));
00299         mpLines.Vertex(origin + Vector3(e,0,0));
00300         
00301         
00302         
00303         mpLines.End();
00304     }
00305 };
00306 
00307 
00308 // class cTargetMarker : public SimpleRenderable { public:
00309 class cTargetMarker : public Ogre::BillboardSet { public:
00310     Real        mfDist,mfSize;
00311     Billboard*  mlBillboards[4];
00312     cTargetMarker(Real fDist,Real fSize,const ColourValue vColor) : mfDist(fDist), mfSize(fSize), BillboardSet(GetUniqueName(),4) { PROFILE
00313         setDefaultDimensions(mfSize,mfSize);
00314         int i; for (i=0;i<4;++i) mlBillboards[i] = createBillboard(Vector3::ZERO,vColor);
00315     }
00316     virtual ~cTargetMarker() {}
00317 
00318     // has to be call every Frame
00319     void    SetOgreCam      (const Vector3& vRight,const Vector3& vUp) { PROFILE
00320         if (mParentNode) {
00321             mlBillboards[0]->setPosition(mfDist*( vUp-vRight));// mlBillboards[0]->setRotation(Radian(0));
00322             mlBillboards[1]->setPosition(mfDist*( vUp+vRight));// mlBillboards[1]->setRotation(Radian(0));
00323             mlBillboards[2]->setPosition(mfDist*(-vUp-vRight));// mlBillboards[2]->setRotation(Radian(0));
00324             mlBillboards[3]->setPosition(mfDist*(-vUp+vRight));// mlBillboards[3]->setRotation(Radian(0));
00325         }
00326     }
00327 
00329     virtual void _notifyCurrentCamera   (Camera* cam) { PROFILE
00330         BillboardSet::_notifyCurrentCamera(cam);
00331         Quaternion q = cam->getDerivedOrientation();
00332         if (mParentNode) q = mParentNode->_getDerivedOrientation().UnitInverse() * q;
00333             // Quaternion q = mParentNode->_getDerivedOrientation().Inverse();
00334         SetOgreCam(q * Vector3::UNIT_X,q * Vector3::UNIT_Y);
00335     }
00336 
00337     static std::string GetUniqueName () { PROFILE
00338         static int iLastName = 0;
00339         return strprintf("targetmarker%d",++iLastName);
00340     }
00341 };
00342 
00343 
00344 // ***** ***** scene node visitor
00345 
00346 class SceneNodeVisitor { public:
00347     virtual void Visit(const SceneNode *node) = 0;
00348 };
00349 
00350 void VisitSceneNode(const SceneNode *node, SceneNodeVisitor *visitor){
00351     if(node && visitor){
00352         // visit
00353         visitor->Visit(node);
00354         
00355         // Iterate through all the child-nodes
00356         SceneNode::ConstChildNodeIterator nodei = node->getChildIterator();
00357 
00358         while (nodei.hasMoreElements())
00359         {
00360             const SceneNode* child = static_cast<const SceneNode*>(nodei.getNext());
00361             // Add this subnode and its children...
00362             VisitSceneNode(child,visitor);
00363         }       
00364     }
00365 }
00366 
00368 class OrientationPositionScale { public:
00369     Ogre::Quaternion mOrientation;
00370     Ogre::Vector3 mPosition;
00371     Ogre::Vector3 mScale;
00372     
00376     OrientationPositionScale(const Node *target, const Node *root){
00377         mOrientation = target->getOrientation();
00378         mPosition = target->getPosition();
00379         mScale = target->getScale();
00380         
00381         Node *parent;
00382         
00383         // walk through parent until root reached
00384         while(target && target != root){
00385             parent = target->getParent();
00386             
00387             if(parent){
00388                 
00389                 if (target->getInheritOrientation()){
00390                     // Combine orientation with that of parent
00391                     mOrientation = parent->getOrientation() * mOrientation;
00392                 } else {
00393                     // No inheritence
00394                     //mDerivedOrientation = mOrientation;
00395                 }
00396 
00397                 // Update scale
00398                 //const Vector3& parentScale = mParent->_getDerivedScale();
00399                 if (target->getInheritScale()) {
00400                     // Scale own position by parent scale, NB just combine
00401                     // as equivalent axes, no shearing
00402                     mScale = parent->getScale() * mScale;
00403                 } else {
00404                     // No inheritence
00405                     //mDerivedScale = mScale;
00406                 }
00407 
00408                 // Change position vector based on parent's orientation & scale
00409                 mPosition = parent->getOrientation() * (parent->getScale() * mPosition);
00410 
00411                 // Add altered position vector to parents
00412                 mPosition += parent->getPosition();
00413                 
00414             }
00415 
00416             target = parent;
00417         }
00418     }
00419 };
00420 
00421 class SceneNodeVisitorSubmeshCollector : public SceneNodeVisitor { public:
00422     class DerivedSubmesh { public:
00423         OrientationPositionScale mData;
00424         Ogre::SubMesh *mSubMesh;
00425         
00426         DerivedSubmesh(const Node *parent, const Node *root, Ogre::SubMesh *submesh) : mData(parent,root), mSubMesh(submesh){}
00427     };
00428 
00429     std::map< std::string , std::list<DerivedSubmesh> > mlSubMesh;
00430     const SceneNode *mRoot;
00431     
00432     SceneNodeVisitorSubmeshCollector(const SceneNode *root) : mRoot(root) {}
00433     
00434     void AddEntity(Ogre::Entity *e, const SceneNode *node){
00435         // iterate over all submeshes
00436         Ogre::Mesh::SubMeshIterator it = e->getMesh()->getSubMeshIterator();
00437         while(it.hasMoreElements()){
00438             SubMesh *sm = it.getNext();
00439             // and insert them based on their materialname
00440             mlSubMesh[sm->getMaterialName()].push_back(DerivedSubmesh(mRoot,node,sm));          
00441         }
00442     }
00443         
00444     virtual void Visit(const SceneNode *node){
00445         // iterator over all attached objects
00446         SceneNode::ConstObjectIterator obji = node->getAttachedObjectIterator();
00447         while (obji.hasMoreElements()){
00448             MovableObject* mobj = obji.getNext();
00449             if (mobj->getMovableType() == "Entity"){
00450                 printf("visit entitiy %lx at %lx\n",(long)(mobj),(long)(node));
00451                 AddEntity(reinterpret_cast<Entity*>(mobj),node);
00452             }
00453         }
00454     }
00455 };
00456 
00457 void    cGfx3D::CreateMergedMesh(const char *szMeshname){
00458     SceneNodeVisitorSubmeshCollector v(mpSceneNode);
00459     VisitSceneNode(mpSceneNode,&v);
00460     
00461     // iterator over all materials
00462     for (std::map< std::string , std::list<SceneNodeVisitorSubmeshCollector::DerivedSubmesh> >::iterator itor=v.mlSubMesh.begin();itor!=v.mlSubMesh.end();++itor) {
00463         std::string material = (*itor).first;
00464         std::list<SceneNodeVisitorSubmeshCollector::DerivedSubmesh> &list = (*itor).second;
00465         
00466         for(std::list<SceneNodeVisitorSubmeshCollector::DerivedSubmesh>::const_iterator it = list.begin();it != list.end();++it){
00467             // TODO see staticgeometry ogre
00468         }
00469         
00470         printf("material=%s submeshes=%d\n",material.c_str(),list.size());
00471     }
00472 }
00473 
00474 
00475 // ***** ***** PrepareFrame
00476 
00477 std::list<cGfx3D*>  cGfx3D::gPrepareFrameStepper;
00478 
00479 void    cGfx3D::SetPrepareFrameStep (const bool bOn) {
00480     if (mbPrepareFrameStep == bOn) return;
00481     mbPrepareFrameStep = bOn;
00482     //printf("cGfx3D::SetPrepareFrameStep(%d) start\n",bOn?1:0);
00483     if (mbPrepareFrameStep)  {
00484         gPrepareFrameStepper.push_front(this);
00485         mPrepareFrameItor = gPrepareFrameStepper.begin(); // insert self, constant time
00486         assert(*mPrepareFrameItor == this && "cGfx3D::SetPrepareFrameStep insert broken\n");
00487     } else {
00488         assert(*mPrepareFrameItor == this && "cGfx3D::SetPrepareFrameStep erase broken\n");
00489         gPrepareFrameStepper.erase(mPrepareFrameItor); // remove self, constant time
00490     }
00491     //printf("cGfx3D::SetPrepareFrameStep(%d) end\n",bOn?1:0);
00492 }
00493 
00494 void    cGfx3D::PrepareFrame        () {
00495     std::for_each(gPrepareFrameStepper.begin(),gPrepareFrameStepper.end(),std::mem_fun(&cGfx3D::PrepareFrameStep));
00496 }
00497 
00499 void    cGfx3D::PrepareFrameStep    () {
00500     // SceneManager *   scenenode::getCreator (void) const
00501     if (mpForcePosCam) SetPosition(mpForcePosCam->getDerivedPosition());
00502     if (mpForceRotCam) SetOrientation(mpForceRotCam->getDerivedOrientation());
00503         
00504     Ogre::SceneNode* mpForceLookatSceneNode = (*mpForceLookatTarget) ? (*mpForceLookatTarget)->mpSceneNode : 0;
00505     if (mpForceLookatSceneNode) {
00506         // TODO : test me !
00507         Ogre::SceneNode*    pParent = mpSceneNode ? mpSceneNode->getParentSceneNode() : 0;
00508         Ogre::Vector3       pos1 = mpSceneNode ? mpSceneNode->_getDerivedPosition() : Ogre::Vector3::ZERO;
00509         Ogre::Vector3       pos2 = mpForceLookatSceneNode->_getDerivedPosition();
00510         if (pParent) 
00511                 SetOrientation(Ogre::Vector3(0,0,1).getRotationTo(pos2-pos1) * pParent->_getDerivedOrientation().Inverse());
00512         else    SetOrientation(Ogre::Vector3(0,0,1).getRotationTo(pos2-pos1));
00513     }
00514 }
00515 
00516 // ***** ***** utils
00517 
00518 
00519 void    cGfx3D::UpdateProjected     (const int iFrameNum) {
00520     if (miLastProjectedFrame != iFrameNum) {
00521         miLastProjectedFrame = iFrameNum;
00522         mpSceneNode->needUpdate();
00523         mvProjectedPos = cOgreWrapper::GetSingleton().ProjectSizeAndPosEx(mpSceneNode->_getDerivedPosition(),mfCustomBoundingRadius,mvProjectedSize);
00524     }
00525 }
00526     
00527 cGfx3D* cGfx3D::NewOfSceneNode      (Ogre::SceneNode* pNode)        { assert(pNode);   return new cGfx3D(pNode); }
00528 cGfx3D* cGfx3D::NewChildOfSceneNode (Ogre::SceneNode* pParent)      { assert(pParent);   return new cGfx3D(pParent->createChildSceneNode()); }
00529 cGfx3D* cGfx3D::NewChildOfGfx3D     (cGfx3D* pParent)               { assert(pParent);   return NewChildOfSceneNode(pParent->mpSceneNode); }
00530 cGfx3D* cGfx3D::NewChildOfRoot      (Ogre::SceneManager* pSceneMgr) { assert(pSceneMgr); return NewChildOfSceneNode(pSceneMgr->getRootSceneNode()); }
00531 cGfx3D* cGfx3D::NewFree             (Ogre::SceneManager* pSceneMgr) { assert(pSceneMgr); return new cGfx3D(pSceneMgr->createSceneNode(cOgreWrapper::GetSingleton().GetUniqueName())); }
00532 cGfx3D* cGfx3D::NewTagPoint         (cGfx3D* pParent,const char* szBoneName,const Ogre::Vector3& vOffsetPosition,const Ogre::Quaternion& qOffsetOrientation) { 
00533     assert(pParent); 
00534     cGfx3D* res = new cGfx3D(0); 
00535     res->mpAttachToEntity = pParent->mpEntity;
00536     res->msAttachToBoneName = szBoneName;
00537     return res;
00538 }
00539 
00540 unsigned int cGfx3D::miCount = 0;
00541 
00542 cGfx3D::cGfx3D  (SceneNode* pSceneNode) : 
00543     mpSceneNode             (pSceneNode),
00544     mpTagPoint              (0),
00545     mpAttachToEntity        (0),
00546     mpFastBatch             (0),
00547     mpParticleSystem        (0),
00548     mpFont                  (0),
00549     mpRadar                 (0),
00550     mpTrail                 (0),
00551     mpBeam                  (0),
00552     mpRadialGrid            (0),
00553     mpEntity                (0),
00554     mpAnimState             (0),
00555     mpPathAnimState         (0),
00556     mpBillboardSet          (0),
00557     mpManualObject          (0),
00558     //mpWireBoundingBox     (0),
00559     mpSimpleRenderable      (0),
00560     mfCustomBoundingRadius  (0),
00561     mbHasAABB               (false),
00562     mpForcePosCam           (0),
00563     mpForceRotCam           (0),
00564     mbHasPath               (false),
00565     mbPrepareFrameStep  (false) 
00566 {
00567     ++miCount;  
00568 }
00569 
00570 cGfx3D::~cGfx3D () { PROFILE
00571     --miCount;
00572     Clear();
00573     DestroyPath();
00574     if (mpSceneNode) { cOgreWrapper::GetSingleton().mSceneMgr->destroySceneNode(mpSceneNode->getName()); mpSceneNode = 0; }
00575 }
00576 
00577 
00579 void    cGfx3D::Clear               ()                          { PROFILE 
00580     // TODO : mpTagPoint not released, detach neccessary ?
00581     // TODO : mpBillboardSet not yet released, as there can be multiple per gfx
00582     SetPrepareFrameStep(false);
00583     if (mpSceneNode)            mpSceneNode->detachAllObjects();
00584     if (mpManualObject)         { mpManualObject; mpManualObject = 0; }
00585     if (mpRadar)                { delete mpRadar; mpRadar = 0; }
00586     if (mpTrail)                { cOgreWrapper::GetSingleton().mSceneMgr->getRootSceneNode()->detachObject(mpTrail);
00587                                   delete mpTrail; mpTrail = 0; }
00588     if (mpBeam)                 { delete mpBeam; mpBeam = 0; }
00589     if (mpFastBatch)            { delete mpFastBatch; mpFastBatch = 0; }
00590     if (mpRadialGrid)           { delete mpRadialGrid; mpRadialGrid = 0; }
00591     //if (mpWireBoundingBox)    { delete mpWireBoundingBox; mpWireBoundingBox = 0; }
00592     if (mpSimpleRenderable)     { delete mpSimpleRenderable; mpSimpleRenderable = 0; }
00593     if (mpEntity)               { cOgreWrapper::GetSingleton().mSceneMgr->destroyEntity(mpEntity); mpEntity = 0; }
00594     if (mpParticleSystem)       { 
00595         //cOgreWrapper::GetSingleton().mSceneMgr->destroyParticleSystem(mpParticleSystem); 
00596         
00597         PushUnusedParticleSystem(mpParticleSystem);
00598         
00599         mpParticleSystem = 0; 
00600     }
00601     DestroyPath();
00602 }
00603 
00604 void    cGfx3D::DestroyPath     () {
00605     if(mbHasPath){
00606         mbHasPath = false;
00607 
00608         if (mpPathAnimState) { 
00609             mpPathAnimState = 0; 
00610         }
00611 
00612         cOgreWrapper::GetSingleton().mSceneMgr->destroyAnimation(msPathAnimName);
00613         msPathAnimName = "";
00614     }
00615 }
00616 
00617 bool    cGfx3D::IsInScene       () { return mpSceneNode && mpSceneNode->isInSceneGraph(); }
00618 //bool  cGfx3D::IsInScene       () { return mpSceneNode && mpSceneNode->getParentSceneNode() != 0; }
00619 
00620 void    cGfx3D::SetParent       (cGfx3D* pParent) { PROFILE SetParent(pParent?pParent->mpSceneNode:0); }
00621 void    cGfx3D::SetParent       (SceneNode* pParent) { PROFILE
00622     Ogre::SceneNode* mpOldParent = mpSceneNode ? mpSceneNode->getParentSceneNode() : 0; 
00623     if (mpOldParent == pParent) return;
00624     if (mpOldParent) mpOldParent->removeChild(mpSceneNode);
00625     if (pParent && mpSceneNode) pParent->addChild(mpSceneNode);
00626 }
00627 
00628 Vector3 cGfx3D::GetScale            ()          { PROFILE return (mpSceneNode) ? mpSceneNode->getScale() : Vector3::UNIT_SCALE; }
00629 Vector3 cGfx3D::GetPosition         ()          { PROFILE return (mpSceneNode) ? mpSceneNode->getPosition() : Vector3::ZERO; }
00630 Vector3 cGfx3D::GetDerivedPosition  ()          { PROFILE return (mpSceneNode) ? mpSceneNode->_getDerivedPosition() : Vector3::ZERO; }
00631 Quaternion  cGfx3D::GetOrientation  ()          { PROFILE return (mpSceneNode) ? mpSceneNode->getOrientation () : Quaternion::IDENTITY; }
00632 Quaternion  cGfx3D::GetDerivedOrientation   ()  { PROFILE return (mpSceneNode) ? mpSceneNode->_getDerivedOrientation () : Quaternion::IDENTITY; }
00633 
00634 void    cGfx3D::SetPosition     (const Vector3& vPos)       { PROFILE if (mpSceneNode) mpSceneNode->setPosition(vPos); }
00635 void    cGfx3D::SetScale        (const Vector3& vScale)     {  PROFILE if (mpSceneNode) mpSceneNode->setScale(vScale); }
00636 void    cGfx3D::SetNormaliseNormals (const bool bNormalise) {  PROFILE /* if (mpEntity) TODO removed in ogresvn mpEntity->setNormaliseNormals(bNormalise); */ }
00637 void    cGfx3D::SetOrientation  (const Quaternion& qRot)    { PROFILE if (mpSceneNode) mpSceneNode->setOrientation(qRot); }
00638 void    cGfx3D::SetVisible      (const bool bVisible, const bool bCascade)      { PROFILE if (mpSceneNode) mpSceneNode->setVisible(bVisible, bCascade); }
00639 void    cGfx3D::SetCastShadows      (const bool bCastShadows) { PROFILE
00640     if (mpEntity) mpEntity->setCastShadows(bCastShadows); 
00641     if (mpSimpleRenderable) mpSimpleRenderable->setCastShadows(bCastShadows); 
00642     if (mpManualObject) mpManualObject->setCastShadows(bCastShadows); 
00643     if (mpBeam) mpBeam->setCastShadows(bCastShadows); 
00644     if (mpFastBatch) mpFastBatch->setCastShadows(bCastShadows); 
00645 }
00646 void    cGfx3D::SetMaterial     (const char* szMat) { PROFILE
00647     if (mpBillboardSet) mpBillboardSet->setMaterialName(szMat);
00648     if (mpSimpleRenderable) mpSimpleRenderable->setMaterial(szMat);
00649     if (mpBeam) mpBeam->setMaterial(szMat);
00650 }
00651 
00652 
00653 void    cGfx3D::SetParticleSystem   (const char* szTemplateName) {
00654     if (!mpSceneNode) return;
00655     if (mpParticleSystem) Clear();
00656     
00657     // try to reuse a unused particle system of the same type
00658     mpParticleSystem = PopFromUnusedParticleSystems(szTemplateName);
00659     if(mpParticleSystem == 0){
00660         mpParticleSystem = cOgreWrapper::GetSingleton().mSceneMgr->createParticleSystem(cOgreWrapper::GetSingleton().GetUniqueName(), szTemplateName);
00661         mpParticleSystem->_notifyOrigin(szTemplateName);
00662     }
00663     
00664     AttachObject(mpParticleSystem);
00665 }
00666 
00667 const unsigned int  cGfx3D::GetNumParticles ()  { PROFILE
00668     if (!mpSceneNode) return 0;
00669     if (!mpParticleSystem) return 0;
00670     
00671     return mpParticleSystem->getNumParticles();
00672 }
00673 
00674 
00675 void    cGfx3D::SetManualObject     (Ogre::ManualObject* pManualObject) {
00676     Clear();
00677     mpManualObject = pManualObject;
00678     
00679     AttachObject(mpManualObject);
00680 }
00681 
00682 void    cGfx3D::SetBillboardSet     (Ogre::BillboardSet* pBillboardSet) {
00683     Clear();
00684     mpBillboardSet = pBillboardSet;
00685     
00686     AttachObject(mpBillboardSet);
00687 }
00688 
00689 size_t giLastMeshID = 0;
00690 void    cGfx3D::SetMesh (const char* szMeshName) { PROFILE
00691     //assert(!mpEntity && "cannot attach more than one entity per gfx");
00692     if (mpEntity) Clear();
00693     
00694     // TODO : different scenemanager ???
00695     mpEntity = cOgreWrapper::GetSingleton().mSceneMgr->createEntity(strprintf("objmesh%d",++giLastMeshID),szMeshName);
00696     
00697     AttachObject(mpEntity);
00698 }
00699 
00700 void    cGfx3D::SetAnim     (const char* szAnimName,const bool bLoop) {
00701     if (!mpEntity) return;
00702     if (mpAnimState) { mpAnimState->setEnabled(false); } // stop old anim
00703     // Ogre::Entity::refreshAvailableAnimationState might be interesting for manually edited skeletons
00704     try {
00705         mpAnimState = mpEntity->getAnimationState(szAnimName);
00706         mpAnimState->setEnabled(true);
00707         mpAnimState->setLoop(bLoop);
00708     } catch (Ogre::Exception& e) {
00709         printf("WARNING ! playing anim '%s' failed\n",szAnimName);
00710     }
00711 }
00712 
00713 Real    cGfx3D::GetAnimLength       (const char* szAnimName) {
00714     try {
00715         if (mpEntity) return mpEntity->getAnimationState(szAnimName)->getLength();
00716     } catch (Ogre::Exception& e) {
00717         printf("WARNING ! length check for anim '%s' failed\n",szAnimName);
00718     }
00719     return 0;
00720 }
00721 void    cGfx3D::SetAnimTimePos      (const Real fTimeInSeconds) { if (mpAnimState) mpAnimState->setTimePosition(fTimeInSeconds); }
00722 Real    cGfx3D::GetAnimTimePos      () { return mpAnimState ? mpAnimState->getTimePosition() : 0; }
00723 bool    cGfx3D::IsAnimLooped        () { return mpAnimState ? mpAnimState->getLoop() : 0; }
00724 
00725 void    cGfx3D::SetPathAnimTimePos      (const Real fTimeInSeconds) { if (mpPathAnimState) mpPathAnimState->setTimePosition(fTimeInSeconds); }
00726 Real    cGfx3D::GetPathAnimTimePos      () { return mpPathAnimState ? mpPathAnimState->getTimePosition() : 0; }
00727 bool    cGfx3D::IsPathAnimLooped        () { return mpPathAnimState ? mpPathAnimState->getLoop() : 0; }
00728 
00729 bool    cGfx3D::HasBone             (const char* szBoneName) {
00730     return mpEntity && mpEntity->getSkeleton() && cOgreWrapper::SearchBoneByName(*mpEntity->getSkeleton(),szBoneName) != 0;
00731 }
00732 
00733 void    cGfx3D::SetWireBoundingBox  (const Ogre::AxisAlignedBox& aabb) {
00734     if (!mpSceneNode) return;
00735     //if (mpSimpleRenderable) Clear();
00736     if (!mpSimpleRenderable) {
00737         mpSimpleRenderable = new cRobSimpleRenderable();
00738         mpSimpleRenderable->setMaterial("BaseWhiteNoLighting");
00739         AttachObject(mpSimpleRenderable);
00740     }
00741     
00742     mAABB = aabb;
00743     mbHasAABB = true;
00744     
00745     Ogre::Vector3 p000 = aabb.getMinimum();
00746     Ogre::Vector3 p111 = aabb.getMaximum();
00747     Ogre::Vector3 d = p111-p000;
00748     Ogre::Vector3 p100 = p000 + Ogre::Vector3(d.x,0,0);
00749     Ogre::Vector3 p010 = p000 + Ogre::Vector3(0,d.y,0);
00750     Ogre::Vector3 p001 = p000 + Ogre::Vector3(0,0,d.z);
00751     Ogre::Vector3 p011 = p000 + Ogre::Vector3(0,d.y,d.z);
00752     Ogre::Vector3 p101 = p000 + Ogre::Vector3(d.x,0,d.z);
00753     Ogre::Vector3 p110 = p000 + Ogre::Vector3(d.x,d.y,0);
00754     //printf("SetWireBoundingBox p000(%f,%f,%f) p111(%f,%f,%f)\n",p000.x,p000.y,p000.z,p111.x,p111.y,p111.z);
00755     
00756     mpSimpleRenderable->Begin(24,0,false,false,Ogre::RenderOperation::OT_LINE_LIST);
00757     mpSimpleRenderable->Vertex(p000);mpSimpleRenderable->Vertex(p001);
00758     mpSimpleRenderable->Vertex(p000);mpSimpleRenderable->Vertex(p010);
00759     mpSimpleRenderable->Vertex(p000);mpSimpleRenderable->Vertex(p100);
00760     
00761     mpSimpleRenderable->Vertex(p111);mpSimpleRenderable->Vertex(p110);
00762     mpSimpleRenderable->Vertex(p111);mpSimpleRenderable->Vertex(p101);
00763     mpSimpleRenderable->Vertex(p111);mpSimpleRenderable->Vertex(p011);
00764     
00765     mpSimpleRenderable->Vertex(p110);mpSimpleRenderable->Vertex(p100);
00766     mpSimpleRenderable->Vertex(p110);mpSimpleRenderable->Vertex(p010);
00767     
00768     mpSimpleRenderable->Vertex(p101);mpSimpleRenderable->Vertex(p100);
00769     mpSimpleRenderable->Vertex(p101);mpSimpleRenderable->Vertex(p001);
00770     
00771     mpSimpleRenderable->Vertex(p011);mpSimpleRenderable->Vertex(p010);
00772     mpSimpleRenderable->Vertex(p011);mpSimpleRenderable->Vertex(p001);
00773     mpSimpleRenderable->End();
00774     
00775         /*
00776     if (!mpWireBoundingBox) {
00777         mpWireBoundingBox = new Ogre::WireBoundingBox();
00778         cOgreWrapper::GetSingleton().GetRootSceneNode()->attachObject(mpWireBoundingBox);
00779         mpWireBoundingBox->setMaterial("matDebugBoundingBox");
00780         //AttachObject(mpWireBoundingBox);
00781         mpWireBoundingBox->setVisible(true);
00782     }
00783     mpWireBoundingBox->setBoundingBox(aabb);
00784     */
00785     /*
00786     if (!pBBox->isVisible()) pBBox->setVisible(true);
00787     virtual const AxisAlignedBox &  getBoundingBox (void) const         Retrieves the local axis-aligned bounding box for this object. 
00788     virtual const AxisAlignedBox &  getWorldBoundingBox (bool derive=false) const
00789     */
00790 }
00791 
00792 void    cGfx3D::SetWireBoundingBox  (const Vector3& vMin,const Vector3& vMax) {
00793     //printf("SetWireBoundingBox min(%f,%f,%f) max(%f,%f,%f)\n",vMin.x,vMin.y,vMin.z,vMax.x,vMax.y,vMax.z);
00794     //SetWireBoundingBox(Ogre::AxisAlignedBox(vMin,vMax)); 
00795     SetWireBoundingBox(Ogre::AxisAlignedBox(vMin.x,vMin.y,vMin.z,vMax.x,vMax.y,vMax.z)); 
00796 }
00797 
00798 void    cGfx3D::SetWireBoundingBox  (Ogre::MovableObject& mov) { 
00799     SetWireBoundingBox(mov.getWorldBoundingBox()); 
00800 }
00801 
00802 void    cGfx3D::SetWireBoundingBox  (Ogre::Entity& entity) {
00803     MeshShape* pMeshShape = MeshShape::GetMeshShape(&entity);
00804     SetWireBoundingBox(pMeshShape->mvMin,pMeshShape->mvMax); // warning ! can't have rotation / position this way 
00805     //SetWireBoundingBox(entity.getWorldBoundingBox()); 
00806     SceneNode* scenenode = entity.getParentSceneNode();
00807     if (!scenenode) return; // TODO : tagpoint (like knife in hand) attachment currently not supported...
00808     SetPosition(scenenode->_getDerivedPosition());
00809 }
00810 
00811 void    cGfx3D::SetWireBoundingBox  (cGfx3D& gfx3D) {
00812     if (gfx3D.mbHasAABB) {
00813         SetWireBoundingBox(mAABB);
00814         SetPosition(gfx3D.GetPosition());
00815     } else if (gfx3D.mpEntity) {
00816         SetWireBoundingBox(*gfx3D.mpEntity);
00817         SetPosition(gfx3D.GetPosition());
00818     }
00819 }
00820 
00822 void    cGfx3D::SetSimpleRenderable () {
00823     if (!mpSceneNode) return;
00824     if (!mpSimpleRenderable) {
00825         mpSimpleRenderable = new cRobSimpleRenderable();
00826         AttachObject(mpSimpleRenderable);
00827     }
00828 }
00829 
00831 void    cGfx3D::SetTextFont         (const char* szFontName) {
00832     mpFont = FontManager::getSingleton().getByName( szFontName );
00833     if (mpFont.isNull()) OGRE_EXCEPT( Exception::ERR_ITEM_NOT_FOUND, "Could not find font " + std::string(szFontName), "cGfx3D::SetTextFont" );
00834     mpFont->load();
00835     
00836     if (!mpSimpleRenderable) {
00837         mpSimpleRenderable = new cRobSimpleRenderable();
00838         AttachObject(mpSimpleRenderable);
00839     }
00840     // we need depthchecking for 3d-text... but same material also used by gfx2d and overlay stuff... so clone and cache
00841     static std::map<std::string,std::string> mDepthCheckFontMaterial;
00842     std::string& a = mDepthCheckFontMaterial[szFontName];
00843     if (a == "") {
00844         Ogre::MaterialPtr mpMaterial = mpFont->getMaterial();
00845         mpMaterial = mpMaterial->clone(cOgreWrapper::GetSingleton().GetUniqueName());
00846         mpMaterial->setDepthCheckEnabled(true);
00847         mpMaterial->setDepthWriteEnabled(true);
00848         mpMaterial->setLightingEnabled(false);
00849         mpMaterial->getTechnique(0)->getPass(0)->setCullingMode( Ogre::CULL_NONE ) ;
00850         mpMaterial->getTechnique(0)->getPass(0)->setManualCullingMode( Ogre::MANUAL_CULL_NONE ) ;
00851         mpMaterial->getTechnique(0)->getPass(0)->setSceneBlending(Ogre::SBF_SOURCE_ALPHA,Ogre::SBF_ONE_MINUS_SOURCE_ALPHA);
00852         mpMaterial->getTechnique(0)->getPass(0)->setAlphaRejectSettings(Ogre::CMPF_GREATER,230);
00853         a = mpMaterial->getName();
00854     }
00855     mpSimpleRenderable->setMaterial(a);
00856 }
00857 
00859 void    cGfx3D::SetText             (const char* szText,const Real fSize,const ColourValue col,const float mfWrapMaxW,Ogre::GuiHorizontalAlignment align) {
00860     if (mpFont.isNull()) return;
00861     if (!mpSceneNode) return;
00862     if (!mpSimpleRenderable) return;
00863     if (!szText) return;
00864     int iLen = strlen(szText);
00865     
00866     // Derive space with from a capital A
00867     Real mSpaceWidth = mpFont->getGlyphAspectRatio(cOgreFontHelper::UNICODE_ZERO) * fSize;
00868     float mWrapMaxW = 0;
00869     
00870     Ogre::UTFString sUTFText;
00871     try {
00872         sUTFText = szText;
00873     } catch (...) {
00874         printdebug("unicode","WARNING, cGfx3D::SetText exception, unicode error?\n");
00875     }
00876     
00877     cOgreFontHelper myFontHelper(mpFont,fSize,fSize,mSpaceWidth,mWrapMaxW,cOgreFontHelper::Alignment(align));
00878     cOgreFontHelper::cTextIterator itor(myFontHelper,sUTFText);
00879     
00880     
00881     // set up variables used in loop
00882     Real inL = 0;
00883     Real inT = 0;
00884     Real left = inL;
00885     Real top = inT;
00886     Real u1, u2, v1, v2; 
00887     Real z = 0.0;
00888     Ogre::Vector3 n(0,0,-1.0);
00889     int  iCurIndex = 0;
00890     
00891     // iterate over all chars in caption
00892     
00893     mpSimpleRenderable->Begin(iLen*4,iLen*6,false,false,Ogre::RenderOperation::OT_TRIANGLE_LIST);
00894     
00895     while (itor.HasNext()) {
00896         cOgreFontHelper::unicode_char c = itor.Next();
00897         if (cOgreFontHelper::IsWhiteSpace(c)) {
00898             // whitespace character, skip triangles
00899             mpSimpleRenderable->SkipVertices(4);
00900             mpSimpleRenderable->SkipIndices(6);
00901         } else {
00902             // draw character
00903             float left = itor.x;
00904             float top = itor.y;
00905             float w = myFontHelper.GetCharWidth(c);
00906             float h = fSize;
00907             const Ogre::Font::UVRect& uvRect = mpFont->getGlyphTexCoords(c);
00908             u1 = uvRect.left;
00909             v1 = uvRect.top;
00910             u2 = uvRect.right;
00911             v2 = uvRect.bottom;
00912             
00913             // todo : TEST ME
00914             mpSimpleRenderable->Vertex(Ogre::Vector3(left+0,top+h,z),n,u1,v1,col);
00915             mpSimpleRenderable->Vertex(Ogre::Vector3(left+w,top+h,z),n,u2,v1,col);
00916             mpSimpleRenderable->Vertex(Ogre::Vector3(left+0,top+0,z),n,u1,v2,col);
00917             mpSimpleRenderable->Vertex(Ogre::Vector3(left+w,top+0,z),n,u2,v2,col);
00918             mpSimpleRenderable->Index(iCurIndex+0);
00919             mpSimpleRenderable->Index(iCurIndex+1);
00920             mpSimpleRenderable->Index(iCurIndex+2);
00921             mpSimpleRenderable->Index(iCurIndex+1);
00922             mpSimpleRenderable->Index(iCurIndex+3);
00923             mpSimpleRenderable->Index(iCurIndex+2);
00924             iCurIndex += 4; // 4 new vertices added
00925         }
00926     }
00927     mpSimpleRenderable->End();
00928 }
00929 
00930 void    cGfx3D::SetRadar    () {
00931     if (!mpSceneNode) return;
00932     if (mpRadar) Clear();
00933     
00934     mpRadar = new cRadar();
00935     AttachObject(&mpRadar->mpLines);
00936     AttachObject(&mpRadar->mpDots);
00937 }
00938 
00939 void    cGfx3D::SetBeam     (const bool bUseVertexColour) {
00940     if (!mpSceneNode) return;
00941     if (mpBeam) Clear();
00942     
00943     mpBeam = new cSimpleBeam(bUseVertexColour);
00944     mpBeam->_notifyCurrentCamera(0); // init
00945     AttachObject(mpBeam);
00946 }
00947 
00948 void    cGfx3D::SetRadialGrid   () {
00949     if (!mpSceneNode) return;
00950     if (mpRadialGrid) Clear();
00951     
00952     mpRadialGrid = new cRadialGrid();
00953     AttachObject(&mpRadialGrid->mpCircles);
00954     AttachObject(&mpRadialGrid->mpLines);
00955 }
00956 
00957 
00958 void    cGfx3D::SetFastBatch    () {
00959     if (!mpSceneNode) return;
00960     if (mpFastBatch) Clear();
00961     
00962     mpFastBatch = new cFastBatch();
00963     AttachObject(mpFastBatch);
00964 }
00965 
00967 void    cGfx3D::SetStarfield        (const size_t iNumStars,const Real fRad,const Real fColoring,const char* szMatName) { PROFILE
00968     if (!mpSceneNode) return;
00969 
00970     cRobSimpleRenderable* starfield = new cRobSimpleRenderable();
00971     starfield->setMaterial(szMatName);
00972     starfield->Begin(iNumStars,0,false,false,Ogre::RenderOperation::OT_POINT_LIST);
00973     int i; for (i=0;i<iNumStars;++i) {
00974         Real fGray = Math::RangeRandom(fColoring,1);
00975             starfield->Vertex(
00976                 Vector3(Math::RangeRandom(-1,1),Math::RangeRandom(-1,1),Math::RangeRandom(-1,1)).normalisedCopy()*fRad,
00977                 ColourValue(fGray-Math::RangeRandom(0,fColoring),
00978                             fGray-Math::RangeRandom(0,fColoring),
00979                             fGray-Math::RangeRandom(0,fColoring) )
00980             );
00981     }
00982     starfield->End();
00983     AttachObject(starfield);
00984 }
00985 
00986 
00987 
00988 size_t giLastBillboardID = 0;
00989 void    cGfx3D::SetBillboard    (const Vector3 vPos,const Real fRadius,const char* szMatName) { PROFILE // "explosion"
00990     if (!mpSceneNode) return;
00991     mpBillboardSet = cOgreWrapper::GetSingleton().mSceneMgr->createBillboardSet(strprintf("billboardset%d",++giLastBillboardID),1);
00992     mpBillboardSet->setMaterialName(szMatName);
00993     mpBillboardSet->setDefaultDimensions(fRadius,fRadius);
00994     Billboard* mybillboard = mpBillboardSet->createBillboard(vPos);
00995     // mybillboard->setRotation(Radian(Math::RangeRandom(0.0,Math::PI*2.0))); // breaks texcoords
00996     AttachObject(mpBillboardSet);
00997 }
00998 
00999 size_t giLastRibbonID = 0;
01000 void    cGfx3D::SetTrail (const Vector3 vPos,const Real fLength, const unsigned int iElements, const char* szMatName,
01001                         const Real fR,const Real fG,const Real fB, const Real fA,
01002                         const Real fDeltaR,const Real fDeltaG,const Real fDeltaB, const Real fDeltaA,
01003                         const Real fW,const Real fDeltaW) { PROFILE
01004     if (!mpSceneNode) return;
01005     if(mpTrail)Clear();
01006     
01007     mpTrail = cOgreWrapper::GetSingleton().mSceneMgr->createRibbonTrail(strprintf("ribbontrail%d",++giLastRibbonID));
01008 
01009     // set scene node to root because its not needed for trails
01010     mpSceneNode->setPosition(Ogre::Vector3());
01011 
01012     mpTrail->setNumberOfChains(1);
01013     mpTrail->setMaxChainElements(iElements);
01014     mpTrail->setMaterialName(szMatName);
01015     mpTrail->setTrailLength(fLength);
01016 
01017     // TODO : this won't work in a nonstandard sceneman, determine the scenemanager from scenenode
01018     cOgreWrapper::GetSingleton().mSceneMgr->getRootSceneNode()->attachObject(mpTrail);
01019 
01020     mpTrail->setInitialColour(0, fR,fG,fB,fA);
01021     mpTrail->setColourChange(0, fDeltaR,fDeltaG,fDeltaB,fDeltaA);
01022     mpTrail->setInitialWidth(0, fW);
01023     mpTrail->setWidthChange(0, fDeltaW);
01024 
01025     mpTrail->addNode(mpSceneNode);
01026 }
01027 
01028 void    cGfx3D::SetTargetTracker    (const Real fDist,const Real fSize,const ColourValue vColor,const char* szMatName) { PROFILE // "explosion"
01029     if (!mpSceneNode) return;
01030     cTargetMarker* x = new cTargetMarker(fDist,fSize,vColor);
01031     x->setMaterialName(szMatName);
01032     AttachObject(x);
01033 }
01034 
01035 void    cGfx3D::SetExplosion    (const Real fRadius,const char* szMatName) { PROFILE // "explosion"
01036     SetBillboard(Vector3::ZERO,fRadius,szMatName);
01037 }
01038 
01039 void    cGfx3D::AttachObject    (Ogre::MovableObject* pObj) {
01040     if (mpSceneNode) mpSceneNode->attachObject(pObj);
01041     if (mpAttachToEntity) {
01042         mpTagPoint = mpAttachToEntity->attachObjectToBone(msAttachToBoneName.c_str(),pObj,Ogre::Quaternion::IDENTITY,Ogre::Vector3::ZERO);
01043     }
01044 }
01045 
01046 void    cGfx3D::DetachObject    (Ogre::MovableObject* pObj) {
01047     if (mpSceneNode) mpSceneNode->detachObject(pObj);
01048     if (mpAttachToEntity) {
01049         mpAttachToEntity->detachObjectFromBone(pObj);
01050     }
01051 }
01052 
01053 };

Generated on Wed May 23 06:00:14 2012 for cpp by  doxygen 1.5.6