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

Revision 1561, 11.5 KB checked in by gumbau, 18 years ago (diff)

Added F1 key functionality

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