source: GTP/trunk/App/Demos/Geom/Demo_LodTrees/main.cpp @ 1540

Revision 1540, 10.1 KB checked in by gumbau, 18 years ago (diff)

Demo updated with the new version of the programming interface.

Line 
1/*      ==========================================================================
2 *      (C) 2006 Universitat Jaume I
3 *      ==========================================================================
4 *      PROYECT:        GAME TOOLS
5 *      ==========================================================================*/
6/**     CONTENT:       
7        *
8        *
9        *       @file   main.cpp
10/** COMMENTS:
11        * Model must be in "media/models" folder.
12        * Lod file must be in "media/GT" folder.
13/*===========================================================================*/
14#include "ExampleApplication.h"
15#include "GeoLodTreeLibrary.h"
16#include "GeoMeshLoader.h"
17
18
19// Distance values
20#define dist_min 300
21#define dist_max 700
22
23// Model name
24#define model_name "arbol"
25
26
27//Global variables
28Entity* entity;
29Geometry::LodTreeLibrary* myTrees;
30Ogre::Mesh *ogreMesh=NULL;
31Geometry::GeoMeshLoader *meshloader=NULL;
32bool force_maxLODfactor = false;
33
34Ogre::Vector3 forest_center;
35
36ColourValue color=ColourValue::Red;
37
38Camera* theCam;
39Entity* pPlaneEnt;
40
41OverlayElement* mInfo;
42OverlayElement* mInfo2;
43
44
45
46class LodTreeFrameListener : public ExampleFrameListener
47{
48        int manage;
49
50public:
51
52    LodTreeFrameListener(RenderWindow* win, Camera* cam)
53        : ExampleFrameListener(win, cam, false, false)
54    {
55                manage=1;
56        }
57
58        bool frameStarted(const FrameEvent& evt)
59    {
60                Vector3 dist;
61                int distance=0,inc2=0,d;
62                unsigned int nlod,diflods;
63
64                // Move upto 80 units/second
65                Real MoveFactor = 180.0 * evt.timeSinceLastFrame;
66
67                // Copy the current state of the input devices
68                mInputDevice->capture();
69
70                // If this is the first frame, pick a speed
71                if (evt.timeSinceLastFrame == 0)
72                {
73                        mMoveScale = 1;
74                        mRotScale = 0.1;
75                }
76                // Otherwise scale movement units by time passed since last frame
77                else
78                {
79                        // Move about 100 units per second,
80                        mMoveScale = mMoveSpeed * evt.timeSinceLastFrame;
81                        // Take about 10 seconds for full rotation
82                        mRotScale = mRotateSpeed * evt.timeSinceLastFrame;
83                }
84
85                mRotX = 0;
86        mRotY = 0;
87            mTranslateVector = Vector3::ZERO;
88
89                //LOD selection
90                int difdist = dist_max - dist_min;
91       
92                int i=0;
93
94                dist = forest_center - mCamera->getPosition();
95                distance =dist.length();
96
97                float lodfactor = (float)(distance - dist_min) / (float)(dist_max - dist_min);
98                lodfactor = 1.0f - lodfactor;
99
100                if (lodfactor<0.0f)
101                        lodfactor=0.0f;
102                if (lodfactor>1.0f)
103                        lodfactor=1.0f;
104
105                if (force_maxLODfactor)
106                        lodfactor=1.0f;
107
108                static float lodfactorBefore = -1.0f;
109                if (fabsf(lodfactorBefore-lodfactor)>0.05f)
110                {
111                        myTrees->GoToLod(lodfactor);
112//                      DumpDataToOgreBuffers(ogreMesh,myTrees);
113                        lodfactorBefore=lodfactor;
114                }
115
116                // Move the cam
117                if(mInputDevice->isKeyDown(Ogre::KC_UP) ||
118                   mInputDevice->isKeyDown(Ogre::KC_W) ||
119                   mInputDevice->isKeyDown(Ogre::KC_NUMPAD5))
120                  mTranslateVector.z = -mMoveScale;
121
122                if(mInputDevice->isKeyDown(Ogre::KC_DOWN) ||
123                   mInputDevice->isKeyDown(Ogre::KC_S) ||
124                   mInputDevice->isKeyDown(Ogre::KC_NUMPAD2))
125                  mTranslateVector.z = mMoveScale;
126
127                if (mInputDevice->isKeyDown(Ogre::KC_A) ||
128                        mInputDevice->isKeyDown(Ogre::KC_NUMPAD1))
129                        mTranslateVector.x = -mMoveScale;
130
131                if (mInputDevice->isKeyDown(Ogre::KC_D) ||
132                        mInputDevice->isKeyDown(Ogre::KC_NUMPAD3))
133                        mTranslateVector.x = mMoveScale;
134
135                // Instead of moving the ship left and right, rotate it using yaw()
136                if(mInputDevice->isKeyDown(Ogre::KC_LEFT))
137                  mCamera->yaw(mRotScale);
138
139                force_maxLODfactor=mInputDevice->isKeyDown(Ogre::KC_F2);                 
140
141                if(mInputDevice->isKeyDown(Ogre::KC_RIGHT))
142                  mCamera->yaw(-mRotScale);
143
144                if(mInputDevice->isKeyDown(Ogre::KC_ESCAPE))
145                {
146                        //delete myTrees;
147                    return false;
148                }
149
150        if( mInputDevice->getMouseButton( 1 ) )
151        {
152            mTranslateVector.x += mInputDevice->getMouseRelativeX() * 0.13;
153            mTranslateVector.y -= mInputDevice->getMouseRelativeY() * 0.13;
154        }
155        else
156        {
157            mRotX = Degree(-mInputDevice->getMouseRelativeX() * 0.13);
158            mRotY = Degree(-mInputDevice->getMouseRelativeY() * 0.13);
159        }
160
161
162                char cadena[256];
163
164                               
165                sprintf(cadena,"Distance: %d",distance);
166               
167                mInfo->setCaption(cadena);
168
169                sprintf(cadena,"LOD factor: %f",lodfactor);
170
171                mInfo2->setCaption(cadena);
172
173                mCamera->yaw(mRotX);
174        mCamera->pitch(mRotY);
175        mCamera->moveRelative(mTranslateVector);
176
177                return true;
178    }
179};
180
181class CustomIndexData : public Geometry::IndexData
182{
183private:
184        Ogre::Mesh *targetMesh;
185        Ogre::HardwareIndexBufferSharedPtr ibuf;
186        Ogre::RenderOperation mRenderOp;
187        unsigned long* pIdx;
188public:
189        CustomIndexData(Ogre::Mesh *ogremesh):Geometry::IndexData(){
190                targetMesh=ogremesh;
191                pIdx=NULL;
192        }
193        virtual ~CustomIndexData(void){}
194
195        virtual void Begin(unsigned int submeshid, unsigned int indexcount){
196                targetMesh->getSubMesh(submeshid)->_getRenderOperation(mRenderOp,0);
197                ibuf = mRenderOp.indexData->indexBuffer;
198                mRenderOp.indexData->indexCount = indexcount;
199                pIdx = static_cast<unsigned long*>(ibuf->lock(Ogre::HardwareBuffer::HBL_NORMAL));
200        }
201        virtual void SetIndex(unsigned int i, unsigned int index){
202                pIdx[i] = index; //lodStripsLib->dataRetrievalInterface->GetIndex(k+offset);
203        }
204        virtual void End(){
205                ibuf->unlock();
206        }
207
208        virtual void BorrowIndexData(const Geometry::IndexData *){}
209};
210
211
212class LodTreeApplication : public ExampleApplication
213{
214protected:
215public:
216    LodTreeApplication(){}
217    ~LodTreeApplication(){}
218
219protected:
220   
221
222
223    // Just override the mandatory create scene method
224    void createScene(void)
225    {
226//              mat = new MaterialPtr[1];
227               
228        theCam = mCamera;
229                theCam->setPosition(0,20,dist_min-40);
230        // Set ambient light
231        mSceneMgr->setAmbientLight(ColourValue(0.4, 0.4, 0.4));
232
233        // Create a directional light
234                Light* l = mSceneMgr->createLight("MainLight");
235                l->setType(Light::LT_DIRECTIONAL);
236        l->setDirection(0.0,-1.0,0.0);
237       
238        // Define a floor plane mesh
239                Plane plane( Vector3::UNIT_Y, 0 );
240
241                MeshManager::getSingleton().createPlane("ground",
242                        ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, plane,
243                        1500,1500,20,20,true,1,5,5,Vector3::UNIT_Z);
244
245                Entity* suelo = mSceneMgr->createEntity( "GroundEntity", "ground" );
246                mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(suelo);
247               
248
249                suelo->setMaterialName("Examples/GrassFloor");
250                suelo->setCastShadows(false);       
251
252       
253        mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox");
254
255        // My node to which all objects will be attached
256        SceneNode* myRootNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
257
258                std::string model_file=model_name;
259                model_file.append(".mesh");
260
261                //Models
262        entity = mSceneMgr->createEntity(model_name, "../../../OgreStuff/media/GT/ML12m.mesh");
263
264                ogreMesh = entity->getMesh().getPointer();
265
266                // load LOD info from the object
267                meshloader=new Geometry::GeoMeshLoader;
268                Geometry::Mesh *themesh = meshloader->load("../../../OgreStuff/media/GT/ML12m.mesh");
269
270                if (!meshloader->GetLodStripsData())
271            OGRE_EXCEPT(1, "The loaded mesh does not contain LOD info for the trunk","LOD Demo");
272                if (!meshloader->GetTreeSimpSeq())
273            OGRE_EXCEPT(1, "The loaded mesh does not contain LOD info for the foliage","LOD Demo");
274
275                myTrees = new Geometry::LodTreeLibrary( meshloader->GetLodStripsData(),
276                                                                                                meshloader->GetTreeSimpSeq(),
277                                                                                                themesh,
278                                                                                                new CustomIndexData(ogreMesh));
279
280                entity->setNormaliseNormals(true);
281
282                for (int submesh=0; submesh < ogreMesh->getNumSubMeshes(); submesh++)
283                {
284                        bool istrunk = myTrees->GetLeavesSubMesh()!=submesh;
285                        if (istrunk)
286                                entity->getSubEntity(submesh)->setMaterialName("Examples/Populifolia/trunk");
287                        else
288                                entity->getSubEntity(submesh)->setMaterialName("Examples/Populifolia/leaf");
289                }
290
291                forest_center=Ogre::Vector3(150.0f,0.0f,0.0f);
292                for (int i=1; i<8; i++) // 20
293                        for (int j=1; j<8; j++) // 20
294                        {
295                                char newTreeName[16]="";
296                                sprintf(newTreeName,"arbol_%d_%d",i,j);
297                                Ogre::SceneNode * auxnode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
298                                Ogre::Entity *auxent = entity->clone(newTreeName);
299                                auxnode->attachObject( auxent );
300                                auxnode->scale(4.0f,4.0f,4.0f);
301                                auxnode->rotate(Ogre::Vector3(0,0,1),Ogre::Degree(rand()%360));
302                                auxnode->rotate(Ogre::Vector3(1,0,0),Ogre::Radian(-3.14159f*0.5f),Ogre::Node::TS_WORLD);
303                                float randomsepx = (float)((rand()%18)-9);
304                                float randomsepy = (float)((rand()%12)-6);
305                                auxnode->translate(i*30.0f+randomsepx,0.0f,-j*30.0f-randomsepx);
306                                auxent->setNormaliseNormals(true);
307                        }
308
309                if (!meshloader->GetLodStripsData() || !meshloader->GetTreeSimpSeq())
310            OGRE_EXCEPT(1, "The loaded mesh does not contain any LOD info","LOD Demo");
311
312
313        // show overlay
314        Overlay* pOver = OverlayManager::getSingleton().getByName("Demo_LodStrips/Overlay");   
315        mInfo = OverlayManager::getSingleton().getOverlayElement("Demo_LodStrips/Info_1");
316                mInfo2 = OverlayManager::getSingleton().getOverlayElement("Demo_LodStrips/Info_2");
317            pOver->show();
318
319    }
320
321    void createFrameListener(void)
322    {
323        mFrameListener= new LodTreeFrameListener(mWindow, mCamera);
324        mFrameListener->showDebugOverlay(true);
325        mRoot->addFrameListener(mFrameListener);
326    }
327
328};
329
330
331
332#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
333#define WIN32_LEAN_AND_MEAN
334#include "windows.h"
335#endif
336
337#ifdef __cplusplus
338extern "C" {
339#endif
340
341#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
342INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
343#else
344int main(int argc, char **argv)
345#endif
346{
347    // Create application object
348    LodTreeApplication app;
349
350    try {
351        app.go();
352    } catch( Exception& e ) {
353#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
354        MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
355#else
356        std::cerr << "An exception has occured: " << e.getFullDescription();
357#endif
358    }
359
360
361    return 0;
362}
363
364#ifdef __cplusplus
365}
366#endif
Note: See TracBrowser for help on using the repository browser.