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 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 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 }
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); } } }