void RenderAABB (NewtonWorld* const world) { glDisable (GL_LIGHTING); glDisable(GL_TEXTURE_2D); glColor3f(0.0f, 0.0f, 1.0f); glBegin(GL_LINES); //glVertex3f (-20.3125000f, 3.54991579f, 34.3441200f); //glVertex3f (-19.6875000f, 3.54257250f, 35.2211456f); for (NewtonBody* body = NewtonWorldGetFirstBody(world); body; body = NewtonWorldGetNextBody(world, body)) { dVector p0; dVector p1; dMatrix matrix; NewtonCollision* const collision = NewtonBodyGetCollision(body); NewtonBodyGetMatrix (body, &matrix[0][0]); NewtonCollisionCalculateAABB (collision, &matrix[0][0], &p0[0], &p1[0]); // CalculateAABB (collision, matrix, p0, p1); glVertex3f (p0.m_x, p0.m_y, p0.m_z); glVertex3f (p1.m_x, p0.m_y, p0.m_z); glVertex3f (p0.m_x, p1.m_y, p0.m_z); glVertex3f (p1.m_x, p1.m_y, p0.m_z); glVertex3f (p0.m_x, p1.m_y, p1.m_z); glVertex3f (p1.m_x, p1.m_y, p1.m_z); glVertex3f (p0.m_x, p0.m_y, p1.m_z); glVertex3f (p1.m_x, p0.m_y, p1.m_z); glVertex3f (p0.m_x, p0.m_y, p0.m_z); glVertex3f (p0.m_x, p1.m_y, p0.m_z); glVertex3f (p1.m_x, p0.m_y, p0.m_z); glVertex3f (p1.m_x, p1.m_y, p0.m_z); glVertex3f (p0.m_x, p0.m_y, p1.m_z); glVertex3f (p0.m_x, p1.m_y, p1.m_z); glVertex3f (p1.m_x, p0.m_y, p1.m_z); glVertex3f (p1.m_x, p1.m_y, p1.m_z); glVertex3f (p0.m_x, p0.m_y, p0.m_z); glVertex3f (p0.m_x, p0.m_y, p1.m_z); glVertex3f (p1.m_x, p0.m_y, p0.m_z); glVertex3f (p1.m_x, p0.m_y, p1.m_z); glVertex3f (p0.m_x, p1.m_y, p0.m_z); glVertex3f (p0.m_x, p1.m_y, p1.m_z); glVertex3f (p1.m_x, p1.m_y, p0.m_z); glVertex3f (p1.m_x, p1.m_y, p1.m_z); } glEnd(); }
void SetAutoSleepMode (NewtonWorld* const world, int mode) { mode = mode ? 0 : 1; for (const NewtonBody* body = NewtonWorldGetFirstBody (world); body; body = NewtonWorldGetNextBody (world, body)) { NewtonBodySetAutoSleep (body, mode); } }
void RenderCenterOfMass (NewtonWorld* const world) { glDisable (GL_LIGHTING); glDisable(GL_TEXTURE_2D); glColor3f(0.0f, 0.0f, 1.0f); glBegin(GL_LINES); for (NewtonBody* body = NewtonWorldGetFirstBody(world); body; body = NewtonWorldGetNextBody(world, body)) { dMatrix matrix; dVector com(0.0f); NewtonBodyGetCentreOfMass (body, &com[0]); NewtonBodyGetMatrix (body, &matrix[0][0]); dVector o (matrix.TransformVector (com)); dVector x (o + matrix.RotateVector (dVector (1.0f, 0.0f, 0.0f, 0.0f))); glColor3f (1.0f, 0.0f, 0.0f); glVertex3f (o.m_x, o.m_y, o.m_z); glVertex3f (x.m_x, x.m_y, x.m_z); dVector y (o + matrix.RotateVector (dVector (0.0f, 1.0f, 0.0f, 0.0f))); glColor3f (0.0f, 1.0f, 0.0f); glVertex3f (o.m_x, o.m_y, o.m_z); glVertex3f (y.m_x, y.m_y, y.m_z); dVector z (o + matrix.RotateVector (dVector (0.0f, 0.0f, 1.0f, 0.0f))); glColor3f (0.0f, 0.0f, 1.0f); glVertex3f (o.m_x, o.m_y, o.m_z); glVertex3f (z.m_x, z.m_y, z.m_z); } glEnd(); }
void RigidBodyWorld::UpdatePhysics () { RigidBodyWorldDesc* const desc = (RigidBodyWorldDesc*) RigidBodyWorldDesc::GetDescriptor(); float timestep = 1.0f / desc->m_minFps; if (timestep > 1.0f / 60.0f) { timestep = 1.0f / 60.0f; } desc->m_updateRigidBodyMatrix = false; NewtonUpdate(desc->m_newton, timestep); TimeValue t (GetCOREInterface()->GetTime()); float scale = 1.0f / float (GetMasterScale(UNITS_METERS)); for (NewtonBody* body = NewtonWorldGetFirstBody(desc->m_newton); body; body = NewtonWorldGetNextBody(desc->m_newton, body)) { dMatrix matrix; INode* const node = (INode*)NewtonBodyGetUserData(body); NewtonBodyGetMatrix(body, &matrix[0][0]); matrix = desc->m_systemMatrix * matrix * desc->m_systemMatrixInv; matrix.m_posit = matrix.m_posit.Scale (scale); Matrix3 maxMatrix (GetMatrixFromdMatrix (matrix)); node->SetNodeTM(t, maxMatrix); } UpdateViewPorts (); desc->m_updateRigidBodyMatrix = true; }
void SetShowMeshCollision (SceneManager& me, int mode) { NewtonTreeCollisionCallback showFaceCallback; showFaceCallback = NULL; if (mode) { showFaceCallback = ShowMeshCollidingFaces; } // iterate the world for (const NewtonBody* body = NewtonWorldGetFirstBody (me.m_world); body; body = NewtonWorldGetNextBody (me.m_world, body)) { NewtonCollision* collision; NewtonCollisionInfoRecord info; collision = NewtonBodyGetCollision (body); NewtonCollisionGetInfo (collision, &info); switch (info.m_collisionType) { case SERIALIZE_ID_TREE: case SERIALIZE_ID_SCENE: case SERIALIZE_ID_USERMESH: case SERIALIZE_ID_HEIGHTFIELD: { NewtonStaticCollisionSetDebugCallback (collision, showFaceCallback); break; } default: break; } } }
void RenderContactPoints (NewtonWorld* const world) { glDisable (GL_LIGHTING); glDisable(GL_TEXTURE_2D); glPointSize(8.0f); glColor3f(1.0f, 0.0f, 0.0f); glBegin(GL_POINTS); for (NewtonBody* body = NewtonWorldGetFirstBody(world); body; body = NewtonWorldGetNextBody(world, body)) { for (NewtonJoint* joint = NewtonBodyGetFirstContactJoint(body); joint; joint = NewtonBodyGetNextContactJoint(body, joint)) { if (NewtonJointIsActive (joint)) { for (void* contact = NewtonContactJointGetFirstContact (joint); contact; contact = NewtonContactJointGetNextContact (joint, contact)) { dVector point(0.0f); dVector normal(0.0f); NewtonMaterial* const material = NewtonContactGetMaterial (contact); NewtonMaterialGetContactPositionAndNormal (material, body, &point.m_x, &normal.m_x); // if we are display debug info we need to block other threads from writing the data at the same time glVertex3f (point.m_x, point.m_y, point.m_z); } } } } glEnd(); glPointSize(1.0f); }
Body* World::getFirstBody() const { NewtonBody* body = NewtonWorldGetFirstBody( m_world ); if( body ) return (Body*) NewtonBodyGetUserData(body); return NULL; }
void Friction (DemoEntityManager* const scene) { // load the skybox scene->CreateSkyBox(); // load the scene from a ngd file format char fileName[2048]; dGetWorkingFileName ("frictionDemo.ngd", fileName); scene->LoadScene (fileName); // set a default material call back NewtonWorld* const world = scene->GetNewton(); int defaultMaterialID = NewtonMaterialGetDefaultGroupID (world); NewtonMaterialSetCollisionCallback (world, defaultMaterialID, defaultMaterialID, UserOnAABBOverlap, UserContactFriction); //NewtonMaterialSetDefaultCollidable(world, defaultMaterialID, defaultMaterialID, 0); // customize the scene after loading // set a user friction variable in the body for variable friction demos // later this will be done using LUA script int index = 0; for (NewtonBody* body = NewtonWorldGetFirstBody(world); body; body = NewtonWorldGetNextBody(world, body)) { dFloat Ixx; dFloat Iyy; dFloat Izz; dFloat mass; NewtonBodyGetMass (body, &mass, &Ixx, &Iyy, &Izz); if (mass > 0.0f) { // use the new instance feature to ass per shape information NewtonCollision* const collision = NewtonBodyGetCollision(body); // use the collision user data to save the coefficient of friction dFloat coefficientOfFriction = dFloat (index) * 0.03f; NewtonCollisionSetUserData (collision, *((void**)&coefficientOfFriction)); // DemoEntity* const entity = (DemoEntity*) NewtonBodyGetUserData (body); // dVariable* const friction = entity->CreateVariable (FRICTION_VAR_NAME); // dAssert (friction); // friction->SetValue(dFloat (index) * 0.03f); index ++; } } // place camera into position dQuaternion rot; dVector origin (-70.0f, 10.0f, 0.0f, 0.0f); scene->SetCameraMatrix(rot, origin); // ExportScene (scene->GetNewton(), "../../../media/test1.ngd"); }
void RenderNormalForces (NewtonWorld* const world) { glDisable (GL_LIGHTING); glDisable(GL_TEXTURE_2D); glColor3f(0.0f, 0.5f, 1.0f); glBegin(GL_LINES); dFloat length = 1.0f / 50.0f; for (NewtonBody* body = NewtonWorldGetFirstBody(world); body; body = NewtonWorldGetNextBody(world, body)) { RenderBodyContactsForces (body, length); } glEnd(); }
void RigidBodyWorld::Undo() const { TimeValue t (GetCOREInterface()->GetTime()); theHold.Begin(); RigidBodyWorldDesc* const desc = (RigidBodyWorldDesc*) RigidBodyWorldDesc::GetDescriptor(); for (NewtonBody* body = NewtonWorldGetFirstBody(desc->m_newton); body; body = NewtonWorldGetNextBody(desc->m_newton, body)) { INode* const node = (INode*)NewtonBodyGetUserData(body); RigidBodyController* const control = desc->GetRigidBodyControl(node); control->SaveUndoState(t); } theHold.Accept ("newton Undo"); }
void DemoCameraListener::InterpolateMatrices (DemoEntityManager* const scene, dFloat param) { NewtonWorld* const world = scene->GetNewton(); // interpolate the Camera matrix; m_camera->InterpolateMatrix (*scene, param); // interpolate the location of all entities in the world for (NewtonBody* body = NewtonWorldGetFirstBody(world); body; body = NewtonWorldGetNextBody(world, body)) { DemoEntity* const entity = (DemoEntity*)NewtonBodyGetUserData(body); if (entity) { entity->InterpolateMatrix (*scene, param); } } }
void DebugRenderWorldCollision (const NewtonWorld* const world, DEBUG_DRAW_MODE mode) { glDisable(GL_TEXTURE_2D); if (mode == m_lines) { glDisable (GL_LIGHTING); glBegin(GL_LINES); } else { glBegin(GL_TRIANGLES); } for (NewtonBody* body = NewtonWorldGetFirstBody(world); body; body = NewtonWorldGetNextBody(world, body)) { NewtonCollision* const collision = NewtonBodyGetCollision(body); int collisionType = NewtonCollisionGetType (collision); switch (collisionType) { //SERIALIZE_ID_SPHERE: //SERIALIZE_ID_CAPSULE: //SERIALIZE_ID_CHAMFERCYLINDER: //SERIALIZE_ID_TAPEREDCAPSULE: //SERIALIZE_ID_CYLINDER: //SERIALIZE_ID_TAPEREDCYLINDER: //SERIALIZE_ID_BOX: //SERIALIZE_ID_CONE: //SERIALIZE_ID_CONVEXHULL: //SERIALIZE_ID_NULL: //SERIALIZE_ID_COMPOUND: //SERIALIZE_ID_CLOTH_PATCH: //SERIALIZE_ID_DEFORMABLE_SOLID: // case SERIALIZE_ID_TREE: // case SERIALIZE_ID_SCENE: // case SERIALIZE_ID_USERMESH: case SERIALIZE_ID_HEIGHTFIELD: // case SERIALIZE_ID_COMPOUND_BREAKABLE: break; default: DebugShowBodyCollision (body, mode); } } glEnd(); glDisable (GL_LIGHTING); glBegin(GL_LINES); glColor3f(1.0f, 1.0f, 0.0f); for (int i = 0; i < g_debugDisplayCount; i += 2) { glVertex3f (g_debugDisplayCallback[i].m_x, g_debugDisplayCallback[i].m_y, g_debugDisplayCallback[i].m_z); glVertex3f (g_debugDisplayCallback[i+1].m_x, g_debugDisplayCallback[i+1].m_y, g_debugDisplayCallback[i+1].m_z); } glEnd(); }
void NewtonImport::BuildSceneFromWorld(NewtonWorld* const world) { dPluginInterface* const interface = (dPluginInterface*)NewtonWorldGetUserData(world); dPluginScene* const scene = interface->GetScene(); dScene::dTreeNode* const root = scene->GetRootNode(); for (NewtonBody* body = NewtonWorldGetFirstBody(world); body; body = NewtonWorldGetNextBody(world, body)) { NewtonCollision* const collision = NewtonBodyGetCollision(body); dScene::dTreeNode* const modelNode = scene->CreateModelNode(root); dScene::dTreeNode* const rigiBodyNode = scene->CreateRigidbodyNode(modelNode); dScene::dTreeNode* const collisionNode = scene->CreateCollisionFromNewtonCollision(rigiBodyNode, collision); collisionNode; } }
void world::tick(real dt) { const real MIN_FPS = 10.0; if (dt > 1.0 / MIN_FPS) dt = 1.0 / MIN_FPS; _lastStep = 0; for (_accum += dt; _accum >= _freq; _accum -= _freq, _lastStep += _freq) NewtonUpdate(_world, _freq); // Iterate over each body and lerp it NewtonBody *_body = NewtonWorldGetFirstBody(_world); while (_body) { bodyCast(_body)->lerp(dt); _body = NewtonWorldGetNextBody(_world, _body); } }
// create physics scene void PrimitiveCollision (DemoEntityManager* const scene) { // load the skybox scene->CreateSkyBox(); // customize the scene after loading // set a user friction variable in the body for variable friction demos // later this will be done using LUA script NewtonWorld* const world = scene->GetNewton(); dMatrix offsetMatrix (dGetIdentityMatrix()); int materialID = NewtonMaterialGetDefaultGroupID (world); // disable collision NewtonMaterialSetDefaultCollidable (world, materialID, materialID, 0); AddSinglePrimitive (scene, -10.0f, _SPHERE_PRIMITIVE, materialID); AddSinglePrimitive (scene, -8.0f, _BOX_PRIMITIVE, materialID); AddSinglePrimitive (scene, -6.0f, _CAPSULE_PRIMITIVE, materialID); AddSinglePrimitive (scene, -4.0f, _CYLINDER_PRIMITIVE, materialID); AddSinglePrimitive (scene, -2.0f, _CONE_PRIMITIVE, materialID); AddSinglePrimitive (scene, 4.0f, _CHAMFER_CYLINDER_PRIMITIVE, materialID); AddSinglePrimitive (scene, 6.0f, _RANDOM_CONVEX_HULL_PRIMITIVE, materialID); AddSinglePrimitive (scene, 8.0f, _REGULAR_CONVEX_HULL_PRIMITIVE, materialID); // here we will change the standard gravity force callback and apply null and add a for (NewtonBody* body = NewtonWorldGetFirstBody(world); body; body = NewtonWorldGetNextBody(world, body)) { DemoEntity* const entity = (DemoEntity*) NewtonBodyGetUserData(body); entity->SetUserData (new ShowCollisionCollide(body)); NewtonBodySetForceAndTorqueCallback(body, PhysicsSpinBody); NewtonBodySetAutoSleep (body, 0); } // place camera into position //dMatrix camMatrix (dYawMatrix(90.0f * dDegreeToRad)); dMatrix camMatrix (dGetIdentityMatrix()); dQuaternion rot (camMatrix); dVector origin (-15.0f, 0.0f, 0.0f, 0.0f); scene->SetCameraMatrix(rot, origin); }
dNewtonBody* dNewton::GetFirstBody() const { NewtonBody* const newtonBody = NewtonWorldGetFirstBody(m_world); return newtonBody ? (dNewtonBody*) NewtonBodyGetUserData(newtonBody) : NULL; }
void PrecessingTops (DemoEntityManager* const scene) { scene->CreateSkyBox(); // customize the scene after loading // set a user friction variable in the body for variable friction demos // later this will be done using LUA script dMatrix offsetMatrix (dGetIdentityMatrix()); CreateLevelMesh (scene, "flatPlane.ngd", 1); dVector location (0.0f, 0.0f, 0.0f, 0.0f); dVector size (3.0f, 2.0f, 0.0f, 0.0f); // create an array of cones const int count = 10; // all shapes use the x axis as the axis of symmetry, to make an upright cone we apply a 90 degree rotation local matrix dMatrix shapeOffsetMatrix (dRollMatrix(-3.141592f/2.0f)); AddPrimitiveArray(scene, 50.0f, location, size, count, count, 5.0f, _CONE_PRIMITIVE, 0, shapeOffsetMatrix); // till the cont 30 degrees, and apply a local high angular velocity dMatrix matrix (dRollMatrix (-25.0f * 3.141592f / 180.0f)); dVector omega (0.0f, 50.0f, 0.0f); omega = matrix.RotateVector (omega); dVector damp (0.0f, 0.0f, 0.0f, 0.0f); int topscount = 0; NewtonBody* array[count * count]; NewtonWorld* const world = scene->GetNewton(); for (NewtonBody* body = NewtonWorldGetFirstBody(world); body; body = NewtonWorldGetNextBody(world, body)) { NewtonCollision* const collision = NewtonBodyGetCollision(body); dVector com; if (NewtonCollisionGetType (collision) == SERIALIZE_ID_CONE) { array[topscount] = body; topscount ++; } } for (int i = 0; i < topscount ; i ++) { dMatrix bodyMatrix; NewtonBody* const body = array[i]; NewtonBodyGetMatrix(body, &bodyMatrix[0][0]); matrix.m_posit = bodyMatrix.m_posit; matrix.m_posit.m_y += 1.0f; NewtonBodySetMatrix(body, &matrix[0][0]); dFloat Ixx; dFloat Iyy; dFloat Izz; dFloat mass; NewtonBodyGetMassMatrix(body, &mass, &Ixx, &Iyy, &Izz); NewtonBodySetMassMatrix(body, mass, Ixx, Iyy * 8.0f, Izz); NewtonBodySetOmega (body, &omega[0]); NewtonBodySetAutoSleep (body, 0); NewtonBodySetLinearDamping(body, 0.0f); NewtonBodySetAngularDamping (body, &damp[0]); } // place camera into position dMatrix camMatrix (dGetIdentityMatrix()); dQuaternion rot (camMatrix); dVector origin (-40.0f, 5.0f, 0.0f, 0.0f); scene->SetCameraMatrix(rot, origin); }
INT_PTR CALLBACK RigidBodyWorld::Proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { RigidBodyWorld* const world = (RigidBodyWorld *)GetWindowLong (hWnd, GWLP_USERDATA); RigidBodyWorldDesc* const desc = (RigidBodyWorldDesc*) RigidBodyWorldDesc::GetDescriptor(); switch (msg) { case WM_INITDIALOG: { RigidBodyWorld* const world = (RigidBodyWorld *)lParam; SetWindowLong(hWnd, GWLP_USERDATA, (LONG)world); world->m_myWindow = hWnd; world->RigidBodyWorld::InitUI(hWnd); break; } case WM_DESTROY: { world->StopsSimulation (); world->RigidBodyWorld::DestroyUI(hWnd); break; } case WM_ENABLE: { //EnableWindow(obj->m_worldPaneHandle, (BOOL) wParam); break; } case WM_TIMER: { world->UpdatePhysics (); break; } case WM_COMMAND: { switch (LOWORD(wParam)) { case IDC_MAKE_RIGIDBODY: { world->StopsSimulation (); Interface* const ip = GetCOREInterface(); int selectionCount = ip->GetSelNodeCount(); for (int i = 0; i < selectionCount; i ++) { INode* const node = ip->GetSelNode(i); Object* const obj = node->GetObjOrWSMRef(); if (obj) { world->AttachRigiBodyController (node); } } world->UpdateViewPorts(); break; } case IDC_DELETE_RIGIDBODY: { world->StopsSimulation (); Interface* const ip = GetCOREInterface(); int selectionCount = ip->GetSelNodeCount(); for (int i = 0; i < selectionCount; i ++) { INode* const node = ip->GetSelNode(i); world->DetachRigiBodyController (node); } world->UpdateViewPorts (); break; } case IDC_SHOW_GIZMOS: { world->StopsSimulation (); for (NewtonBody* body = NewtonWorldGetFirstBody(desc->m_newton); body; body = NewtonWorldGetNextBody(desc->m_newton, body)) { INode* const node = (INode*)NewtonBodyGetUserData(body); RigidBodyController* const bodyInfo = (RigidBodyController*)desc->GetRigidBodyControl(node); _ASSERTE (bodyInfo); bodyInfo->m_hideGizmos = FALSE; } world->UpdateViewPorts(); break; } case IDC_HIDE_GIZMOS: { world->StopsSimulation (); for (NewtonBody* body = NewtonWorldGetFirstBody(desc->m_newton); body; body = NewtonWorldGetNextBody(desc->m_newton, body)) { INode* const node = (INode*)NewtonBodyGetUserData(body); RigidBodyController* const bodyInfo = (RigidBodyController*)desc->GetRigidBodyControl(node); _ASSERTE (bodyInfo); bodyInfo->m_hideGizmos = TRUE; } world->UpdateViewPorts(); break; } case IDC_SELECT_ALL: { world->StopsSimulation (); world->m_selectionChange = false; Interface* const ip = GetCOREInterface(); ip->ClearNodeSelection(FALSE); for (NewtonBody* body = NewtonWorldGetFirstBody(desc->m_newton); body; body = NewtonWorldGetNextBody(desc->m_newton, body)) { INode* const node = (INode*)NewtonBodyGetUserData(body); ip->SelectNode(node, 0); } world->m_selectionChange = true; world->SelectionSetChanged (ip, NULL); world->UpdateViewPorts(); break; } case IDC_REMOVE_ALL: { world->StopsSimulation (); Interface* const ip = GetCOREInterface(); ip->ClearNodeSelection(FALSE); for (NewtonBody* body = NewtonWorldGetFirstBody(desc->m_newton); body; ) { INode* const node = (INode*)NewtonBodyGetUserData(body); body = NewtonWorldGetNextBody(desc->m_newton, body); world->DetachRigiBodyController (node); } world->UpdateViewPorts(); break; } case IDC_MINUMIN_SIMULATION_RATE: { world->StopsSimulation (); desc->m_minFps = world->m_minFps->GetFloat(); break; } case IDC_GRAVITY_X: case IDC_GRAVITY_Y: case IDC_GRAVITY_Z: { world->StopsSimulation (); dVector gravity (world->m_gravity[0]->GetFloat(), world->m_gravity[1]->GetFloat(), world->m_gravity[2]->GetFloat(), 0.0f); //world->m_gravity[0]->SetText(gravity.m_x, 1); //world->m_gravity[1]->SetText(gravity.m_y, 1); //world->m_gravity[2]->SetText(gravity.m_z, 1); desc->m_gravity = desc->m_systemMatrix.RotateVector(gravity.Scale(float (GetMasterScale(UNITS_METERS)))); break; } case IDC_PREVIEW_WORLD: { if (IsDlgButtonChecked(hWnd, IDC_PREVIEW_WORLD) == BST_CHECKED) { world->Undo(); unsigned timeOut = unsigned (1000.0f / desc->m_minFps); SetTimer(hWnd, TIMER_ID, timeOut, NULL); } else { world->StopsSimulation (); } break; } case IDC_STEP_WORLD: { world->StopsSimulation (); world->Undo(); world->UpdatePhysics (); break; } } break; } default: return FALSE; } return TRUE; }
void RenderJointsDebugInfo (NewtonWorld* const world, dFloat size) { glDisable(GL_TEXTURE_2D); glDisable (GL_LIGHTING); glBegin(GL_LINES); // this will go over the joint list twice, for (NewtonBody* body = NewtonWorldGetFirstBody(world); body; body = NewtonWorldGetNextBody(world, body)) { for (NewtonJoint* joint = NewtonBodyGetFirstJoint(body); joint; joint = NewtonBodyGetNextJoint(body, joint)) { NewtonJointRecord info; NewtonJointGetInfo (joint, &info); if (strcmp (info.m_descriptionType, "customJointNotInfo")) { // draw first frame dMatrix matrix0; NewtonBodyGetMatrix (info.m_attachBody_0, &matrix0[0][0]); matrix0 = dMatrix (&info.m_attachmenMatrix_0[0][0]) * matrix0; dVector o0 (matrix0.m_posit); dVector x (o0 + matrix0.RotateVector (dVector (size, 0.0f, 0.0f, 0.0f))); glColor3f (1.0f, 0.0f, 0.0f); glVertex3f (o0.m_x, o0.m_y, o0.m_z); glVertex3f (x.m_x, x.m_y, x.m_z); dVector y (o0 + matrix0.RotateVector (dVector (0.0f, size, 0.0f, 0.0f))); glColor3f (0.0f, 1.0f, 0.0f); glVertex3f (o0.m_x, o0.m_y, o0.m_z); glVertex3f (y.m_x, y.m_y, y.m_z); dVector z (o0 + matrix0.RotateVector (dVector (0.0f, 0.0f, size, 0.0f))); glColor3f (0.0f, 0.0f, 1.0f); glVertex3f (o0.m_x, o0.m_y, o0.m_z); glVertex3f (z.m_x, z.m_y, z.m_z); // draw second frame dMatrix matrix1 (dGetIdentityMatrix()); if (info.m_attachBody_1) { NewtonBodyGetMatrix (info.m_attachBody_1, &matrix1[0][0]); } matrix1 = dMatrix (&info.m_attachmenMatrix_1[0][0]) * matrix1; dVector o1 (matrix1.m_posit); x = o1 + matrix1.RotateVector (dVector (size, 0.0f, 0.0f, 0.0f)); glColor3f (1.0f, 0.0f, 0.0f); glVertex3f (o1.m_x, o1.m_y, o1.m_z); glVertex3f (x.m_x, x.m_y, x.m_z); y = o1 + matrix1.RotateVector (dVector (0.0f, size, 0.0f, 0.0f)); glColor3f (0.0f, 1.0f, 0.0f); glVertex3f (o1.m_x, o1.m_y, o1.m_z); glVertex3f (y.m_x, y.m_y, y.m_z); z = o1 + matrix1.RotateVector (dVector (0.0f, 0.0f, size, 0.0f)); glColor3f (0.0f, 0.0f, 1.0f); glVertex3f (o1.m_x, o1.m_y, o1.m_z); glVertex3f (z.m_x, z.m_y, z.m_z); if (!strcmp (info.m_descriptionType, "limitballsocket")) { // draw the cone limit of this joint int steps = 12; dMatrix coneMatrix (dRollMatrix(info.m_maxAngularDof[1])); dMatrix ratationStep (dPitchMatrix(2.0f * 3.14151693f / steps)); dVector p0 (coneMatrix.RotateVector(dVector (size * 0.5f, 0.0f, 0.0f, 0.0f))); dVector q0 (matrix1.TransformVector(p0)); glColor3f (1.0f, 1.0f, 0.0f); for (int i = 0; i < (steps + 1); i ++) { dVector p1 (ratationStep.RotateVector(p0)); dVector q1 (matrix1.TransformVector(p1)); glVertex3f (o0.m_x, o0.m_y, o0.m_z); glVertex3f (q0.m_x, q0.m_y, q0.m_z); glVertex3f (q0.m_x, q0.m_y, q0.m_z); glVertex3f (q1.m_x, q1.m_y, q1.m_z); p0 = p1; q0 = q1; } } } } } glEnd(); }