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
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
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
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
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
00084 for(ParticleSystemListIterator it = glUnusedParticleSystem.begin(); it != glUnusedParticleSystem.end();){
00085
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
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
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
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
00202
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);
00213 case 2: return ColourValue(0.5,0.5,0.5,1);
00214 case 3: return ColourValue(0,1,0,1);
00215 case 4: return ColourValue(1,0.5,0,1);
00216 case 7: return ColourValue(1,0,0,1);
00217 case 8: return ColourValue(0.5,0,1,1);
00218 default : return ColourValue(1,1,1,1);
00219 };
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230 }
00231
00232 void Step () { PROFILE
00233 Quaternion qcam = cOgreWrapper::GetSingleton().mCamera->getDerivedOrientation();
00234
00235 Vector3 origin = qcam * Vector3(0,-20,-100);
00236 Vector3 zero = cOgreWrapper::GetSingleton().mCamera->getDerivedPosition();
00237
00238 Real maxrange = 20;
00239
00240 size_t numLines = 0;
00241
00242 unsigned int i;
00243 for (i=0;i<mlCircle.size();++i) numLines += mlCircle[i].miSegments;
00244 numLines += 2;
00245
00246
00247 mpDots.Begin(1,0,true,false,Ogre::RenderOperation::OT_POINT_LIST);
00248 mpDots.Vertex(origin);
00249 mpDots.End();
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
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
00297
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
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
00319 void SetOgreCam (const Vector3& vRight,const Vector3& vUp) { PROFILE
00320 if (mParentNode) {
00321 mlBillboards[0]->setPosition(mfDist*( vUp-vRight));
00322 mlBillboards[1]->setPosition(mfDist*( vUp+vRight));
00323 mlBillboards[2]->setPosition(mfDist*(-vUp-vRight));
00324 mlBillboards[3]->setPosition(mfDist*(-vUp+vRight));
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
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
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
00353 visitor->Visit(node);
00354
00355
00356 SceneNode::ConstChildNodeIterator nodei = node->getChildIterator();
00357
00358 while (nodei.hasMoreElements())
00359 {
00360 const SceneNode* child = static_cast<const SceneNode*>(nodei.getNext());
00361
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
00384 while(target && target != root){
00385 parent = target->getParent();
00386
00387 if(parent){
00388
00389 if (target->getInheritOrientation()){
00390
00391 mOrientation = parent->getOrientation() * mOrientation;
00392 } else {
00393
00394
00395 }
00396
00397
00398
00399 if (target->getInheritScale()) {
00400
00401
00402 mScale = parent->getScale() * mScale;
00403 } else {
00404
00405
00406 }
00407
00408
00409 mPosition = parent->getOrientation() * (parent->getScale() * mPosition);
00410
00411
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
00436 Ogre::Mesh::SubMeshIterator it = e->getMesh()->getSubMeshIterator();
00437 while(it.hasMoreElements()){
00438 SubMesh *sm = it.getNext();
00439
00440 mlSubMesh[sm->getMaterialName()].push_back(DerivedSubmesh(mRoot,node,sm));
00441 }
00442 }
00443
00444 virtual void Visit(const SceneNode *node){
00445
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
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
00468 }
00469
00470 printf("material=%s submeshes=%d\n",material.c_str(),list.size());
00471 }
00472 }
00473
00474
00475
00476
00477 std::list<cGfx3D*> cGfx3D::gPrepareFrameStepper;
00478
00479 void cGfx3D::SetPrepareFrameStep (const bool bOn) {
00480 if (mbPrepareFrameStep == bOn) return;
00481 mbPrepareFrameStep = bOn;
00482
00483 if (mbPrepareFrameStep) {
00484 gPrepareFrameStepper.push_front(this);
00485 mPrepareFrameItor = gPrepareFrameStepper.begin();
00486 assert(*mPrepareFrameItor == this && "cGfx3D::SetPrepareFrameStep insert broken\n");
00487 } else {
00488 assert(*mPrepareFrameItor == this && "cGfx3D::SetPrepareFrameStep erase broken\n");
00489 gPrepareFrameStepper.erase(mPrepareFrameItor);
00490 }
00491
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
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
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
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
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
00581
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
00592 if (mpSimpleRenderable) { delete mpSimpleRenderable; mpSimpleRenderable = 0; }
00593 if (mpEntity) { cOgreWrapper::GetSingleton().mSceneMgr->destroyEntity(mpEntity); mpEntity = 0; }
00594 if (mpParticleSystem) {
00595
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
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 }
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
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
00692 if (mpEntity) Clear();
00693
00694
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); }
00703
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
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
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
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790 }
00791
00792 void cGfx3D::SetWireBoundingBox (const Vector3& vMin,const Vector3& vMax) {
00793
00794
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);
00805
00806 SceneNode* scenenode = entity.getParentSceneNode();
00807 if (!scenenode) return;
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
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
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
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
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
00899 mpSimpleRenderable->SkipVertices(4);
00900 mpSimpleRenderable->SkipIndices(6);
00901 } else {
00902
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
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;
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);
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
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
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
01010 mpSceneNode->setPosition(Ogre::Vector3());
01011
01012 mpTrail->setNumberOfChains(1);
01013 mpTrail->setMaxChainElements(iElements);
01014 mpTrail->setMaterialName(szMatName);
01015 mpTrail->setTrailLength(fLength);
01016
01017
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
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
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 };