source: GTP/trunk/App/Demos/Illum/Envmap/Mesh.cpp @ 843

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