source: GTP/branches/IllumWPdeliver2008dec/IlluminationWP/demos/Standalone/EnvMap [DirectX]/Mesh.cpp @ 3255

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