OSDN Git Service

3bd0e0ced2648bb740b8c2570b70779b207bb22f
[dtxmania/dtxmania.git] / SlimDXc_Jun2010(VC++2008) / source / direct3d9 / SimplificationMesh.cpp
1 #include "stdafx.h"\r
2 /*\r
3 * Copyright (c) 2007-2010 SlimDX Group\r
4\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
11\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
14\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
21 * THE SOFTWARE.\r
22 */\r
23 #include <d3d9.h>\r
24 #include <d3dx9.h>\r
25 #include <vcclr.h>\r
26 \r
27 #include "../ComObject.h"\r
28 #include "../Utilities.h"\r
29 #include "../DataStream.h"\r
30 \r
31 #include "Device.h"\r
32 #include "Texture.h"\r
33 #include "IndexBuffer.h"\r
34 #include "VertexBuffer.h"\r
35 #include "Mesh.h"\r
36 #include "SimplificationMesh.h"\r
37 #include "ProgressiveMesh.h"\r
38 \r
39 #include "Direct3D9Exception.h"\r
40 \r
41 using namespace System;\r
42 using namespace System::IO;\r
43 using namespace System::Runtime::InteropServices;\r
44 \r
45 namespace SlimDX\r
46 {\r
47 namespace Direct3D9\r
48 {\r
49         SimplificationMesh::SimplificationMesh( Mesh^ mesh, array<AttributeWeights>^ vertexAttributeWeights, array<float>^ vertexWeights )\r
50         {\r
51                 ID3DXSPMesh *result;\r
52 \r
53                 DWORD *adjacencyIn = NULL;\r
54                 pin_ptr<int> pinnedAdj;\r
55                 array<int>^ adjacency = mesh->GetAdjacency();\r
56 \r
57                 if( adjacency != nullptr )\r
58                 {\r
59                         pinnedAdj = &adjacency[0];\r
60                         adjacencyIn = reinterpret_cast<DWORD*>( pinnedAdj );\r
61                 }\r
62 \r
63                 pin_ptr<AttributeWeights> pinnedVAW = &vertexAttributeWeights[0];\r
64                 pin_ptr<float> pinnedVW = &vertexWeights[0];\r
65 \r
66                 HRESULT hr = D3DXCreateSPMesh( mesh->InternalPointer, adjacencyIn,\r
67                         reinterpret_cast<const D3DXATTRIBUTEWEIGHTS*>( pinnedVAW ), reinterpret_cast<const FLOAT *>( pinnedVW ), &result );\r
68                 \r
69                 if( RECORD_D3D9( hr ).IsFailure )\r
70                         throw gcnew Direct3D9Exception( Result::Last );\r
71 \r
72                 Construct(result);\r
73         }\r
74 \r
75         SimplificationMesh::SimplificationMesh( Mesh^ mesh, array<AttributeWeights>^ vertexAttributeWeights )\r
76         {\r
77                 ID3DXSPMesh *result;\r
78 \r
79                 DWORD *adjacencyIn = NULL;\r
80                 pin_ptr<int> pinnedAdj;\r
81                 array<int>^ adjacency = mesh->GetAdjacency();\r
82 \r
83                 if( adjacency != nullptr )\r
84                 {\r
85                         pinnedAdj = &adjacency[0];\r
86                         adjacencyIn = reinterpret_cast<DWORD*>( pinnedAdj );\r
87                 }\r
88 \r
89                 pin_ptr<AttributeWeights> pinnedVAW = &vertexAttributeWeights[0];\r
90 \r
91                 HRESULT hr = D3DXCreateSPMesh( mesh->InternalPointer, adjacencyIn,\r
92                         reinterpret_cast<const D3DXATTRIBUTEWEIGHTS*>( pinnedVAW ), NULL, &result );\r
93                 \r
94                 if( RECORD_D3D9( hr ).IsFailure )\r
95                         throw gcnew Direct3D9Exception( Result::Last );\r
96 \r
97                 Construct(result);\r
98         }\r
99 \r
100         SimplificationMesh::SimplificationMesh( Mesh^ mesh, array<float>^ vertexWeights )\r
101         {\r
102                 ID3DXSPMesh *result;\r
103 \r
104                 DWORD *adjacencyIn = NULL;\r
105                 pin_ptr<int> pinnedAdj;\r
106                 array<int>^ adjacency = mesh->GetAdjacency();\r
107 \r
108                 if( adjacency != nullptr )\r
109                 {\r
110                         pinnedAdj = &adjacency[0];\r
111                         adjacencyIn = reinterpret_cast<DWORD*>( pinnedAdj );\r
112                 }\r
113 \r
114                 pin_ptr<float> pinnedVW = &vertexWeights[0];\r
115 \r
116                 HRESULT hr = D3DXCreateSPMesh( mesh->InternalPointer, adjacencyIn,\r
117                         NULL, reinterpret_cast<const FLOAT *>( pinnedVW ), &result );\r
118                 \r
119                 if( RECORD_D3D9( hr ).IsFailure )\r
120                         throw gcnew Direct3D9Exception( Result::Last );\r
121 \r
122                 Construct(result);\r
123         }\r
124 \r
125         SimplificationMesh::SimplificationMesh( Mesh^ mesh )\r
126         {\r
127                 ID3DXSPMesh *result;\r
128 \r
129                 DWORD *adjacencyIn = NULL;\r
130                 pin_ptr<int> pinnedAdj;\r
131                 array<int>^ adjacency = mesh->GetAdjacency();\r
132 \r
133                 if( adjacency != nullptr )\r
134                 {\r
135                         pinnedAdj = &adjacency[0];\r
136                         adjacencyIn = reinterpret_cast<DWORD*>( pinnedAdj );\r
137                 }\r
138 \r
139                 HRESULT hr = D3DXCreateSPMesh( mesh->InternalPointer, adjacencyIn, NULL, NULL, &result );\r
140                 \r
141                 if( RECORD_D3D9( hr ).IsFailure )\r
142                         throw gcnew Direct3D9Exception( Result::Last );\r
143 \r
144                 Construct(result);\r
145         }\r
146 \r
147         Mesh^ SimplificationMesh::Clone( SlimDX::Direct3D9::Device^ device, MeshFlags options, array<VertexElement>^ vertexDeclaration, [Out] array<int>^% vertexRemap )\r
148         {\r
149                 ID3DXMesh *result;\r
150 \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
156 \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
159                 \r
160                 if( RECORD_D3D9( hr ).IsFailure )\r
161                 {\r
162                         vertexRemap = nullptr;\r
163                         return nullptr;\r
164                 }\r
165 \r
166                 Mesh^ mesh = Mesh::FromPointer( result );\r
167                 mesh->SetAdjacency( adjacencyOut );\r
168 \r
169                 return mesh;\r
170         }\r
171 \r
172         Mesh^ SimplificationMesh::Clone( SlimDX::Direct3D9::Device^ device, MeshFlags options, array<VertexElement>^ vertexDeclaration )\r
173         {\r
174                 ID3DXMesh *result;\r
175 \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
179 \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
182                 \r
183                 if( RECORD_D3D9( hr ).IsFailure )\r
184                         return nullptr;\r
185 \r
186                 Mesh^ mesh = Mesh::FromPointer( result );\r
187                 mesh->SetAdjacency( adjacencyOut );\r
188 \r
189                 return mesh;\r
190         }\r
191 \r
192         Mesh^ SimplificationMesh::Clone( SlimDX::Direct3D9::Device^ device, MeshFlags options, SlimDX::Direct3D9::VertexFormat fvf, [Out] array<int>^% vertexRemap )\r
193         {\r
194                 ID3DXMesh *result;\r
195 \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
200 \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
203                 \r
204                 if( RECORD_D3D9( hr ).IsFailure )\r
205                 {\r
206                         vertexRemap = nullptr;\r
207                         return nullptr;\r
208                 }\r
209 \r
210                 Mesh^ mesh = Mesh::FromPointer( result );\r
211                 mesh->SetAdjacency( adjacencyOut );\r
212 \r
213                 return mesh;\r
214         }\r
215 \r
216         Mesh^ SimplificationMesh::Clone( SlimDX::Direct3D9::Device^ device, MeshFlags options, SlimDX::Direct3D9::VertexFormat fvf )\r
217         {\r
218                 ID3DXMesh *result;\r
219 \r
220                 array<int>^ adjacencyOut = gcnew array<int>( FaceCount * 3 );\r
221                 pin_ptr<int> pinnedAdj = &adjacencyOut[0];\r
222 \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
225                 \r
226                 if( RECORD_D3D9( hr ).IsFailure )\r
227                         return nullptr;\r
228 \r
229                 Mesh^ mesh = Mesh::FromPointer( result );\r
230                 mesh->SetAdjacency( adjacencyOut );\r
231 \r
232                 return mesh;\r
233         }\r
234 \r
235         ProgressiveMesh^ SimplificationMesh::CloneProgressive( SlimDX::Direct3D9::Device^ device, MeshFlags options, array<VertexElement>^ vertexDeclaration, [Out] array<int>^% vertexRemap, [Out] array<float>^% errorsByFace )\r
236         {\r
237                 ID3DXPMesh *result;\r
238 \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
244 \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
247                 \r
248                 if( RECORD_D3D9( hr ).IsFailure )\r
249                 {\r
250                         errorsByFace = nullptr;\r
251                         vertexRemap = nullptr;\r
252                         return nullptr;\r
253                 }\r
254 \r
255                 return ProgressiveMesh::FromPointer( result );\r
256         }\r
257 \r
258         ProgressiveMesh^ SimplificationMesh::CloneProgressive( SlimDX::Direct3D9::Device^ device, MeshFlags options, array<VertexElement>^ vertexDeclaration, [Out] array<int>^% vertexRemap )\r
259         {\r
260                 ID3DXPMesh *result;\r
261 \r
262                 pin_ptr<VertexElement> pinnedDecl = &vertexDeclaration[0];\r
263                 vertexRemap = gcnew array<int>( VertexCount );\r
264                 pin_ptr<int> pinnedVR = &vertexRemap[0];\r
265 \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
268                 \r
269                 if( RECORD_D3D9( hr ).IsFailure )\r
270                 {\r
271                         vertexRemap = nullptr;\r
272                         return nullptr;\r
273                 }\r
274 \r
275                 return ProgressiveMesh::FromPointer( result );\r
276         }\r
277 \r
278         ProgressiveMesh^ SimplificationMesh::CloneProgressive( SlimDX::Direct3D9::Device^ device, MeshFlags options, array<VertexElement>^ vertexDeclaration )\r
279         {\r
280                 ID3DXPMesh *result;\r
281 \r
282                 pin_ptr<VertexElement> pinnedDecl = &vertexDeclaration[0];\r
283 \r
284                 HRESULT hr = InternalPointer->ClonePMesh( static_cast<DWORD>( options ), reinterpret_cast<const D3DVERTEXELEMENT9*>( pinnedDecl ),\r
285                         device->InternalPointer, NULL, NULL, &result );\r
286                 \r
287                 if( RECORD_D3D9( hr ).IsFailure )\r
288                         return nullptr;\r
289 \r
290                 return ProgressiveMesh::FromPointer( result );\r
291         }\r
292 \r
293         ProgressiveMesh^ SimplificationMesh::CloneProgressive( SlimDX::Direct3D9::Device^ device, MeshFlags options, SlimDX::Direct3D9::VertexFormat fvf, [Out] array<int>^% vertexRemap, [Out] array<float>^% errorsByFace )\r
294         {\r
295                 ID3DXPMesh *result;\r
296 \r
297                 vertexRemap = gcnew array<int>( VertexCount );\r
298                 errorsByFace = gcnew array<float>( FaceCount );\r
299 \r
300                 pin_ptr<float> pinnedEBF = &errorsByFace[0];\r
301                 pin_ptr<int> pinnedVR = &vertexRemap[0];\r
302 \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
305                 \r
306                 if( RECORD_D3D9( hr ).IsFailure )\r
307                 {\r
308                         errorsByFace = nullptr;\r
309                         vertexRemap = nullptr;\r
310                         return nullptr;\r
311                 }\r
312 \r
313                 return ProgressiveMesh::FromPointer( result );\r
314         }\r
315 \r
316         ProgressiveMesh^ SimplificationMesh::CloneProgressive( SlimDX::Direct3D9::Device^ device, MeshFlags options, SlimDX::Direct3D9::VertexFormat fvf, [Out] array<int>^% vertexRemap )\r
317         {\r
318                 ID3DXPMesh *result;\r
319 \r
320                 vertexRemap = gcnew array<int>( VertexCount );\r
321                 pin_ptr<int> pinnedVR = &vertexRemap[0];\r
322 \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
325                 \r
326                 if( RECORD_D3D9( hr ).IsFailure )\r
327                 {\r
328                         vertexRemap = nullptr;\r
329                         return nullptr;\r
330                 }\r
331 \r
332                 return ProgressiveMesh::FromPointer( result );\r
333         }\r
334 \r
335         ProgressiveMesh^ SimplificationMesh::CloneProgressive( SlimDX::Direct3D9::Device^ device, MeshFlags options, SlimDX::Direct3D9::VertexFormat fvf )\r
336         {\r
337                 ID3DXPMesh *result;\r
338 \r
339                 HRESULT hr = InternalPointer->ClonePMeshFVF( static_cast<DWORD>( options ), static_cast<DWORD>( fvf ),\r
340                         device->InternalPointer, NULL, NULL, &result );\r
341                 \r
342                 if( RECORD_D3D9( hr ).IsFailure )\r
343                         return nullptr;\r
344 \r
345                 return ProgressiveMesh::FromPointer( result );\r
346         }\r
347 \r
348         array<VertexElement>^ SimplificationMesh::GetDeclaration()\r
349         {\r
350                 D3DVERTEXELEMENT9 elementBuffer[MAX_FVF_DECL_SIZE];\r
351                 HRESULT hr = InternalPointer->GetDeclaration( elementBuffer );\r
352                 \r
353                 if( RECORD_D3D9( hr ).IsFailure )\r
354                         return nullptr;\r
355 \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
361 \r
362                 return elements;\r
363         }\r
364 \r
365         SlimDX::Direct3D9::Device^ SimplificationMesh::Device::get()\r
366         {\r
367                 IDirect3DDevice9* device;\r
368                 HRESULT hr = InternalPointer->GetDevice( &device );\r
369                 \r
370                 if( RECORD_D3D9( hr ).IsFailure )\r
371                         return nullptr;\r
372 \r
373                 return SlimDX::Direct3D9::Device::FromPointer( device );\r
374         }\r
375 \r
376         array<AttributeWeights>^ SimplificationMesh::GetVertexAttributeWeights()\r
377         {\r
378                 array<AttributeWeights>^ results = gcnew array<AttributeWeights>( MaximumVertexCount );\r
379                 pin_ptr<AttributeWeights> pinnedResults = &results[0];\r
380 \r
381                 HRESULT hr = InternalPointer->GetVertexAttributeWeights( reinterpret_cast<D3DXATTRIBUTEWEIGHTS*>( pinnedResults ) );\r
382                 \r
383                 if( RECORD_D3D9( hr ).IsFailure )\r
384                         return nullptr;\r
385 \r
386                 return results;\r
387         }\r
388 \r
389         array<float>^ SimplificationMesh::GetVertexWeights()\r
390         {\r
391                 array<float>^ results = gcnew array<float>( MaximumVertexCount );\r
392                 pin_ptr<float> pinnedResults = &results[0];\r
393 \r
394                 HRESULT hr = InternalPointer->GetVertexWeights( reinterpret_cast<FLOAT*>( pinnedResults ) );\r
395                 \r
396                 if( RECORD_D3D9( hr ).IsFailure )\r
397                         return nullptr;\r
398 \r
399                 return results;\r
400         }\r
401 \r
402         Result SimplificationMesh::ReduceFaces( int faces )\r
403         {\r
404                 HRESULT hr = InternalPointer->ReduceFaces( faces );\r
405                 return RECORD_D3D9( hr );\r
406         }\r
407 \r
408         Result SimplificationMesh::ReduceVertices( int vertices )\r
409         {\r
410                 HRESULT hr = InternalPointer->ReduceVertices( vertices );\r
411                 return RECORD_D3D9( hr );\r
412         }\r
413 \r
414         int SimplificationMesh::MaximumFaceCount::get()\r
415         {\r
416                 return InternalPointer->GetMaxFaces();\r
417         }\r
418 \r
419         int SimplificationMesh::MaximumVertexCount::get()\r
420         {\r
421                 return InternalPointer->GetMaxVertices();\r
422         }\r
423 \r
424         int SimplificationMesh::FaceCount::get()\r
425         {\r
426                 return InternalPointer->GetNumFaces();\r
427         }\r
428 \r
429         int SimplificationMesh::VertexCount::get()\r
430         {\r
431                 return InternalPointer->GetNumVertices();\r
432         }\r
433 \r
434         SlimDX::Direct3D9::VertexFormat SimplificationMesh::VertexFormat::get()\r
435         {\r
436                 return static_cast<SlimDX::Direct3D9::VertexFormat>( InternalPointer->GetFVF() );\r
437         }\r
438 \r
439         MeshFlags SimplificationMesh::CreationOptions::get()\r
440         {\r
441                 return static_cast<MeshFlags>( InternalPointer->GetOptions() );\r
442         }\r
443 }\r
444 }