static DemoEntityManager::dListNode* LoadScene(DemoEntityManager* const scene, const char* const name, const dMatrix& location) { char fileName[2048]; GetWorkingFileName (name, fileName); DemoEntityManager::dListNode* const lastEnt = scene->GetLast(); scene->LoadScene (fileName); for (DemoEntityManager::dListNode* node = lastEnt->GetNext(); node; node = node->GetNext()) { DemoEntity* const entity = node->GetInfo(); dMatrix matrix (entity->GetNextMatrix() * location); entity->ResetMatrix(*scene, matrix); } return lastEnt->GetNext(); }
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); } } }