NewtonCollision* dCollisionCompoundNodeInfo::CreateNewtonCollision (NewtonWorld* const world, dScene* const scene, dScene::dTreeNode* const myNode) const { dAssert (IsType (dCollisionCompoundNodeInfo::GetRttiType())); // get the collision node int collisionID = GetShapeId (); NewtonCollision* const collision = NewtonCreateCompoundCollision(world, collisionID); NewtonCompoundCollisionBeginAddRemove(collision); // create space to load all sub shapes for (void* link = scene->GetFirstChildLink(myNode); link; link = scene->GetNextChildLink (myNode, link)) { dScene::dTreeNode* childNode = scene->GetNodeFromLink(link); dNodeInfo* info = scene->GetInfoFromNode(childNode); if (info->IsType (dCollisionNodeInfo::GetRttiType())) { dCollisionNodeInfo* collInfo = (dCollisionNodeInfo*) scene->GetInfoFromNode(childNode); NewtonCollision* const convex = collInfo->CreateNewtonCollision (world, scene, childNode); if (convex) { NewtonCompoundCollisionAddSubCollision(collision, convex); NewtonDestroyCollision(convex); } } } NewtonCompoundCollisionEndAddRemove(collision); return collision; }
iPhysicsCollision* iPhysics::createCompound(vector<iPhysicsCollision*>& collisions, uint64 worldID) { iPhysicsCollision* result = nullptr; const NewtonWorld* world = static_cast<const NewtonWorld*>(getWorld(worldID)->getNewtonWorld()); if (world != nullptr) { NewtonCollision* collision = NewtonCreateCompoundCollision(static_cast<const NewtonWorld*>(world), 0); result = new iPhysicsCollision(collision, worldID); _collisionsListMutex.lock(); _collisions[result->getID()] = result; _collisionsListMutex.unlock(); NewtonCompoundCollisionBeginAddRemove(collision); for (auto subcollision : collisions) { NewtonCompoundCollisionAddSubCollision(static_cast<NewtonCollision*>(collision), static_cast<NewtonCollision*>(subcollision->_collision)); } NewtonCompoundCollisionEndAddRemove(collision); } return result; }
NzCompoundGeom::NzCompoundGeom(NzPhysWorld* physWorld, NzBaseGeom** geoms, unsigned int geomCount) : NzBaseGeom(physWorld) { m_collision = NewtonCreateCompoundCollision(physWorld->GetHandle(), 0); NewtonCompoundCollisionBeginAddRemove(m_collision); for (unsigned int i = 0; i < geomCount; ++i) { if (geoms[i]->GetType() == nzGeomType_Compound) NazaraError("Cannot add compound geoms to other compound geoms"); else NewtonCompoundCollisionAddSubCollision(m_collision, geoms[i]->GetHandle()); } NewtonCompoundCollisionEndAddRemove(m_collision); }
void cCollideShapeNewton::CreateFromShapeVec(tCollideShapeVec &avShapes) { std::vector<NewtonCollision*> vNewtonColliders; vNewtonColliders.reserve(avShapes.size()); mvSubShapes.reserve(avShapes.size()); mfVolume =0; for(size_t i=0; i< avShapes.size(); i++) { mvSubShapes.push_back(avShapes[i]); cCollideShapeNewton *pNewtonShape = static_cast<cCollideShapeNewton*>(avShapes[i]); vNewtonColliders.push_back(pNewtonShape->GetNewtonCollision()); mfVolume += pNewtonShape->GetVolume(); } mpNewtonCollision = NewtonCreateCompoundCollision(mpNewtonWorld, (int)vNewtonColliders.size(), &vNewtonColliders[0]); // Create bounding volume cVector3f vFinalMax = avShapes[0]->GetBoundingVolume().GetMax(); cVector3f vFinalMin = avShapes[0]->GetBoundingVolume().GetMin(); for(size_t i=1; i< avShapes.size(); i++) { cVector3f vMax = avShapes[i]->GetBoundingVolume().GetMax(); cVector3f vMin = avShapes[i]->GetBoundingVolume().GetMin(); if(vFinalMax.x < vMax.x) vFinalMax.x = vMax.x; if(vFinalMin.x > vMin.x) vFinalMin.x = vMin.x; if(vFinalMax.y < vMax.y) vFinalMax.y = vMax.y; if(vFinalMin.y > vMin.y) vFinalMin.y = vMin.y; if(vFinalMax.z < vMax.z) vFinalMax.z = vMax.z; if(vFinalMin.z > vMin.z) vFinalMin.z = vMin.z; } mBoundingVolume.SetLocalMinMax(vFinalMin, vFinalMax); }
NewtonCollision* CompoundCollider3D::CreateHandle(PhysWorld3D* world) const { NewtonCollision* compoundCollision = NewtonCreateCompoundCollision(world->GetHandle(), 0); NewtonCompoundCollisionBeginAddRemove(compoundCollision); for (const Collider3DRef& geom : m_geoms) { if (geom->GetType() == ColliderType3D_Compound) { CompoundCollider3D* compoundGeom = static_cast<CompoundCollider3D*>(geom.Get()); for (const Collider3DRef& piece : compoundGeom->GetGeoms()) NewtonCompoundCollisionAddSubCollision(compoundCollision, piece->GetHandle(world)); } else NewtonCompoundCollisionAddSubCollision(compoundCollision, geom->GetHandle(world)); } NewtonCompoundCollisionEndAddRemove(compoundCollision); return compoundCollision; }
NewtonCollision* CreateChassisCollision (NewtonWorld* const world) const { dMatrix offset (dGetIdentityMatrix()); offset.m_posit.m_y = 0.7f; NewtonCollision* const convex0 = NewtonCreateConvexHull (world, 8, &VehicleHullShape0[0][0], 3 * sizeof (dFloat), 0.001f, 0, NULL); NewtonCollision* const convex1 = NewtonCreateConvexHull (world, 8, &VehicleHullShape1[0][0], 3 * sizeof (dFloat), 0.001f, 0, &offset[0][0]); NewtonCollision* const collision = NewtonCreateCompoundCollision(world, 0); NewtonCompoundCollisionBeginAddRemove(collision); NewtonCompoundCollisionAddSubCollision (collision, convex0); NewtonCompoundCollisionAddSubCollision (collision, convex1); NewtonCompoundCollisionEndAddRemove (collision); NewtonDestroyCollision (convex0); NewtonDestroyCollision (convex1); return collision; }
static void AddSingleCompound(DemoEntityManager* const scene) { NewtonWorld* const world = scene->GetNewton(); NewtonCollision* compoundCollision = NewtonCreateCompoundCollision(world, 0); NewtonCompoundCollisionBeginAddRemove(compoundCollision); NewtonCollision* boxCollision = NewtonCreateBox(world, 50, 50, 50, 0, NULL); NewtonCompoundCollisionAddSubCollision(compoundCollision, boxCollision); NewtonDestroyCollision(boxCollision); dMatrix matrix(dGetIdentityMatrix()); matrix.m_posit.m_y = 10.0f; NewtonCompoundCollisionEndAddRemove(compoundCollision); NewtonBody* compoundBody = NewtonCreateDynamicBody(world, compoundCollision, &matrix[0][0]); NewtonDestroyCollision(compoundCollision); // scale after creating body slows everything down. Without the scale it runs fine even though the body is huge NewtonCollisionSetScale(NewtonBodyGetCollision(compoundBody), 0.05f, 0.05f, 0.05f); // adding some visualization NewtonBodySetMassProperties (compoundBody, 1.0f, NewtonBodyGetCollision(compoundBody)); NewtonBodySetTransformCallback(compoundBody, DemoEntity::TransformCallback); NewtonBodySetForceAndTorqueCallback(compoundBody, PhysicsApplyGravityForce); DemoMesh* mesh = new DemoMesh("geometry", NewtonBodyGetCollision(compoundBody), "smilli.tga", "smilli.tga", "smilli.tga"); DemoEntity* const entity = new DemoEntity(matrix, NULL); entity->SetMesh(mesh, dGetIdentityMatrix()); mesh->Release(); NewtonBodySetUserData(compoundBody, entity); scene->Append(entity); NewtonBodySetSimulationState(compoundBody, 0); NewtonBodySetSimulationState(compoundBody, 1); }
void CreateCastingShapes(DemoEntityManager* const scene, dFloat size) { NewtonWorld* const world = scene->GetNewton(); int materialID = NewtonMaterialGetDefaultGroupID(world); dSetRandSeed (0); dVector shapeSize (size, size, size, 0.0f); PrimitiveType castSelection[] = {_SPHERE_PRIMITIVE, _CAPSULE_PRIMITIVE, _BOX_PRIMITIVE, _CYLINDER_PRIMITIVE, _REGULAR_CONVEX_HULL_PRIMITIVE, _CHAMFER_CYLINDER_PRIMITIVE}; m_count = sizeof (castSelection) / sizeof (castSelection[0]); m_castingGeometries = new DemoMesh*[m_count]; m_castingShapeArray = new NewtonCollision*[m_count]; dMatrix alignMatrix (dRollMatrix(3.141592f * 90.0f / 180.0f)); for (int i = 0; i < m_count; i ++) { dVector shapeSize (size + RandomVariable (size / 2.0f), size + RandomVariable (size / 2.0f), size + RandomVariable (size / 2.0f), 0.0f); #if 1 m_castingShapeArray[i] = CreateConvexCollision (world, &alignMatrix[0][0], shapeSize, castSelection[i], materialID); #else m_castingShapeArray[i] = NewtonCreateCompoundCollision (world, materialID); NewtonCompoundCollisionBeginAddRemove(m_castingShapeArray[i]); NewtonCollision* const collision = CreateConvexCollision (world, &alignMatrix[0][0], shapeSize, castSelection[i], materialID); NewtonCompoundCollisionAddSubCollision (m_castingShapeArray[i], collision); NewtonDestroyCollision(collision); NewtonCompoundCollisionEndAddRemove(m_castingShapeArray[i]); #endif m_castingGeometries[i] = new DemoMesh("geometry", m_castingShapeArray[i], "smilli.tga", "smilli.tga", "smilli.tga"); } // make and entity for showing the result of the convex cast dMatrix matrix (dGetIdentityMatrix()); matrix.m_posit.m_y = 2.0f; m_currentCastingShape = 0; m_castingEntity = new DemoEntity (matrix, NULL); m_castingEntity->SetMesh(m_castingGeometries[m_currentCastingShape], dGetIdentityMatrix()); }
NewtonCollision* CreateConvexCollision (NewtonWorld* world, const dMatrix& srcMatrix, const dVector& originalSize, PrimitiveType type, int materialID__) { dVector size (originalSize); NewtonCollision* collision = NULL; switch (type) { case _NULL_PRIMITIVE: { collision = NewtonCreateNull (world); break; } case _SPHERE_PRIMITIVE: { // create the collision collision = NewtonCreateSphere (world, size.m_x * 0.5f, 0, NULL); break; } case _BOX_PRIMITIVE: { // create the collision collision = NewtonCreateBox (world, size.m_x, size.m_y, size.m_z, 0, NULL); break; } case _CONE_PRIMITIVE: { dFloat r = size.m_x * 0.5f; dFloat h = size.m_y; // create the collision collision = NewtonCreateCone (world, r, h, 0, NULL); break; } case _CYLINDER_PRIMITIVE: { // create the collision collision = NewtonCreateCylinder (world, size.m_x * 0.5f, size.m_y, 0, NULL); break; } case _CAPSULE_PRIMITIVE: { // create the collision collision = NewtonCreateCapsule (world, size.m_x * 0.5f, size.m_y, 0, NULL); break; } case _TAPERED_CAPSULE_PRIMITIVE: { // create the collision collision = NewtonCreateTaperedCapsule (world, size.m_x * 0.5f, size.m_z * 0.5f, size.m_y, 0, NULL); break; } case _CHAMFER_CYLINDER_PRIMITIVE: { // create the collision collision = NewtonCreateChamferCylinder (world, size.m_x * 0.5f, size.m_y, 0, NULL); break; } case _TAPERED_CYLINDER_PRIMITIVE: { // create the collision collision = NewtonCreateTaperedCylinder (world, size.m_x * 0.5f, size.m_z * 0.5f, size.m_y, 0, NULL); break; } case _RANDOM_CONVEX_HULL_PRIMITIVE: { // Create a clouds of random point around the origin #define SAMPLE_COUNT 200 dVector cloud [SAMPLE_COUNT]; // make sure that at least the top and bottom are present cloud [0] = dVector ( size.m_x * 0.5f, 0.0f, 0.0f, 0.0f); cloud [1] = dVector (-size.m_x * 0.5f, 0.0f, 0.0f, 0.0f); cloud [2] = dVector ( 0.0f, size.m_y * 0.5f, 0.0f, 0.0f); cloud [3] = dVector ( 0.0f, -size.m_y * 0.5f, 0.0f, 0.0f); cloud [4] = dVector (0.0f, 0.0f, size.m_z * 0.5f, 0.0f); cloud [5] = dVector (0.0f, 0.0f, -size.m_z * 0.5f, 0.0f); int count = 6; // populate the cloud with pseudo Gaussian random points for (int i = 6; i < SAMPLE_COUNT; i ++) { cloud [i].m_x = RandomVariable(size.m_x); cloud [i].m_y = RandomVariable(size.m_y); cloud [i].m_z = RandomVariable(size.m_z); count ++; } collision = NewtonCreateConvexHull (world, count, &cloud[0].m_x, sizeof (dVector), 0.01f, 0, NULL); break; } case _REGULAR_CONVEX_HULL_PRIMITIVE: { // Create a clouds of random point around the origin #define STEPS_HULL 6 //#define STEPS_HULL 3 dVector cloud [STEPS_HULL * 4 + 256]; int count = 0; dFloat radius = size.m_y; dFloat height = size.m_x * 0.999f; dFloat x = - height * 0.5f; dMatrix rotation (dPitchMatrix(2.0f * 3.141592f / STEPS_HULL)); for (int i = 0; i < 4; i ++) { dFloat pad = ((i == 1) || (i == 2)) * 0.25f * radius; dVector p (x, 0.0f, radius + pad); x += 0.3333f * height; dMatrix acc (dGetIdentityMatrix()); for (int j = 0; j < STEPS_HULL; j ++) { cloud[count] = acc.RotateVector(p); acc = acc * rotation; count ++; } } collision = NewtonCreateConvexHull (world, count, &cloud[0].m_x, sizeof (dVector), 0.02f, 0, NULL); break; } case _COMPOUND_CONVEX_CRUZ_PRIMITIVE: { //dMatrix matrix (GetIdentityMatrix()); dMatrix matrix (dPitchMatrix(15.0f * 3.1416f / 180.0f) * dYawMatrix(15.0f * 3.1416f / 180.0f) * dRollMatrix(15.0f * 3.1416f / 180.0f)); // NewtonCollision* const collisionA = NewtonCreateBox (world, size.m_x, size.m_x * 0.25f, size.m_x * 0.25f, 0, &matrix[0][0]); // NewtonCollision* const collisionB = NewtonCreateBox (world, size.m_x * 0.25f, size.m_x, size.m_x * 0.25f, 0, &matrix[0][0]); // NewtonCollision* const collisionC = NewtonCreateBox (world, size.m_x * 0.25f, size.m_x * 0.25f, size.m_x, 0, &matrix[0][0]); matrix.m_posit = dVector (size.m_x * 0.5f, 0.0f, 0.0f, 1.0f); NewtonCollision* const collisionA = NewtonCreateBox (world, size.m_x, size.m_x * 0.25f, size.m_x * 0.25f, 0, &matrix[0][0]); matrix.m_posit = dVector (0.0f, size.m_x * 0.5f, 0.0f, 1.0f); NewtonCollision* const collisionB = NewtonCreateBox (world, size.m_x * 0.25f, size.m_x, size.m_x * 0.25f, 0, &matrix[0][0]); matrix.m_posit = dVector (0.0f, 0.0f, size.m_x * 0.5f, 1.0f); NewtonCollision* const collisionC = NewtonCreateBox (world, size.m_x * 0.25f, size.m_x * 0.25f, size.m_x, 0, &matrix[0][0]); collision = NewtonCreateCompoundCollision (world, 0); NewtonCompoundCollisionBeginAddRemove(collision); NewtonCompoundCollisionAddSubCollision (collision, collisionA); NewtonCompoundCollisionAddSubCollision (collision, collisionB); NewtonCompoundCollisionAddSubCollision (collision, collisionC); NewtonCompoundCollisionEndAddRemove(collision); NewtonDestroyCollision(collisionA); NewtonDestroyCollision(collisionB); NewtonDestroyCollision(collisionC); break; } default: dAssert (0); } dMatrix matrix (srcMatrix); matrix.m_front = matrix.m_front.Scale (1.0f / dSqrt (matrix.m_front % matrix.m_front)); matrix.m_right = matrix.m_front * matrix.m_up; matrix.m_right = matrix.m_right.Scale (1.0f / dSqrt (matrix.m_right % matrix.m_right)); matrix.m_up = matrix.m_right * matrix.m_front; NewtonCollisionSetMatrix(collision, &matrix[0][0]); return collision; }
void CustomPlayerController::Init(dFloat mass, dFloat outerRadius, dFloat innerRadius, dFloat height, dFloat stairStep, const dMatrix& localAxis) { dAssert (stairStep >= 0.0f); dAssert (innerRadius >= 0.0f); dAssert (outerRadius >= innerRadius); dAssert (height >= stairStep); dAssert (localAxis[0].m_w == dFloat (0.0f)); dAssert (localAxis[1].m_w == dFloat (0.0f)); CustomPlayerControllerManager* const manager = (CustomPlayerControllerManager*) GetManager(); NewtonWorld* const world = manager->GetWorld(); SetRestrainingDistance (0.0f); m_outerRadio = outerRadius; m_innerRadio = innerRadius; m_height = height; m_stairStep = stairStep; SetClimbSlope(45.0f * 3.1416f/ 180.0f); m_upVector = localAxis[0]; m_frontVector = localAxis[1]; m_groundPlane = dVector (0.0f, 0.0f, 0.0f, 0.0f); m_groundVelocity = dVector (0.0f, 0.0f, 0.0f, 0.0f); const int steps = 12; dVector convexPoints[2][steps]; // create an inner thin cylinder dFloat shapeHigh = height; dAssert (shapeHigh > 0.0f); dVector p0 (0.0f, m_innerRadio, 0.0f, 0.0f); dVector p1 (shapeHigh, m_innerRadio, 0.0f, 0.0f); for (int i = 0; i < steps; i ++) { dMatrix rotation (dPitchMatrix (i * 2.0f * 3.141592f / steps)); convexPoints[0][i] = localAxis.RotateVector(rotation.RotateVector(p0)); convexPoints[1][i] = localAxis.RotateVector(rotation.RotateVector(p1)); } NewtonCollision* const supportShape = NewtonCreateConvexHull(world, steps * 2, &convexPoints[0][0].m_x, sizeof (dVector), 0.0f, 0, NULL); // create the outer thick cylinder dMatrix outerShapeMatrix (localAxis); dFloat capsuleHigh = m_height - stairStep; dAssert (capsuleHigh > 0.0f); m_sphereCastOrigin = capsuleHigh * 0.5f + stairStep; outerShapeMatrix.m_posit = outerShapeMatrix[0].Scale(m_sphereCastOrigin); outerShapeMatrix.m_posit.m_w = 1.0f; NewtonCollision* const bodyCapsule = NewtonCreateCapsule(world, 0.25f, 0.5f, 0, &outerShapeMatrix[0][0]); NewtonCollisionSetScale(bodyCapsule, capsuleHigh, m_outerRadio * 4.0f, m_outerRadio * 4.0f); // compound collision player controller NewtonCollision* const playerShape = NewtonCreateCompoundCollision(world, 0); NewtonCompoundCollisionBeginAddRemove(playerShape); NewtonCompoundCollisionAddSubCollision (playerShape, supportShape); NewtonCompoundCollisionAddSubCollision (playerShape, bodyCapsule); NewtonCompoundCollisionEndAddRemove (playerShape); // create the kinematic body dMatrix locationMatrix (dGetIdentityMatrix()); m_body = NewtonCreateKinematicBody(world, playerShape, &locationMatrix[0][0]); // players must have weight, otherwise they are infinitely strong when they collide NewtonCollision* const shape = NewtonBodyGetCollision(m_body); NewtonBodySetMassProperties(m_body, mass, shape); // make the body collidable with other dynamics bodies, by default NewtonBodySetCollidable (m_body, true); dFloat castHigh = capsuleHigh * 0.4f; dFloat castRadio = (m_innerRadio * 0.5f > 0.05f) ? m_innerRadio * 0.5f : 0.05f; dVector q0 (0.0f, castRadio, 0.0f, 0.0f); dVector q1 (castHigh, castRadio, 0.0f, 0.0f); for (int i = 0; i < steps; i ++) { dMatrix rotation (dPitchMatrix (i * 2.0f * 3.141592f / steps)); convexPoints[0][i] = localAxis.RotateVector(rotation.RotateVector(q0)); convexPoints[1][i] = localAxis.RotateVector(rotation.RotateVector(q1)); } m_castingShape = NewtonCreateConvexHull(world, steps * 2, &convexPoints[0][0].m_x, sizeof (dVector), 0.0f, 0, NULL); m_supportShape = NewtonCompoundCollisionGetCollisionFromNode (shape, NewtonCompoundCollisionGetNodeByIndex (shape, 0)); m_upperBodyShape = NewtonCompoundCollisionGetCollisionFromNode (shape, NewtonCompoundCollisionGetNodeByIndex (shape, 1)); NewtonDestroyCollision (bodyCapsule); NewtonDestroyCollision (supportShape); NewtonDestroyCollision (playerShape); m_isJumping = false; }
void CustomVehicleController::Init (NewtonCollision* const chassisShape, const dMatrix& vehicleFrame, dFloat mass, const dVector& gravityVector) { m_finalized = false; m_externalContactStatesCount = 0; m_sleepCounter = VEHICLE_SLEEP_COUNTER; m_freeContactList = m_externalContactStatesPoll.GetFirst(); CustomVehicleControllerManager* const manager = (CustomVehicleControllerManager*) GetManager(); NewtonWorld* const world = manager->GetWorld(); // create a compound collision NewtonCollision* const vehShape = NewtonCreateCompoundCollision(world, 0); NewtonCompoundCollisionBeginAddRemove(vehShape); // if the shape is a compound collision ass all the pieces one at a time int shapeType = NewtonCollisionGetType (chassisShape); if (shapeType == SERIALIZE_ID_COMPOUND) { for (void* node = NewtonCompoundCollisionGetFirstNode(chassisShape); node; node = NewtonCompoundCollisionGetNextNode (chassisShape, node)) { NewtonCollision* const subCollision = NewtonCompoundCollisionGetCollisionFromNode(chassisShape, node); NewtonCompoundCollisionAddSubCollision (vehShape, subCollision); } } else { dAssert ((shapeType == SERIALIZE_ID_CONVEXHULL) || (shapeType == SERIALIZE_ID_BOX)); NewtonCompoundCollisionAddSubCollision (vehShape, chassisShape); } NewtonCompoundCollisionEndAddRemove (vehShape); // create the rigid body for this vehicle dMatrix locationMatrix (dGetIdentityMatrix()); m_body = NewtonCreateDynamicBody(world, vehShape, &locationMatrix[0][0]); // set vehicle mass, inertia and center of mass NewtonBodySetMassProperties (m_body, mass, vehShape); // set linear and angular drag to zero dVector drag(0.0f, 0.0f, 0.0f, 0.0f); NewtonBodySetLinearDamping(m_body, 0); NewtonBodySetAngularDamping(m_body, &drag[0]); // destroy the collision help shape NewtonDestroyCollision (vehShape); // initialize vehicle internal components NewtonBodyGetCentreOfMass (m_body, &m_chassisState.m_com[0]); m_chassisState.m_comOffset = dVector (0.0f, 0.0f, 0.0f, 0.0f); m_chassisState.m_gravity = gravityVector; m_chassisState.m_gravityMag = dSqrt (gravityVector % gravityVector); m_chassisState.Init(this, vehicleFrame); // m_stateList.Append(&m_staticWorld); m_stateList.Append(&m_chassisState); // create the normalized size tire shape m_tireCastShape = NewtonCreateChamferCylinder(world, 0.5f, 1.0f, 0, NULL); // initialize all components to empty m_engine = NULL; m_brakes = NULL; m_steering = NULL; m_handBrakes = NULL; SetDryRollingFrictionTorque (100.0f/4.0f); SetAerodynamicsDownforceCoefficient (0.5f * dSqrt (gravityVector % gravityVector), 60.0f * 0.447f); }
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 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); }
dNewtonCollisionCompound::dNewtonCollisionCompound(dNewtonWorld* const world) :dNewtonCollision(world, 0) { NewtonWaitForUpdateToFinish(m_myWorld->m_world); SetShape(NewtonCreateCompoundCollision(m_myWorld->m_world, 0)); }