source: GTP/trunk/App/Demos/Illum/MultipleReflections/Mesh.cpp @ 2242

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