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);
}
Beispiel #7
0
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;

	}
}
Beispiel #14
0
        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);

}
Beispiel #16
0
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();
}