OSDN Git Service

#36897 [DTXC] MIDIインポート機能の呼び出し口を、ファイルメニュー内にも配置。
[dtxmania/dtxmania.git] / SlimDXc_Jun2010(VC++2008) / source / direct3d9 / BaseMesh.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 "Direct3D9Exception.h"\r
32 \r
33 #include "Device.h"\r
34 #include "Texture.h"\r
35 #include "IndexBuffer.h"\r
36 #include "VertexBuffer.h"\r
37 #include "Mesh.h"\r
38 #include "BaseMesh.h"\r
39 #include "SkinInfo.h"\r
40 \r
41 using namespace System;\r
42 using namespace System::IO;\r
43 using namespace System::Drawing;\r
44 using namespace System::Runtime::InteropServices;\r
45 \r
46 namespace SlimDX\r
47 {\r
48 namespace Direct3D9\r
49 {\r
50         Mesh^ BaseMesh::Clone( SlimDX::Direct3D9::Device^ device, MeshFlags flags, array<VertexElement>^ elements )\r
51         {\r
52                 ID3DXMesh* mesh;\r
53                 pin_ptr<VertexElement> pinned_elements = &elements[0];\r
54 \r
55                 HRESULT hr = InternalPointer->CloneMesh( static_cast<DWORD>( flags ), reinterpret_cast<const D3DVERTEXELEMENT9*>( pinned_elements ),\r
56                         device->InternalPointer, &mesh );\r
57                 \r
58                 if( RECORD_D3D9( hr ).IsFailure )\r
59                         return nullptr;\r
60 \r
61                 return Mesh::FromPointer( mesh );\r
62         }\r
63 \r
64         Mesh^ BaseMesh::Clone( SlimDX::Direct3D9::Device^ device, MeshFlags flags, SlimDX::Direct3D9::VertexFormat fvf )\r
65         {\r
66                 ID3DXMesh* mesh;\r
67 \r
68                 HRESULT hr = InternalPointer->CloneMeshFVF( static_cast<DWORD>( flags ), static_cast<DWORD>( fvf ), \r
69                         device->InternalPointer, &mesh );\r
70 \r
71                 if( RECORD_D3D9( hr ).IsFailure )\r
72                         return nullptr;\r
73 \r
74                 return Mesh::FromPointer( mesh );\r
75         }\r
76 \r
77         Result BaseMesh::DrawSubset( int subset )\r
78         {\r
79                 HRESULT hr = InternalPointer->DrawSubset( subset );\r
80                 return RECORD_D3D9( hr );\r
81         }\r
82 \r
83         SlimDX::Direct3D9::Device^ BaseMesh::Device::get()\r
84         {\r
85                 IDirect3DDevice9* device;\r
86                 HRESULT hr = InternalPointer->GetDevice( &device );\r
87                 \r
88                 if( RECORD_D3D9( hr ).IsFailure )\r
89                         return nullptr;\r
90 \r
91                 return SlimDX::Direct3D9::Device::FromPointer( device );\r
92         }\r
93 \r
94         IndexBuffer^ BaseMesh::IndexBuffer::get()\r
95         {\r
96                 IDirect3DIndexBuffer9* ib;\r
97                 HRESULT hr = InternalPointer->GetIndexBuffer( &ib );\r
98                 \r
99                 if( RECORD_D3D9( hr ).IsFailure )\r
100                         return nullptr;\r
101 \r
102                 return SlimDX::Direct3D9::IndexBuffer::FromPointer( ib );\r
103         }\r
104 \r
105         VertexBuffer^ BaseMesh::VertexBuffer::get()\r
106         {\r
107                 IDirect3DVertexBuffer9* vb;\r
108                 HRESULT hr = InternalPointer->GetVertexBuffer( &vb );\r
109                 \r
110                 if( RECORD_D3D9( hr ).IsFailure )\r
111                         return nullptr;\r
112 \r
113                 return SlimDX::Direct3D9::VertexBuffer::FromPointer( vb );\r
114         }\r
115 \r
116         array<VertexElement>^ BaseMesh::GetDeclaration()\r
117         {\r
118                 D3DVERTEXELEMENT9 elementBuffer[MAX_FVF_DECL_SIZE];\r
119                 HRESULT hr = InternalPointer->GetDeclaration( elementBuffer );\r
120                 \r
121                 if( RECORD_D3D9( hr ).IsFailure )\r
122                         return nullptr;\r
123 \r
124                 // Apparently the returned decl does not include an End element. This is bizarre and confusing,\r
125                 // not to mention completely unexpected. We patch it up here.\r
126                 int count = D3DXGetDeclLength( elementBuffer ) + 1;\r
127                 array<VertexElement>^ elements = gcnew array<VertexElement>( count );\r
128                 pin_ptr<VertexElement> pinnedElements = &elements[0];\r
129                 memcpy( pinnedElements, elementBuffer, count * sizeof(D3DVERTEXELEMENT9) );\r
130                 elements[count - 1] = VertexElement::VertexDeclarationEnd;\r
131 \r
132                 return elements;\r
133         }\r
134 \r
135         array<AttributeRange>^ BaseMesh::GetAttributeTable()\r
136         {\r
137                 DWORD count = 0;\r
138                 HRESULT hr = InternalPointer->GetAttributeTable( NULL, &count );\r
139 \r
140                 if( RECORD_D3D9( hr ).IsFailure || count == 0 )\r
141                         return nullptr;\r
142 \r
143                 array<AttributeRange>^ attribTable = gcnew array<AttributeRange>( count );\r
144                 pin_ptr<AttributeRange> pinnedTable = &attribTable[0];\r
145                 hr = InternalPointer->GetAttributeTable( reinterpret_cast<D3DXATTRIBUTERANGE*>( pinnedTable ), &count );\r
146                 \r
147                 if( RECORD_D3D9( hr ).IsFailure )\r
148                         return nullptr;\r
149 \r
150                 return attribTable;\r
151         }\r
152 \r
153         DataStream^ BaseMesh::LockIndexBuffer( LockFlags flags )\r
154         {\r
155                 void* data;\r
156                 HRESULT hr = InternalPointer->LockIndexBuffer( static_cast<DWORD>( flags ), &data );\r
157                 \r
158                 if( RECORD_D3D9( hr ).IsFailure )\r
159                         return nullptr;\r
160 \r
161                 // determine the size of the buffer\r
162                 int size = 6 * FaceCount;\r
163                 if( (CreationOptions & MeshFlags::Use32Bit) == MeshFlags::Use32Bit )\r
164                         size *= 2;\r
165 \r
166                 bool readOnly = (flags & LockFlags::ReadOnly) == LockFlags::ReadOnly;\r
167                 return gcnew DataStream( data, size, true, !readOnly, false );\r
168         }\r
169 \r
170         Result BaseMesh::UnlockIndexBuffer()\r
171         {\r
172                 HRESULT hr = InternalPointer->UnlockIndexBuffer();\r
173                 return RECORD_D3D9( hr );\r
174         }\r
175 \r
176         DataStream^ BaseMesh::LockVertexBuffer( LockFlags flags )\r
177         {\r
178                 void* data;\r
179                 HRESULT hr = InternalPointer->LockVertexBuffer( static_cast<DWORD>( flags ), &data );\r
180                 \r
181                 if( RECORD_D3D9( hr ).IsFailure )\r
182                         return nullptr;\r
183 \r
184                 // determine the size of the buffer\r
185                 int size = BytesPerVertex * VertexCount;\r
186 \r
187                 bool readOnly = (flags & LockFlags::ReadOnly) == LockFlags::ReadOnly;\r
188                 return gcnew DataStream( data, size, true, !readOnly, false );\r
189         }\r
190 \r
191         Result BaseMesh::UnlockVertexBuffer()\r
192         {\r
193                 HRESULT hr = InternalPointer->UnlockVertexBuffer();\r
194                 return RECORD_D3D9( hr );\r
195         }\r
196 \r
197         array<int>^ BaseMesh::GenerateAdjacency( float epsilon )\r
198         {\r
199                 // allocate the array to write the adjacency into\r
200                 array<int>^ adjacency = gcnew array<int>( 3 * FaceCount );\r
201                 pin_ptr<int> pinnedAdj = &adjacency[0];\r
202 \r
203                 HRESULT hr = InternalPointer->GenerateAdjacency( epsilon, reinterpret_cast<DWORD*>( pinnedAdj ) );\r
204                 \r
205                 if( RECORD_D3D9( hr ).IsFailure )\r
206                         return nullptr;\r
207 \r
208                 return adjacency;\r
209         }\r
210 \r
211         array<int>^ BaseMesh::ConvertAdjacencyToPointReps( array<int>^ adjacency )\r
212         {\r
213                 array<int>^ points = gcnew array<int>( VertexCount );\r
214                 pin_ptr<int> pinnedAdj = &adjacency[0];\r
215                 pin_ptr<int> pinnedPoints = &points[0];\r
216 \r
217                 HRESULT hr = InternalPointer->ConvertAdjacencyToPointReps( reinterpret_cast<const DWORD*>( pinnedAdj ),\r
218                         reinterpret_cast<DWORD*>( pinnedPoints ) );\r
219                 \r
220                 if( RECORD_D3D9( hr ).IsFailure )\r
221                         return nullptr;\r
222 \r
223                 return points;\r
224         }\r
225 \r
226         array<int>^ BaseMesh::ConvertPointRepsToAdjacency( array<int>^ points )\r
227         {\r
228                 array<int>^ adjacency = gcnew array<int>( 3 * FaceCount );\r
229                 pin_ptr<int> pinnedAdj = &adjacency[0];\r
230                 pin_ptr<int> pinnedPoints = &points[0];\r
231 \r
232                 HRESULT hr = InternalPointer->ConvertPointRepsToAdjacency( reinterpret_cast<const DWORD*>( pinnedPoints ),\r
233                         reinterpret_cast<DWORD*>( pinnedAdj ) );\r
234                 \r
235                 if( RECORD_D3D9( hr ).IsFailure )\r
236                         return nullptr;\r
237 \r
238                 return adjacency;\r
239         }\r
240 \r
241         Result BaseMesh::UpdateSemantics( array<VertexElement>^ elements )\r
242         {\r
243                 pin_ptr<VertexElement> pinnedElements = &elements[0];\r
244 \r
245                 HRESULT hr = InternalPointer->UpdateSemantics( reinterpret_cast<D3DVERTEXELEMENT9*>( pinnedElements ) );\r
246                 return RECORD_D3D9( hr );\r
247         }\r
248 \r
249         IndexBuffer^ BaseMesh::ConvertSubsetToSingleStrip( int attributeId, MeshFlags options, [Out] int% indexCount )\r
250         {\r
251                 IDirect3DIndexBuffer9 *result;\r
252                 DWORD count;\r
253 \r
254                 HRESULT hr = D3DXConvertMeshSubsetToSingleStrip( InternalPointer, attributeId, static_cast<DWORD>( options ),\r
255                         &result, &count );\r
256 \r
257                 if( RECORD_D3D9( hr ).IsFailure )\r
258                 {\r
259                         indexCount = 0;\r
260                         return nullptr;\r
261                 }\r
262 \r
263                 indexCount = count;\r
264                 return SlimDX::Direct3D9::IndexBuffer::FromPointer( result );\r
265         }\r
266 \r
267         IndexBuffer^ BaseMesh::ConvertSubsetToStrips( int attributeId, MeshFlags options, [Out] int% indexCount,\r
268                 [Out] array<int>^% stripLengths )\r
269         {\r
270                 IDirect3DIndexBuffer9 *result;\r
271                 ID3DXBuffer *buffer;\r
272                 DWORD numIndices;\r
273                 DWORD numStrips;\r
274 \r
275                 HRESULT hr = D3DXConvertMeshSubsetToStrips( InternalPointer, attributeId, static_cast<DWORD>( options ),\r
276                         &result, &numIndices, &buffer, &numStrips );\r
277 \r
278                 if( RECORD_D3D9( hr ).IsFailure )\r
279                 {\r
280                         indexCount = 0;\r
281                         stripLengths = nullptr;\r
282                         return nullptr;\r
283                 }\r
284 \r
285                 indexCount = numIndices;\r
286                 stripLengths = Utilities::ReadRange<int>( buffer, numStrips );\r
287                 return SlimDX::Direct3D9::IndexBuffer::FromPointer( result );\r
288         }\r
289 \r
290         bool BaseMesh::Intersects( Ray ray, [Out] float% distance, [Out] int% faceIndex, [Out] array<IntersectInformation>^% hits )\r
291         {\r
292                 ID3DXBuffer *allHits;\r
293                 BOOL result;\r
294                 FLOAT dist;\r
295                 DWORD count;\r
296                 DWORD face;\r
297 \r
298                 HRESULT hr = D3DXIntersect( InternalPointer, reinterpret_cast<const D3DXVECTOR3*>( &ray.Position ),\r
299                         reinterpret_cast<const D3DXVECTOR3*>( &ray.Direction ), &result, &face, NULL, NULL, &dist, &allHits, &count );\r
300 \r
301                 if( RECORD_D3D9( hr ).IsFailure )\r
302                 {\r
303                         hits = nullptr;\r
304                         faceIndex = 0;\r
305                         distance = 0;\r
306                         return false;\r
307                 }\r
308 \r
309                 faceIndex = face;\r
310                 distance = dist;\r
311 \r
312                 if( allHits == NULL )\r
313                         hits = nullptr;\r
314                 else\r
315                         hits = Utilities::ReadRange<IntersectInformation>( allHits, count );\r
316 \r
317                 if( result )\r
318                         return true;\r
319                 else\r
320                         return false;\r
321         }\r
322 \r
323         bool BaseMesh::Intersects( Ray ray, [Out] float% distance )\r
324         {\r
325                 BOOL result;\r
326                 FLOAT dist;\r
327 \r
328                 HRESULT hr = D3DXIntersect( InternalPointer, reinterpret_cast<const D3DXVECTOR3*>( &ray.Position ),\r
329                         reinterpret_cast<const D3DXVECTOR3*>( &ray.Direction ), &result, NULL, NULL, NULL, &dist, NULL, NULL );\r
330 \r
331                 if( RECORD_D3D9( hr ).IsFailure )\r
332                 {\r
333                         distance = 0;\r
334                         return false;\r
335                 }\r
336 \r
337                 distance = dist;\r
338                 if( result )\r
339                         return true;\r
340                 else\r
341                         return false;\r
342         }\r
343 \r
344         bool BaseMesh::Intersects( Ray ray )\r
345         {\r
346                 BOOL result;\r
347 \r
348                 HRESULT hr = D3DXIntersect( InternalPointer, reinterpret_cast<const D3DXVECTOR3*>( &ray.Position ),\r
349                         reinterpret_cast<const D3DXVECTOR3*>( &ray.Direction ), &result, NULL, NULL, NULL, NULL, NULL, NULL );\r
350 \r
351                 if( RECORD_D3D9( hr ).IsFailure || !result )\r
352                         return false;\r
353 \r
354                 return true;\r
355         }\r
356 \r
357         bool BaseMesh::IntersectsSubset( Ray ray, int attributeId, [Out] float% distance, [Out] int% faceIndex, [Out] array<IntersectInformation>^% hits )\r
358         {\r
359                 ID3DXBuffer *allHits;\r
360                 BOOL result;\r
361                 FLOAT dist;\r
362                 DWORD count;\r
363                 DWORD face;\r
364 \r
365                 HRESULT hr = D3DXIntersectSubset( InternalPointer, attributeId, reinterpret_cast<const D3DXVECTOR3*>( &ray.Position ),\r
366                         reinterpret_cast<const D3DXVECTOR3*>( &ray.Direction ), &result, &face, NULL, NULL, &dist, &allHits, &count );\r
367 \r
368                 if( RECORD_D3D9( hr ).IsFailure )\r
369                 {\r
370                         hits = nullptr;\r
371                         faceIndex = 0;\r
372                         distance = 0;\r
373                         return false;\r
374                 }\r
375 \r
376                 faceIndex = face;\r
377                 distance = dist;\r
378                 hits = Utilities::ReadRange<IntersectInformation>( allHits, count );\r
379 \r
380                 if( result )\r
381                         return true;\r
382                 else\r
383                         return false;\r
384         }\r
385 \r
386         bool BaseMesh::IntersectsSubset( Ray ray, int attributeId, [Out] float% distance )\r
387         {\r
388                 BOOL result;\r
389                 FLOAT dist;\r
390 \r
391                 HRESULT hr = D3DXIntersectSubset( InternalPointer, attributeId, reinterpret_cast<const D3DXVECTOR3*>( &ray.Position ),\r
392                         reinterpret_cast<const D3DXVECTOR3*>( &ray.Direction ), &result, NULL, NULL, NULL, &dist, NULL, NULL );\r
393 \r
394                 if( RECORD_D3D9( hr ).IsFailure )\r
395                 {\r
396                         distance = 0;\r
397                         return false;\r
398                 }\r
399 \r
400                 distance = dist;\r
401                 if( result )\r
402                         return true;\r
403                 else\r
404                         return false;\r
405         }\r
406 \r
407         bool BaseMesh::IntersectsSubset( Ray ray, int attributeId )\r
408         {\r
409                 BOOL result;\r
410 \r
411                 HRESULT hr = D3DXIntersectSubset( InternalPointer, attributeId, reinterpret_cast<const D3DXVECTOR3*>( &ray.Position ),\r
412                         reinterpret_cast<const D3DXVECTOR3*>( &ray.Direction ), &result, NULL, NULL, NULL, NULL, NULL, NULL );\r
413 \r
414                 if( RECORD_D3D9( hr ).IsFailure || !result )\r
415                         return false;\r
416 \r
417                 return true;\r
418         }\r
419 \r
420         int BaseMesh::FaceCount::get()\r
421         {\r
422                 return InternalPointer->GetNumFaces();\r
423         }\r
424 \r
425         int BaseMesh::VertexCount::get()\r
426         {\r
427                 return InternalPointer->GetNumVertices();\r
428         }\r
429 \r
430         SlimDX::Direct3D9::VertexFormat BaseMesh::VertexFormat::get()\r
431         {\r
432                 return static_cast<SlimDX::Direct3D9::VertexFormat>( InternalPointer->GetFVF() );\r
433         }\r
434 \r
435         int BaseMesh::BytesPerVertex::get()\r
436         {\r
437                 return InternalPointer->GetNumBytesPerVertex();\r
438         }\r
439 \r
440         MeshFlags BaseMesh::CreationOptions::get()\r
441         {\r
442                 return static_cast<MeshFlags>( InternalPointer->GetOptions() );\r
443         }\r
444 }\r
445 }