2 CDTestFramework http://codercorner.com
3 Copyright (c) 2007-2008 Pierre Terdiman, pierre@codercorner.com
5 This software is provided 'as-is', without any express or implied warranty.
6 In no event will the authors be held liable for any damages arising from the use of this software.
7 Permission is granted to anyone to use this software for any purpose,
8 including commercial applications, and to alter it and redistribute it freely,
9 subject to the following restrictions:
11 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13 3. This notice may not be removed or altered from any source distribution.
20 #include "RenderingHelpers.h"
22 ////////////////////////
24 void DrawLine(const Point& p0, const Point& p1, const Point& color, float line_width)
26 glDisable(GL_LIGHTING);
27 glLineWidth(line_width);
28 glColor4f(color.x, color.y, color.z, 1.0f);
29 Point tmp[] = {p0, p1};
30 glEnableClientState(GL_VERTEX_ARRAY);
31 glVertexPointer(3, GL_FLOAT, sizeof(Point), &tmp[0].x);
32 glDrawArrays(GL_LINES, 0, 2);
33 glDisableClientState(GL_VERTEX_ARRAY);
34 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
35 glEnable(GL_LIGHTING);
38 void DrawTriangle(const Point& p0, const Point& p1, const Point& p2, const Point& color)
40 // glDisable(GL_LIGHTING);
41 glColor4f(color.x, color.y, color.z, 1.0f);
42 Point tmp[] = {p0, p1, p2};
43 glEnableClientState(GL_VERTEX_ARRAY);
44 glVertexPointer(3, GL_FLOAT, sizeof(Point), &tmp[0].x);
45 glDrawArrays(GL_TRIANGLES, 0, 3);
46 glDisableClientState(GL_VERTEX_ARRAY);
47 // glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
48 // glEnable(GL_LIGHTING);
52 ////////////////////////
54 static void SetupGLMatrix(const Point& pos)
56 float glmat[16]; //4x4 column major matrix for OpenGL.
80 void SetupGLMatrix(const Point& pos, const Matrix3x3& rot)
82 float glmat[16]; //4x4 column major matrix for OpenGL.
83 glmat[0] = rot.m[0][0];
84 glmat[1] = rot.m[0][1];
85 glmat[2] = rot.m[0][2];
88 glmat[4] = rot.m[1][0];
89 glmat[5] = rot.m[1][1];
90 glmat[6] = rot.m[1][2];
93 glmat[8] = rot.m[2][0];
94 glmat[9] = rot.m[2][1];
95 glmat[10] = rot.m[2][2];
103 glMultMatrixf(glmat);
106 void SetupGLMatrix(const Matrix4x4& world)
108 SetupGLMatrix(world.GetTrans(), world);
111 ////////////////////////
113 static void RenderSphere(float radius)
115 glutSolidSphere(radius, 12, 12); // Radius / slices / stacks
118 void DrawSphere(const Sphere& sphere)
121 SetupGLMatrix(sphere.mCenter);
122 RenderSphere(sphere.mRadius);
126 ////////////////////////
128 static void RenderBox(int size)
133 void DrawOBB(const OBB& obb)
136 SetupGLMatrix(obb.mCenter, obb.mRot);
137 glScalef(obb.mExtents.x, obb.mExtents.y, obb.mExtents.z);
142 ////////////////////////
144 static float gCylinderData[]={
145 1.0f,0.0f,1.0f,1.0f,0.0f,1.0f,1.0f,0.0f,0.0f,1.0f,0.0f,0.0f,
146 0.866025f,0.500000f,1.0f,0.866025f,0.500000f,1.0f,0.866025f,0.500000f,0.0f,0.866025f,0.500000f,0.0f,
147 0.500000f,0.866025f,1.0f,0.500000f,0.866025f,1.0f,0.500000f,0.866025f,0.0f,0.500000f,0.866025f,0.0f,
148 -0.0f,1.0f,1.0f,-0.0f,1.0f,1.0f,-0.0f,1.0f,0.0f,-0.0f,1.0f,0.0f,
149 -0.500000f,0.866025f,1.0f,-0.500000f,0.866025f,1.0f,-0.500000f,0.866025f,0.0f,-0.500000f,0.866025f,0.0f,
150 -0.866025f,0.500000f,1.0f,-0.866025f,0.500000f,1.0f,-0.866025f,0.500000f,0.0f,-0.866025f,0.500000f,0.0f,
151 -1.0f,-0.0f,1.0f,-1.0f,-0.0f,1.0f,-1.0f,-0.0f,0.0f,-1.0f,-0.0f,0.0f,
152 -0.866025f,-0.500000f,1.0f,-0.866025f,-0.500000f,1.0f,-0.866025f,-0.500000f,0.0f,-0.866025f,-0.500000f,0.0f,
153 -0.500000f,-0.866025f,1.0f,-0.500000f,-0.866025f,1.0f,-0.500000f,-0.866025f,0.0f,-0.500000f,-0.866025f,0.0f,
154 0.0f,-1.0f,1.0f,0.0f,-1.0f,1.0f,0.0f,-1.0f,0.0f,0.0f,-1.0f,0.0f,
155 0.500000f,-0.866025f,1.0f,0.500000f,-0.866025f,1.0f,0.500000f,-0.866025f,0.0f,0.500000f,-0.866025f,0.0f,
156 0.866026f,-0.500000f,1.0f,0.866026f,-0.500000f,1.0f,0.866026f,-0.500000f,0.0f,0.866026f,-0.500000f,0.0f,
157 1.0f,0.0f,1.0f,1.0f,0.0f,1.0f,1.0f,0.0f,0.0f,1.0f,0.0f,0.0f
160 static float gCylinderDataCapsTop[]={
161 0.866026f,-0.500000f,1.000000f,0.000000f,1.000000f,1.000000f,
162 0.000000f,1.000000f,1.000000f,0.000000f,1.000000f,1.000000f,
163 0.500000f,-0.866025f,1.000000f,0.000000f,1.000000f,1.000000f,
164 0.500000f,-0.866025f,1.000000f,0.000000f,1.000000f,1.000000f,
165 0.000000f,1.000000f,1.000000f,0.000000f,1.000000f,1.000000f,
166 0.000000f,-1.000000f,1.000000f,0.000000f,1.000000f,1.000000f,
167 0.000000f,-1.000000f,1.000000f,0.000000f,1.000000f,1.000000f,
168 0.000000f,1.000000f,1.000000f,0.000000f,1.000000f,1.000000f,
169 -0.500000f,-0.866025f,1.000000f,0.000000f,1.000000f,1.000000f,
170 -0.500000f,-0.866025f,1.000000f,0.000000f,1.000000f,1.000000f,
171 0.000000f,1.000000f,1.000000f,0.000000f,1.000000f,1.000000f,
172 -0.866025f,-0.500000f,1.000000f,0.000000f,1.000000f,1.000000f,
173 -0.866025f,-0.500000f,1.000000f,0.000000f,1.000000f,1.000000f,
174 0.000000f,1.000000f,1.000000f,0.000000f,1.000000f,1.000000f,
175 -1.000000f,-0.000000f,1.000000f,0.000000f,1.000000f,1.000000f,
176 -1.000000f,-0.000000f,1.000000f,0.000000f,1.000000f,1.000000f,
177 0.000000f,1.000000f,1.000000f,0.000000f,1.000000f,1.000000f,
178 -0.866025f,0.500000f,1.000000f,0.000000f,1.000000f,1.000000f,
179 -0.866025f,0.500000f,1.000000f,0.000000f,1.000000f,1.000000f,
180 0.000000f,1.000000f,1.000000f,0.000000f,1.000000f,1.000000f,
181 -0.500000f,0.866025f,1.000000f,0.000000f,1.000000f,1.000000f,
182 -0.500000f,0.866025f,1.000000f,0.000000f,1.000000f,1.000000f,
183 0.000000f,1.000000f,1.000000f,0.000000f,1.000000f,1.000000f,
184 -0.000000f,1.000000f,1.000000f,0.000000f,1.000000f,1.000000f,
185 -0.000000f,1.000000f,1.000000f,0.000000f,1.000000f,1.000000f,
186 0.000000f,1.000000f,1.000000f,0.000000f,1.000000f,1.000000f,
187 0.500000f,0.866025f,1.000000f,0.000000f,1.000000f,1.000000f,
188 0.500000f,0.866025f,1.000000f,0.000000f,1.000000f,1.000000f,
189 0.000000f,1.000000f,1.000000f,0.000000f,1.000000f,1.000000f,
190 0.866025f,0.500000f,1.000000f,0.000000f,1.000000f,1.000000f,
191 0.866025f,0.500000f,1.000000f,0.000000f,1.000000f,1.000000f,
192 0.000000f,1.000000f,1.000000f,0.000000f,1.000000f,1.000000f,
193 1.000000f,0.000000f,1.000000f,0.000000f,1.000000f,1.000000f,
194 1.000000f,0.000000f,1.000000f,0.000000f,1.000000f,1.000000f,
195 0.000000f,1.000000f,1.000000f,0.000000f,1.000000f,1.000000f,
196 0.866026f,-0.500000f,1.000000f,0.000000f,1.000000f,1.000000f,
199 static float gCylinderDataCapsBottom[]={
200 1.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,
201 0.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,
202 0.866025f,0.500000f,0.000000f,0.000000f,-1.000000f,0.000000f,
203 0.866025f,0.500000f,0.000000f,0.000000f,-1.000000f,0.000000f,
204 0.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,
205 0.500000f,0.866025f,0.000000f,0.000000f,-1.000000f,0.000000f,
206 0.500000f,0.866025f,0.000000f,0.000000f,-1.000000f,0.000000f,
207 0.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,
208 -0.000000f,1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,
209 -0.000000f,1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,
210 0.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,
211 -0.500000f,0.866025f,0.000000f,0.000000f,-1.000000f,0.000000f,
212 -0.500000f,0.866025f,0.000000f,0.000000f,-1.000000f,0.000000f,
213 0.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,
214 -0.866025f,0.500000f,0.000000f,0.000000f,-1.000000f,0.000000f,
215 -0.866025f,0.500000f,0.000000f,0.000000f,-1.000000f,0.000000f,
216 0.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,
217 -1.000000f,-0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,
218 -1.000000f,-0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,
219 0.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,
220 -0.866025f,-0.500000f,0.000000f,0.000000f,-1.000000f,0.000000f,
221 -0.866025f,-0.500000f,0.000000f,0.000000f,-1.000000f,0.000000f,
222 0.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,
223 -0.500000f,-0.866025f,0.000000f,0.000000f,-1.000000f,0.000000f,
224 -0.500000f,-0.866025f,0.000000f,0.000000f,-1.000000f,0.000000f,
225 0.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,
226 0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,
227 0.000000f,-1.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,
228 0.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,
229 0.500000f,-0.866025f,0.000000f,0.000000f,-1.000000f,0.000000f,
230 0.500000f,-0.866025f,0.000000f,0.000000f,-1.000000f,0.000000f,
231 0.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,
232 0.866026f,-0.500000f,0.000000f,0.000000f,-1.000000f,0.000000f,
233 0.866026f,-0.500000f,0.000000f,0.000000f,-1.000000f,0.000000f,
234 0.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,
235 1.000000f,0.000000f,0.000000f,0.000000f,-1.000000f,0.000000f,
238 static void RenderCylinder()
240 glEnableClientState(GL_VERTEX_ARRAY);
241 glEnableClientState(GL_NORMAL_ARRAY);
242 glVertexPointer(3, GL_FLOAT, 2*3*sizeof(float), gCylinderData);
243 glNormalPointer(GL_FLOAT, 2*3*sizeof(float), gCylinderData+3);
244 glDrawArrays(GL_TRIANGLE_STRIP, 0, 13*2);
246 glVertexPointer(3, GL_FLOAT, 2*3*sizeof(float), gCylinderDataCapsTop);
247 glNormalPointer(GL_FLOAT, 2*3*sizeof(float), gCylinderDataCapsTop+3);
248 glDrawArrays(GL_TRIANGLES, 0, 36);
250 glVertexPointer(3, GL_FLOAT, 2*3*sizeof(float), gCylinderDataCapsBottom);
251 glNormalPointer(GL_FLOAT, 2*3*sizeof(float), gCylinderDataCapsBottom+3);
252 glDrawArrays(GL_TRIANGLES, 0, 36);
254 glDisableClientState(GL_VERTEX_ARRAY);
255 glDisableClientState(GL_NORMAL_ARRAY);
258 void DrawCapsule(const Matrix4x4& world, const Point& p0, const Point& p1, float r)
260 const float h = p0.Distance(p1);
263 SetupGLMatrix(world);
266 glTranslatef(0.0f, h*0.5f, 0.0f);
271 glTranslatef(0.0f,-h*0.5f, 0.0f);
276 glTranslatef(0.0f,h*0.5f, 0.0f);
278 glRotatef(90.0f,1.0f,0.0f,0.0f);
288 #include "NxPhysics.h"
289 #include "DrawObjects.h"
293 static float gPlaneData[]={
294 -1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
295 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,
296 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f
300 static void RenderPlane()
302 glEnableClientState(GL_VERTEX_ARRAY);
303 glEnableClientState(GL_NORMAL_ARRAY);
304 glVertexPointer(3, GL_FLOAT, 2*3*sizeof(float), gPlaneData);
305 glNormalPointer(GL_FLOAT, 2*3*sizeof(float), gPlaneData+3);
306 glDrawArrays(GL_TRIANGLES, 0, 6);
307 glDisableClientState(GL_VERTEX_ARRAY);
308 glDisableClientState(GL_NORMAL_ARRAY);
311 void SetupGLMatrix(const NxVec3& pos, const NxMat33& orient)
313 float glmat[16]; //4x4 column major matrix for OpenGL.
314 orient.getColumnMajorStride4(&(glmat[0]));
315 pos.get(&(glmat[12]));
317 //clear the elements we don't need:
318 glmat[3] = glmat[7] = glmat[11] = 0.0f;
321 glMultMatrixf(&(glmat[0]));
324 void DrawLine(const NxVec3& p0, const NxVec3& p1, const NxVec3& color, float lineWidth)
326 glDisable(GL_LIGHTING);
327 glLineWidth(lineWidth);
328 glColor4f(color.x, color.y, color.z, 1.0f);
329 NxVec3 av3LineEndpoints[] = {p0, p1};
330 glEnableClientState(GL_VERTEX_ARRAY);
331 glVertexPointer(3, GL_FLOAT, sizeof(NxVec3), &av3LineEndpoints[0].x);
332 glDrawArrays(GL_LINES, 0, 2);
333 glDisableClientState(GL_VERTEX_ARRAY);
334 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
335 glEnable(GL_LIGHTING);
338 void DrawTriangle(const NxVec3& p0, const NxVec3& p1, const NxVec3& p2, const NxVec3& color)
340 glDisable(GL_LIGHTING);
341 glColor4f(color.x, color.y, color.z, 1.0f);
342 NxVec3 av3LineEndpoints[] = {p0, p1, p2};
343 glEnableClientState(GL_VERTEX_ARRAY);
344 glVertexPointer(3, GL_FLOAT, sizeof(NxVec3), &av3LineEndpoints[0].x);
345 glDrawArrays(GL_TRIANGLES, 0, 3);
346 glDisableClientState(GL_VERTEX_ARRAY);
347 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
348 glEnable(GL_LIGHTING);
351 void DrawCircle(NxU32 nbSegments, const NxMat34& matrix, const NxVec3& color, const NxF32 radius, const bool semicircle)
353 NxF32 step = NxTwoPiF32/NxF32(nbSegments);
354 NxU32 segs = nbSegments;
360 for(NxU32 i=0;i<segs;i++)
363 if(j==nbSegments) j=0;
365 NxF32 angle0 = NxF32(i)*step;
366 NxF32 angle1 = NxF32(j)*step;
369 matrix.multiply(NxVec3(radius * sinf(angle0), radius * cosf(angle0), 0.0f), p0);
370 matrix.multiply(NxVec3(radius * sinf(angle1), radius * cosf(angle1), 0.0f), p1);
372 DrawLine(p0, p1, color);
377 void DrawEllipse(NxU32 nbSegments, const NxMat34& matrix, const NxVec3& color, const NxF32 radius1, const NxF32 radius2, const bool semicircle)
379 NxF32 step = NxTwoPiF32/NxF32(nbSegments);
380 NxU32 segs = nbSegments;
386 for(NxU32 i=0;i<segs;i++)
389 if(j==nbSegments) j=0;
391 NxF32 angle0 = NxF32(i)*step;
392 NxF32 angle1 = NxF32(j)*step;
395 matrix.multiply(NxVec3(radius1 * sinf(angle0), radius2 * cosf(angle0), 0.0f), p0);
396 matrix.multiply(NxVec3(radius1 * sinf(angle1), radius2 * cosf(angle1), 0.0f), p1);
398 DrawLine(p0, p1, color);
402 void DrawWirePlane(NxShape* plane, const NxVec3& color)
406 void DrawPlane(NxShape* plane)
408 NxMat34 pose = plane->getGlobalPose();
409 NxPlaneShape* planeShape = plane->isPlane();
410 NxPlane p = planeShape->getPlane();
416 glDisable(GL_LIGHTING);
417 glColor4f(0.1f, 0.2f, 0.3f, 1.0f);
419 SetupGLMatrix(pose.t, pose.M);
420 glScalef(1024,0,1024);
422 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
423 glEnable(GL_LIGHTING);
427 void DrawWireBox(const NxBox& obb, const NxVec3& color, float lineWidth)
429 // Compute obb vertices
431 NxComputeBoxPoints(obb, pp);
434 const NxU32* Indices = NxGetBoxEdges();
435 for(NxU32 i=0;i<12;i++)
437 NxU32 VRef0 = *Indices++;
438 NxU32 VRef1 = *Indices++;
439 DrawLine(pp[VRef0], pp[VRef1], color, lineWidth);
443 void DrawWireBox(NxShape* box, const NxVec3& color, float lineWidth)
446 box->isBox()->getWorldOBB(obb);
448 DrawWireBox(obb, color, lineWidth);
452 void DrawWireSphere(NxShape* sphere, const NxVec3& color)
454 NxMat34 pose = sphere->getGlobalPose();
457 NxReal r = sphere->isSphere()->getRadius();
459 NxVec3 c0; pose.M.getColumn(0, c0);
460 NxVec3 c1; pose.M.getColumn(1, c1);
461 NxVec3 c2; pose.M.getColumn(2, c2);
462 DrawCircle(20, pose, color, r);
464 pose.M.setColumn(0, c1);
465 pose.M.setColumn(1, c2);
466 pose.M.setColumn(2, c0);
467 DrawCircle(20, pose, color, r);
469 pose.M.setColumn(0, c2);
470 pose.M.setColumn(1, c0);
471 pose.M.setColumn(2, c1);
472 DrawCircle(20, pose, color, r);
477 void DrawSphere(NxShape* sphere)
479 NxMat34 pose = sphere->getGlobalPose();
482 SetupGLMatrix(pose.t, pose.M);
483 NxReal r = sphere->isSphere()->getRadius();
489 void DrawWireCapsule(NxShape* capsule, const NxVec3& color)
491 NxMat34 pose = capsule->getGlobalPose();
493 NxReal r = capsule->isCapsule()->getRadius();
494 NxReal h = capsule->isCapsule()->getHeight();
497 pose.M.getColumn(1, SG.p1);
503 NxVec3 c0; pose.M.getColumn(0, c0);
504 NxVec3 c1; pose.M.getColumn(1, c1);
505 NxVec3 c2; pose.M.getColumn(2, c2);
506 DrawLine(SG.p0 + c0*r, SG.p1 + c0*r, color);
507 DrawLine(SG.p0 - c0*r, SG.p1 - c0*r, color);
508 DrawLine(SG.p0 + c2*r, SG.p1 + c2*r, color);
509 DrawLine(SG.p0 - c2*r, SG.p1 - c2*r, color);
511 pose.M.setColumn(0, -c1);
512 pose.M.setColumn(1, -c0);
513 pose.M.setColumn(2, c2);
515 DrawCircle(20, pose, color, r, true); //halfcircle -- flipped
517 pose.M.setColumn(0, c1);
518 pose.M.setColumn(1, -c0);
519 pose.M.setColumn(2, c2);
521 DrawCircle(20, pose, color, r, true);
523 pose.M.setColumn(0, -c1);
524 pose.M.setColumn(1, c2);
525 pose.M.setColumn(2, c0);
527 DrawCircle(20, pose, color, r, true);//halfcircle -- good
529 pose.M.setColumn(0, c1);
530 pose.M.setColumn(1, c2);
531 pose.M.setColumn(2, c0);
533 DrawCircle(20, pose, color, r, true);
535 pose.M.setColumn(0, c2);
536 pose.M.setColumn(1, c0);
537 pose.M.setColumn(2, c1);
539 DrawCircle(20, pose, color, r); //full circle
541 DrawCircle(20, pose, color, r);
544 static void computeBasis(const NxVec3& dir, NxVec3& right, NxVec3& up)
546 // Derive two remaining vectors
547 if(fabsf(dir.y)>0.9999f) right = NxVec3(1.0f, 0.0f, 0.0f);
548 else right = (NxVec3(0.0f, 1.0f, 0.0f) ^ dir);
553 void DrawWireCapsule(const NxCapsule& capsule, const NxVec3& color)
555 NxReal r = capsule.radius;
556 NxVec3 dir = capsule.p0 - capsule.p1;
557 NxReal h = dir.magnitude();
559 pose.t = (capsule.p0 + capsule.p1)*0.5f;
565 computeBasis(dir, right, up);
566 pose.M.setColumn(0, right);
567 pose.M.setColumn(1, dir);
568 pose.M.setColumn(2, up);
575 // NxMat34 pose = capsule->getGlobalPose();
576 // const NxReal & r = capsule->isCapsule()->getRadius();
577 // const NxReal & h = capsule->isCapsule()->getHeight();
582 pose.M.getColumn(1, SG.p1);
588 NxVec3 c0; pose.M.getColumn(0, c0);
589 NxVec3 c1; pose.M.getColumn(1, c1);
590 NxVec3 c2; pose.M.getColumn(2, c2);
591 DrawLine(SG.p0 + c0*r, SG.p1 + c0*r, color);
592 DrawLine(SG.p0 - c0*r, SG.p1 - c0*r, color);
593 DrawLine(SG.p0 + c2*r, SG.p1 + c2*r, color);
594 DrawLine(SG.p0 - c2*r, SG.p1 - c2*r, color);
596 pose.M.setColumn(0, -c1);
597 pose.M.setColumn(1, -c0);
598 pose.M.setColumn(2, c2);
600 DrawCircle(20, pose, color, r, true); //halfcircle -- flipped
602 pose.M.setColumn(0, c1);
603 pose.M.setColumn(1, -c0);
604 pose.M.setColumn(2, c2);
606 DrawCircle(20, pose, color, r, true);
608 pose.M.setColumn(0, -c1);
609 pose.M.setColumn(1, c2);
610 pose.M.setColumn(2, c0);
612 DrawCircle(20, pose, color, r, true);//halfcircle -- good
614 pose.M.setColumn(0, c1);
615 pose.M.setColumn(1, c2);
616 pose.M.setColumn(2, c0);
618 DrawCircle(20, pose, color, r, true);
620 pose.M.setColumn(0, c2);
621 pose.M.setColumn(1, c0);
622 pose.M.setColumn(2, c1);
624 DrawCircle(20, pose, color, r); //full circle
626 DrawCircle(20, pose, color, r);
629 void DrawCapsule(const NxVec3& color, NxF32 r, NxF32 h)
631 glColor4f(color.x, color.y, color.z, 1.0f);
634 glTranslatef(0.0f, h*0.5f, 0.0f);
640 glTranslatef(0.0f,-h*0.5f, 0.0f);
646 glTranslatef(0.0f,h*0.5f, 0.0f);
648 glRotatef(90.0f,1.0f,0.0f,0.0f);
653 typedef NxVec3 Point;
654 typedef struct _Triangle { NxU32 p0; NxU32 p1; NxU32 p2; } Triangle;
656 void DrawWireConvex(NxShape* mesh, const NxVec3& color)
658 if(mesh->userData == NULL) return;
660 NxMat34 pose = mesh->getGlobalPose();
662 NxConvexMeshDesc meshDesc = *((NxConvexMeshDesc*)(mesh->userData));
663 // mesh->isConvexMesh()->getConvexMesh().saveToDesc(meshDesc);
665 NxU32 nbVerts = meshDesc.numVertices;
666 NxU32 nbTriangles = meshDesc.numTriangles;
668 Point* points = (Point *)meshDesc.points;
669 Triangle* triangles = (Triangle *)meshDesc.triangles;
673 float glmat[16]; //4x4 column major matrix for OpenGL.
674 pose.M.getColumnMajorStride4(&(glmat[0]));
675 pose.t.get(&(glmat[12]));
677 //clear the elements we don't need:
678 glmat[3] = glmat[7] = glmat[11] = 0.0f;
681 glMultMatrixf(&(glmat[0]));
685 DrawLine(points[triangles->p0], points[triangles->p1], color);
686 DrawLine(points[triangles->p1], points[triangles->p2], color);
687 DrawLine(points[triangles->p2], points[triangles->p0], color);
694 void DrawTriangleList(int iTriangleCount, Triangle *pTriangles, Point *pPoints)
696 static int iBufferSize=0;
697 static float *pfVertexBuffer=NULL;
698 static float *pfNormalBuffer=NULL;
700 if(iBufferSize < iTriangleCount*3)
702 iBufferSize=3*iTriangleCount;
704 delete[] pfVertexBuffer;
705 pfVertexBuffer = new float[iBufferSize*3];
707 delete[] pfNormalBuffer;
708 pfNormalBuffer = new float[iBufferSize*3];
711 float *pfDestinationVertex=pfVertexBuffer;
712 float *pfDestinationNormal=pfNormalBuffer;
714 for(int iTriangle=0; iTriangle<iTriangleCount; iTriangle++)
716 *pfDestinationVertex++=pPoints[pTriangles->p0].x;
717 *pfDestinationVertex++=pPoints[pTriangles->p0].y;
718 *pfDestinationVertex++=pPoints[pTriangles->p0].z;
719 *pfDestinationVertex++=pPoints[pTriangles->p1].x;
720 *pfDestinationVertex++=pPoints[pTriangles->p1].y;
721 *pfDestinationVertex++=pPoints[pTriangles->p1].z;
722 *pfDestinationVertex++=pPoints[pTriangles->p2].x;
723 *pfDestinationVertex++=pPoints[pTriangles->p2].y;
724 *pfDestinationVertex++=pPoints[pTriangles->p2].z;
726 NxVec3 edge1 = pPoints[pTriangles->p1] - pPoints[pTriangles->p0];
727 NxVec3 edge2 = pPoints[pTriangles->p2] - pPoints[pTriangles->p0];
728 NxVec3 normal = edge1.cross(edge2);
731 *pfDestinationNormal++=normal.x;
732 *pfDestinationNormal++=normal.y;
733 *pfDestinationNormal++=normal.z;
734 *pfDestinationNormal++=normal.x;
735 *pfDestinationNormal++=normal.y;
736 *pfDestinationNormal++=normal.z;
737 *pfDestinationNormal++=normal.x;
738 *pfDestinationNormal++=normal.y;
739 *pfDestinationNormal++=normal.z;
744 glEnableClientState(GL_VERTEX_ARRAY);
745 glVertexPointer(3, GL_FLOAT, 0, pfVertexBuffer);
746 glEnableClientState(GL_NORMAL_ARRAY);
747 glNormalPointer(GL_FLOAT, 0, pfNormalBuffer);
749 glDrawArrays(GL_TRIANGLES, 0, 3*iTriangleCount);
751 glDisableClientState(GL_VERTEX_ARRAY);
752 glDisableClientState(GL_NORMAL_ARRAY);
756 void DrawConvex(NxShape* mesh)
758 NxConvexMeshDesc meshDesc;
760 // SRM : Please note that I looked into a crash issue posed by
761 // one of our customers, and this code (i.e. reinterpreting the
762 // NxShape's userData as an NxConvexMeshDesc * was crashing because
763 // in the SampleRaycastCar demo, it sets that pointer equal to the
764 // NxWheel because that is used in NxVehicle::handleContactPair(). Thus
765 // in order to allow this code not to crash on the PS3, we should
766 // simply force the shape to save its description here.
767 mesh->isConvexMesh()->getConvexMesh().saveToDesc(meshDesc);
769 if(mesh->userData != NULL)
771 meshDesc = *((NxConvexMeshDesc*)(mesh->userData));
773 mesh->isConvexMesh()->getConvexMesh().saveToDesc(meshDesc);
777 NxMat34 pose = mesh->getGlobalPose();
779 NxU32 nbVerts = meshDesc.numVertices;
780 NxU32 nbTriangles = meshDesc.numTriangles;
782 Point* points = (Point *)meshDesc.points;
783 Triangle* triangles = (Triangle *)meshDesc.triangles;
787 float glmat[16]; //4x4 column major matrix for OpenGL.
788 pose.M.getColumnMajorStride4(&(glmat[0]));
789 pose.t.get(&(glmat[12]));
791 //clear the elements we don't need:
792 glmat[3] = glmat[7] = glmat[11] = 0.0f;
795 glMultMatrixf(&(glmat[0]));
797 DrawTriangleList(nbTriangles, triangles, points);
802 void DrawWireMesh(NxShape* mesh, const NxVec3& color)
804 if(mesh->userData == NULL) return;
806 NxMat34 pose = mesh->getGlobalPose();
808 NxTriangleMeshDesc meshDesc = *((NxTriangleMeshDesc*)(mesh->userData));
809 // mesh->isTriangleMesh()->getTriangleMesh().saveToDesc(meshDesc);
811 NxU32 nbVerts = meshDesc.numVertices;
812 NxU32 nbTriangles = meshDesc.numTriangles;
814 Point* points = (Point *)meshDesc.points;
815 Triangle* triangles = (Triangle *)meshDesc.triangles;
819 float glmat[16]; //4x4 column major matrix for OpenGL.
820 pose.M.getColumnMajorStride4(&(glmat[0]));
821 pose.t.get(&(glmat[12]));
823 //clear the elements we don't need:
824 glmat[3] = glmat[7] = glmat[11] = 0.0f;
827 glMultMatrixf(&(glmat[0]));
831 DrawLine(points[triangles->p0], points[triangles->p1], color);
832 DrawLine(points[triangles->p1], points[triangles->p2], color);
833 DrawLine(points[triangles->p2], points[triangles->p0], color);
840 void DrawMesh(NxShape* mesh)
842 if(mesh->userData == NULL) return;
844 NxMat34 pose = mesh->getGlobalPose();
846 NxTriangleMeshDesc meshDesc = *((NxTriangleMeshDesc*)(mesh->userData));
847 // mesh->isTriangleMesh()->getTriangleMesh().saveToDesc(meshDesc);
849 NxU32 nbVerts = meshDesc.numVertices;
850 NxU32 nbTriangles = meshDesc.numTriangles;
852 Point* points = (Point *)meshDesc.points;
853 Triangle* triangles = (Triangle *)meshDesc.triangles;
857 float glmat[16]; //4x4 column major matrix for OpenGL.
858 pose.M.getColumnMajorStride4(&(glmat[0]));
859 pose.t.get(&(glmat[12]));
861 //clear the elements we don't need:
862 glmat[3] = glmat[7] = glmat[11] = 0.0f;
865 glMultMatrixf(&(glmat[0]));
867 if(meshDesc.heightFieldVerticalAxis != NX_NOT_HEIGHTFIELD)
869 glDisable(GL_LIGHT0);
873 DrawTriangleList(nbTriangles, triangles, points);
875 if(meshDesc.heightFieldVerticalAxis != NX_NOT_HEIGHTFIELD)
877 glDisable(GL_LIGHT1);
884 void DrawWheelShape(NxShape* wheel)
886 if(wheel->is(NX_SHAPE_WHEEL) != NULL)
888 NxWheelShape* wheelShape = (NxWheelShape*)wheel;
892 wheel->getGlobalPose().getColumnMajor44(glmat);
894 NxWheelShapeDesc wheelShapeDesc;
896 float r = wheelShape->getRadius();
897 float a = wheelShape->getSteerAngle();
899 glMultMatrixf(&(glmat[0]));
900 glTranslatef(-r/2,0,0);
902 glRotatef(NxMath::radToDeg(a),0,1,0);
910 void DrawArrow(const NxVec3& posA, const NxVec3& posB, const NxVec3& color)
912 NxVec3 vec = posB - posA;
914 NxNormalToTangents(vec, t1, t2);
919 NxVec3 lobe1 = posB - t0*0.15 + t1 * 0.15;
920 NxVec3 lobe2 = posB - t0*0.15 - t1 * 0.15;
921 NxVec3 lobe3 = posB - t0*0.15 + t2 * 0.15;
922 NxVec3 lobe4 = posB - t0*0.15 - t2 * 0.15;
924 NxVec3 v3ArrowShape[] = {
925 NxVec3(posA), NxVec3(posB),
926 NxVec3(posB), NxVec3(lobe1),
927 NxVec3(posB), NxVec3(lobe2),
928 NxVec3(posB), NxVec3(lobe3),
929 NxVec3(posB), NxVec3(lobe4),
932 glDisable(GL_LIGHTING);
934 glColor4f(color.x,color.y,color.z,1.0f);
935 glEnableClientState(GL_VERTEX_ARRAY);
936 glVertexPointer(3, GL_FLOAT, sizeof(NxVec3), &v3ArrowShape[0].x);
937 glDrawArrays(GL_LINES, 0, sizeof(v3ArrowShape)/sizeof(NxVec3));
938 glDisableClientState(GL_VERTEX_ARRAY);
939 glColor4f(1.0f,1.0f,1.0f,1.0f);
942 void DrawContactPoint(const NxVec3& pos, const NxReal radius, const NxVec3& color)
947 NxVec3 c0; pose.M.getColumn(0, c0);
948 NxVec3 c1; pose.M.getColumn(1, c1);
949 NxVec3 c2; pose.M.getColumn(2, c2);
950 DrawCircle(20, pose, color, radius);
952 pose.M.setColumn(0, c1);
953 pose.M.setColumn(1, c2);
954 pose.M.setColumn(2, c0);
955 DrawCircle(20, pose, color, radius);
957 pose.M.setColumn(0, c2);
958 pose.M.setColumn(1, c0);
959 pose.M.setColumn(2, c1);
960 DrawCircle(20, pose, color, radius);
963 void DrawWireShape(NxShape *shape, const NxVec3& color)
965 switch(shape->getType())
968 DrawWirePlane(shape, color);
971 DrawWireBox(shape, color);
973 case NX_SHAPE_SPHERE:
974 DrawWireSphere(shape, color);
976 case NX_SHAPE_CAPSULE:
977 DrawWireCapsule(shape, color);
979 case NX_SHAPE_CONVEX:
980 DrawWireConvex(shape, color);
983 DrawWireMesh(shape, color);
988 void DrawShape(NxShape* shape)
990 switch(shape->getType())
998 case NX_SHAPE_SPHERE:
1001 case NX_SHAPE_CAPSULE:
1004 case NX_SHAPE_CONVEX:
1010 case NX_SHAPE_WHEEL:
1011 DrawWheelShape(shape);
1016 void DrawActor(NxActor* actor, NxActor* gSelectedActor)
1018 NxShape*const* shapes = actor->getShapes();
1019 NxU32 nShapes = actor->getNbShapes();
1020 if (actor == gSelectedActor)
1024 DrawWireShape(shapes[nShapes], NxVec3(1,1,1));
1027 nShapes = actor->getNbShapes();
1030 DrawShape(shapes[nShapes]);
1034 void DrawWireActor(NxActor* actor)
1036 NxShape*const* shapes = actor->getShapes();
1037 NxU32 nShapes = actor->getNbShapes();
1038 nShapes = actor->getNbShapes();
1041 DrawWireShape(shapes[nShapes], NxVec3(1,1,1));
1045 static void DrawActorShadow(NxActor* actor, const float* ShadowMat)
1048 glMultMatrixf(ShadowMat);
1050 glDisable(GL_LIGHTING);
1051 glColor4f(0.05f, 0.1f, 0.15f, 1.0f);
1053 NxShape*const* shapes = actor->getShapes();
1054 NxU32 nShapes = actor->getNbShapes();
1057 switch(shapes[nShapes]->getType())
1060 DrawBox(shapes[nShapes]);
1062 case NX_SHAPE_SPHERE:
1063 DrawSphere(shapes[nShapes]);
1065 case NX_SHAPE_CAPSULE:
1066 DrawCapsule(shapes[nShapes]);
1068 case NX_SHAPE_CONVEX:
1069 DrawConvex(shapes[nShapes]);
1074 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
1075 glEnable(GL_LIGHTING);
1081 void DrawActorShadow(NxActor* actor)
1083 const static float ShadowMat[]={ 1,0,0,0, 0,0,0,0, 0,0,1,0, 0,0,0,1 };
1084 DrawActorShadow(actor, ShadowMat);
1087 void DrawActorShadow2(NxActor* actor)
1089 const static float ShadowMat[]={ 1,0,0,0, 1,0,-0.2,0, 0,0,1,0, 0,0,0,1 };
1090 DrawActorShadow(actor, ShadowMat);
1093 void DrawActorShadowZUp(NxActor* actor)
1095 const static float ShadowMat[]={ 1,0,0,0, 0,1,0,0, 0,0,0,0, 0,0,0,1 };
1096 DrawActorShadow(actor, ShadowMat);
1099 void DrawCloth(NxCloth *cloth, bool shadows)
1101 NxMeshData meshData = cloth->getMeshData();
1103 NxU32 numVertices = *meshData.numVerticesPtr;
1104 NxU32 numTriangles = *meshData.numIndicesPtr / 3;
1106 glEnableClientState(GL_VERTEX_ARRAY);
1107 glEnableClientState(GL_NORMAL_ARRAY);
1108 glVertexPointer(3, GL_FLOAT, 0, meshData.verticesPosBegin);
1109 glNormalPointer(GL_FLOAT, 0, meshData.verticesNormalBegin);
1111 #ifdef __CELLOS_LV2__
1112 glDrawRangeElements(GL_TRIANGLES, 0, numVertices-1, 3*numTriangles, GL_UNSIGNED_INT, meshData.indicesBegin);
1114 glDrawElements(GL_TRIANGLES, 3*numTriangles, GL_UNSIGNED_INT, meshData.indicesBegin);
1118 const static float ShadowMat[]={ 1,0,0,0, 0,0,0,0, 0,0,1,0, 0,0,0,1 };
1120 glMultMatrixf(ShadowMat);
1121 glDisable(GL_LIGHTING);
1122 glColor4f(0.05f, 0.1f, 0.15f,1.0f);
1124 #ifdef __CELLOS_LV2__
1125 glDrawRangeElements(GL_TRIANGLES, 0, numVertices-1, 3*numTriangles, GL_UNSIGNED_INT, meshData.indicesBegin);
1127 glDrawElements(GL_TRIANGLES, 3*numTriangles, GL_UNSIGNED_INT, meshData.indicesBegin);
1130 glColor4f(1.0f, 1.0f, 1.0f,1.0f);
1131 glEnable(GL_LIGHTING);
1135 glDisableClientState(GL_VERTEX_ARRAY);
1136 glDisableClientState(GL_NORMAL_ARRAY);
1140 #include <windows.h>
1141 typedef BOOL (APIENTRY *PFNWGLSWAPINTERVALFARPROC)( int );
1142 PFNWGLSWAPINTERVALFARPROC wglSwapIntervalEXT = 0;
1149 if (wglSwapIntervalEXT == NULL)
1151 const char* extensions = (const char*)glGetString(GL_EXTENSIONS);
1152 if (strstr(extensions, "WGL_EXT_swap_control") != 0)
1154 wglSwapIntervalEXT = (PFNWGLSWAPINTERVALFARPROC)wglGetProcAddress( "wglSwapIntervalEXT" );
1157 if (wglSwapIntervalEXT != NULL)
1159 vsyncState = 1 - vsyncState;
1160 wglSwapIntervalEXT(vsyncState);