void dCollisionConeNodeInfo::CalculateInertiaGeometry (dScene* world, dVector& inertia, dVector& centerOfMass) const { NewtonWorld* newton = world->GetNewtonWorld(); NewtonCollision* box = NewtonCreateCylinder(newton, m_radius, m_height, 0, &m_matrix[0][0]); CalculateGeometryProperies (box, inertia, centerOfMass); NewtonReleaseCollision (newton, box); }
NzCylinderGeom::NzCylinderGeom(NzPhysWorld* physWorld, float length, float radius, const NzMatrix4f& transformMatrix) : NzBaseGeom(physWorld), m_length(length), m_radius(radius) { m_collision = NewtonCreateCylinder(physWorld->GetHandle(), radius, length, 0, transformMatrix); }
NewtonCollision* CreateNewtonCylinder (NewtonWorld* world, NewtonEntity *ent, float height, float radius, int shapeId, const glm::mat4& orientation) { // Place the shape origin at the geometrical center of the entity glm::vec3 origin( (ent->maxBox + ent->minBox)*0.5f ); glm::mat4 offset = glm::gtc::matrix_transform::translate(orientation,origin); // now create a collision Box for this entity return NewtonCreateCylinder(world, radius, height, shapeId, &offset[0][0]); }
iPhysicsCollision* iPhysics::createCylinder(float32 radius, float32 height, const iaMatrixf& offset, uint64 worldID) { iPhysicsCollision* result = nullptr; const NewtonWorld* world = static_cast<const NewtonWorld*>(getWorld(worldID)->getNewtonWorld()); if (world != nullptr) { NewtonCollision* collision = NewtonCreateCylinder(static_cast<const NewtonWorld*>(world), radius, height, 0, 0, offset.getData()); result = new iPhysicsCollision(collision, worldID); NewtonCollisionSetUserID(static_cast<const NewtonCollision*>(collision), result->getID()); _collisionsListMutex.lock(); _collisions[result->getID()] = result; _collisionsListMutex.unlock(); } return result; }
void AddRollingBeats (NewtonWorld* nWorld) { dFloat mass; dFloat Ixx; dFloat Iyy; dFloat Izz; NewtonBody* bar; NewtonCollision* collision; dMatrix location (GetIdentityMatrix()); location.m_posit.m_x = 5.0f; location.m_posit.m_y = 2.0f; location.m_posit.m_z = -2.0f; dVector size (10.0f, 0.25f, 0.25f); bar = NULL; // ///////////////////////////////////////////////////////////////////////////////////// // // create a bar and attach it to the world with a hinge with limits // // //////////////////////////////////////////////////////////////////////////////////// { CustomHinge* joint; RenderPrimitive* visualObject; // create the a graphic character (use a visualObject as our body visualObject = new CylinderPrimitive (location, size.m_y, size.m_x); // create a collision primitive to be shared by all links collision = NewtonCreateCylinder (nWorld, size.m_y, size.m_x, NULL); // craete the bar body bar = NewtonCreateBody(nWorld, collision); NewtonReleaseCollision (nWorld, collision); // attach graphic object to the rigid body NewtonBodySetUserData(bar, visualObject); // set a destructor function NewtonBodySetDestructorCallback (bar, PhysicsBodyDestructor); // set the tranform call back function NewtonBodySetTransformCallback (bar, PhysicsSetTransform); // set the force and torque call back funtion NewtonBodySetForceAndTorqueCallback (bar,PhysicsApplyGravityForce); // calculate a acurate momenet of inertia mass = 5.0f; Ixx = 0.7f * mass * (size.m_y * size.m_y + size.m_z * size.m_z) / 12.0f; Iyy = 0.7f * mass * (size.m_x * size.m_x + size.m_z * size.m_z) / 12.0f; Izz = 0.7f * mass * (size.m_x * size.m_x + size.m_y * size.m_y) / 12.0f; // set the mass matrix NewtonBodySetMassMatrix (bar, mass, Ixx, Iyy, Izz); // set the matrix for both the rigid nody and the graphic body NewtonBodySetMatrix (bar, &location[0][0]); PhysicsSetTransform (bar, &location[0][0]); dVector pin (0.0f, 1.0f, 0.0f); dVector pivot (location.m_posit); pivot.m_x -= size.m_x * 0.5f; // connect these two bodies by a ball and sockect joint //joint = NewtonConstraintCreateHinge (nWorld, &pivot.m_x, &pin.m_x, link0, link1); joint = new CustomHinge (pivot, pin, bar, NULL); // no limits //joint->EnableLimits (true); //joint->SetAngleLimis (-30.0f * 3.1416f/180.0f, 30.0f * 3.1416f/180.0f); } { // //////////////////////////////////////////////////////////////////////////////////// // // add a sliding visualObject with limits // NewtonBody* beat; CustomSlider* joint; RenderPrimitive* visualObject; dMatrix beatLocation (location); dVector beatSize (0.5f, 2.0f, 2.0f); beatLocation.m_posit.m_x += size.m_x * 0.25f; // create the a graphic character (use a visualObject as our body visualObject = new BoxPrimitive (beatLocation, beatSize); // create a collision primitive to be shared by all links collision = NewtonCreateBox (nWorld, beatSize.m_x, beatSize.m_y, beatSize.m_z, NULL); beat = NewtonCreateBody(nWorld, collision); NewtonReleaseCollision (nWorld, collision); // attach graphic object to the rigid body NewtonBodySetUserData(beat, visualObject); // set a destyuctor function NewtonBodySetDestructorCallback (beat, PhysicsBodyDestructor); // set the tranform call back function NewtonBodySetTransformCallback (beat, PhysicsSetTransform); // set the force and torque call back funtion NewtonBodySetForceAndTorqueCallback (beat,PhysicsApplyGravityForce); // calculate a acurate momenet of inertia mass = 5.0f; Ixx = 0.7f * mass * (beatSize.m_y * beatSize.m_y + beatSize.m_z * beatSize.m_z) / 12.0f; Iyy = 0.7f * mass * (beatSize.m_x * beatSize.m_x + beatSize.m_z * beatSize.m_z) / 12.0f; Izz = 0.7f * mass * (beatSize.m_x * beatSize.m_x + beatSize.m_y * beatSize.m_y) / 12.0f; // set the mass matrix NewtonBodySetMassMatrix (beat, mass, Ixx, Iyy, Izz); // set the matrix for both the rigid nody and the graphic body NewtonBodySetMatrix (beat, &beatLocation[0][0]); PhysicsSetTransform (beat, &beatLocation[0][0]); // set the pivot relative for the first bar dVector pivot (beatLocation.m_posit); dVector pin (beatLocation.m_front); joint = new CustomSlider (pivot, pin, beat, bar); // claculate the minimum and maximum limit for this joints dFloat minLimits = ((location.m_posit.m_x - beatLocation.m_posit.m_x) - size.m_x * 0.5f); dFloat maxLimits = ((location.m_posit.m_x - beatLocation.m_posit.m_x) + size.m_x * 0.5f); joint->EnableLimits(true); joint->SetLimis (minLimits, maxLimits); } { // //////////////////////////////////////////////////////////////////////////////////// // // add a corkscrew visualObject with limits // // //////////////////////////////////////////////////////////////////////////////////// NewtonBody* beat; CustomCorkScrew* joint; RenderPrimitive* visualObject; dMatrix beatLocation (location); dVector beatSize (0.5f, 1.25f, 1.25f); beatLocation.m_posit.m_x -= size.m_x * 0.25f; // create the a graphic character (use a visualObject as our body //visualObject = new BoxPrimitive (beatLocation, beatSize); visualObject = new ChamferCylinderPrimitive (beatLocation, beatSize.m_y, beatSize.m_x); // create a collision primitive to be shared by all links collision = NewtonCreateChamferCylinder (nWorld, beatSize.m_y, beatSize.m_x, NULL); beat = NewtonCreateBody(nWorld, collision); NewtonReleaseCollision (nWorld, collision); // attach graphic object to the rigid body NewtonBodySetUserData(beat, visualObject); // set a destyuctor function NewtonBodySetDestructorCallback (beat, PhysicsBodyDestructor); // set the tranform call back function NewtonBodySetTransformCallback (beat, PhysicsSetTransform); // set the force and torque call back funtion NewtonBodySetForceAndTorqueCallback (beat,PhysicsApplyGravityForce); // calculate a acurate momenet of inertia mass = 5.0f; Ixx = 0.7f * mass * (beatSize.m_y * beatSize.m_y + beatSize.m_z * beatSize.m_z) / 12.0f; Iyy = 0.7f * mass * (beatSize.m_x * beatSize.m_x + beatSize.m_z * beatSize.m_z) / 12.0f; Izz = 0.7f * mass * (beatSize.m_x * beatSize.m_x + beatSize.m_y * beatSize.m_y) / 12.0f; // set the mass matrix NewtonBodySetMassMatrix (beat, mass, Ixx, Iyy, Izz); // set the matrix for both the rigid nody and the graphic body NewtonBodySetMatrix (beat, &beatLocation[0][0]); PhysicsSetTransform (beat, &beatLocation[0][0]); // set the pivot relative for the first bar dVector pivot (beatLocation.m_posit); dVector pin (beatLocation.m_front); joint = new CustomCorkScrew (pivot, pin, beat, bar); // claculate the minimum and maximum limit for this joints dFloat minLimits = ((location.m_posit.m_x - beatLocation.m_posit.m_x) - size.m_x * 0.5f); dFloat maxLimits = ((location.m_posit.m_x - beatLocation.m_posit.m_x) + size.m_x * 0.5f); joint->EnableLimits(true); joint->SetLimis (minLimits, maxLimits); } { // //////////////////////////////////////////////////////////////////////////////////// // // add a universal joint visualObject with limits // // //////////////////////////////////////////////////////////////////////////////////// NewtonBody* beat; CustomUniversal* joint; RenderPrimitive* visualObject; dMatrix beatLocation (location); dVector beatSize (0.5f, 1.25f, 1.25f); beatLocation.m_posit.m_x -= size.m_x * 0.5f; // create the a graphic character (use a visualObject as our body //visualObject = new BoxPrimitive (beatLocation, beatSize); visualObject = new ChamferCylinderPrimitive (beatLocation, beatSize.m_y, beatSize.m_x); // create a collision primitive to be shared by all links collision = NewtonCreateChamferCylinder (nWorld, beatSize.m_y, beatSize.m_x, NULL); beat = NewtonCreateBody(nWorld, collision); NewtonReleaseCollision (nWorld, collision); // attach graphic object to the rigid body NewtonBodySetUserData(beat, visualObject); // set a destyuctor function NewtonBodySetDestructorCallback (beat, PhysicsBodyDestructor); // set the tranform call back function NewtonBodySetTransformCallback (beat, PhysicsSetTransform); // set the force and torque call back funtion NewtonBodySetForceAndTorqueCallback (beat,PhysicsApplyGravityForce); // calculate a acurate momenet of inertia mass = 5.0f; Ixx = 0.7f * mass * (beatSize.m_y * beatSize.m_y + beatSize.m_z * beatSize.m_z) / 12.0f; Iyy = 0.7f * mass * (beatSize.m_x * beatSize.m_x + beatSize.m_z * beatSize.m_z) / 12.0f; Izz = 0.7f * mass * (beatSize.m_x * beatSize.m_x + beatSize.m_y * beatSize.m_y) / 12.0f; // set the mass matrix NewtonBodySetMassMatrix (beat, mass, Ixx, Iyy, Izz); // set the matrix for both the rigid nody and the graphic body NewtonBodySetMatrix (beat, &beatLocation[0][0]); PhysicsSetTransform (beat, &beatLocation[0][0]); // set the pivot relative for the first bar dVector pivot (beatLocation.m_posit); dVector pin0 (beatLocation.m_front); dVector pin1 (beatLocation.m_up); // tell this joint to destroiy its local private data when destroyed joint = new CustomUniversal (pivot, pin0, pin1, beat, bar); } { // //////////////////////////////////////////////////////////////////////////////////// // // add a universal joint visualObject with limits // // //////////////////////////////////////////////////////////////////////////////////// NewtonBody* beat; CustomUniversal* joint; RenderPrimitive* visualObject; dMatrix beatLocation (location); dVector beatSize (0.5f, 1.25f, 1.25f); beatLocation.m_posit.m_x = size.m_x; // create the a graphic character (use a visualObject as our body //visualObject = new BoxPrimitive (beatLocation, beatSize); visualObject = new ChamferCylinderPrimitive (beatLocation, beatSize.m_y, beatSize.m_x); // create a collision primitive to be shared by all links collision = NewtonCreateChamferCylinder (nWorld, beatSize.m_y, beatSize.m_x, NULL); beat = NewtonCreateBody(nWorld, collision); NewtonReleaseCollision (nWorld, collision); // attach graphic object to the rigid body NewtonBodySetUserData(beat, visualObject); // set a destyuctor function NewtonBodySetDestructorCallback (beat, PhysicsBodyDestructor); // set the tranform call back function NewtonBodySetTransformCallback (beat, PhysicsSetTransform); // set the force and torque call back funtion NewtonBodySetForceAndTorqueCallback (beat,PhysicsApplyGravityForce); // calculate a acurate momenet of inertia mass = 5.0f; Ixx = 0.7f * mass * (beatSize.m_y * beatSize.m_y + beatSize.m_z * beatSize.m_z) / 12.0f; Iyy = 0.7f * mass * (beatSize.m_x * beatSize.m_x + beatSize.m_z * beatSize.m_z) / 12.0f; Izz = 0.7f * mass * (beatSize.m_x * beatSize.m_x + beatSize.m_y * beatSize.m_y) / 12.0f; // set the mass matrix NewtonBodySetMassMatrix (beat, mass, Ixx, Iyy, Izz); // set the matrix for both the rigid nody and the graphic body NewtonBodySetMatrix (beat, &beatLocation[0][0]); PhysicsSetTransform (beat, &beatLocation[0][0]); // set the pivot relative for the first bar dVector pivot (beatLocation.m_posit); dVector pin0 (beatLocation.m_front.Scale(-1.0f)); dVector pin1 (beatLocation.m_up); // tell this joint to destroiy its local private data when destroyed joint = new CustomUniversal (pivot, pin0, pin1, beat, bar); } }
NewtonCollision* CylinderCollider3D::CreateHandle(PhysWorld3D* world) const { return NewtonCreateCylinder(world->GetHandle(), m_radius, m_length, 0, m_matrix); }
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; }
cCollideShapeNewton::cCollideShapeNewton(eCollideShapeType aType, const cVector3f &avSize, cMatrixf* apOffsetMtx, NewtonWorld* apNewtonWorld, iPhysicsWorld *apWorld) : iCollideShape(apWorld) { mpNewtonCollision = NULL; mpNewtonWorld = apNewtonWorld; mvSize = avSize; mType = aType; mfVolume = 0; float *pMtx = NULL; cMatrixf mtxTranspose; if(apOffsetMtx) { m_mtxOffset = *apOffsetMtx; mtxTranspose = m_mtxOffset.GetTranspose(); pMtx = &(mtxTranspose.m[0][0]); } else m_mtxOffset = cMatrixf::Identity; //////////////////////////////////////////// // Create Newton collision switch(aType) { case eCollideShapeType_Null: mpNewtonCollision = NewtonCreateNull(apNewtonWorld); break; case eCollideShapeType_Box: mpNewtonCollision = NewtonCreateBox(apNewtonWorld, mvSize.x, mvSize.y, mvSize.z, pMtx); break; case eCollideShapeType_Sphere: mpNewtonCollision = NewtonCreateSphere(apNewtonWorld, mvSize.x, mvSize.y, mvSize.z, pMtx); break; case eCollideShapeType_Cylinder: mpNewtonCollision = NewtonCreateCylinder(apNewtonWorld, mvSize.x, mvSize.y, pMtx); break; case eCollideShapeType_Capsule: mpNewtonCollision = NewtonCreateCapsule(apNewtonWorld, mvSize.x, mvSize.y, pMtx); break; } //////////////////////////////////////////// // Calculate Bounding volume and volume. if(mType == eCollideShapeType_Box) { mBoundingVolume.SetSize(mvSize); mfVolume = mvSize.x * mvSize.y *mvSize.z; } else if(mType == eCollideShapeType_Sphere) { mBoundingVolume.SetSize(mvSize*2); mfVolume = (4.0f / 3.0f) * kPif * (mvSize.x*mvSize.x*mvSize.x); } else if(mType == eCollideShapeType_Cylinder || mType == eCollideShapeType_Capsule) { mBoundingVolume.SetSize(cVector3f(mvSize.y,mvSize.x*2,mvSize.x*2)); //Not gonna be correct for capsule... if(mType == eCollideShapeType_Cylinder) mfVolume = kPif * (mvSize.x*mvSize.x)*mvSize.y; else { //Height of the cylinder part. float fCylHeight = mvSize.y - (mvSize.x*2); mfVolume =0; //The volume of the cylinder part. if(fCylHeight>0) mfVolume += kPif * (mvSize.x*mvSize.x)*fCylHeight; //The volume of the sphere part. mfVolume += (4.0f / 3.0f) * kPif * (mvSize.x*mvSize.x*mvSize.x); } } mBoundingVolume.SetTransform(m_mtxOffset); }
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); }
dNewtonCollisionCylinder::dNewtonCollisionCylinder(dNewtonWorld* const world, dFloat radio0, dFloat radio1, dFloat height) :dNewtonAlignedShapes(world, 0) { NewtonWaitForUpdateToFinish(m_myWorld->m_world); SetShape(NewtonCreateCylinder(m_myWorld->m_world, radio0, radio1, height, 0, NULL)); }