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

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