source: GTP/trunk/App/Games/Jungle_Rumble/src/Object3d.cpp @ 1378

Revision 1378, 13.0 KB checked in by giegl, 18 years ago (diff)

GTPD - Jungle Rumble - integrate into GTP SVN structure

Line 
1#include "dxstdafx.h"
2#include "./Object3d.h"
3
4#include "GameManager.h"
5#include "Scene.h"
6#include <stdio.h>
7
8Object3d::Object3d(void) : Node()
9{
10        myMesh = NULL;
11        myProgressiveMesh = NULL;
12       
13        adjacencyInfo = NULL;
14        g_dwNumMaterials = 0;
15       
16        this->isAPMesh = false;
17        this->modelLoaded = false;
18        this->isManagedByResourceManager = false;
19        this->deleteMesh = true;
20
21        this->pVertices = NULL;
22        this->pIndices = NULL;
23        this->writeBuffer = NULL;
24
25        this->maxFaces = 0;
26        this->minFaces = 0;
27        this->nodeType |= Scene::NODE_OBJECT3D;
28        this->xfilename = "";
29}
30
31Object3d::~Object3d(void)
32{
33        //TODO noch mehr releasen? leaks gefunden!
34        if(myMesh!=NULL && !(isManagedByResourceManager)) {
35                (myMesh)->Release();
36        }
37       
38        if(myProgressiveMesh!=NULL) {
39                myProgressiveMesh->Release();
40        }
41
42        if(!(isManagedByResourceManager)) {
43                delete [] adjacencyInfo;
44        }
45
46        this->Materials.clear();
47
48        /*for(UINT i = 0; i < Textures.size(); i++) {
49                if (Textures[i] != 0 && (!this->isTerrainPatch))
50                        Textures[i]->Release();
51                        Textures[i] = 0;
52        }*/
53
54        if(this->pVertices) {
55                delete[] this->pVertices;
56                this->pVertices = NULL;
57        }
58        if(this->pIndices) {
59                delete[] this->pIndices;
60                this->pIndices = NULL;
61        }
62        if(this->writeBuffer) {
63                delete this->writeBuffer;
64                this->writeBuffer = NULL;
65        }
66}
67
68LPD3DXMESH* Object3d::getMesh()
69{
70        return &myMesh;
71}
72
73void Object3d::setMesh(LPD3DXMESH *_mesh) {
74        this->myMesh = *_mesh;
75}
76
77LPD3DXPMESH* Object3d::getProgressiveMesh()
78{
79        return &myProgressiveMesh;
80}
81
82void Object3d::loadMeshFromFile(std::string filename)
83{
84        //this->myScene->manager->printToConsole(filename);
85        bool success = this->myScene->manager->resManager.loadXModel(filename, this);
86        if(!success) {
87                // set everything to NULL
88                myMesh = NULL;
89                this->g_dwNumMaterials = 0;
90                this->modelLoaded = false;
91                this->myScene->manager->printToConsole("loading model failed!");
92        } else {
93                this->xfilename = filename;
94                //this->myScene->manager->printToConsole("3d model loaded successfully!");
95        }
96
97}
98
99void Object3d::computeAdjacency () {
100        if(myMesh!=NULL) {
101                if (adjacencyInfo != NULL)
102                        delete [] adjacencyInfo;
103               
104                //generate new DWORD array
105                adjacencyInfo = new DWORD[(myMesh)->GetNumFaces() * 3];
106                memset(adjacencyInfo,0,(myMesh)->GetNumFaces() * 3);
107
108                // Get the adjacency info of the mesh.
109                (myMesh)->GenerateAdjacency(0.0f, adjacencyInfo);
110        }
111}
112
113void Object3d::computeNormals()
114{
115        if(myMesh!=NULL) {
116                // if mesh vertices have no normal variables defined, add them
117                if ( !((myMesh)->GetFVF() & D3DFVF_NORMAL))
118                {
119                        // define a temp mesh for the mesh with normal variables
120                        LPD3DXMESH pTempMesh;
121
122                        // clone the mesh, add normal variables
123                        (myMesh)->CloneMeshFVF((myMesh)->GetOptions(),
124                                                                        (myMesh)->GetFVF() | D3DFVF_NORMAL,
125                                                                        DXUTGetD3DDevice(),
126                                                                        &pTempMesh
127                                                                        );
128                       
129                        // release the old mesh
130                        (myMesh)->Release();
131                        myMesh = pTempMesh;
132                }
133
134                if (adjacencyInfo == NULL)
135                        computeAdjacency();
136
137                D3DXComputeNormals(
138                        myMesh,
139                        adjacencyInfo
140                );
141        }
142}
143
144bool Object3d::isModelLoaded()
145{
146        return this->modelLoaded;
147}
148
149void Object3d::setModelLoaded(bool value) {
150        this->modelLoaded = value;
151}
152
153void Object3d::setXFilename(std::string _xfilename) {
154        this->xfilename = _xfilename;
155}
156
157void Object3d::generateAndUsePMesh(float *weights) {
158        if(this->myProgressiveMesh != NULL)
159                this->myProgressiveMesh->Release();
160
161        if(adjacencyInfo == NULL) {
162                this->computeAdjacency();
163        }
164       
165        //generate progressive mesh:
166        HRESULT hr = D3DXGeneratePMesh(
167                        myMesh,
168                        this->adjacencyInfo, // adjacency
169                        0,                  // default vertex attribute weights
170                        weights,                  // default vertex weights
171                        1,                  // simplify as low as possible
172                        D3DXMESHSIMP_FACE,  // simplify by face count
173                        &myProgressiveMesh);
174
175        if(FAILED(hr))
176        {
177                // go to previous state:
178                if(this->myProgressiveMesh != NULL) {
179                        this->myProgressiveMesh->Release();
180                        this->myProgressiveMesh = NULL;
181                }
182                this->isAPMesh = false;
183        } else {
184                // set to original detail
185                maxFaces = this->myProgressiveMesh->GetMaxFaces();
186                minFaces = this->myProgressiveMesh->GetMinFaces() + 40;
187
188                //set to max
189                this->myProgressiveMesh->SetNumFaces(maxFaces);
190               
191                // this is now a progressive mesh! :)
192                this->isAPMesh = true;
193        }
194}
195
196void Object3d::generateAndUsePMesh() {
197        this->generateAndUsePMesh(NULL);
198}
199
200bool Object3d::isPMesh() {
201        return this->isAPMesh;
202}
203
204void Object3d::generatePhysicMesh(int type)
205{       
206        if(this->pVertices) {
207                delete[] this->pVertices;
208                this->pVertices = NULL;
209        }
210        if(this->pIndices) {
211                delete[] this->pIndices;
212                this->pIndices = NULL;
213        }
214        if(this->writeBuffer) {
215                delete this->writeBuffer;
216                this->writeBuffer = NULL;
217        }
218        this->shapeType = type;
219        NxInitCooking();
220
221        int numVertices = (myMesh)->GetNumVertices();
222        int numFaces = (myMesh)->GetNumFaces();
223        int vertexSize = (myMesh)->GetNumBytesPerVertex();
224
225        //Vertex Data
226        byte* verPointer;
227        pVertices = new NxVec3[numVertices];
228        (myMesh)->LockVertexBuffer(0, (void**)&verPointer);
229        bool changed=false;
230        for(int i=0;i<numVertices;i++) {
231                pVertices[i].x = ((float *) verPointer)[0];
232                pVertices[i].y = ((float *) verPointer)[1];
233                pVertices[i].z = ((float *) verPointer)[2];
234                //If terrain is exactly plain, move one point so that it's not! Otherwise it CHRASHES!!!
235                if(i>=1 && pVertices[i-1].y-pVertices[i].y!=0) {
236                        changed = true;
237                } else if(i>=1 && i==numVertices-1 && changed==false) {
238                        pVertices[i].y+=0.0005f;
239                }
240                verPointer+=vertexSize;
241        }
242        (myMesh)->UnlockVertexBuffer();
243
244        //Indices Data
245        WORD *indexPointer;             
246        pIndices = new DWORD[3*numFaces];
247        (myMesh)->LockIndexBuffer(0, (void**) &indexPointer);
248        for(int i=0;i<3*numFaces;i++) {
249                pIndices[i] = (WORD) indexPointer[i];
250        }
251        (myMesh)->UnlockIndexBuffer();
252
253        if(type!=this->COL_CONVEX) {
254                // Build the triangle mesh.
255                this->pTriangleMeshDesc.numVertices                             = numVertices;
256                this->pTriangleMeshDesc.numTriangles                    = numFaces;
257                this->pTriangleMeshDesc.pointStrideBytes                = sizeof(NxVec3);
258                this->pTriangleMeshDesc.triangleStrideBytes             = 3*sizeof(DWORD);
259                this->pTriangleMeshDesc.points                                  = pVertices;
260                this->pTriangleMeshDesc.triangles                               = pIndices;
261                this->pTriangleMeshDesc.flags                                   = 0;
262                if(type==this->COL_HEIGHTFIELD) {
263                        this->pTriangleMeshDesc.heightFieldVerticalAxis= NX_Y;   
264                        this->pTriangleMeshDesc.heightFieldVerticalExtent= -1000.0f;
265                }
266
267                if(!this->pTriangleMeshDesc.isValid()) {
268                        this->myScene->manager->printToConsole("pTriangleMeshDesc IS NOT VALID!");
269                }
270
271                if(writeBuffer!=NULL)
272                        delete this->writeBuffer;
273                this->writeBuffer = new MemoryWriteBuffer;
274                if(!NxCookTriangleMesh(this->pTriangleMeshDesc, *this->writeBuffer)) {
275                        this->myScene->manager->printToConsole("COOKING NOT SUCCESSFULL!!!!!");
276                }
277
278                //Create the mesh from the cooked data.
279                MemoryReadBuffer readBuffer(this->writeBuffer->data);
280                this->pTriangleMesh = this->myScene->manager->pPhysicsSDK->createTriangleMesh(readBuffer);
281
282                //Use PMap as coldet model?
283                if(type==this->COL_PMAP) {
284                        std::string pmapFilename;
285                        pmapFilename = this->xfilename+".pmap";
286                        NxPMap pPMap;
287                        pPMap.dataSize  = 0;
288                        pPMap.data              = NULL;
289
290                        // PMap stuff
291                        this->myScene->manager->printToConsole("trying to load pmap");
292                       
293                        FILE* fp = fopen(pmapFilename.c_str(), "rb");
294                        if(!fp) {
295                                // Not found => create PMap
296                                this->myScene->manager->printToConsole("please wait while precomputing pmap...");
297                                if(NxCreatePMap(pPMap, *this->pTriangleMesh, 64))
298                                        {
299                                        // The pmap has successfully been created, save it to disk for later use
300                                        fp = fopen(pmapFilename.c_str(), "wb");
301                                        if(fp)
302                                        {
303                                                fwrite(pPMap.data, pPMap.dataSize, 1, fp);
304                                                fclose(fp);
305                                                fp = NULL;
306                                        }
307
308                                        //assign pmap to mesh
309                                        this->pTriangleMesh->loadPMap(pPMap);
310
311                                        // sdk created data => sdk deletes it
312                                        NxReleasePMap(pPMap);
313                                        }
314                                this->myScene->manager->printToConsole("...done!");
315                        } else {
316                                // Found pmap file
317                                pPMap.dataSize  = getFileSize(pmapFilename.c_str());
318                                pPMap.data              = new NxU8[pPMap.dataSize];
319                                fread(pPMap.data, pPMap.dataSize, 1, fp);
320                                fclose(fp);
321
322                                //assign pmap to mesh
323                                this->pTriangleMesh->loadPMap(pPMap);
324
325                                //we created data => we delete it
326                                delete pPMap.data;
327                        }
328                }
329
330                this->pMeshShapeDesc.meshData = this->pTriangleMesh;
331                if(!pMeshShapeDesc.isValid()) {
332                        this->myScene->manager->printToConsole("SHAPEDESCRIPTOR IS NOT VALID!");
333                }
334                this->pActorDesc.shapes.pushBack(&pMeshShapeDesc);
335               
336                if(!this->pActorDesc.isValid()) {
337                        this->myScene->manager->printToConsole("generatePhysicsMesh:: ActorDescriptor is not valid!!");
338                        return;
339                }
340        } else {
341                this->pConvexDesc.numVertices          = numVertices;
342                this->pConvexDesc.pointStrideBytes     = sizeof(NxVec3);
343                this->pConvexDesc.points               = this->pVertices;
344                this->pConvexDesc.flags                = NX_CF_COMPUTE_CONVEX;
345               
346
347                if(!this->pConvexDesc.isValid()) {
348                        this->myScene->manager->printToConsole("pConvexMeshDesc IS NOT VALID!");
349                }
350
351                if(writeBuffer!=NULL)
352                        delete this->writeBuffer;
353                this->writeBuffer = new MemoryWriteBuffer;
354                if(NxCookConvexMesh(this->pConvexDesc, *this->writeBuffer))
355                {
356                        this->pConvexShapeDesc.meshData = this->myScene->manager->pPhysicsSDK->createConvexMesh(MemoryReadBuffer(this->writeBuffer->data));
357                        if(this->pConvexShapeDesc.meshData) {
358                                this->pActorDesc.shapes.pushBack(&this->pConvexShapeDesc);
359                        } else {
360                                this->myScene->manager->printToConsole("Getting convexShapeDesc from SDK failed!");
361                        }
362                } else {
363                        this->myScene->manager->printToConsole("Cooking pConvexMeshDesc FAILED! MAYBE NX_CF_USE_LEGACY_COOKER FLAG WOULD HELP?");
364                }
365        }
366               
367        NxCloseCooking();
368}
369
370NxU32 Object3d::getFileSize(const char* name)
371{
372        #ifndef SEEK_END
373        #define SEEK_END 2
374        #endif
375       
376        FILE* File = fopen(name, "rb");
377        if(!File)
378                return 0;
379
380        fseek(File, 0, SEEK_END);
381        NxU32 eof_ftell = ftell(File);
382        fclose(File);
383        return eof_ftell;
384}
385
386NxShapeDesc* Object3d::getPhysicShape()
387{
388        switch(this->shapeType)
389        {
390                case this->COL_CONVEX:
391                        return &this->pConvexShapeDesc;
392                        break;
393                case this->COL_MESH:
394                        return &this->pMeshShapeDesc;
395                        break;
396                default:
397                        return NULL;
398                        break;
399        }
400}
401
402Node* Object3d::clone()
403{
404        //this->myScene->manager->printToConsole("Object3d.clone not implemented!");
405
406        Object3d* obj = (Object3d*) this->myScene->createNode(Scene::NODE_OBJECT3D,*this->father, true, false);
407        this->cloneChildren(obj);
408        return this->cloneObject3d(obj);
409}
410
411Object3d* Object3d::cloneObject3d(Object3d* obj)
412{
413        obj->setMesh(&this->myMesh);
414        //set number of materials
415        obj->g_dwNumMaterials = (DWORD)this->Materials.size();
416        //set adjacency info
417        obj->adjacencyInfo = this->adjacencyInfo;
418        //set materials & textures:
419        obj->Materials.resize(this->Materials.size());
420        obj->Textures.resize(this->Textures.size());
421        for (UINT i = 0; i < this->Materials.size(); i++) {
422                obj->Materials[i] = this->Materials[i];
423                obj->Textures[i] = this->Textures[i];
424        }
425
426        obj->minAABBox = this->minAABBox;
427        obj->maxAABBox = this->maxAABBox;
428
429        obj->setXFilename(this->xfilename);
430        obj->isManagedByResourceManager = true;
431        obj->setModelLoaded(true);
432        obj->softKill = this->softKill;
433        obj->softKillDuration = this->softKillDuration;
434
435        //if(this->pActor!=NULL) {
436        //Physic Stuff
437        obj->pBodyDesc = this->pBodyDesc;
438        obj->pActorDesc.body = &obj->pBodyDesc;
439        obj->pActorDesc = this->pActorDesc;
440        //obj->setBehaveAs(this->behaveAs);
441        //}
442        obj->aClone = true;
443        return obj;
444}
445
446void Object3d::setDetail(Vector ObjectCenter) {
447        if(this->isPMesh()) {
448                //jetzt mus etwas passieren :)
449                Vector dist = this->myScene->getActiveCamera()->getPosition() - ObjectCenter;
450                float distance = sqrt(dist.x*dist.x + dist.y*dist.y + dist.z*dist.z);
451               
452                if (distance < 150) {
453                        this->myProgressiveMesh->SetNumFaces(this->maxFaces/4);
454                } else {
455                        float maxdist = sqrt(2 * this->myScene->getWidth() * this->myScene->getWidth());
456                        float factor = (maxdist - distance)/maxdist/2;
457                        float myNumberOfFaces = (maxFaces - minFaces) * factor;
458                        this->myProgressiveMesh->SetNumFaces((DWORD)myNumberOfFaces);
459                        //this->myProgressiveMesh->SetNumFaces(this->minFaces);
460                }
461        }
462}
463
464void Object3d::OnDestroyDevice( void* pUserContext )
465{
466        if(myMesh!=NULL && !(isManagedByResourceManager)) {
467                SAFE_RELEASE(myMesh);//->Release();
468        }
469       
470        if(myProgressiveMesh!=NULL) {
471                SAFE_RELEASE(myProgressiveMesh);//->Release();
472        }
473
474        if(!(isManagedByResourceManager)) {
475                delete [] adjacencyInfo;
476        }
477
478        this->Textures.clear();
479        this->Materials.clear();
480}
481
482HRESULT Object3d::OnResetDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )
483{
484        if(this->xfilename.compare("")!=0) {
485                this->loadMeshFromFile(this->xfilename);
486        }
487        return S_OK;
488}
489
490/*void Object3d::update(float dt)
491{
492        Node::update(dt);
493        if(this->timeToLive!=-100) {
494                if(this->timeToLive<=this->softKillDuration) {
495                        this->doingSoftKill = true;
496                        this->softKillAlpha = this->timeToLive/this->softKillDuration;
497                }
498        }
499}*/
Note: See TracBrowser for help on using the repository browser.