static void LoadFloor(DemoEntityManager* const scene, NewtonCollision* const sceneCollision) { NewtonWorld* const world = scene->GetNewton(); // add a flat plane dMatrix matrix (dGetIdentityMatrix()); DemoEntityManager::dListNode* const floorNode = LoadScene(scene, "flatPlane.ngd", matrix); DemoEntity* const entity = floorNode->GetInfo(); DemoMesh* const mesh = (DemoMesh*)entity->GetMesh(); dAssert (mesh->IsType(DemoMesh::GetRttiType())); NewtonCollision* const tree = NewtonCreateTreeCollision(world, 0); NewtonTreeCollisionBeginBuild(tree); dFloat* const vertex = mesh->m_vertex; for (DemoMesh::dListNode* node = mesh->GetFirst(); node; node = node->GetNext()){ DemoSubMesh* const subMesh = &node->GetInfo(); unsigned int* const indices = subMesh->m_indexes; int trianglesCount = subMesh->m_indexCount; for (int i = 0; i < trianglesCount; i += 3) { dVector face[3]; int index = indices[i + 0] * 3; face[0] = dVector (vertex[index + 0], vertex[index + 1], vertex[index + 2]); index = indices[i + 1] * 3; face[1] = dVector (vertex[index + 0], vertex[index + 1], vertex[index + 2]); index = indices[i + 2] * 3; face[2] = dVector (vertex[index + 0], vertex[index + 1], vertex[index + 2]); int matID = 0; //matID = matID == 2 ? 1 : 2 ; NewtonTreeCollisionAddFace(tree, 3, &face[0].m_x, sizeof (dVector), matID); } } NewtonTreeCollisionEndBuild (tree, 1); // add the collision tree to the collision scene void* const proxy = NewtonSceneCollisionAddSubCollision (sceneCollision, tree); // destroy the original tree collision NewtonDestroyCollision (tree); // set the parameter on the added collision share matrix = entity->GetCurrentMatrix(); NewtonCollision* const collisionTree = NewtonSceneCollisionGetCollisionFromNode (sceneCollision, proxy); NewtonSceneCollisionSetSubCollisionMatrix (sceneCollision, proxy, &matrix[0][0]); NewtonCollisionSetUserData(collisionTree, entity); // set the application level callback, for debug display #ifdef USE_STATIC_MESHES_DEBUG_COLLISION NewtonStaticCollisionSetDebugCallback (collisionTree, ShowMeshCollidingFaces); #endif }
void dNewtonCollision::DeleteShape() { if (m_shape) { NewtonWaitForUpdateToFinish(m_myWorld->m_world); NewtonCollisionSetUserData(m_shape, NULL); NewtonDestroyCollision(m_shape); m_myWorld->m_collisionCache.Remove(m_collisionCacheNode); m_shape = NULL; m_collisionCacheNode = 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 AddCollisionSingleShape(DemoEntityManager* const scene) { dMatrix offsetMatrix (dGetIdentityMatrix()); NewtonCollision* const box = NewtonCreateBox (scene->GetNewton(), 4.0f, 0.1f, 4.0f, 0, &offsetMatrix[0][0]) ; DemoMesh* const mesh = new DemoMesh (" box", box, "metal_30.tga", "metal_30.tga", "metal_30.tga"); // add compound to the scene collision dMatrix matrix; void* proxy; NewtonCollision* shape; matrix = dRollMatrix(15.0f * 3.1416f / 180.0f); matrix.m_posit.m_y = 4.0f; matrix.m_posit.m_x = 3.0f; matrix.m_posit.m_z = 0.0f; proxy = NewtonSceneCollisionAddSubCollision (m_sceneCollision, box); shape = NewtonSceneCollisionGetCollisionFromNode (m_sceneCollision, proxy); NewtonSceneCollisionSetSubCollisionMatrix (m_sceneCollision, proxy, &matrix[0][0]); NewtonCollisionSetUserData(shape, mesh); mesh->AddRef(); matrix = dRollMatrix(-15.0f * 3.1416f / 180.0f); matrix.m_posit.m_y = 8.0f; matrix.m_posit.m_x = -3.0f; matrix.m_posit.m_z = 0.0f; proxy = NewtonSceneCollisionAddSubCollision (m_sceneCollision, box); shape = NewtonSceneCollisionGetCollisionFromNode (m_sceneCollision, proxy); NewtonSceneCollisionSetSubCollisionMatrix (m_sceneCollision, proxy, &matrix[0][0]); NewtonCollisionSetUserData(shape, mesh); mesh->AddRef(); NewtonDestroyCollision(box); mesh->Release(); }
void AddCollisionHeightFieldMesh(DemoEntityManager* const scene) { int size = 101; dFloat* const elevation = new dFloat[size * size]; //y = a * sin(x)* (sin (z)) ^2 for (int i = 0; i < size; i ++) { dFloat z = 3.1416f * i / (size - 1); dFloat z2 = dSin (z); z2 = z2 * z2 * 5.0f; for (int j = 0; j < size; j ++) { dFloat x = 3.1416f * j / (size - 1); dFloat y = z2 * dSin(x); elevation[j * size + i] = y; } } dFloat cellsize = 0.25f; DemoMesh* const mesh = new DemoMesh ("terrain", elevation, size, cellsize, 1.0f/16.0f, size - 1); int width = size; int height = size; char* const attibutes = new char [size * size]; memset (attibutes, 0, width * height * sizeof (char)); NewtonCollision* const collision = NewtonCreateHeightFieldCollision (scene->GetNewton(), width, height, 1, 0, elevation, attibutes, 1.0f, cellsize, 0); void* const proxy = NewtonSceneCollisionAddSubCollision (m_sceneCollision, collision); NewtonDestroyCollision(collision); // set the parameter on the added collision share dMatrix matrix (dGetIdentityMatrix()); matrix.m_posit.m_y = -2.0f; matrix.m_posit.m_x = -15.0f; matrix.m_posit.m_z = -10.0f; NewtonCollision* const terrainCollision = NewtonSceneCollisionGetCollisionFromNode (m_sceneCollision, proxy ); NewtonSceneCollisionSetSubCollisionMatrix (m_sceneCollision, proxy, &matrix[0][0]); NewtonCollisionSetUserData(terrainCollision, mesh); delete[] elevation; delete[] attibutes; }
void Restitution (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 NewtonWorld* const world = scene->GetNewton(); dMatrix offsetMatrix (dGetIdentityMatrix()); int defaultMaterialID = NewtonMaterialGetDefaultGroupID (world); NewtonMaterialSetCollisionCallback (world, defaultMaterialID, defaultMaterialID, NULL, UserContactRestitution); CreateLevelMesh (scene, "flatPlane.ngd", 0); dVector location (0.0f, 0.0f, 0.0f, 0.0f); dVector size (0.5f, 0.5f, 1.0f, 0.0f); // create some spheres dVector sphSize (1.0f, 1.0f, 1.0f, 0.0f); NewtonCollision* const sphereCollision = CreateConvexCollision (world, offsetMatrix, sphSize, _SPHERE_PRIMITIVE, 0); DemoMesh* const sphereMesh = new DemoMesh("sphere", sphereCollision, "smilli.tga", "smilli.tga", "smilli.tga"); // create some boxes too dVector boxSize (1.0f, 0.5f, 2.0f, 0.0f); NewtonCollision* const boxCollision = CreateConvexCollision (world, offsetMatrix, boxSize, _BOX_PRIMITIVE, 0); DemoMesh* const boxMesh = new DemoMesh("box", boxCollision, "smilli.tga", "smilli.tga", "smilli.tga"); int zCount = 10; dFloat spacing = 4.0f; dMatrix matrix (dGetIdentityMatrix()); dVector origin (matrix.m_posit); origin.m_x -= 0.0f; // create a simple scene for (int i = 0; i < zCount; i ++) { dFloat z; dFloat x; dFloat mass; dVector size (1.0f, 0.5f, 2.0f, 0.0f); x = origin.m_x; z = origin.m_z + (i - zCount / 2) * spacing; mass = 1.0f; matrix.m_posit = FindFloor (world, dVector (x, 100.0f, z), 200.0f); matrix.m_posit.m_w = 1.0f; float restitution; NewtonBody* body; NewtonCollision* collision; matrix.m_posit.m_y += 4.0f; body = CreateSimpleSolid (scene, sphereMesh, mass, matrix, sphereCollision, defaultMaterialID); NewtonBodySetLinearDamping (body, 0.0f); collision = NewtonBodyGetCollision(body); restitution = i * 0.1f + 0.083f; NewtonCollisionSetUserData (collision, *((void**)&restitution)); matrix.m_posit.m_y += 4.0f; //body = CreateSimpleSolid (scene, sphereMesh, mass, matrix, sphereCollision, defaultMaterialID, shapeOffsetMatrix); body = CreateSimpleSolid (scene, boxMesh, mass, matrix, boxCollision, defaultMaterialID); NewtonBodySetLinearDamping (body, 0.0f); collision = NewtonBodyGetCollision(body); restitution = i * 0.1f + 0.083f; NewtonCollisionSetUserData (collision, *((void**)&restitution)); matrix.m_posit.m_y += 4.0f; body = CreateSimpleSolid (scene, sphereMesh, mass, matrix, sphereCollision, defaultMaterialID); NewtonBodySetLinearDamping (body, 0.0f); collision = NewtonBodyGetCollision(body); restitution = i * 0.1f + 0.083f; NewtonCollisionSetUserData (collision, *((void**)&restitution)); matrix.m_posit.m_y += 4.0f; dVector boxSize (1.0f, 0.5f, 2.0f, 0.0f); body = CreateSimpleSolid (scene, boxMesh, mass, matrix, boxCollision, defaultMaterialID); NewtonBodySetLinearDamping (body, 0.0f); collision = NewtonBodyGetCollision(body); restitution = i * 0.1f + 0.083f; NewtonCollisionSetUserData (collision, *((void**)&restitution)); } boxMesh->Release(); sphereMesh->Release(); NewtonDestroyCollision(boxCollision); NewtonDestroyCollision(sphereCollision); dMatrix camMatrix (dGetIdentityMatrix()); dQuaternion rot (camMatrix); origin = dVector (-25.0f, 5.0f, 0.0f, 0.0f); scene->SetCameraMatrix(rot, origin); }
void AddCollisionTreeMesh (DemoEntityManager* const scene) { // open the level data char fullPathName[2048]; GetWorkingFileName ("playground.ngd", fullPathName); scene->LoadScene (fullPathName); // find the visual mesh and make a collision tree NewtonWorld* const world = scene->GetNewton(); DemoEntity* const entity = scene->GetLast()->GetInfo(); DemoMesh* const mesh = (DemoMesh*)entity->GetMesh(); dAssert (mesh->IsType(DemoMesh::GetRttiType())); NewtonCollision* const tree = NewtonCreateTreeCollision(world, 0); NewtonTreeCollisionBeginBuild(tree); dFloat* const vertex = mesh->m_vertex; for (DemoMesh::dListNode* node = mesh->GetFirst(); node; node = node->GetNext()){ DemoSubMesh* const subMesh = &node->GetInfo(); unsigned int* const indices = subMesh->m_indexes; int trianglesCount = subMesh->m_indexCount; for (int i = 0; i < trianglesCount; i += 3) { dVector face[3]; int index = indices[i + 0] * 3; face[0] = dVector (vertex[index + 0], vertex[index + 1], vertex[index + 2]); index = indices[i + 1] * 3; face[1] = dVector (vertex[index + 0], vertex[index + 1], vertex[index + 2]); index = indices[i + 2] * 3; face[2] = dVector (vertex[index + 0], vertex[index + 1], vertex[index + 2]); int matID = 0; //matID = matID == 2 ? 1 : 2 ; NewtonTreeCollisionAddFace(tree, 3, &face[0].m_x, sizeof (dVector), matID); } } NewtonTreeCollisionEndBuild (tree, 0); // add the collision tree to the collision scene void* const proxy = NewtonSceneCollisionAddSubCollision (m_sceneCollision, tree); // destroy the original tree collision NewtonDestroyCollision (tree); // set the parameter on the added collision share dMatrix matrix (entity->GetCurrentMatrix()); NewtonCollision* const collisionTree = NewtonSceneCollisionGetCollisionFromNode (m_sceneCollision, proxy); NewtonSceneCollisionSetSubCollisionMatrix (m_sceneCollision, proxy, &matrix[0][0]); NewtonCollisionSetUserData(collisionTree, mesh); // set the application level callback #ifdef USE_STATIC_MESHES_DEBUG_COLLISION NewtonStaticCollisionSetDebugCallback (collisionTree, ShowMeshCollidingFaces); #endif mesh->AddRef(); scene->RemoveEntity (entity); #ifdef USE_TEST_ALL_FACE_USER_RAYCAST_CALLBACK // set a ray cast callback for all face ray cast NewtonTreeCollisionSetUserRayCastCallback (collisionTree, AllRayHitCallback); dVector p0 (0, 100, 0, 0); dVector p1 (0, -100, 0, 0); dVector normal(0.0f); dLong id; dFloat parameter; parameter = NewtonCollisionRayCast (collisionTree, &p0[0], &p1[0], &normal[0], &id); #endif }
void CreateRagdollExperiment_0(const dMatrix& location) { static dJointDefinition jointsDefinition[] = { { "body" }, { "leg", 100.0f,{ -15.0f, 15.0f, 30.0f },{ 0.0f, 0.0f, 180.0f }, dAnimationRagdollJoint::m_threeDof }, { "foot", 100.0f,{ -15.0f, 15.0f, 30.0f },{ 0.0f, 90.0f, 0.0f }, dAnimationRagdollJoint::m_twoDof }, }; const int definitionCount = sizeof (jointsDefinition)/sizeof (jointsDefinition[0]); NewtonWorld* const world = GetWorld(); DemoEntityManager* const scene = (DemoEntityManager*)NewtonWorldGetUserData(world); DemoEntity* const modelEntity = DemoEntity::LoadNGD_mesh("selfbalance_01.ngd", GetWorld(), scene->GetShaderCache()); dMatrix matrix0(modelEntity->GetCurrentMatrix()); //matrix0.m_posit = location; //modelEntity->ResetMatrix(*scene, matrix0); scene->Append(modelEntity); // add the root childBody NewtonBody* const rootBody = CreateBodyPart(modelEntity); // build the rag doll with rigid bodies connected by joints dDynamicsRagdoll* const dynamicRagdoll = new dDynamicsRagdoll(rootBody, dGetIdentityMatrix()); AddModel(dynamicRagdoll); dynamicRagdoll->SetCalculateLocalTransforms(true); // save the controller as the collision user data, for collision culling NewtonCollisionSetUserData(NewtonBodyGetCollision(rootBody), dynamicRagdoll); int stackIndex = 0; DemoEntity* childEntities[32]; dAnimationJoint* parentBones[32]; for (DemoEntity* child = modelEntity->GetChild(); child; child = child->GetSibling()) { parentBones[stackIndex] = dynamicRagdoll; childEntities[stackIndex] = child; stackIndex++; } // walk model hierarchic adding all children designed as rigid body bones. while (stackIndex) { stackIndex--; DemoEntity* const entity = childEntities[stackIndex]; dAnimationJoint* parentNode = parentBones[stackIndex]; const char* const name = entity->GetName().GetStr(); for (int i = 0; i < definitionCount; i++) { if (!strcmp(jointsDefinition[i].m_boneName, name)) { NewtonBody* const childBody = CreateBodyPart(entity); // connect this body part to its parent with a rag doll joint parentNode = CreateChildNode(childBody, parentNode, jointsDefinition[i]); NewtonCollisionSetUserData(NewtonBodyGetCollision(childBody), parentNode); break; } } for (DemoEntity* child = entity->GetChild(); child; child = child->GetSibling()) { parentBones[stackIndex] = parentNode; childEntities[stackIndex] = child; stackIndex++; } } SetModelMass (100.0f, dynamicRagdoll); // set the collision mask // note this container work best with a material call back for setting bit field //dAssert(0); //controller->SetDefaultSelfCollisionMask(); // transform the entire contraction to its location dMatrix worldMatrix(modelEntity->GetCurrentMatrix() * location); worldMatrix.m_posit = location.m_posit; NewtonBodySetMatrixRecursive(rootBody, &worldMatrix[0][0]); // attach effectors here for (dAnimationJoint* joint = GetFirstJoint(dynamicRagdoll); joint; joint = GetNextJoint(joint)) { if (joint->GetAsRoot()) { dAssert(dynamicRagdoll == joint); dynamicRagdoll->SetHipEffector(joint); } else if (joint->GetAsLeaf()) { dynamicRagdoll->SetFootEffector(joint); } } dynamicRagdoll->Finalize(); //return controller; }
static void MakeFunnyCompound (DemoEntityManager* const scene, const dVector& origin) { NewtonWorld* const world = scene->GetNewton(); // create an empty compound collision NewtonCollision* const compound = NewtonCreateCompoundCollision (world, 0); #if 1 NewtonCompoundCollisionBeginAddRemove(compound); // add a bunch of convex collision at random position and orientation over the surface of a big sphere float radio = 5.0f; for (int i = 0 ; i < 300; i ++) { NewtonCollision* collision = NULL; float pitch = RandomVariable (1.0f) * 2.0f * 3.1416f; float yaw = RandomVariable (1.0f) * 2.0f * 3.1416f; float roll = RandomVariable (1.0f) * 2.0f * 3.1416f; float x = RandomVariable (0.5f); float y = RandomVariable (0.5f); float z = RandomVariable (0.5f); if ((x == 0.0f) && (y == 0.0f) && (z == 0.0f)){ x = 0.1f; } dVector p (x, y, z, 1.0f) ; p = p.Scale (radio / dSqrt (p % p)); dMatrix matrix (dPitchMatrix (pitch) * dYawMatrix (yaw) * dRollMatrix (roll)); matrix.m_posit = p; int r = dRand(); switch ((r >>2) & 3) { case 0: { collision = NewtonCreateSphere(world, 0.5, 0, &matrix[0][0]) ; break; } case 1: { collision = NewtonCreateCapsule(world, 0.3f, 0.2f, 0.5f, 0, &matrix[0][0]) ; break; } case 2: { collision = NewtonCreateCylinder(world, 0.25, 0.5, 0.25, 0, &matrix[0][0]) ; break; } case 3: { collision = NewtonCreateCone(world, 0.25, 0.25, 0, &matrix[0][0]) ; break; } } dAssert (collision); // we can set a collision id, and use data per sub collision NewtonCollisionSetUserID(collision, i); NewtonCollisionSetUserData(collision, (void*) i); // add this new collision NewtonCompoundCollisionAddSubCollision (compound, collision); NewtonDestroyCollision(collision); } // finish adding shapes NewtonCompoundCollisionEndAddRemove(compound); { // remove the first 10 shapes // test remove shape form a compound NewtonCompoundCollisionBeginAddRemove(compound); void* node = NewtonCompoundCollisionGetFirstNode(compound); for (int i = 0; i < 10; i ++) { //NewtonCollision* const collision = NewtonCompoundCollisionGetCollisionFromNode(compound, node); void* const nextNode = NewtonCompoundCollisionGetNextNode(compound, node); NewtonCompoundCollisionRemoveSubCollision(compound, node); node = nextNode; } // finish remove void* handle1 = NewtonCompoundCollisionGetNodeByIndex (compound, 30); void* handle2 = NewtonCompoundCollisionGetNodeByIndex (compound, 100); NewtonCollision* const shape1 = NewtonCompoundCollisionGetCollisionFromNode (compound, handle1); NewtonCollision* const shape2 = NewtonCompoundCollisionGetCollisionFromNode (compound, handle2); NewtonCollision* const copyShape1 = NewtonCollisionCreateInstance (shape1); NewtonCollision* const copyShape2 = NewtonCollisionCreateInstance (shape2); // you can also remove shape by their index NewtonCompoundCollisionRemoveSubCollisionByIndex (compound, 30); NewtonCompoundCollisionRemoveSubCollisionByIndex (compound, 100); handle1 = NewtonCompoundCollisionAddSubCollision (compound, copyShape1); handle2 = NewtonCompoundCollisionAddSubCollision (compound, copyShape2); NewtonDestroyCollision(copyShape1); NewtonDestroyCollision(copyShape2); NewtonCompoundCollisionEndAddRemove(compound); } { // show how to modify the children of a compound collision NewtonCompoundCollisionBeginAddRemove(compound); for (void* node = NewtonCompoundCollisionGetFirstNode(compound); node; node = NewtonCompoundCollisionGetNextNode(compound, node)) { NewtonCollision* const collision = NewtonCompoundCollisionGetCollisionFromNode(compound, node); // you can scale, change the matrix, change the inertia, do anything you want with the change NewtonCollisionSetUserData(collision, NULL); } NewtonCompoundCollisionEndAddRemove(compound); } // NewtonCollisionSetScale(compound, 0.5f, 0.25f, 0.125f); #else //test Yeside compound shape shape // - Rotation="1.5708 -0 0" Translation="0 0 0.024399" Size="0.021 0.096" Pos="0 0 0.115947" // - Rotation="1.5708 -0 0" Translation="0 0 0.056366" Size="0.195 0.024" Pos="0 0 0.147914" // - Rotation="1.5708 -0 0" Translation="0 0 -0.056366" Size="0.0065 0.07 Pos="0 0 0.035182" NewtonCompoundCollisionBeginAddRemove(compound); NewtonCollision* collision; dMatrix offsetMatrix (dPitchMatrix(1.5708f)); offsetMatrix.m_posit.m_z = 0.115947f; collision = NewtonCreateCylinder (world, 0.021f, 0.096f, 0, &offsetMatrix[0][0]) ; NewtonCompoundCollisionAddSubCollision (compound, collision); NewtonDestroyCollision(collision); offsetMatrix.m_posit.m_z = 0.035182f; collision = NewtonCreateCylinder (world, 0.0065f, 0.07f, 0, &offsetMatrix[0][0]) ; NewtonCompoundCollisionAddSubCollision (compound, collision); NewtonDestroyCollision(collision); offsetMatrix.m_posit.m_z = 0.147914f; collision = NewtonCreateCylinder (world, 0.195f, 0.024f, 0, &offsetMatrix[0][0]) ; NewtonCompoundCollisionAddSubCollision (compound, collision); NewtonDestroyCollision(collision); NewtonCompoundCollisionEndAddRemove(compound); #endif // for now we will simple make simple Box, make a visual Mesh DemoMesh* const visualMesh = new DemoMesh ("big ball", compound, "metal_30.tga", "metal_30.tga", "metal_30.tga"); int instaceCount = 2; dMatrix matrix (dGetIdentityMatrix()); matrix.m_posit = origin; for (int ix = 0; ix < instaceCount; ix ++) { for (int iz = 0; iz < instaceCount; iz ++) { dFloat y = origin.m_y; dFloat x = origin.m_x + (ix - instaceCount/2) * 15.0f; dFloat z = origin.m_z + (iz - instaceCount/2) * 15.0f; matrix.m_posit = FindFloor (world, dVector (x, y + 10.0f, z, 0.0f), 20.0f); ; matrix.m_posit.m_y += 15.0f; CreateSimpleSolid (scene, visualMesh, 10.0f, matrix, compound, 0); } } visualMesh->Release(); NewtonDestroyCollision(compound); }
static void LoadHangingBridge (DemoEntityManager* const scene, TriggerManager* const triggerManager, NewtonCollision* const sceneCollision, const char* const name, const dMatrix& location, NewtonBody* const playGroundBody) { NewtonWorld* const world = scene->GetNewton(); DemoEntityManager::dListNode* const bridgeNodes = scene->GetLast(); LoadScene(scene, name, location); // add bridge foundations for (DemoEntityManager::dListNode* node = bridgeNodes->GetNext(); node; node = node->GetNext()) { DemoEntity* const entity = node->GetInfo(); if (entity->GetName().Find("ramp") != -1) { DemoMesh* const mesh = (DemoMesh*)entity->GetMesh(); dAssert (mesh->IsType(DemoMesh::GetRttiType())); NewtonCollision* const collision = NewtonCreateConvexHull(world, mesh->m_vertexCount, mesh->m_vertex, 3 * sizeof (dFloat), 0, 0, NULL); void* const proxy = NewtonSceneCollisionAddSubCollision (sceneCollision, collision); NewtonDestroyCollision (collision); // get the location of this tire relative to the car chassis dMatrix matrix (entity->GetNextMatrix()); NewtonCollision* const bridgeCollision = NewtonSceneCollisionGetCollisionFromNode (sceneCollision, proxy); NewtonSceneCollisionSetSubCollisionMatrix (sceneCollision, proxy, &matrix[0][0]); NewtonCollisionSetUserData(bridgeCollision, entity); } } // add all the planks that form the bridge dTree<NewtonBody*, dString> planks; dFloat plankMass = 30.0f; for (DemoEntityManager::dListNode* node = bridgeNodes->GetNext(); node; node = node->GetNext()) { DemoEntity* const entity = node->GetInfo(); if (entity->GetName().Find("plank") != -1) { DemoMesh* const mesh = (DemoMesh*)entity->GetMesh(); dAssert (mesh->IsType(DemoMesh::GetRttiType())); // note: because the mesh matrix can have scale, for simplicity just apply the local mesh matrix to the vertex cloud dVector pool[128]; const dMatrix& meshMatrix = entity->GetMeshMatrix(); meshMatrix.TransformTriplex(&pool[0].m_x, sizeof (dVector), mesh->m_vertex, 3 * sizeof (dFloat), mesh->m_vertexCount); NewtonCollision* const collision = NewtonCreateConvexHull(world, mesh->m_vertexCount, &pool[0].m_x, sizeof (dVector), 0, 0, NULL); NewtonBody* const body = CreateSimpleBody (world, entity, plankMass, entity->GetNextMatrix(), collision, 0); NewtonDestroyCollision (collision); planks.Insert(body, entity->GetName()); } } // connect each plant with a hinge // calculate the with of a plank dFloat plankwidth = 0.0f; dVector planksideDir (1.0f, 0.0f, 0.0f, 0.0f); { NewtonBody* const body0 = planks.Find("plank01")->GetInfo(); NewtonBody* const body1 = planks.Find("plank02")->GetInfo(); dMatrix matrix0; dMatrix matrix1; NewtonBodyGetMatrix(body0, &matrix0[0][0]); NewtonBodyGetMatrix(body1, &matrix1[0][0]); planksideDir = matrix1.m_posit - matrix0.m_posit; planksideDir = planksideDir.Scale (1.0f / dSqrt (planksideDir % planksideDir)); dVector dir (matrix0.UnrotateVector(planksideDir)); NewtonCollision* const shape = NewtonBodyGetCollision(body0); dVector p0; dVector p1; NewtonCollisionSupportVertex(shape, &dir[0], &p0[0]); dVector dir1 (dir.Scale (-1.0f)); NewtonCollisionSupportVertex(shape, &dir1[0], &p1[0]); plankwidth = dAbs (0.5f * ((p1 - p0) % dir)); } dTree<NewtonBody*, dString>::Iterator iter (planks); iter.Begin(); dMatrix matrix0; NewtonBody* body0 = iter.GetNode()->GetInfo(); NewtonBodyGetMatrix(body0, &matrix0[0][0]); for (iter ++; iter; iter ++) { NewtonBody* const body1 = iter.GetNode()->GetInfo(); dMatrix matrix1; NewtonBodyGetMatrix(body1, &matrix1[0][0]); // calculate the hinge parameter form the matrix location of each plank dMatrix pinMatrix0 (dGetIdentityMatrix()); pinMatrix0[0] = pinMatrix0[1] * planksideDir; pinMatrix0[0] = pinMatrix0[0].Scale (1.0f / dSqrt (pinMatrix0[0] % pinMatrix0[0])); pinMatrix0[2] = pinMatrix0[0] * pinMatrix0[1]; pinMatrix0[0][3] = 0.0f; pinMatrix0[1][3] = 0.0f; pinMatrix0[2][3] = 0.0f; // calculate the pivot pinMatrix0[3] = matrix0.m_posit + pinMatrix0[2].Scale (plankwidth); pinMatrix0[3][3] = 1.0f; dMatrix pinMatrix1 (pinMatrix0); pinMatrix1[3] = matrix1.m_posit - pinMatrix1[2].Scale (plankwidth); pinMatrix1[3][3] = 1.0f; // connect these two plank by a hinge, there a wiggle space between eh hinge that give therefore use the alternate hinge constructor new CustomHinge (pinMatrix0, pinMatrix1, body0, body1); body0 = body1; matrix0 = matrix1; } // connect the last and first plank to the bridge base { iter.Begin(); body0 = iter.GetNode()->GetInfo(); NewtonBodyGetMatrix(body0, &matrix0[0][0]); dMatrix pinMatrix0 (dGetIdentityMatrix()); pinMatrix0[0] = pinMatrix0[1] * planksideDir; pinMatrix0[0] = pinMatrix0[0].Scale (1.0f / dSqrt (pinMatrix0[0] % pinMatrix0[0])); pinMatrix0[2] = pinMatrix0[0] * pinMatrix0[1]; pinMatrix0[0][3] = 0.0f; pinMatrix0[1][3] = 0.0f; pinMatrix0[2][3] = 0.0f; pinMatrix0[3] = matrix0.m_posit - pinMatrix0[2].Scale (plankwidth); new CustomHinge (pinMatrix0, body0, playGroundBody); } { iter.End(); body0 = iter.GetNode()->GetInfo(); NewtonBodyGetMatrix(body0, &matrix0[0][0]); dMatrix pinMatrix0 (dGetIdentityMatrix()); pinMatrix0[0] = pinMatrix0[1] * planksideDir; pinMatrix0[0] = pinMatrix0[0].Scale (1.0f / dSqrt (pinMatrix0[0] % pinMatrix0[0])); pinMatrix0[2] = pinMatrix0[0] * pinMatrix0[1]; pinMatrix0[0][3] = 0.0f; pinMatrix0[1][3] = 0.0f; pinMatrix0[2][3] = 0.0f; pinMatrix0[3] = matrix0.m_posit + pinMatrix0[2].Scale (plankwidth); new CustomHinge (pinMatrix0, body0, playGroundBody); } }
static void LoadSlide (DemoEntityManager* const scene, TriggerManager* const triggerManager, NewtonCollision* const sceneCollision, const char* const name, const dMatrix& location, NewtonBody* const playGroundBody) { NewtonWorld* const world = scene->GetNewton(); DemoEntityManager::dListNode* const bridgeNodes = scene->GetLast(); LoadScene(scene, name, location); // add bridge foundations for (DemoEntityManager::dListNode* node = bridgeNodes->GetNext(); node; node = node->GetNext()) { DemoEntity* const entity = node->GetInfo(); if (entity->GetName().Find("ramp") != -1) { DemoMesh* const mesh = (DemoMesh*)entity->GetMesh(); dAssert (mesh->IsType(DemoMesh::GetRttiType())); NewtonCollision* const collision = NewtonCreateConvexHull(world, mesh->m_vertexCount, mesh->m_vertex, 3 * sizeof (dFloat), 0, 0, NULL); void* const proxy = NewtonSceneCollisionAddSubCollision (sceneCollision, collision); NewtonDestroyCollision (collision); // get the location of this tire relative to the car chassis dMatrix matrix (entity->GetNextMatrix()); NewtonCollision* const bridgeCollision = NewtonSceneCollisionGetCollisionFromNode (sceneCollision, proxy); NewtonSceneCollisionSetSubCollisionMatrix (sceneCollision, proxy, &matrix[0][0]); NewtonCollisionSetUserData(bridgeCollision, entity); } } // add start triggers CustomTriggerController* trigger0 = NULL; CustomTriggerController* trigger1 = NULL; for (DemoEntityManager::dListNode* node = bridgeNodes->GetNext(); node;) { DemoEntity* const entity = node->GetInfo(); node = node->GetNext() ; if (entity->GetName().Find("startTrigger") != -1) { DemoMesh* const mesh = (DemoMesh*)entity->GetMesh(); dAssert (mesh->IsType(DemoMesh::GetRttiType())); // create a trigger to match his mesh NewtonCollision* const collision = NewtonCreateConvexHull(world, mesh->m_vertexCount, mesh->m_vertex, 3 * sizeof (dFloat), 0, 0, NULL); dMatrix matrix (entity->GetNextMatrix()); CustomTriggerController* const controller = triggerManager->CreateTrigger(matrix, collision, NULL); NewtonDestroyCollision (collision); if (!trigger0) { trigger0 = controller; } else { trigger1 = controller; } // remove this entity from the scene, since we do not wan the trigger to be visible // to see triggers click "show collision mesh, and or "show contact points" in the main menu. scene->RemoveEntity(entity); } } // add the platform object for (DemoEntityManager::dListNode* node = bridgeNodes->GetNext(); node;) { DemoEntity* const entity = node->GetInfo(); node = node->GetNext() ; if (entity->GetName().Find("platform") != -1) { // make a platform object PlaformEntityEntity* const platformEntity = new PlaformEntityEntity (scene, entity, trigger0->GetBody(), trigger1->GetBody()); // store the platform in the trigger use data trigger0->SetUserData(platformEntity); trigger1->SetUserData(platformEntity); // remove this entity from the scene scene->RemoveEntity(entity); } } }
void dNewtonCollision::SetShape(NewtonCollision* const shape) { m_shape = shape; NewtonCollisionSetUserData(m_shape, this); m_collisionCacheNode = m_myWorld->m_collisionCache.Append(this); }