3 * Copyright (c) 2007-2010 SlimDX Group
\r
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
\r
6 * of this software and associated documentation files (the "Software"), to deal
\r
7 * in the Software without restriction, including without limitation the rights
\r
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
\r
9 * copies of the Software, and to permit persons to whom the Software is
\r
10 * furnished to do so, subject to the following conditions:
\r
12 * The above copyright notice and this permission notice shall be included in
\r
13 * all copies or substantial portions of the Software.
\r
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
\r
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
\r
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
\r
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
\r
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
\r
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
\r
27 #include "../ComObject.h"
\r
28 #include "../Utilities.h"
\r
29 #include "../DataStream.h"
\r
32 #include "Texture.h"
\r
33 #include "IndexBuffer.h"
\r
34 #include "VertexBuffer.h"
\r
36 #include "SimplificationMesh.h"
\r
37 #include "ProgressiveMesh.h"
\r
39 #include "Direct3D9Exception.h"
\r
41 using namespace System;
\r
42 using namespace System::IO;
\r
43 using namespace System::Runtime::InteropServices;
\r
49 SimplificationMesh::SimplificationMesh( Mesh^ mesh, array<AttributeWeights>^ vertexAttributeWeights, array<float>^ vertexWeights )
\r
51 ID3DXSPMesh *result;
\r
53 DWORD *adjacencyIn = NULL;
\r
54 pin_ptr<int> pinnedAdj;
\r
55 array<int>^ adjacency = mesh->GetAdjacency();
\r
57 if( adjacency != nullptr )
\r
59 pinnedAdj = &adjacency[0];
\r
60 adjacencyIn = reinterpret_cast<DWORD*>( pinnedAdj );
\r
63 pin_ptr<AttributeWeights> pinnedVAW = &vertexAttributeWeights[0];
\r
64 pin_ptr<float> pinnedVW = &vertexWeights[0];
\r
66 HRESULT hr = D3DXCreateSPMesh( mesh->InternalPointer, adjacencyIn,
\r
67 reinterpret_cast<const D3DXATTRIBUTEWEIGHTS*>( pinnedVAW ), reinterpret_cast<const FLOAT *>( pinnedVW ), &result );
\r
69 if( RECORD_D3D9( hr ).IsFailure )
\r
70 throw gcnew Direct3D9Exception( Result::Last );
\r
75 SimplificationMesh::SimplificationMesh( Mesh^ mesh, array<AttributeWeights>^ vertexAttributeWeights )
\r
77 ID3DXSPMesh *result;
\r
79 DWORD *adjacencyIn = NULL;
\r
80 pin_ptr<int> pinnedAdj;
\r
81 array<int>^ adjacency = mesh->GetAdjacency();
\r
83 if( adjacency != nullptr )
\r
85 pinnedAdj = &adjacency[0];
\r
86 adjacencyIn = reinterpret_cast<DWORD*>( pinnedAdj );
\r
89 pin_ptr<AttributeWeights> pinnedVAW = &vertexAttributeWeights[0];
\r
91 HRESULT hr = D3DXCreateSPMesh( mesh->InternalPointer, adjacencyIn,
\r
92 reinterpret_cast<const D3DXATTRIBUTEWEIGHTS*>( pinnedVAW ), NULL, &result );
\r
94 if( RECORD_D3D9( hr ).IsFailure )
\r
95 throw gcnew Direct3D9Exception( Result::Last );
\r
100 SimplificationMesh::SimplificationMesh( Mesh^ mesh, array<float>^ vertexWeights )
\r
102 ID3DXSPMesh *result;
\r
104 DWORD *adjacencyIn = NULL;
\r
105 pin_ptr<int> pinnedAdj;
\r
106 array<int>^ adjacency = mesh->GetAdjacency();
\r
108 if( adjacency != nullptr )
\r
110 pinnedAdj = &adjacency[0];
\r
111 adjacencyIn = reinterpret_cast<DWORD*>( pinnedAdj );
\r
114 pin_ptr<float> pinnedVW = &vertexWeights[0];
\r
116 HRESULT hr = D3DXCreateSPMesh( mesh->InternalPointer, adjacencyIn,
\r
117 NULL, reinterpret_cast<const FLOAT *>( pinnedVW ), &result );
\r
119 if( RECORD_D3D9( hr ).IsFailure )
\r
120 throw gcnew Direct3D9Exception( Result::Last );
\r
125 SimplificationMesh::SimplificationMesh( Mesh^ mesh )
\r
127 ID3DXSPMesh *result;
\r
129 DWORD *adjacencyIn = NULL;
\r
130 pin_ptr<int> pinnedAdj;
\r
131 array<int>^ adjacency = mesh->GetAdjacency();
\r
133 if( adjacency != nullptr )
\r
135 pinnedAdj = &adjacency[0];
\r
136 adjacencyIn = reinterpret_cast<DWORD*>( pinnedAdj );
\r
139 HRESULT hr = D3DXCreateSPMesh( mesh->InternalPointer, adjacencyIn, NULL, NULL, &result );
\r
141 if( RECORD_D3D9( hr ).IsFailure )
\r
142 throw gcnew Direct3D9Exception( Result::Last );
\r
147 Mesh^ SimplificationMesh::Clone( SlimDX::Direct3D9::Device^ device, MeshFlags options, array<VertexElement>^ vertexDeclaration, [Out] array<int>^% vertexRemap )
\r
151 pin_ptr<VertexElement> pinnedDecl = &vertexDeclaration[0];
\r
152 array<int>^ adjacencyOut = gcnew array<int>( FaceCount * 3 );
\r
153 pin_ptr<int> pinnedAdj = &adjacencyOut[0];
\r
154 vertexRemap = gcnew array<int>( VertexCount );
\r
155 pin_ptr<int> pinnedVR = &vertexRemap[0];
\r
157 HRESULT hr = InternalPointer->CloneMesh( static_cast<DWORD>( options ), reinterpret_cast<const D3DVERTEXELEMENT9*>( pinnedDecl ),
\r
158 device->InternalPointer, reinterpret_cast<DWORD*>( pinnedAdj ), reinterpret_cast<DWORD*>( pinnedVR ), &result );
\r
160 if( RECORD_D3D9( hr ).IsFailure )
\r
162 vertexRemap = nullptr;
\r
166 Mesh^ mesh = Mesh::FromPointer( result );
\r
167 mesh->SetAdjacency( adjacencyOut );
\r
172 Mesh^ SimplificationMesh::Clone( SlimDX::Direct3D9::Device^ device, MeshFlags options, array<VertexElement>^ vertexDeclaration )
\r
176 pin_ptr<VertexElement> pinnedDecl = &vertexDeclaration[0];
\r
177 array<int>^ adjacencyOut = gcnew array<int>( FaceCount * 3 );
\r
178 pin_ptr<int> pinnedAdj = &adjacencyOut[0];
\r
180 HRESULT hr = InternalPointer->CloneMesh( static_cast<DWORD>( options ), reinterpret_cast<const D3DVERTEXELEMENT9*>( pinnedDecl ),
\r
181 device->InternalPointer, reinterpret_cast<DWORD*>( pinnedAdj ), NULL, &result );
\r
183 if( RECORD_D3D9( hr ).IsFailure )
\r
186 Mesh^ mesh = Mesh::FromPointer( result );
\r
187 mesh->SetAdjacency( adjacencyOut );
\r
192 Mesh^ SimplificationMesh::Clone( SlimDX::Direct3D9::Device^ device, MeshFlags options, SlimDX::Direct3D9::VertexFormat fvf, [Out] array<int>^% vertexRemap )
\r
196 array<int>^ adjacencyOut = gcnew array<int>( FaceCount * 3 );
\r
197 pin_ptr<int> pinnedAdj = &adjacencyOut[0];
\r
198 vertexRemap = gcnew array<int>( VertexCount );
\r
199 pin_ptr<int> pinnedVR = &vertexRemap[0];
\r
201 HRESULT hr = InternalPointer->CloneMeshFVF( static_cast<DWORD>( options ), static_cast<DWORD>( fvf ),
\r
202 device->InternalPointer, reinterpret_cast<DWORD*>( pinnedAdj ), reinterpret_cast<DWORD*>( pinnedVR ), &result );
\r
204 if( RECORD_D3D9( hr ).IsFailure )
\r
206 vertexRemap = nullptr;
\r
210 Mesh^ mesh = Mesh::FromPointer( result );
\r
211 mesh->SetAdjacency( adjacencyOut );
\r
216 Mesh^ SimplificationMesh::Clone( SlimDX::Direct3D9::Device^ device, MeshFlags options, SlimDX::Direct3D9::VertexFormat fvf )
\r
220 array<int>^ adjacencyOut = gcnew array<int>( FaceCount * 3 );
\r
221 pin_ptr<int> pinnedAdj = &adjacencyOut[0];
\r
223 HRESULT hr = InternalPointer->CloneMeshFVF( static_cast<DWORD>( options ), static_cast<DWORD>( fvf ),
\r
224 device->InternalPointer, reinterpret_cast<DWORD*>( pinnedAdj ), NULL, &result );
\r
226 if( RECORD_D3D9( hr ).IsFailure )
\r
229 Mesh^ mesh = Mesh::FromPointer( result );
\r
230 mesh->SetAdjacency( adjacencyOut );
\r
235 ProgressiveMesh^ SimplificationMesh::CloneProgressive( SlimDX::Direct3D9::Device^ device, MeshFlags options, array<VertexElement>^ vertexDeclaration, [Out] array<int>^% vertexRemap, [Out] array<float>^% errorsByFace )
\r
237 ID3DXPMesh *result;
\r
239 pin_ptr<VertexElement> pinnedDecl = &vertexDeclaration[0];
\r
240 vertexRemap = gcnew array<int>( VertexCount );
\r
241 errorsByFace = gcnew array<float>( FaceCount );
\r
242 pin_ptr<float> pinnedEBF = &errorsByFace[0];
\r
243 pin_ptr<int> pinnedVR = &vertexRemap[0];
\r
245 HRESULT hr = InternalPointer->ClonePMesh( static_cast<DWORD>( options ), reinterpret_cast<const D3DVERTEXELEMENT9*>( pinnedDecl ),
\r
246 device->InternalPointer, reinterpret_cast<DWORD*>( pinnedVR ), reinterpret_cast<FLOAT*>( pinnedEBF ), &result );
\r
248 if( RECORD_D3D9( hr ).IsFailure )
\r
250 errorsByFace = nullptr;
\r
251 vertexRemap = nullptr;
\r
255 return ProgressiveMesh::FromPointer( result );
\r
258 ProgressiveMesh^ SimplificationMesh::CloneProgressive( SlimDX::Direct3D9::Device^ device, MeshFlags options, array<VertexElement>^ vertexDeclaration, [Out] array<int>^% vertexRemap )
\r
260 ID3DXPMesh *result;
\r
262 pin_ptr<VertexElement> pinnedDecl = &vertexDeclaration[0];
\r
263 vertexRemap = gcnew array<int>( VertexCount );
\r
264 pin_ptr<int> pinnedVR = &vertexRemap[0];
\r
266 HRESULT hr = InternalPointer->ClonePMesh( static_cast<DWORD>( options ), reinterpret_cast<const D3DVERTEXELEMENT9*>( pinnedDecl ),
\r
267 device->InternalPointer, reinterpret_cast<DWORD*>( pinnedVR ), NULL, &result );
\r
269 if( RECORD_D3D9( hr ).IsFailure )
\r
271 vertexRemap = nullptr;
\r
275 return ProgressiveMesh::FromPointer( result );
\r
278 ProgressiveMesh^ SimplificationMesh::CloneProgressive( SlimDX::Direct3D9::Device^ device, MeshFlags options, array<VertexElement>^ vertexDeclaration )
\r
280 ID3DXPMesh *result;
\r
282 pin_ptr<VertexElement> pinnedDecl = &vertexDeclaration[0];
\r
284 HRESULT hr = InternalPointer->ClonePMesh( static_cast<DWORD>( options ), reinterpret_cast<const D3DVERTEXELEMENT9*>( pinnedDecl ),
\r
285 device->InternalPointer, NULL, NULL, &result );
\r
287 if( RECORD_D3D9( hr ).IsFailure )
\r
290 return ProgressiveMesh::FromPointer( result );
\r
293 ProgressiveMesh^ SimplificationMesh::CloneProgressive( SlimDX::Direct3D9::Device^ device, MeshFlags options, SlimDX::Direct3D9::VertexFormat fvf, [Out] array<int>^% vertexRemap, [Out] array<float>^% errorsByFace )
\r
295 ID3DXPMesh *result;
\r
297 vertexRemap = gcnew array<int>( VertexCount );
\r
298 errorsByFace = gcnew array<float>( FaceCount );
\r
300 pin_ptr<float> pinnedEBF = &errorsByFace[0];
\r
301 pin_ptr<int> pinnedVR = &vertexRemap[0];
\r
303 HRESULT hr = InternalPointer->ClonePMeshFVF( static_cast<DWORD>( options ), static_cast<DWORD>( fvf ),
\r
304 device->InternalPointer, reinterpret_cast<DWORD*>( pinnedVR ), reinterpret_cast<FLOAT*>( pinnedEBF ), &result );
\r
306 if( RECORD_D3D9( hr ).IsFailure )
\r
308 errorsByFace = nullptr;
\r
309 vertexRemap = nullptr;
\r
313 return ProgressiveMesh::FromPointer( result );
\r
316 ProgressiveMesh^ SimplificationMesh::CloneProgressive( SlimDX::Direct3D9::Device^ device, MeshFlags options, SlimDX::Direct3D9::VertexFormat fvf, [Out] array<int>^% vertexRemap )
\r
318 ID3DXPMesh *result;
\r
320 vertexRemap = gcnew array<int>( VertexCount );
\r
321 pin_ptr<int> pinnedVR = &vertexRemap[0];
\r
323 HRESULT hr = InternalPointer->ClonePMeshFVF( static_cast<DWORD>( options ), static_cast<DWORD>( fvf ),
\r
324 device->InternalPointer, reinterpret_cast<DWORD*>( pinnedVR ), NULL, &result );
\r
326 if( RECORD_D3D9( hr ).IsFailure )
\r
328 vertexRemap = nullptr;
\r
332 return ProgressiveMesh::FromPointer( result );
\r
335 ProgressiveMesh^ SimplificationMesh::CloneProgressive( SlimDX::Direct3D9::Device^ device, MeshFlags options, SlimDX::Direct3D9::VertexFormat fvf )
\r
337 ID3DXPMesh *result;
\r
339 HRESULT hr = InternalPointer->ClonePMeshFVF( static_cast<DWORD>( options ), static_cast<DWORD>( fvf ),
\r
340 device->InternalPointer, NULL, NULL, &result );
\r
342 if( RECORD_D3D9( hr ).IsFailure )
\r
345 return ProgressiveMesh::FromPointer( result );
\r
348 array<VertexElement>^ SimplificationMesh::GetDeclaration()
\r
350 D3DVERTEXELEMENT9 elementBuffer[MAX_FVF_DECL_SIZE];
\r
351 HRESULT hr = InternalPointer->GetDeclaration( elementBuffer );
\r
353 if( RECORD_D3D9( hr ).IsFailure )
\r
356 int count = D3DXGetDeclLength( elementBuffer ) + 1;
\r
357 array<VertexElement>^ elements = gcnew array<VertexElement>( count );
\r
358 pin_ptr<VertexElement> pinnedElements = &elements[0];
\r
359 memcpy( pinnedElements, elementBuffer, count * sizeof(D3DVERTEXELEMENT9) );
\r
360 elements[count - 1] = VertexElement::VertexDeclarationEnd;
\r
365 SlimDX::Direct3D9::Device^ SimplificationMesh::Device::get()
\r
367 IDirect3DDevice9* device;
\r
368 HRESULT hr = InternalPointer->GetDevice( &device );
\r
370 if( RECORD_D3D9( hr ).IsFailure )
\r
373 return SlimDX::Direct3D9::Device::FromPointer( device );
\r
376 array<AttributeWeights>^ SimplificationMesh::GetVertexAttributeWeights()
\r
378 array<AttributeWeights>^ results = gcnew array<AttributeWeights>( MaximumVertexCount );
\r
379 pin_ptr<AttributeWeights> pinnedResults = &results[0];
\r
381 HRESULT hr = InternalPointer->GetVertexAttributeWeights( reinterpret_cast<D3DXATTRIBUTEWEIGHTS*>( pinnedResults ) );
\r
383 if( RECORD_D3D9( hr ).IsFailure )
\r
389 array<float>^ SimplificationMesh::GetVertexWeights()
\r
391 array<float>^ results = gcnew array<float>( MaximumVertexCount );
\r
392 pin_ptr<float> pinnedResults = &results[0];
\r
394 HRESULT hr = InternalPointer->GetVertexWeights( reinterpret_cast<FLOAT*>( pinnedResults ) );
\r
396 if( RECORD_D3D9( hr ).IsFailure )
\r
402 Result SimplificationMesh::ReduceFaces( int faces )
\r
404 HRESULT hr = InternalPointer->ReduceFaces( faces );
\r
405 return RECORD_D3D9( hr );
\r
408 Result SimplificationMesh::ReduceVertices( int vertices )
\r
410 HRESULT hr = InternalPointer->ReduceVertices( vertices );
\r
411 return RECORD_D3D9( hr );
\r
414 int SimplificationMesh::MaximumFaceCount::get()
\r
416 return InternalPointer->GetMaxFaces();
\r
419 int SimplificationMesh::MaximumVertexCount::get()
\r
421 return InternalPointer->GetMaxVertices();
\r
424 int SimplificationMesh::FaceCount::get()
\r
426 return InternalPointer->GetNumFaces();
\r
429 int SimplificationMesh::VertexCount::get()
\r
431 return InternalPointer->GetNumVertices();
\r
434 SlimDX::Direct3D9::VertexFormat SimplificationMesh::VertexFormat::get()
\r
436 return static_cast<SlimDX::Direct3D9::VertexFormat>( InternalPointer->GetFVF() );
\r
439 MeshFlags SimplificationMesh::CreationOptions::get()
\r
441 return static_cast<MeshFlags>( InternalPointer->GetOptions() );
\r