PlaformEntityEntity (DemoEntityManager* const scene, DemoEntity* const source, NewtonBody* const triggerPort0, NewtonBody* const triggerPort1) :DemoEntity (source->GetNextMatrix(), NULL) { scene->Append(this); DemoMesh* const mesh = (DemoMesh*)source->GetMesh(); dAssert (mesh->IsType(DemoMesh::GetRttiType())); SetMesh(mesh, source->GetMeshMatrix()); const dFloat mass = 100.0f; dMatrix matrix (source->GetNextMatrix()) ; NewtonWorld* const world = scene->GetNewton(); // 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 = 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* body = CreateSimpleBody (world, this, 100, matrix, collision, 0); NewtonDestroyCollision(collision); // attach a kinematic joint controller joint to move this body dVector pivot; NewtonBodyGetCentreOfMass (body, &pivot[0]); pivot = matrix.TransformVector(pivot); m_driver = new FerryDriver (body, pivot, triggerPort0, triggerPort1); m_driver->SetMaxLinearFriction (50.0f * dAbs (mass * DEMO_GRAVITY)); m_driver->SetMaxAngularFriction(50.0f * dAbs (mass * DEMO_GRAVITY)); }
NewtonBody* CreateSimpleSolid (DemoEntityManager* const scene, DemoMesh* const mesh, dFloat mass, const dMatrix& matrix, NewtonCollision* const collision, int materialId) { dAssert (mesh); dAssert (collision); // add an new entity to the world DemoEntity* const entity = new DemoEntity(matrix, NULL); scene->Append (entity); entity->SetMesh(mesh, dGetIdentityMatrix()); return CreateSimpleBody (scene->GetNewton(), entity, mass, matrix, collision, materialId); }
StupidComplexOfConvexShapes (DemoEntityManager* const scene, int count) :DemoEntity (dGetIdentityMatrix(), NULL) ,m_rayP0(0.0f, 0.0f, 0.0f, 0.0f) ,m_rayP1(0.0f, 0.0f, 0.0f, 0.0f) { scene->Append(this); count = 40; //count = 1; const dFloat size = 0.5f; DemoMesh* gemetries[32]; NewtonCollision* collisionArray[32]; NewtonWorld* const world = scene->GetNewton(); int materialID = NewtonMaterialGetDefaultGroupID(world); // create a pool of predefined convex mesh // PrimitiveType selection[] = {_SPHERE_PRIMITIVE, _BOX_PRIMITIVE, _CAPSULE_PRIMITIVE, _CYLINDER_PRIMITIVE, _CONE_PRIMITIVE, _TAPERED_CAPSULE_PRIMITIVE, _TAPERED_CYLINDER_PRIMITIVE, _CHAMFER_CYLINDER_PRIMITIVE, _RANDOM_CONVEX_HULL_PRIMITIVE, _REGULAR_CONVEX_HULL_PRIMITIVE}; PrimitiveType selection[] = {_SPHERE_PRIMITIVE}; for (int i = 0; i < int (sizeof (collisionArray) / sizeof (collisionArray[0])); i ++) { int index = dRand() % (sizeof (selection) / sizeof (selection[0])); dVector shapeSize (size + RandomVariable (size / 2.0f), size + RandomVariable (size / 2.0f), size + RandomVariable (size / 2.0f), 0.0f); shapeSize = dVector(size, size, size, 0.0f); collisionArray[i] = CreateConvexCollision (world, dGetIdentityMatrix(), shapeSize, selection[index], materialID); gemetries[i] = new DemoMesh("geometry", collisionArray[i], "wood_4.tga", "wood_4.tga", "wood_1.tga"); } // make a large complex of plane by adding lost of these shapes at a random location and oriention; NewtonCollision* const compound = NewtonCreateCompoundCollision (world, materialID); NewtonCompoundCollisionBeginAddRemove(compound); for (int i = 0 ; i < count; i ++) { for (int j = 0 ; j < count; j ++) { 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 = size * (j - count / 2) + RandomVariable (size * 0.5f); float y = RandomVariable (size * 2.0f); float z = size * (i - count / 2) + RandomVariable (size * 0.5f); dMatrix matrix (dPitchMatrix (pitch) * dYawMatrix (yaw) * dRollMatrix (roll)); matrix.m_posit = dVector (x, y, z, 1.0f); int index = dRand() % (sizeof (selection) / sizeof (selection[0])); DemoEntity* const entity = new DemoEntity(matrix, this); entity->SetMesh(gemetries[index], dGetIdentityMatrix()); NewtonCollisionSetMatrix (collisionArray[index], &matrix[0][0]); NewtonCompoundCollisionAddSubCollision (compound, collisionArray[index]); } } NewtonCompoundCollisionEndAddRemove(compound); CreateSimpleBody (world, NULL, 0.0f, dGetIdentityMatrix(), compound, 0); // destroy all collision shapes after they are used NewtonDestroyCollision(compound); for (int i = 0; i < int (sizeof (collisionArray) / sizeof (collisionArray[0])); i ++) { gemetries[i]->Release(); NewtonDestroyCollision(collisionArray[i]); } // now make and array of collision shapes for convex casting by mouse point click an drag CreateCastingShapes(scene, size * 2.0f); }
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); } }