Imported Upstream version 2.81
[platform/upstream/libbullet.git] / Demos / DX11ClothDemo / cloth_renderer.cpp
1 //--------------------------------------------------------------------------------------\r
2 // File: BasicHLSL10.cpp\r
3 //\r
4 // This sample shows a simple example of the Microsoft Direct3D's High-Level \r
5 // Shader Language (HLSL) using the Effect interface. \r
6 //\r
7 // Copyright (c) Microsoft Corporation. All rights reserved.\r
8 //--------------------------------------------------------------------------------------\r
9 \r
10 #include "DXUT.h"\r
11 #include "DXUTcamera.h"\r
12 #include "DXUTgui.h"\r
13 #include "DXUTsettingsDlg.h"\r
14 #include "SDKmisc.h"\r
15 #include "SDKMesh.h"\r
16 #include "resource.h"\r
17 \r
18 #include "btBulletDynamicsCommon.h"\r
19 #include "LinearMath/btHashMap.h"\r
20 #include "btDirectComputeSupport.h"\r
21 #include "BulletSoftBody/btSoftRigidDynamicsWorld.h"\r
22 #include "BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolverVertexBuffer_DX11.h"\r
23 #include "BulletSoftBody/btSoftBodyHelpers.h"\r
24 #include "vectormath/vmInclude.h"\r
25 \r
26 class btDefaultSoftBodySolver;\r
27 class btCPUSoftBodySolver;\r
28 class btCPUSoftBodyVertexSolver;\r
29 class btDX11SoftBodySolver;\r
30 class btDX11SIMDAwareSoftBodySolver;\r
31 \r
32 #include "BulletSoftBody/btSoftBodySolvers.h"\r
33 #include "BulletSoftBody/btDefaultSoftBodySolver.h"\r
34 \r
35 #include "BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolver_DX11.h"\r
36 #include "BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolver_DX11SIMDAware.h"\r
37 \r
38 #include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"\r
39 \r
40 #define USE_SIMDAWARE_SOLVER\r
41 //#define USE_GPU_SOLVER\r
42 #define USE_GPU_COPY\r
43 const int numFlags = 5;\r
44 const int clothWidth = 40;\r
45 const int clothHeight = 60;\r
46 float _windAngle = 1.0;//0.4;\r
47 float _windStrength = 15;\r
48 \r
49 \r
50 //#define TABLETEST\r
51 \r
52 \r
53 #include <fstream>\r
54 \r
55 #include <cmath>\r
56 \r
57 using Vectormath::Aos::Vector3;\r
58 \r
59 \r
60 class piece_of_cloth;\r
61 class btBroadphaseInterface;\r
62 class btCollisionShape;\r
63 class btOverlappingPairCache;\r
64 class btCollisionDispatcher;\r
65 class btConstraintSolver;\r
66 struct btCollisionAlgorithmCreateFunc;\r
67 class btDefaultCollisionConfiguration;\r
68 \r
69 int paused = 0;\r
70 \r
71 float global_shift_x = 0;\r
72 float global_shift_y = 0;\r
73 float global_shift_z = 0;\r
74 \r
75 namespace BTAcceleratedSoftBody\r
76 {\r
77         class BulletPhysicsDevice;\r
78         class CPUDevice;\r
79         class DX11Device;       \r
80 }\r
81 namespace Vectormath\r
82 {\r
83         namespace Aos\r
84         {\r
85                 class Transform3;\r
86         }\r
87 }\r
88 \r
89 \r
90 \r
91 const float flagSpacing = 30.f;\r
92 \r
93 #include <iostream>\r
94 using namespace std;\r
95 \r
96 //--------------------------------------------------------------------------------------\r
97 // Global variables\r
98 //--------------------------------------------------------------------------------------\r
99 CDXUTDialogResourceManager  g_DialogResourceManager; // manager for shared resources of dialogs\r
100 //CModelViewerCamera          g_Camera;               // A model viewing camera\r
101 CFirstPersonCamera          g_Camera;               // A model viewing camera\r
102 CDXUTDirectionWidget        g_LightControl;\r
103 CD3DSettingsDlg             g_D3DSettingsDlg;       // Device settings dialog\r
104 CDXUTDialog                 g_HUD;                  // manages the 3D   \r
105 CDXUTDialog                 g_SampleUI;             // dialog for sample specific controls\r
106 D3DXMATRIXA16               g_mCenterMesh;\r
107 float                       g_fLightScale;\r
108 int                         g_nNumActiveLights;\r
109 int                         g_nActiveLight;\r
110 bool                        g_bShowHelp = false;    // If true, it renders the UI control text\r
111 \r
112 // Direct3D9 resources\r
113 CDXUTTextHelper*            g_pTxtHelper = NULL;\r
114 \r
115 CDXUTSDKMesh                g_Mesh11;\r
116 \r
117 ID3D11InputLayout*          g_pVertexLayout11 = NULL;\r
118 ID3D11Buffer*               g_pVertexBuffer = NULL;\r
119 //ID3D11Buffer*               g_pIndexBuffer = NULL;\r
120 ID3D11VertexShader*         g_pVertexShader = NULL;\r
121 ID3D11GeometryShader*         g_pGeometryShader = NULL;\r
122 ID3D11PixelShader*          g_pPixelShader = NULL;\r
123 ID3D11SamplerState*         g_pSamLinear = NULL;\r
124 \r
125 ID3D11RasterizerState *g_pRasterizerState = NULL;\r
126 ID3D11RasterizerState *g_pRasterizerStateWF = NULL;\r
127 \r
128 bool g_wireFrame = false;\r
129 \r
130 struct CB_VS_PER_OBJECT\r
131 {\r
132     D3DXMATRIX m_WorldViewProj;\r
133     D3DXMATRIX m_World;\r
134 };\r
135 UINT                        g_iCBVSPerObjectBind = 0;\r
136 \r
137 struct CB_PS_PER_OBJECT\r
138 {\r
139     D3DXVECTOR4 m_vObjectColor;\r
140 };\r
141 UINT                        g_iCBPSPerObjectBind = 0;\r
142 \r
143 struct CB_PS_PER_FRAME\r
144 {\r
145     D3DXVECTOR4 m_vLightDirAmbient;\r
146 };\r
147 UINT                        g_iCBPSPerFrameBind = 1;\r
148 \r
149 ID3D11Buffer*               g_pcbVSPerObject = NULL;\r
150 ID3D11Buffer*               g_pcbPSPerObject = NULL;\r
151 ID3D11Buffer*               g_pcbPSPerFrame = NULL;\r
152 \r
153 ID3D11Device* g_pd3dDevice;\r
154 \r
155 \r
156 \r
157 \r
158 // Create our vertex input layout\r
159 const D3D11_INPUT_ELEMENT_DESC layout[] =\r
160 {\r
161     { "POSITION",  0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0,  D3D11_INPUT_PER_VERTEX_DATA, 0 },\r
162     { "NORMAL",    0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },\r
163     { "TEXCOORD",  0, DXGI_FORMAT_R32G32_FLOAT,    0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 },\r
164 };\r
165 \r
166 struct vertex_struct \r
167 {\r
168         D3DXVECTOR3 Pos;\r
169         D3DXVECTOR3 Normal;\r
170         D3DXVECTOR2 Texcoord;\r
171 };\r
172 \r
173 \r
174 \r
175 \r
176 \r
177 #include "capsule.h"\r
178 #include "cap.h"\r
179 #include "cylinder.h"\r
180 #include "cloth.h"\r
181 \r
182 \r
183 \r
184 //cylinder cyl_1;\r
185 //cap cap_1;\r
186 btRigidBody *capCollider;\r
187 capsule my_capsule;\r
188 \r
189 \r
190 btAlignedObjectArray<piece_of_cloth> cloths;\r
191 \r
192 //////////////////////////////////////////\r
193 // Bullet globals\r
194 \r
195 btAlignedObjectArray<btCollisionShape*> m_collisionShapes;\r
196 btBroadphaseInterface*  m_broadphase;\r
197 btCollisionDispatcher*  m_dispatcher;\r
198 btConstraintSolver*     m_solver;\r
199 btDefaultCollisionConfiguration* m_collisionConfiguration;\r
200 BTAcceleratedSoftBody::DX11SupportHelper m_dxSupport;\r
201 \r
202 btAlignedObjectArray<btSoftBody *> m_flags;\r
203 btSoftRigidDynamicsWorld* m_dynamicsWorld;\r
204 \r
205 btDefaultSoftBodySolver *g_defaultSolver = NULL;\r
206 btCPUSoftBodySolver *g_cpuSolver = NULL;\r
207 btDX11SoftBodySolver *g_dx11Solver = NULL;\r
208 btDX11SIMDAwareSoftBodySolver *g_dx11SIMDSolver = NULL;\r
209 \r
210 btSoftBodySolverOutput *g_softBodyOutput = NULL;\r
211 \r
212 btSoftBodySolver *g_solver = NULL;\r
213 \r
214 // End bullet globals\r
215 //////////////////////////////////////////\r
216 \r
217 // Helper to test and add links correctly.\r
218 // Records links that have already been generated\r
219 static bool testAndAddLink( btAlignedObjectArray<int> &trianglesForLinks, btSoftBody *softBody, int triangle, int *triangleVertexIndexArray, int numVertices, int vertex0, int vertex1, int nonLinkVertex, btSoftBody::Material *structuralMaterial, bool createBendLinks, btSoftBody::Material *bendMaterial )\r
220 {               \r
221         if( trianglesForLinks[ numVertices * vertex0 + vertex1 ] >= 0 && createBendLinks)\r
222         {\r
223                 // Already have link so find other triangle and generate cross link\r
224 \r
225                 int otherTriangle = trianglesForLinks[numVertices * vertex0 + vertex1];\r
226                 int otherIndices[3] = {triangleVertexIndexArray[otherTriangle * 3], triangleVertexIndexArray[otherTriangle * 3 + 1], triangleVertexIndexArray[otherTriangle * 3 + 2]};\r
227 \r
228                 int nodeA;\r
229                 // Test all links of the other triangle against this link. The one that's not part of it is what we want.\r
230                 if( otherIndices[0] != vertex0 && otherIndices[0] != vertex1 )\r
231                         nodeA = otherIndices[0];\r
232                 if( otherIndices[1] != vertex0 && otherIndices[1] != vertex1 )\r
233                         nodeA = otherIndices[1];\r
234                 if( otherIndices[2] != vertex0 && otherIndices[2] != vertex1 )\r
235                         nodeA = otherIndices[2];\r
236 \r
237                 softBody->appendLink( nodeA, nonLinkVertex, bendMaterial );\r
238 \r
239                 return true;\r
240         } else {\r
241                 // Don't yet have link so create it\r
242                 softBody->appendLink( vertex0, vertex1, structuralMaterial );\r
243 \r
244                 // If we added a new link, set the triangle array\r
245                 trianglesForLinks[numVertices * vertex0 + vertex1] = triangle;\r
246                 trianglesForLinks[numVertices * vertex1 + vertex0] = triangle;\r
247                 return true;\r
248         }\r
249 }\r
250 \r
251 btSoftBody *createFromIndexedMesh( btVector3 *vertexArray, int numVertices, int *triangleVertexIndexArray, int numTriangles, bool createBendLinks )\r
252 {\r
253         btSoftBody* softBody = new btSoftBody(&(m_dynamicsWorld->getWorldInfo()), numVertices, vertexArray, 0);\r
254         btSoftBody::Material * structuralMaterial = softBody->appendMaterial();\r
255         btSoftBody::Material * bendMaterial;\r
256         if( createBendLinks )\r
257         {\r
258                 bendMaterial = softBody->appendMaterial();\r
259                 bendMaterial->m_kLST = 0.7;\r
260         } else {\r
261                 bendMaterial = NULL;\r
262         }\r
263         structuralMaterial->m_kLST = 1.0;\r
264         \r
265 \r
266         // List of values for each link saying which triangle is associated with that link\r
267         // -1 to start. Once a value is entered we know the "other" triangle\r
268         // and can add a link across the link\r
269         btAlignedObjectArray<int> triangleForLinks;\r
270         triangleForLinks.resize( numVertices * numVertices, -1 );\r
271         for( int triangle = 0; triangle < numTriangles; ++triangle )\r
272         {\r
273                 int index[3] = {triangleVertexIndexArray[triangle * 3], triangleVertexIndexArray[triangle * 3 + 1], triangleVertexIndexArray[triangle * 3 + 2]};\r
274                 softBody->appendFace( index[0], index[1], index[2] );\r
275                 \r
276                 // Generate the structural links directly from the triangles\r
277                 testAndAddLink( triangleForLinks, softBody, triangle, triangleVertexIndexArray, numVertices, index[0], index[1], index[2], structuralMaterial, createBendLinks, bendMaterial );\r
278                 testAndAddLink( triangleForLinks, softBody, triangle, triangleVertexIndexArray, numVertices, index[1], index[2], index[0], structuralMaterial, createBendLinks, bendMaterial );\r
279                 testAndAddLink( triangleForLinks, softBody, triangle, triangleVertexIndexArray, numVertices, index[2], index[0], index[1], structuralMaterial, createBendLinks, bendMaterial);\r
280         }\r
281 \r
282         return softBody;\r
283 }\r
284 \r
285 /**\r
286  * Create a sequence of flag objects and add them to the world.\r
287  */\r
288 void createFlag( int width, int height, btAlignedObjectArray<btSoftBody *> &flags )\r
289 {\r
290         // First create a triangle mesh to represent a flag\r
291 \r
292         using namespace BTAcceleratedSoftBody;  \r
293         using Vectormath::Aos::Matrix3;\r
294         using Vectormath::Aos::Vector3;\r
295 \r
296         // Allocate a simple mesh consisting of a vertex array and a triangle index array\r
297         btIndexedMesh mesh;\r
298         mesh.m_numVertices = width*height;\r
299         mesh.m_numTriangles = 2*(width-1)*(height-1);\r
300 \r
301         btVector3 *vertexArray = new btVector3[mesh.m_numVertices];\r
302 \r
303         mesh.m_vertexBase = reinterpret_cast<const unsigned char*>(vertexArray);\r
304         int *triangleVertexIndexArray = new int[3*mesh.m_numTriangles]; \r
305         mesh.m_triangleIndexBase = reinterpret_cast<const unsigned char*>(triangleVertexIndexArray);\r
306         mesh.m_triangleIndexStride = sizeof(int)*3;\r
307         mesh.m_vertexStride = sizeof(Vector3);\r
308 \r
309         // Generate normalised object space vertex coordinates for a rectangular flag\r
310         float zCoordinate = 0.0f;\r
311         \r
312         Matrix3 defaultScale(Vector3(5.f, 0.f, 0.f), Vector3(0.f, 20.f, 0.f), Vector3(0.f, 0.f, 1.f));\r
313         for( int y = 0; y < height; ++y )\r
314         {\r
315                 float yCoordinate = y*2.0f/float(height) - 1.0f;\r
316                 for( int x = 0; x < width; ++x )\r
317                 {                       \r
318                         float xCoordinate = x*2.0f/float(width) - 1.0f;\r
319 \r
320                         Vector3 vertex(xCoordinate, yCoordinate, zCoordinate);\r
321                         Vector3 transformedVertex = defaultScale*vertex;\r
322 \r
323                         vertexArray[y*width + x] = btVector3(transformedVertex.getX(), transformedVertex.getY(), transformedVertex.getZ() );\r
324 \r
325                 }\r
326         }\r
327 \r
328         // Generate vertex indices for triangles\r
329         for( int y = 0; y < (height-1); ++y )\r
330         {\r
331                 for( int x = 0; x < (width-1); ++x )\r
332                 {       \r
333                         // Triangle 0\r
334                         // Top left of square on mesh\r
335                         {\r
336                                 int vertex0 = y*width + x;\r
337                                 int vertex1 = vertex0 + 1;\r
338                                 int vertex2 = vertex0 + width;\r
339                                 int triangleIndex = 2*y*(width-1) + 2*x;\r
340                                 triangleVertexIndexArray[(mesh.m_triangleIndexStride*triangleIndex)/sizeof(int)] = vertex0;\r
341                                 triangleVertexIndexArray[(mesh.m_triangleIndexStride*triangleIndex+1)/sizeof(int)+1] = vertex1;\r
342                                 triangleVertexIndexArray[(mesh.m_triangleIndexStride*triangleIndex+2)/sizeof(int)+2] = vertex2;\r
343                         }\r
344 \r
345                         // Triangle 1\r
346                         // Bottom right of square on mesh\r
347                         {\r
348                                 int vertex0 = y*width + x + 1;\r
349                                 int vertex1 = vertex0 + width;\r
350                                 int vertex2 = vertex1 - 1;\r
351                                 int triangleIndex = 2*y*(width-1) + 2*x + 1;\r
352                                 triangleVertexIndexArray[(mesh.m_triangleIndexStride*triangleIndex)/sizeof(int)] = vertex0;\r
353                                 triangleVertexIndexArray[(mesh.m_triangleIndexStride*triangleIndex)/sizeof(int)+1] = vertex1;\r
354                                 triangleVertexIndexArray[(mesh.m_triangleIndexStride*triangleIndex)/sizeof(int)+2] = vertex2;\r
355                         }\r
356                 }\r
357         }\r
358 \r
359         \r
360         float rotateAngleRoundZ = 0.5;\r
361         float rotateAngleRoundX = 0.5;\r
362         btMatrix3x3 defaultRotate;\r
363         defaultRotate[0] = btVector3(cos(rotateAngleRoundZ), sin(rotateAngleRoundZ), 0.f); \r
364         defaultRotate[1] = btVector3(-sin(rotateAngleRoundZ), cos(rotateAngleRoundZ), 0.f);\r
365         defaultRotate[2] = btVector3(0.f, 0.f, 1.f);\r
366 \r
367 \r
368         //btMatrix3x3 defaultRotateAndScale( (defaultRotateX*defaultRotate) );\r
369 #ifdef TABLETEST\r
370         btMatrix3x3 defaultRotateX;\r
371         rotateAngleRoundX = 3.141592654/2;\r
372         defaultRotateX[0] = btVector3(1.f, 0.f, 0.f);\r
373         defaultRotateX[1] = btVector3( 0.f, cos(rotateAngleRoundX), sin(rotateAngleRoundX));\r
374         defaultRotateX[2] = btVector3(0.f, -sin(rotateAngleRoundX), cos(rotateAngleRoundX));\r
375         btMatrix3x3 defaultRotateAndScale( (defaultRotateX) );\r
376 #else\r
377         btMatrix3x3 defaultRotateX;\r
378         defaultRotateX[0] = btVector3(1.f, 0.f, 0.f);\r
379         defaultRotateX[1] = btVector3( 0.f, cos(rotateAngleRoundX), sin(rotateAngleRoundX));\r
380         defaultRotateX[2] = btVector3(0.f, -sin(rotateAngleRoundX), cos(rotateAngleRoundX));\r
381         btMatrix3x3 defaultRotateAndScale( (defaultRotateX) );\r
382 #endif\r
383 \r
384 \r
385         // Construct the sequence flags applying a slightly different translation to each one to arrange them\r
386         // appropriately in the scene.\r
387         for( int i = 0; i < numFlags; ++i )\r
388         {\r
389                 float zTranslate = flagSpacing * (i-numFlags/2);\r
390 \r
391                 btVector3 defaultTranslate(0.f, 20.f, zTranslate);\r
392 \r
393                 btTransform transform( defaultRotateAndScale, defaultTranslate );\r
394 \r
395 \r
396                 btSoftBody *softBody = createFromIndexedMesh( vertexArray, mesh.m_numVertices, triangleVertexIndexArray, mesh.m_numTriangles, true );\r
397 \r
398 \r
399                 for( int i = 0; i < mesh.m_numVertices; ++i )\r
400                 {\r
401                         softBody->setMass(i, 10.f/mesh.m_numVertices);\r
402                 }\r
403 \r
404 #ifndef TABLETEST\r
405                 // Set the fixed points\r
406                 softBody->setMass((height-1)*(width), 0.f);\r
407                 softBody->setMass((height-1)*(width) + width - 1, 0.f);\r
408                 softBody->setMass((height-1)*width + width/2, 0.f);\r
409 #endif\r
410 \r
411                 softBody->m_cfg.collisions = btSoftBody::fCollision::CL_SS+btSoftBody::fCollision::CL_RS;       \r
412                 softBody->m_cfg.kLF = 0.0005f;\r
413                 softBody->m_cfg.kVCF = 0.001f;\r
414                 softBody->m_cfg.kDP = 0.f;\r
415                 softBody->m_cfg.kDG = 0.f;\r
416                 \r
417                 flags.push_back( softBody );\r
418 \r
419                 softBody->transform( transform );\r
420                 softBody->setFriction( 0.8f );\r
421                 m_dynamicsWorld->addSoftBody( softBody );\r
422         }\r
423 \r
424         delete [] vertexArray;\r
425         delete [] triangleVertexIndexArray;\r
426 }\r
427 \r
428 \r
429 \r
430 \r
431 \r
432 void updatePhysicsWorld()\r
433 {\r
434         static int counter = 0;\r
435 \r
436         // Change wind velocity a bit based on a frame counter\r
437         if( (counter % 400) == 0 )\r
438         {\r
439                 _windAngle = (_windAngle + 0.05f);\r
440                 if( _windAngle > (2*3.141) )\r
441                         _windAngle = 0;\r
442 \r
443                 for( int flagIndex = 0; flagIndex < m_flags.size(); ++flagIndex )\r
444                 {               \r
445                         btSoftBody *cloth = 0;\r
446 \r
447                         cloth = m_flags[flagIndex];\r
448 \r
449                         float localWind = _windAngle + 0.5*(((float(rand())/RAND_MAX))-0.1);\r
450                         float xCoordinate = cos(localWind)*_windStrength;\r
451                         float zCoordinate = sin(localWind)*_windStrength;\r
452 \r
453                         cloth->setWindVelocity( btVector3(xCoordinate, 0, zCoordinate) );\r
454                 }\r
455         }\r
456 #ifndef TABLETEST\r
457         if (capCollider)\r
458         {\r
459                 btVector3 origin( capCollider->getWorldTransform().getOrigin() );\r
460                 origin.setZ( origin.getZ() + 0.01 );\r
461                 capCollider->getWorldTransform().setOrigin( origin );\r
462         }\r
463 #endif\r
464 \r
465         counter++;\r
466 }\r
467 \r
468 void initBullet(void)\r
469 {\r
470 \r
471 \r
472 #ifdef USE_GPU_SOLVER\r
473         g_dx11Solver = new btDX11SoftBodySolver( g_pd3dDevice, DXUTGetD3D11DeviceContext() );\r
474         g_solver = g_dx11Solver;\r
475 #ifdef USE_GPU_COPY\r
476         g_softBodyOutput = new btSoftBodySolverOutputDXtoDX( g_pd3dDevice, DXUTGetD3D11DeviceContext() );\r
477 #else // #ifdef USE_GPU_COPY\r
478         g_softBodyOutput = new btSoftBodySolverOutputDXtoCPU;\r
479 #endif // #ifdef USE_GPU_COPY\r
480 #else\r
481 #ifdef USE_SIMDAWARE_SOLVER\r
482         g_dx11SIMDSolver = new btDX11SIMDAwareSoftBodySolver( g_pd3dDevice, DXUTGetD3D11DeviceContext() );\r
483         g_solver = g_dx11SIMDSolver;\r
484         g_softBodyOutput = new btSoftBodySolverOutputDXtoCPU;\r
485 #ifdef USE_GPU_COPY\r
486         g_softBodyOutput = new btSoftBodySolverOutputDXtoDX( g_pd3dDevice, DXUTGetD3D11DeviceContext() );\r
487 #else // #ifdef USE_GPU_COPY\r
488         g_softBodyOutput = new btSoftBodySolverOutputDXtoCPU;\r
489 #endif // #ifdef USE_GPU_COPY\r
490 #else\r
491         g_cpuSolver = new btCPUSoftBodySolver;\r
492         g_solver = g_cpuSolver;\r
493         g_softBodyOutput = new btSoftBodySolverOutputCPUtoCPU;\r
494         //g_defaultSolver = new btDefaultSoftBodySolver;\r
495         //g_solver = g_defaultSolver;\r
496 #endif\r
497 #endif\r
498 \r
499         if (g_dx11SIMDSolver)\r
500                 g_dx11SIMDSolver->setEnableUpdateBounds(true);\r
501 \r
502         if (g_dx11Solver)\r
503                 g_dx11Solver->setEnableUpdateBounds(true);\r
504 \r
505         // Initialise CPU physics device\r
506         //m_collisionConfiguration = new btDefaultCollisionConfiguration();\r
507         m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();\r
508         m_dispatcher = new      btCollisionDispatcher(m_collisionConfiguration);\r
509         m_broadphase = new btDbvtBroadphase();\r
510         btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver;\r
511         m_solver = sol;\r
512 \r
513         m_dynamicsWorld = new btSoftRigidDynamicsWorld(m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration, g_solver);       \r
514 \r
515         m_dynamicsWorld->setGravity(btVector3(0,-10,0));        \r
516         btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.)));   \r
517         m_collisionShapes.push_back(groundShape);\r
518         btTransform groundTransform;\r
519         groundTransform.setIdentity();\r
520         groundTransform.setOrigin(btVector3(0,-50,0));\r
521 \r
522         m_dynamicsWorld->getWorldInfo().air_density                     =       (btScalar)1.2;\r
523         m_dynamicsWorld->getWorldInfo().water_density           =       0;\r
524         m_dynamicsWorld->getWorldInfo().water_offset            =       0;\r
525         m_dynamicsWorld->getWorldInfo().water_normal            =       btVector3(0,0,0);\r
526         m_dynamicsWorld->getWorldInfo().m_gravity.setValue(0,-10,0);\r
527         \r
528 #if 0\r
529         {\r
530                 btScalar mass(0.);\r
531 \r
532                 //rigidbody is dynamic if and only if mass is non zero, otherwise static\r
533                 bool isDynamic = (mass != 0.f);\r
534 \r
535                 btVector3 localInertia(0,0,0);\r
536                 if (isDynamic)\r
537                         groundShape->calculateLocalInertia(mass,localInertia);\r
538 \r
539                 //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects\r
540                 btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);\r
541                 btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia);\r
542                 btRigidBody* body = new btRigidBody(rbInfo);\r
543 \r
544                 //add the body to the dynamics world\r
545                 m_dynamicsWorld->addRigidBody(body);\r
546         }\r
547  \r
548 #endif\r
549 #if 0\r
550         {               \r
551                 btScalar mass(0.);\r
552 \r
553                 //btScalar mass(1.);\r
554 \r
555                 //rigidbody is dynamic if and only if mass is non zero, otherwise static\r
556                 bool isDynamic = (mass != 0.f);\r
557                 \r
558                 btCollisionShape *capsuleShape = new btCapsuleShape(5, 10);\r
559                 capsuleShape->setMargin( 0.5 );\r
560                 \r
561                 \r
562 \r
563                 my_capsule.set_collision_shape(capsuleShape);\r
564 \r
565                 btVector3 localInertia(0,0,0);\r
566                 if (isDynamic)\r
567                         capsuleShape->calculateLocalInertia(mass,localInertia);\r
568 \r
569                 m_collisionShapes.push_back(capsuleShape);\r
570                 btTransform capsuleTransform;\r
571                 capsuleTransform.setIdentity();\r
572 #ifdef TABLETEST\r
573                 capsuleTransform.setOrigin(btVector3(0, 10, -11));\r
574                 const btScalar pi = 3.141592654;\r
575                 capsuleTransform.setRotation(btQuaternion(0, 0, pi/2));\r
576 #else\r
577                 capsuleTransform.setOrigin(btVector3(0, 20, -10));\r
578                 \r
579                 const btScalar pi = 3.141592654;\r
580                 //capsuleTransform.setRotation(btQuaternion(0, 0, pi/2));\r
581                 capsuleTransform.setRotation(btQuaternion(0, 0, 0));\r
582 #endif\r
583                 btDefaultMotionState* myMotionState = new btDefaultMotionState(capsuleTransform);\r
584                 btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,capsuleShape,localInertia);\r
585                 btRigidBody* body = new btRigidBody(rbInfo);\r
586                 body->setFriction( 0.8f );\r
587                 my_capsule.set_collision_object(body);\r
588 \r
589                 m_dynamicsWorld->addRigidBody(body);\r
590                 //cap_1.collisionShape = body;\r
591                 capCollider = body;\r
592         }\r
593 #endif\r
594 \r
595 \r
596         createFlag( clothWidth, clothHeight, m_flags );\r
597 \r
598         // Create output buffer descriptions for ecah flag\r
599         // These describe where the simulation should send output data to\r
600         for( int flagIndex = 0; flagIndex < m_flags.size(); ++flagIndex )\r
601         {               \r
602                 // In this case we have a DX11 output buffer with a vertex at index 0, 8, 16 and so on as well as a normal at 3, 11, 19 etc.\r
603                 // Copies will be performed GPU-side directly into the output buffer\r
604 #ifdef USE_GPU_COPY\r
605                 btDX11VertexBufferDescriptor *vertexBufferDescriptor = new btDX11VertexBufferDescriptor(DXUTGetD3D11DeviceContext(), cloths[flagIndex].pVB[0], cloths[flagIndex].g_pVB_UAV, 0, 8, 3, 8);\r
606                 cloths[flagIndex].m_vertexBufferDescriptor = vertexBufferDescriptor;\r
607 #else  // #ifdef USE_GPU_COPY\r
608                 btCPUVertexBufferDescriptor *vertexBufferDescriptor = new btCPUVertexBufferDescriptor(cloths[flagIndex].cpu_buffer, 0, 8, 3, 8);\r
609                 cloths[flagIndex].m_vertexBufferDescriptor = vertexBufferDescriptor;\r
610 #endif // #ifdef USE_GPU_COPY\r
611         }\r
612 \r
613         g_solver->optimize( m_dynamicsWorld->getSoftBodyArray() );\r
614 \r
615 }\r
616 \r
617 \r
618 \r
619 \r
620 \r
621 \r
622 \r
623 \r
624 \r
625 \r
626 \r
627 \r
628 \r
629 \r
630 \r
631 \r
632 \r
633 \r
634 \r
635 \r
636 \r
637 \r
638 \r
639 \r
640 \r
641 \r
642 \r
643 \r
644 \r
645 \r
646 \r
647 \r
648 \r
649 \r
650 \r
651 //--------------------------------------------------------------------------------------\r
652 // UI control IDs\r
653 //--------------------------------------------------------------------------------------\r
654 #define IDC_TOGGLEFULLSCREEN    1\r
655 #define IDC_TOGGLEREF           3\r
656 #define IDC_CHANGEDEVICE        4\r
657 #define IDC_PAUSE               5\r
658 #define IDC_WIREFRAME           6\r
659 \r
660 //--------------------------------------------------------------------------------------\r
661 // Forward declarations \r
662 //--------------------------------------------------------------------------------------\r
663 bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, void* pUserContext );\r
664 void CALLBACK OnFrameMove( double fTime, float fElapsedTime, void* pUserContext );\r
665 LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing,\r
666                           void* pUserContext );\r
667 void CALLBACK OnKeyboard( UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext );\r
668 void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserContext );\r
669 \r
670 bool CALLBACK IsD3D11DeviceAcceptable(const CD3D11EnumAdapterInfo *AdapterInfo, UINT Output, const CD3D11EnumDeviceInfo *DeviceInfo,\r
671                                        DXGI_FORMAT BackBufferFormat, bool bWindowed, void* pUserContext );\r
672 HRESULT CALLBACK OnD3D11CreateDevice( ID3D11Device* pd3dDevice, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc,\r
673                                       void* pUserContext );\r
674 HRESULT CALLBACK OnD3D11ResizedSwapChain( ID3D11Device* pd3dDevice, IDXGISwapChain* pSwapChain,\r
675                                           const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext );\r
676 void CALLBACK OnD3D11ReleasingSwapChain( void* pUserContext );\r
677 void CALLBACK OnD3D11DestroyDevice( void* pUserContext );\r
678 void CALLBACK OnD3D11FrameRender( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3dImmediateContext, double fTime,\r
679                                   float fElapsedTime, void* pUserContext );\r
680 \r
681 void InitApp();\r
682 void RenderText();\r
683 \r
684 \r
685 //--------------------------------------------------------------------------------------\r
686 // Entry point to the program. Initializes everything and goes into a message processing \r
687 // loop. Idle time is used to render the scene.\r
688 //--------------------------------------------------------------------------------------\r
689 int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow )\r
690 {\r
691     // Enable run-time memory check for debug builds.\r
692 #if defined(DEBUG) | defined(_DEBUG)\r
693     _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );\r
694         _CrtSetReportMode ( _CRT_ERROR,   _CRTDBG_MODE_DEBUG);\r
695 #endif\r
696 \r
697     // DXUT will create and use the best device (either D3D9 or D3D11) \r
698     // that is available on the system depending on which D3D callbacks are set below\r
699 \r
700     // Set DXUT callbacks\r
701     DXUTSetCallbackDeviceChanging( ModifyDeviceSettings );\r
702     DXUTSetCallbackMsgProc( MsgProc );\r
703     DXUTSetCallbackKeyboard( OnKeyboard );\r
704     DXUTSetCallbackFrameMove( OnFrameMove );    \r
705 \r
706         \r
707     DXUTSetCallbackD3D11DeviceAcceptable( IsD3D11DeviceAcceptable );\r
708     DXUTSetCallbackD3D11DeviceCreated( OnD3D11CreateDevice );\r
709         \r
710     DXUTSetCallbackD3D11SwapChainResized( OnD3D11ResizedSwapChain );\r
711     DXUTSetCallbackD3D11FrameRender( OnD3D11FrameRender );\r
712     DXUTSetCallbackD3D11SwapChainReleasing( OnD3D11ReleasingSwapChain );\r
713         \r
714     DXUTSetCallbackD3D11DeviceDestroyed( OnD3D11DestroyDevice );\r
715 \r
716 \r
717     InitApp();\r
718     DXUTInit( true, true, NULL ); // Parse the command line, show msgboxes on error, no extra command line params\r
719     DXUTSetCursorSettings( true, true ); // Show the cursor and clip it when in full screen\r
720     DXUTCreateWindow( L"Cloth Renderer" );\r
721     DXUTCreateDevice (D3D_FEATURE_LEVEL_11_0, true, 800, 600 );\r
722         DXUTSetMultimonSettings(false);\r
723     //DXUTCreateDevice(true, 640, 480);\r
724     DXUTMainLoop(); // Enter into the DXUT render loop\r
725 \r
726     return DXUTGetExitCode();\r
727 }\r
728 \r
729 \r
730 //--------------------------------------------------------------------------------------\r
731 // Initialize the app \r
732 //--------------------------------------------------------------------------------------\r
733 void InitApp()\r
734 {\r
735     D3DXVECTOR3 vLightDir( 1, 0, 0 );\r
736     D3DXVec3Normalize( &vLightDir, &vLightDir );\r
737     g_LightControl.SetLightDirection( vLightDir );\r
738 \r
739     // Initialize dialogs\r
740     g_D3DSettingsDlg.Init( &g_DialogResourceManager );\r
741     g_HUD.Init( &g_DialogResourceManager );\r
742     g_SampleUI.Init( &g_DialogResourceManager );\r
743 \r
744     g_HUD.SetCallback( OnGUIEvent ); int iY = 10;\r
745     g_HUD.AddButton( IDC_TOGGLEFULLSCREEN, L"Toggle full screen", 0, iY, 170, 23 );\r
746         \r
747     g_HUD.AddButton( IDC_TOGGLEREF, L"Toggle REF (F3)", 0, iY += 26, 170, 23, VK_F3 );\r
748     g_HUD.AddButton( IDC_CHANGEDEVICE, L"Change device (F2)", 0, iY += 26, 170, 23, VK_F2 );\r
749         g_HUD.AddButton( IDC_PAUSE, L"Pause", 0, iY += 26, 170, 23 );\r
750         g_HUD.AddButton( IDC_WIREFRAME, L"Wire frame", 0, iY += 26, 170, 23 );\r
751     \r
752         g_SampleUI.SetCallback( OnGUIEvent ); iY = 10;\r
753 }\r
754 \r
755 \r
756 //--------------------------------------------------------------------------------------\r
757 // Called right before creating a D3D9 or D3D11 device, allowing the app to modify the device settings as needed\r
758 //--------------------------------------------------------------------------------------\r
759 bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, void* pUserContext )\r
760 {\r
761     // Uncomment this to get debug information from D3D11\r
762     //pDeviceSettings->d3d11.CreateFlags |= D3D11_CREATE_DEVICE_DEBUG;\r
763 \r
764     // For the first device created if its a REF device, optionally display a warning dialog box\r
765     static bool s_bFirstTime = true;\r
766     if( s_bFirstTime )\r
767     {\r
768         s_bFirstTime = false;\r
769         if( ( DXUT_D3D11_DEVICE == pDeviceSettings->ver &&\r
770               pDeviceSettings->d3d11.DriverType == D3D_DRIVER_TYPE_REFERENCE ) )\r
771         {\r
772             DXUTDisplaySwitchingToREFWarning( pDeviceSettings->ver );\r
773         }\r
774     }\r
775 \r
776     return true;\r
777 }\r
778 \r
779 \r
780 //--------------------------------------------------------------------------------------\r
781 // Handle updates to the scene.  This is called regardless of which D3D API is used\r
782 //--------------------------------------------------------------------------------------\r
783 void CALLBACK OnFrameMove( double fTime, float fElapsedTime, void* pUserContext )\r
784 {\r
785     // Update the camera's position based on user input \r
786     g_Camera.FrameMove( fElapsedTime );\r
787 }\r
788 \r
789 \r
790 //--------------------------------------------------------------------------------------\r
791 // Render the help and statistics text\r
792 //--------------------------------------------------------------------------------------\r
793 void RenderText()\r
794 {\r
795     UINT nBackBufferHeight = ( DXUTIsAppRenderingWithD3D9() ) ? DXUTGetD3D9BackBufferSurfaceDesc()->Height :\r
796             DXUTGetDXGIBackBufferSurfaceDesc()->Height;\r
797 \r
798     g_pTxtHelper->Begin();\r
799     g_pTxtHelper->SetInsertionPos( 2, 0 );\r
800     g_pTxtHelper->SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 0.0f, 1.0f ) );\r
801     g_pTxtHelper->DrawTextLine( DXUTGetFrameStats( DXUTIsVsyncEnabled() ) );\r
802     g_pTxtHelper->DrawTextLine( DXUTGetDeviceStats() );\r
803 \r
804     // Draw help\r
805     if( g_bShowHelp )\r
806     {\r
807         g_pTxtHelper->SetInsertionPos( 2, nBackBufferHeight - 20 * 6 );\r
808         g_pTxtHelper->SetForegroundColor( D3DXCOLOR( 1.0f, 0.75f, 0.0f, 1.0f ) );\r
809         g_pTxtHelper->DrawTextLine( L"Controls:" );\r
810 \r
811         g_pTxtHelper->SetInsertionPos( 20, nBackBufferHeight - 20 * 5 );\r
812                 g_pTxtHelper->DrawTextLine( L"Rotate view: Left mouse button\n"\r
813                                                                         L"Move camera: W, A, S, and D\n"\r
814                                     L"Rotate light: Right mouse button\n"\r
815                                     L"Zoom camera: Mouse wheel scroll\n" );\r
816 \r
817         g_pTxtHelper->SetInsertionPos( 550, nBackBufferHeight - 20 * 5 );\r
818         g_pTxtHelper->DrawTextLine( L"Hide help: F1\n"\r
819                                     L"Quit: ESC\n" );\r
820     }\r
821     else\r
822     {\r
823         g_pTxtHelper->SetForegroundColor( D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f ) );\r
824         g_pTxtHelper->DrawTextLine( L"Press F1 for help" );\r
825     }\r
826 \r
827     g_pTxtHelper->End();\r
828 }\r
829 \r
830 \r
831 //--------------------------------------------------------------------------------------\r
832 // Handle messages to the application\r
833 //--------------------------------------------------------------------------------------\r
834 LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing,\r
835                           void* pUserContext )\r
836 {\r
837     // Pass messages to dialog resource manager calls so GUI state is updated correctly\r
838     *pbNoFurtherProcessing = g_DialogResourceManager.MsgProc( hWnd, uMsg, wParam, lParam );\r
839     if( *pbNoFurtherProcessing )\r
840         return 0;\r
841 \r
842     // Pass messages to settings dialog if its active\r
843     if( g_D3DSettingsDlg.IsActive() )\r
844     {\r
845         g_D3DSettingsDlg.MsgProc( hWnd, uMsg, wParam, lParam );\r
846         return 0;\r
847     }\r
848 \r
849     // Give the dialogs a chance to handle the message first\r
850     *pbNoFurtherProcessing = g_HUD.MsgProc( hWnd, uMsg, wParam, lParam );\r
851     if( *pbNoFurtherProcessing )\r
852         return 0;\r
853     *pbNoFurtherProcessing = g_SampleUI.MsgProc( hWnd, uMsg, wParam, lParam );\r
854     if( *pbNoFurtherProcessing )\r
855         return 0;\r
856 \r
857     g_LightControl.HandleMessages( hWnd, uMsg, wParam, lParam );\r
858 \r
859     // Pass all remaining windows messages to camera so it can respond to user input\r
860     g_Camera.HandleMessages( hWnd, uMsg, wParam, lParam );\r
861 \r
862     return 0;\r
863 }\r
864 \r
865 \r
866 //--------------------------------------------------------------------------------------\r
867 // Handle key presses\r
868 //--------------------------------------------------------------------------------------\r
869 void CALLBACK OnKeyboard( UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext )\r
870 {\r
871     if( bKeyDown )\r
872     {\r
873         switch( nChar )\r
874         {\r
875             case VK_F1:\r
876                 g_bShowHelp = !g_bShowHelp; break;\r
877         }\r
878     }\r
879 }\r
880 \r
881 \r
882 //--------------------------------------------------------------------------------------\r
883 // Handles the GUI events\r
884 //--------------------------------------------------------------------------------------\r
885 void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserContext )\r
886 {\r
887     switch( nControlID )\r
888     {\r
889         case IDC_TOGGLEFULLSCREEN:\r
890             DXUTToggleFullScreen(); break;\r
891         case IDC_TOGGLEREF:\r
892             DXUTToggleREF(); break;\r
893         case IDC_CHANGEDEVICE:\r
894             g_D3DSettingsDlg.SetActive( !g_D3DSettingsDlg.IsActive() ); break;\r
895                 case IDC_PAUSE:\r
896                         paused = !paused;\r
897                         break;\r
898                 case IDC_WIREFRAME:\r
899                         g_wireFrame = !g_wireFrame;\r
900                         break;\r
901     }\r
902 \r
903 }\r
904 \r
905 \r
906 //--------------------------------------------------------------------------------------\r
907 // Reject any D3D11 devices that aren't acceptable by returning false\r
908 //--------------------------------------------------------------------------------------\r
909 bool CALLBACK IsD3D11DeviceAcceptable( const CD3D11EnumAdapterInfo *AdapterInfo, UINT Output, const CD3D11EnumDeviceInfo *DeviceInfo,\r
910                                        DXGI_FORMAT BackBufferFormat, bool bWindowed, void* pUserContext )\r
911 {\r
912     return true;\r
913 }\r
914 \r
915 //--------------------------------------------------------------------------------------\r
916 // Use this until D3DX11 comes online and we get some compilation helpers\r
917 //--------------------------------------------------------------------------------------\r
918 HRESULT CompileShaderFromFile( WCHAR* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut )\r
919 {\r
920     HRESULT hr = S_OK;\r
921 \r
922     // find the file\r
923     WCHAR str[MAX_PATH];\r
924     V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, szFileName ) );\r
925 \r
926     // open the file\r
927     HANDLE hFile = CreateFile( str, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,\r
928                                FILE_FLAG_SEQUENTIAL_SCAN, NULL );\r
929     if( INVALID_HANDLE_VALUE == hFile )\r
930         return E_FAIL;\r
931 \r
932     // Get the file size\r
933     LARGE_INTEGER FileSize;\r
934     GetFileSizeEx( hFile, &FileSize );\r
935 \r
936     // create enough space for the file data\r
937     BYTE* pFileData = new BYTE[ FileSize.LowPart ];\r
938     if( !pFileData )\r
939         return E_OUTOFMEMORY;\r
940 \r
941     // read the data in\r
942     DWORD BytesRead;\r
943     if( !ReadFile( hFile, pFileData, FileSize.LowPart, &BytesRead, NULL ) )\r
944         return E_FAIL; \r
945 \r
946     CloseHandle( hFile );\r
947 \r
948     // Compile the shader\r
949     ID3DBlob* pErrorBlob;\r
950     hr = D3DCompile( pFileData, FileSize.LowPart, "none", NULL, NULL, szEntryPoint, szShaderModel, D3D10_SHADER_ENABLE_STRICTNESS, 0, ppBlobOut, &pErrorBlob );\r
951 \r
952     delete []pFileData;\r
953 \r
954     if( FAILED(hr) )\r
955     {\r
956         OutputDebugStringA( (char*)pErrorBlob->GetBufferPointer() );\r
957         SAFE_RELEASE( pErrorBlob );\r
958         return hr;\r
959     }\r
960     SAFE_RELEASE( pErrorBlob );\r
961 \r
962     return S_OK;\r
963 }\r
964 \r
965 \r
966 //--------------------------------------------------------------------------------------\r
967 // Create any D3D11 resources that aren't dependant on the back buffer\r
968 //--------------------------------------------------------------------------------------\r
969 HRESULT CALLBACK OnD3D11CreateDevice( ID3D11Device* pd3dDevice, const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc,\r
970                                       void* pUserContext )\r
971 {\r
972         \r
973     g_pd3dDevice = pd3dDevice;\r
974  \r
975     HRESULT hr;\r
976 \r
977     ID3D11DeviceContext* pd3dImmediateContext = DXUTGetD3D11DeviceContext();\r
978 \r
979     V_RETURN( g_DialogResourceManager.OnD3D11CreateDevice( pd3dDevice, pd3dImmediateContext ) );\r
980     V_RETURN( g_D3DSettingsDlg.OnD3D11CreateDevice( pd3dDevice ) );\r
981     g_pTxtHelper = new CDXUTTextHelper( pd3dDevice, pd3dImmediateContext, &g_DialogResourceManager, 15 );\r
982 \r
983     D3DXVECTOR3 vCenter( 0.25767413f, -28.503521f, 111.00689f);\r
984     FLOAT fObjectRadius = 378.15607f;\r
985 \r
986     D3DXMatrixTranslation( &g_mCenterMesh, -vCenter.x, -vCenter.y, -vCenter.z );\r
987     D3DXMATRIXA16 m;\r
988     D3DXMatrixRotationY( &m, D3DX_PI );\r
989     g_mCenterMesh *= m;\r
990     D3DXMatrixRotationX( &m, D3DX_PI / 2.0f );\r
991     g_mCenterMesh *= m;\r
992 \r
993     // Compile the shaders to a model based on the feature level we acquired\r
994     ID3DBlob* pVertexShaderBuffer = NULL;\r
995         ID3DBlob* pGeometryShaderBuffer = NULL;\r
996     ID3DBlob* pPixelShaderBuffer = NULL;\r
997   \r
998     switch( DXUTGetD3D11DeviceFeatureLevel() )\r
999     {\r
1000         case D3D_FEATURE_LEVEL_11_0:\r
1001             V_RETURN( CompileShaderFromFile( L"cloth_renderer_VS.hlsl", "VSMain", "vs_5_0" , &pVertexShaderBuffer ) );\r
1002                         V_RETURN( CompileShaderFromFile( L"cloth_renderer_PS.hlsl", "GSMain", "gs_5_0" , &pGeometryShaderBuffer ) );\r
1003             V_RETURN( CompileShaderFromFile( L"cloth_renderer_PS.hlsl", "PSMain", "ps_5_0" , &pPixelShaderBuffer ) );\r
1004             break;        \r
1005     }\r
1006 \r
1007     // Create the shaders\r
1008     V_RETURN( pd3dDevice->CreateVertexShader( pVertexShaderBuffer->GetBufferPointer(),\r
1009                                               pVertexShaderBuffer->GetBufferSize(), NULL, &g_pVertexShader ) );\r
1010 \r
1011 \r
1012         V_RETURN( pd3dDevice->CreateGeometryShader( pGeometryShaderBuffer->GetBufferPointer(),\r
1013                                               pGeometryShaderBuffer->GetBufferSize(), NULL, &g_pGeometryShader ) );\r
1014     \r
1015 \r
1016     V_RETURN( pd3dDevice->CreatePixelShader( pPixelShaderBuffer->GetBufferPointer(),\r
1017                                              pPixelShaderBuffer->GetBufferSize(), NULL, &g_pPixelShader ) );\r
1018 \r
1019     \r
1020 \r
1021     V_RETURN( pd3dDevice->CreateInputLayout( layout, ARRAYSIZE( layout ), pVertexShaderBuffer->GetBufferPointer(),\r
1022                                              pVertexShaderBuffer->GetBufferSize(), &g_pVertexLayout11 ) );\r
1023 \r
1024     SAFE_RELEASE( pVertexShaderBuffer );\r
1025     SAFE_RELEASE( pPixelShaderBuffer );\r
1026         SAFE_RELEASE( pGeometryShaderBuffer );\r
1027 \r
1028 \r
1029     // Load the mesh\r
1030     V_RETURN( g_Mesh11.Create( pd3dDevice, L"tiny\\tiny.sdkmesh", true ) );\r
1031 \r
1032 \r
1033     \r
1034 \r
1035     // Create a sampler state\r
1036     D3D11_SAMPLER_DESC SamDesc;\r
1037     SamDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;\r
1038     SamDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;\r
1039     SamDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;\r
1040     SamDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;\r
1041     SamDesc.MipLODBias = 0.0f;\r
1042     SamDesc.MaxAnisotropy = 1;\r
1043     SamDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;\r
1044     SamDesc.BorderColor[0] = SamDesc.BorderColor[1] = SamDesc.BorderColor[2] = SamDesc.BorderColor[3] = 0;\r
1045     SamDesc.MinLOD = 0;\r
1046     SamDesc.MaxLOD = D3D11_FLOAT32_MAX;\r
1047     V_RETURN( pd3dDevice->CreateSamplerState( &SamDesc, &g_pSamLinear ) );\r
1048 \r
1049 \r
1050         \r
1051 \r
1052     // Setup constant buffers\r
1053     D3D11_BUFFER_DESC Desc;\r
1054     Desc.Usage = D3D11_USAGE_DYNAMIC;\r
1055     Desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;\r
1056     Desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;\r
1057     Desc.MiscFlags = 0;\r
1058 \r
1059     Desc.ByteWidth = sizeof( CB_VS_PER_OBJECT );\r
1060     V_RETURN( pd3dDevice->CreateBuffer( &Desc, NULL, &g_pcbVSPerObject ) );\r
1061 \r
1062     Desc.ByteWidth = sizeof( CB_PS_PER_OBJECT );\r
1063     V_RETURN( pd3dDevice->CreateBuffer( &Desc, NULL, &g_pcbPSPerObject ) );\r
1064 \r
1065     Desc.ByteWidth = sizeof( CB_PS_PER_FRAME );\r
1066     V_RETURN( pd3dDevice->CreateBuffer( &Desc, NULL, &g_pcbPSPerFrame ) );\r
1067 \r
1068     // Setup the camera's view parameters\r
1069     \r
1070         \r
1071         D3DXVECTOR3 vecEye( 30.0f, 30.0f, -80.0f );\r
1072     D3DXVECTOR3 vecAt ( 10.0f, 20.0f, -0.0f );\r
1073     \r
1074 \r
1075         g_Camera.SetViewParams( &vecEye, &vecAt );\r
1076 \r
1077         cloths.resize(numFlags);\r
1078 \r
1079         for( int flagIndex =  0; flagIndex < numFlags; ++flagIndex )\r
1080         {\r
1081                 cloths[flagIndex].create_buffers(clothWidth, clothHeight);\r
1082         }\r
1083 \r
1084         initBullet();\r
1085 \r
1086 std::wstring flagTexsName[] = {\r
1087                 L"atiFlag.bmp",\r
1088                 L"amdFlag.bmp",\r
1089         };\r
1090         int numFlagTexs = 2;\r
1091 \r
1092 \r
1093 \r
1094         WCHAR flagTexs[2][MAX_PATH];\r
1095 \r
1096         HRESULT res = DXUTFindDXSDKMediaFileCch(flagTexs[0],MAX_PATH, flagTexsName[0].c_str());\r
1097         res = DXUTFindDXSDKMediaFileCch(flagTexs[1],MAX_PATH, flagTexsName[1].c_str());\r
1098         \r
1099 \r
1100         for( int flagIndex =  0; flagIndex < numFlags; ++flagIndex )\r
1101         {\r
1102                 cloths[flagIndex].create_texture(flagTexs[flagIndex % numFlagTexs]);\r
1103                 cloths[flagIndex].x_offset = 0; \r
1104                 cloths[flagIndex].y_offset = 0; \r
1105                 cloths[flagIndex].z_offset = 0;\r
1106         }\r
1107 \r
1108         \r
1109 \r
1110         my_capsule.create_buffers(50,40);\r
1111         my_capsule.create_texture();\r
1112 \r
1113         //Turn off backface culling\r
1114         D3D11_RASTERIZER_DESC rsDesc;\r
1115         ZeroMemory(&rsDesc,sizeof(D3D11_RASTERIZER_DESC) );\r
1116         rsDesc.CullMode = D3D11_CULL_NONE;\r
1117         rsDesc.FillMode = D3D11_FILL_SOLID;\r
1118         \r
1119         hr = pd3dDevice->CreateRasterizerState(&rsDesc, &g_pRasterizerState);   \r
1120         \r
1121         rsDesc.FillMode = D3D11_FILL_WIREFRAME;\r
1122         hr = pd3dDevice->CreateRasterizerState(&rsDesc, &g_pRasterizerStateWF);\r
1123         \r
1124         SAFE_RELEASE(pd3dImmediateContext);\r
1125 \r
1126 \r
1127         \r
1128     return S_OK;\r
1129 }\r
1130 \r
1131 \r
1132 //--------------------------------------------------------------------------------------\r
1133 // Create any D3D11 resources that depend on the back buffer\r
1134 //--------------------------------------------------------------------------------------\r
1135 HRESULT CALLBACK OnD3D11ResizedSwapChain( ID3D11Device* pd3dDevice, IDXGISwapChain* pSwapChain,\r
1136                                           const DXGI_SURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )\r
1137 {\r
1138     HRESULT hr;\r
1139 \r
1140     V_RETURN( g_DialogResourceManager.OnD3D11ResizedSwapChain( pd3dDevice, pBackBufferSurfaceDesc ) );\r
1141     V_RETURN( g_D3DSettingsDlg.OnD3D11ResizedSwapChain( pd3dDevice, pBackBufferSurfaceDesc ) );\r
1142 \r
1143     // Setup the camera's projection parameters\r
1144     float fAspectRatio = pBackBufferSurfaceDesc->Width / ( FLOAT )pBackBufferSurfaceDesc->Height;\r
1145     g_Camera.SetProjParams( D3DX_PI / 4, fAspectRatio, 2.0f, 4000.0f );\r
1146         //    g_Camera.SetWindow( pBackBufferSurfaceDesc->Width, pBackBufferSurfaceDesc->Height );\r
1147         //    g_Camera.SetButtonMasks( MOUSE_MIDDLE_BUTTON, MOUSE_WHEEL, MOUSE_LEFT_BUTTON );\r
1148 \r
1149 \r
1150         D3DXVECTOR3 vMin = D3DXVECTOR3( -1000.0f, -1000.0f, -1000.0f );\r
1151     D3DXVECTOR3 vMax = D3DXVECTOR3( 1000.0f, 1000.0f, 1000.0f );\r
1152     g_Camera.SetRotateButtons(TRUE, FALSE, FALSE);\r
1153         \r
1154         \r
1155     g_Camera.SetScalers( 0.01f, 30.0f );\r
1156     g_Camera.SetDrag( true );\r
1157     g_Camera.SetEnableYAxisMovement( true );\r
1158     g_Camera.SetClipToBoundary( TRUE, &vMin, &vMax );\r
1159     g_Camera.FrameMove( 0 );\r
1160 \r
1161 \r
1162     g_HUD.SetLocation( pBackBufferSurfaceDesc->Width - 170, 0 );\r
1163     g_HUD.SetSize( 170, 170 );\r
1164     g_SampleUI.SetLocation( pBackBufferSurfaceDesc->Width - 170, pBackBufferSurfaceDesc->Height - 300 );\r
1165     g_SampleUI.SetSize( 170, 300 );\r
1166 \r
1167         //Turn off backface culling\r
1168         D3D11_RASTERIZER_DESC rsDesc;\r
1169         ZeroMemory(&rsDesc,sizeof(D3D11_RASTERIZER_DESC) );\r
1170         rsDesc.CullMode = D3D11_CULL_NONE;\r
1171         rsDesc.FillMode = D3D11_FILL_SOLID;\r
1172         //rsDesc.FillMode = D3D11_FILL_WIREFRAME;\r
1173         \r
1174         \r
1175         ID3D11RasterizerState *pRasterizerState = NULL;\r
1176         pd3dDevice->CreateRasterizerState(&rsDesc, &pRasterizerState);\r
1177         \r
1178         DXUTGetD3D11DeviceContext()->RSSetState(pRasterizerState);\r
1179 \r
1180         SAFE_RELEASE(pRasterizerState);\r
1181 \r
1182     return S_OK;\r
1183 }\r
1184 \r
1185 \r
1186 btClock m_clock;\r
1187 //--------------------------------------------------------------------------------------\r
1188 // Render the scene using the D3D11 device\r
1189 //--------------------------------------------------------------------------------------\r
1190 void CALLBACK OnD3D11FrameRender( ID3D11Device* pd3dDevice, ID3D11DeviceContext* pd3dImmediateContext, double fTime,\r
1191                                   float fElapsedTime, void* pUserContext )\r
1192 {\r
1193 \r
1194 \r
1195 \r
1196 \r
1197         //float ms = getDeltaTimeMicroseconds();\r
1198         btScalar dt = (btScalar)m_clock.getTimeMicroseconds();\r
1199         m_clock.reset();\r
1200 \r
1201         ///step the simulation\r
1202         if (m_dynamicsWorld && !paused)\r
1203         {\r
1204 \r
1205                 m_dynamicsWorld->stepSimulation(dt / 1000000.f);\r
1206 \r
1207                 updatePhysicsWorld();\r
1208         }\r
1209 \r
1210         //paused = 1;\r
1211         \r
1212 \r
1213 \r
1214         ///////////////////////////////////////////////////////\r
1215 \r
1216     HRESULT hr;\r
1217 \r
1218     // If the settings dialog is being shown, then render it instead of rendering the app's scene\r
1219     if( g_D3DSettingsDlg.IsActive() )\r
1220     {\r
1221         g_D3DSettingsDlg.OnRender( fElapsedTime );\r
1222         return;\r
1223     }\r
1224 \r
1225     // Clear the render target and depth stencil\r
1226     float ClearColor[4] = { 0.0f, 0.25f, 0.25f, 0.55f };\r
1227     ID3D11RenderTargetView* pRTV = DXUTGetD3D11RenderTargetView();\r
1228     pd3dImmediateContext->ClearRenderTargetView( pRTV, ClearColor );\r
1229     ID3D11DepthStencilView* pDSV = DXUTGetD3D11DepthStencilView();\r
1230     pd3dImmediateContext->ClearDepthStencilView( pDSV, D3D11_CLEAR_DEPTH, 1.0, 0 );\r
1231 \r
1232 \r
1233         for( int flagIndex = 0; flagIndex < m_flags.size(); ++flagIndex )\r
1234         {       \r
1235                 g_softBodyOutput->copySoftBodyToVertexBuffer( m_flags[flagIndex], cloths[flagIndex].m_vertexBufferDescriptor );\r
1236                 cloths[flagIndex].draw();\r
1237         }\r
1238 \r
1239         my_capsule.draw();\r
1240 \r
1241         \r
1242     DXUT_BeginPerfEvent( DXUT_PERFEVENTCOLOR, L"HUD / Stats" );\r
1243     g_HUD.OnRender( fElapsedTime );\r
1244     g_SampleUI.OnRender( fElapsedTime );\r
1245     RenderText();\r
1246     DXUT_EndPerfEvent();\r
1247 \r
1248 \r
1249 /*\r
1250          SAFE_RELEASE(pRTV);\r
1251      SAFE_RELEASE(pDSV);\r
1252 */\r
1253 \r
1254  \r
1255 }\r
1256 \r
1257 \r
1258 //--------------------------------------------------------------------------------------\r
1259 // Release D3D11 resources created in OnD3D11ResizedSwapChain \r
1260 //--------------------------------------------------------------------------------------\r
1261 void CALLBACK OnD3D11ReleasingSwapChain( void* pUserContext )\r
1262 {\r
1263     g_DialogResourceManager.OnD3D11ReleasingSwapChain();\r
1264         DXUTGetD3D11DeviceContext()->ClearState();\r
1265 }\r
1266 \r
1267 \r
1268 //--------------------------------------------------------------------------------------\r
1269 // Release D3D11 resources created in OnD3D11CreateDevice \r
1270 //--------------------------------------------------------------------------------------\r
1271 void CALLBACK OnD3D11DestroyDevice( void* pUserContext )\r
1272 {\r
1273     g_DialogResourceManager.OnD3D11DestroyDevice();\r
1274     g_D3DSettingsDlg.OnD3D11DestroyDevice();\r
1275     DXUTGetGlobalResourceCache().OnDestroyDevice();\r
1276     SAFE_DELETE( g_pTxtHelper );\r
1277 \r
1278     g_Mesh11.Destroy();\r
1279                 \r
1280 \r
1281         SAFE_RELEASE(g_pGeometryShader);\r
1282     SAFE_RELEASE( g_pVertexLayout11 );\r
1283     SAFE_RELEASE( g_pVertexBuffer );\r
1284     SAFE_RELEASE( g_pVertexShader );\r
1285     SAFE_RELEASE( g_pPixelShader );\r
1286     SAFE_RELEASE( g_pSamLinear );\r
1287 \r
1288     SAFE_RELEASE( g_pcbVSPerObject );\r
1289     SAFE_RELEASE( g_pcbPSPerObject );\r
1290     SAFE_RELEASE( g_pcbPSPerFrame );\r
1291         \r
1292         SAFE_RELEASE( g_pRasterizerState );\r
1293         SAFE_RELEASE( g_pRasterizerStateWF );\r
1294 \r
1295 \r
1296         for( int flagIndex =  0; flagIndex < numFlags; ++flagIndex )\r
1297         {\r
1298                 cloths[flagIndex].destroy();\r
1299         }\r
1300 \r
1301         my_capsule.destroy();\r
1302 \r
1303         // Shouldn't need to delete this as it's just a soft body and will be deleted later by the collision object cleanup.\r
1304         //for( int flagIndex = 0; flagIndex < m_flags.size(); ++flagIndex )\r
1305         //{     \r
1306                 //delete m_flags[flagIndex];\r
1307         //}\r
1308 \r
1309         //cleanup in the reverse order of creation/initialization\r
1310         if( g_defaultSolver )\r
1311                 delete g_defaultSolver;\r
1312         if( g_cpuSolver )\r
1313                 delete g_cpuSolver;\r
1314         if( g_dx11Solver )\r
1315                 delete g_dx11Solver;\r
1316         if( g_dx11SIMDSolver )\r
1317                 delete g_dx11SIMDSolver;\r
1318         if( g_softBodyOutput )\r
1319                 delete g_softBodyOutput;\r
1320         \r
1321 \r
1322         for(int i=0; i< m_collisionShapes.size(); i++)\r
1323                 delete m_collisionShapes[i];\r
1324 \r
1325         //remove the rigidbodies from the dynamics world and delete them\r
1326         int i;\r
1327         for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--)\r
1328         {\r
1329                 btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];\r
1330                 btRigidBody* body = btRigidBody::upcast(obj);\r
1331                 if (body && body->getMotionState())\r
1332                 {\r
1333                         delete body->getMotionState();\r
1334                 }\r
1335                 m_dynamicsWorld->removeCollisionObject( obj );\r
1336                 delete obj;\r
1337         }\r
1338 \r
1339         delete m_dynamicsWorld; \r
1340         delete m_solver;        \r
1341         delete m_broadphase;    \r
1342         delete m_dispatcher;\r
1343         delete m_collisionConfiguration;\r
1344 \r
1345                 \r
1346 }\r
1347 \r
1348 \r
1349 \r
1350 \r
1351 \r
1352 \r
1353 \r
1354 \r
1355 \r
1356 \r