source: GTP/trunk/App/Demos/Illum/Standalone/explosion [DirectX]/Mesh.cpp @ 1485

Revision 1485, 4.9 KB checked in by szirmay, 18 years ago (diff)
Line 
1
2#include "dxstdafx.h"
3#include "Mesh.h"
4
5extern IDirect3DDevice9* g_pd3dDevice;
6
7// source: DirectX SDK Samples / OptimizedMesh
8
9Mesh::Mesh(float preferredDiameter)
10{
11        originalDiameter = 1;
12        this->preferredDiameter = preferredDiameter;
13        originalSize = D3DXVECTOR3(1,1,1);
14        position = D3DXVECTOR3(0,0,0);
15        containerSize = D3DXVECTOR3(1,1,1);
16        numMaterials = 0;
17        pMesh = NULL;
18        //if (g_pd3dDevice == NULL) exit(-1);
19}
20
21Mesh::Mesh(LPCWSTR fileName, float preferredDiameter, D3DXVECTOR3 offset)
22{
23        originalDiameter = 1;
24        this->preferredDiameter = preferredDiameter;
25        originalSize = D3DXVECTOR3(1,1,1);
26        position = D3DXVECTOR3(0,0,0);
27        containerSize = D3DXVECTOR3(1,1,1);
28        numMaterials = 0;
29        pMesh = NULL;
30
31        Load(fileName);
32        Move(offset);
33}
34
35void Mesh::Move(D3DXVECTOR3 movement)
36{
37        position += movement;
38
39        // keep some distance from the walls
40        D3DXVECTOR3 maxOffset = containerSize*0.99f - GetMeshSize();
41        D3DXVECTOR3 minOffset = -maxOffset;
42/*
43        if (position.x > maxOffset.x) position.x = maxOffset.x;
44        if (position.y > maxOffset.y) position.y = maxOffset.y;
45        if (position.z > maxOffset.z) position.z = maxOffset.z;
46
47        if (position.x < minOffset.x) position.x = minOffset.x;
48        if (position.y < minOffset.y) position.y = minOffset.y;
49        if (position.z < minOffset.z) position.z = minOffset.z;*/
50}
51
52Mesh::~Mesh()
53{
54    SAFE_RELEASE( pMesh );
55}
56
57HRESULT Mesh::CalculateMeshSize( )
58{
59        // default size
60        originalSize = D3DXVECTOR3(1,1,1);
61        originalDiameter = 1;
62
63        IDirect3DVertexBuffer9* pMeshVB = NULL;
64        D3DXVECTOR3 minPos, maxPos;
65        BYTE* pVertices;
66
67        // Lock the vertex buffer to generate a simple bounding box
68
69        hr = pMesh->GetVertexBuffer( &pMeshVB );
70        if( SUCCEEDED( hr ) )
71        {
72                hr = pMeshVB->Lock( 0, 0, (void**)&pVertices, D3DLOCK_NOSYSLOCK );
73                if( SUCCEEDED(hr) )
74                {
75                        V( D3DXComputeBoundingBox( ( D3DXVECTOR3*)pVertices, pMesh->GetNumVertices(),
76                                                                        D3DXGetFVFVertexSize( pMesh->GetFVF() ),
77                                                                        &minPos, &maxPos ) );
78
79                        D3DXVECTOR3 vCenter = ( minPos + maxPos ) / 2.0f;
80
81                        // eliminating offset from the mesh
82
83                        DWORD numVerts = pMesh->GetNumVertices();                                       // get the face count
84                        DWORD vertSize = D3DXGetFVFVertexSize(pMesh->GetFVF());         // calculate vertex size
85
86                        for (DWORD i = 0; i < numVerts; i++)                                            // loop through the vertices
87                        {
88                                D3DXVECTOR3 *vPtr=(D3DXVECTOR3*)pVertices;                             
89                                *vPtr -= vCenter;                                                                               // eliminating offset
90                                pVertices += vertSize;                                                                  // set pointer to next vertex
91                        }
92
93                        pMeshVB->Unlock();
94                        pMeshVB->Release();
95
96                        // size of the object
97                        originalSize = ( maxPos - minPos ) / 2.0f;
98                        // object "diameter" is calculated from the size of the bounding box only
99                        originalDiameter = sqrt( originalSize.x * originalSize.x +
100                                                                         originalSize.y * originalSize.y +
101                                                                         originalSize.z * originalSize.z) / 1.732f;
102                }
103        }
104       
105        return hr;
106}
107
108void Mesh::Load( LPCWSTR fileName )
109
110        SAFE_RELEASE( pMesh );
111    pMesh = NULL;
112
113//    HRESULT hr;
114
115    if (FAILED( D3DXLoadMeshFromX(fileName, D3DXMESH_MANAGED, g_pd3dDevice, NULL, NULL, NULL, &numMaterials, &pMesh) ))
116        {
117                MessageBox(NULL, L"Media not found!", fileName, MB_ICONEXCLAMATION);
118                exit(-1);
119        }
120/*     
121        if ( FAILED( CalculateMeshSize() ))
122        {
123                MessageBox(NULL, L"Could not calculate bounding box!\nUsing original mesh size...",
124                        fileName, MB_ICONEXCLAMATION);
125        }
126
127    DWORD *rgdwAdjacency = NULL;
128
129    // Make sure there are normals which are required for lighting
130    if( !(pMesh->GetFVF() & D3DFVF_NORMAL) )
131    {
132        ID3DXMesh* pTempMesh;
133        V( pMesh->CloneMeshFVF( pMesh->GetOptions(),
134                                  pMesh->GetFVF() | D3DFVF_NORMAL,
135                                  g_pd3dDevice, &pTempMesh ) );
136        V( D3DXComputeNormals( pTempMesh, NULL ) );
137
138        SAFE_RELEASE( pMesh );
139        pMesh = pTempMesh;
140    }
141
142    // Optimize the mesh for this graphics card's vertex cache
143    rgdwAdjacency = new DWORD[pMesh->GetNumFaces() * 3];
144    if( rgdwAdjacency == NULL ) return ;
145
146    V( pMesh->ConvertPointRepsToAdjacency(NULL, rgdwAdjacency) );
147    V( pMesh->OptimizeInplace(D3DXMESHOPT_VERTEXCACHE, rgdwAdjacency, NULL, NULL, NULL) );
148    delete[] rgdwAdjacency;     */
149}
150
151void Mesh::computeTangent()
152{
153        //V(D3DXComputeTangentFrame(pMesh,D3DXTANGENT_DONT_NORMALIZE_PARTIALS));
154        D3DXComputeTangentFrameEx(pMesh,
155                                                          D3DDECLUSAGE_TEXCOORD, 0,   
156                                                          D3DDECLUSAGE_TANGENT, 0,
157                                                          D3DDECLUSAGE_BINORMAL, 0,
158                                                          D3DDECLUSAGE_NORMAL, 0,
159                                                          D3DXTANGENT_DONT_NORMALIZE_PARTIALS |
160                                                          D3DXTANGENT_GENERATE_IN_PLACE |
161                                                          D3DXTANGENT_CALCULATE_NORMALS, //|
162//                                                        D3DXTANGENT_DONT_ORTHOGONALIZE,
163                                                          NULL, 0.01f, 0.25f, 0.01f, NULL, NULL);
164
165
166}
167
168
169
170HRESULT Mesh::Draw()
171{
172        HRESULT hr;
173    // Set and draw each of the materials in the mesh
174    for( DWORD iMaterial = 0; iMaterial < numMaterials; iMaterial++ )
175    {
176        V( pMesh->DrawSubset( iMaterial ) );
177    }
178
179    return S_OK;
180}
Note: See TracBrowser for help on using the repository browser.