NewtonBody* CreateRigidBody (NewtonWorld* world, NewtonEntity* ent, NewtonCollision* collision, dFloat mass) { glm::vec3 minBox; glm::vec3 maxBox; glm::vec3 origin; glm::vec3 inertia; NewtonBody* body; glm::mat4 matrix = createMat4(ent->curRotation,ent->curPosition); // Now with the collision Shape we can crate a rigid body body = NewtonCreateBody (world, collision, &matrix[0][0]); // bodies can have a destructor. // this is a function callback that can be used to destroy any local data stored // and that need to be destroyed before the body is destroyed. NewtonBodySetDestructorCallback (body, DestroyBodyCallback); // save the entity as the user data for this body NewtonBodySetUserData (body, ent); ent->body=body; // we need to set the proper center of mass and inertia matrix for this body // the inertia matrix calculated by this function does not include the mass. // therefore it needs to be multiplied by the mass of the body before it is used. NewtonConvexCollisionCalculateInertialMatrix (collision, &inertia[0], &origin[0]); // set the body mass matrix NewtonBodySetMassMatrix (body, mass, mass * inertia.x, mass * inertia.y, mass * inertia.z); // set the body origin NewtonBodySetCentreOfMass (body, &origin[0]); // set the function callback to apply the external forces and torque to the body // the most common force is Gravity NewtonBodySetForceAndTorqueCallback (body, ApplyForceAndTorqueCallback); // set the function callback to set the transformation state of the graphic entity associated with this body // each time the body change position and orientation in the physics world NewtonBodySetTransformCallback (body, SetTransformCallback); return body; }
AdvancePlayerEntity (DemoEntityManager* const scene, CustomPlayerControllerManager* const manager, dFloat radius, dFloat height, const dMatrix& location) :DemoEntity (dGetIdentityMatrix(), NULL) ,m_inputs() ,m_currentTrigger(NULL) ,m_controller(NULL) ,m_currentPlatform(NULL) { // add this entity to the scene for rendering scene->Append(this); // now make a simple player controller, dMatrix playerAxis; playerAxis[0] = dVector (0.0f, 1.0f, 0.0f, 0.0f); // the y axis is the character up vector playerAxis[1] = dVector (1.0f, 0.0f, 0.0f, 0.0f); // the x axis is the character front direction playerAxis[2] = playerAxis[0] * playerAxis[1]; playerAxis[3] = dVector (0.0f, 0.0f, 0.0f, 1.0f); // make the player controller, this function makes a kinematic body m_controller = manager->CreatePlayer(80.0f, radius, radius * 0.5f, height, height * 0.33f, playerAxis); // players by default have the origin at the center of the lower bottom of the collision shape. // you can change this by calling SetPlayerOrigin, for example if a player has it origin at the center of the AABB you can call //m_controller->SetPlayerOrigin (height * 0.5f); // get body from player, and set some parameter NewtonBody* const body = m_controller->GetBody(); // set the user data NewtonBodySetUserData(body, this); // set the transform callback NewtonBodySetTransformCallback (body, DemoEntity::TransformCallback); // set the player matrix NewtonBodySetMatrix(body, &location[0][0]); // create the visual mesh from the player collision shape NewtonCollision* const collision = NewtonBodyGetCollision(body); DemoMesh* const geometry = new DemoMesh("player", collision, "smilli.tga", "smilli.tga", "smilli.tga"); SetMesh(geometry, dGetIdentityMatrix()); geometry->Release(); }
void Car::initPhysics() { NewtonWorld * nWorld = this->controller->getWorld(); NewtonCollision* collision; float mass = 900.0f; vector3df v1 = this->carNode->getBoundingBox().MinEdge; vector3df v2 = this->carNode->getBoundingBox().MaxEdge; dVector minBox(v1.X, v1.Y, v1.Z); dVector maxBox(v2.X, v2.Y, v2.Z); dVector size(maxBox - minBox); dVector origin((maxBox + minBox).Scale(0.5f)); size.m_w = 1.0f; origin.m_w = 1.0f; dMatrix offset(GetIdentityMatrix()); offset.m_posit = origin; collision = NewtonCreateBox(nWorld, size.m_x, size.m_y, size.m_z, 0, &offset[0][0]); dVector inertia; matrix4 m = this->carNode->getRelativeTransformation(); NewtonConvexHullModifierSetMatrix(collision, m.pointer()); NewtonBody * body = NewtonCreateBody(nWorld, collision, m.pointer()); NewtonBodySetUserData(body, this); NewtonConvexCollisionCalculateInertialMatrix(collision, &inertia[0], &origin[0]); NewtonBodySetMassMatrix(body, mass, mass * inertia.m_x, mass * inertia.m_y, mass * inertia.m_z); NewtonBodySetCentreOfMass(body, &origin[0]); NewtonBodySetForceAndTorqueCallback(body, applyCarMoveForce); NewtonBodySetTransformCallback(body, applyCarTransform); int matId = NewtonMaterialGetDefaultGroupID(nWorld); NewtonMaterialSetCollisionCallback(nWorld, matId, matId, this, 0, applyCarCollisionForce); NewtonReleaseCollision(nWorld, collision); this->setCarBodyAndGravity(body, dVector(0,-10,0,0)); this->setLocalCoordinates(this->createChassisMatrix()); }
void Newtonnode::initCube(NewtonWorld *pWorld,const float xlength,const float ylength,const float zlength) { if (pWorld==0) { ion::base::log("Newtonnode::initCube()",ion::base::Error) << "No NewtonWorld pointer given\n"; return; } if ((m_pNewtonCollision!=0) && (m_pNewtonworld!=0)) NewtonReleaseCollision(m_pNewtonworld,m_pNewtonCollision); m_pNewtonworld=pWorld; m_pNewtonCollision=NewtonCreateBox(m_pNewtonworld,xlength,ylength,zlength,0); m_pBody=NewtonCreateBody(m_pNewtonworld,m_pNewtonCollision); NewtonBodySetUserData(m_pBody,this); NewtonBodySetMassMatrix(m_pBody, 1.0f, 1.0f, 1.0f, 1.0f); NewtonReleaseCollision(m_pNewtonworld,m_pNewtonCollision); NewtonBodySetTransformCallback (m_pBody, physicsSetTransform); NewtonBodySetForceAndTorqueCallback (m_pBody, physicsApplyForceAndTorque); }
void NzPhysObject::SetMass(float mass) { if (m_mass > 0.f) { float Ix, Iy, Iz; NewtonBodyGetMassMatrix(m_body, &m_mass, &Ix, &Iy, &Iz); float scale = mass/m_mass; NewtonBodySetMassMatrix(m_body, mass, Ix*scale, Iy*scale, Iz*scale); } else if (mass > 0.f) { NzVector3f inertia, origin; m_geom->ComputeInertialMatrix(&inertia, &origin); NewtonBodySetCentreOfMass(m_body, &origin.x); NewtonBodySetMassMatrix(m_body, mass, inertia.x*mass, inertia.y*mass, inertia.z*mass); NewtonBodySetForceAndTorqueCallback(m_body, &ForceAndTorqueCallback); NewtonBodySetTransformCallback(m_body, &TransformCallback); } m_mass = mass; }
dCustomPlayerController* CreatePlayer(const dMatrix& location, dFloat height, dFloat radius, dFloat mass) { // get the scene DemoEntityManager* const scene = (DemoEntityManager*)NewtonWorldGetUserData(GetWorld()); // set the play coordinate system dMatrix localAxis(dGetIdentityMatrix()); //up is first vector localAxis[0] = dVector(0.0, 1.0f, 0.0f, 0.0f); // up is the second vector localAxis[1] = dVector(1.0, 0.0f, 0.0f, 0.0f); // size if the cross product localAxis[2] = localAxis[0].CrossProduct(localAxis[1]); // make a play controller with default values. dCustomPlayerController* const controller = CreateController(location, localAxis, mass, radius, height, 0.4f); // get body from player, and set some parameter NewtonBody* const body = controller->GetBody(); DemoEntity* const playerEntity = DemoEntity::LoadNGD_mesh("whiteman.ngd", scene->GetNewton(), scene->GetShaderCache()); scene->Append(playerEntity); // set the user data NewtonBodySetUserData(body, playerEntity); // set the transform callback NewtonBodySetTransformCallback(body, DemoEntity::TransformCallback); // save player model with the controller controller->SetUserData(playerEntity); // set higher that 1.0f friction controller->SetFriction(2.0f); //controller->SetFriction(1.0f); return controller; }
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); }
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ bool PhysicsActor::attachBody(pCollisionShape_type _collision) { // valid Newton collision primitives include the following: // Null, Box, Sphere (ovoid), Cone, Capsule, Cylinder, ChamferCylinder, // ConvexHull (not impl yet), CompoundCollision (not impl), // TreeCollision (not impl yet), UserMesh (heightfield) m_pActor = NewtonCreateBody(dynamic_cast<PhysicsZone*>(m_pZone.get())->getZonePtr(), dynamic_cast<CollisionShape*>(_collision.get())->getShapePtr()); NewtonReleaseCollision(dynamic_cast<PhysicsZone*>(m_pZone.get())->getZonePtr(), dynamic_cast<CollisionShape*>(_collision.get())->getShapePtr()); // set the transform call back function NewtonBodySetTransformCallback(m_pActor, TransformCallback); NewtonBodySetForceAndTorqueCallback(m_pActor, ApplyForceAndTorqueCallback); NewtonBodySetAutoactiveCallback(m_pActor, ActivationStateCallback); //NewtonBodySetFreezeTreshold(m_pActor, NewtonBodySetUserData(m_pActor, this); return true; }
static void OnEmitFracturedCompound (NewtonBody* const fracturedCompound) { NewtonWorld* const world = NewtonBodyGetWorld(fracturedCompound); DemoEntityManager* const scene = (DemoEntityManager*)NewtonWorldGetUserData(world); // set the force an torque call back NewtonBodySetForceAndTorqueCallback (fracturedCompound, PhysicsApplyGravityForce); // set the transform callback NewtonBodySetTransformCallback (fracturedCompound, DemoEntity::TransformCallback); // create the visual entity and mesh, and set the use data dMatrix matrix; NewtonBodyGetMatrix (fracturedCompound, &matrix[0][0]); DemoEntity* const visualChunkEntity = new DemoEntity(matrix, NULL); scene->Append(visualChunkEntity); NewtonBodySetUserData (fracturedCompound, visualChunkEntity); // create the mesh geometry and attach it to the entity DemoMesh* const visualChunkMesh = new DemoMesh ("fracturedChuckMesh"); visualChunkEntity->SetMesh (visualChunkMesh, dGetIdentityMatrix()); visualChunkMesh->Release(); // get the fractured compound mesh from the body NewtonCollision* const fracturedCompoundCollision = NewtonBodyGetCollision(fracturedCompound); dAssert (NewtonCollisionGetType(fracturedCompoundCollision) == SERIALIZE_ID_FRACTURED_COMPOUND); // add the vertex data NewtonFracturedCompoundMeshPart* const mainMesh = NewtonFracturedCompoundGetMainMesh (fracturedCompoundCollision); AddMeshVertexwData (visualChunkMesh, mainMesh, fracturedCompoundCollision); // add the mesh indices OnReconstructMainMeshCallBack (fracturedCompound, mainMesh, fracturedCompoundCollision); }
static void AddStructuredFractured (DemoEntityManager* const scene, const dVector& origin, int materialID, const char* const assetName) { // create the shape and visual mesh as a common data to be re used NewtonWorld* const world = scene->GetNewton(); #if 0 // load the mesh asset DemoEntity entity(GetIdentityMatrix(), NULL); entity.LoadNGD_mesh (assetName, world); DemoMesh____* const mesh = entity.GetMesh(); dAssert (mesh); // convert the mesh to a newtonMesh NewtonMesh* const solidMesh = mesh->CreateNewtonMesh (world, entity.GetMeshMatrix() * entity.GetCurrentMatrix()); #else int externalMaterial = LoadTexture("wood_0.tga"); NewtonCollision* const collision = CreateConvexCollision (world, dGetIdentityMatrix(), dVector (3.0f, 3.0f, 3.0f, 0.0), _BOX_PRIMITIVE, 0); NewtonMesh* const solidMesh = NewtonMeshCreateFromCollision(collision); NewtonDestroyCollision(collision); //NewtonMeshTriangulate(solidMesh); NewtonMeshApplyBoxMapping (solidMesh, externalMaterial, externalMaterial, externalMaterial); #endif // create a random point cloud dVector points[MAX_POINT_CLOUD_SIZE]; int pointCount = MakeRandomPoisonPointCloud (solidMesh, points); // int pointCount = MakeRandomGuassianPointCloud (solidMesh, points, MAX_POINT_CLOUD_SIZE); // create and interiors material for texturing the fractured pieces //int internalMaterial = LoadTexture("KAMEN-stup.tga"); int internalMaterial = LoadTexture("concreteBrick.tga"); // crate a texture matrix for uv mapping of fractured pieces dMatrix textureMatrix (dGetIdentityMatrix()); textureMatrix[0][0] = 1.0f / 2.0f; textureMatrix[1][1] = 1.0f / 2.0f; /// create the fractured collision and mesh int debreePhysMaterial = NewtonMaterialGetDefaultGroupID(world); NewtonCollision* structuredFracturedCollision = NewtonCreateFracturedCompoundCollision (world, solidMesh, 0, debreePhysMaterial, pointCount, &points[0][0], sizeof (dVector), internalMaterial, &textureMatrix[0][0], OnReconstructMainMeshCallBack, OnEmitFracturedCompound, OnEmitFracturedChunk); // uncomment this to test serialization #if 0 FILE* file = fopen ("serialize.bin", "wb"); NewtonCollisionSerialize (world, structuredFracturedCollision, DemoEntityManager::SerializeFile, file); NewtonDestroyCollision (structuredFracturedCollision); fclose (file); file = fopen ("serialize.bin", "rb"); structuredFracturedCollision = NewtonCreateCollisionFromSerialization (world, DemoEntityManager::DeserializeFile, file); NewtonFracturedCompoundSetCallbacks (structuredFracturedCollision, OnReconstructMainMeshCallBack, OnEmitFracturedCompound, OnEmitFracturedChunk); fclose (file); #endif #if 0 // test the interface dTree<void*, void*> detachableNodes; NewtonCompoundCollisionBeginAddRemove(structuredFracturedCollision); // remove all chunk that can be detached for the first layer for (void* node = NewtonCompoundCollisionGetFirstNode(structuredFracturedCollision); node; node = NewtonCompoundCollisionGetNextNode(structuredFracturedCollision, node)) { if (NewtonFracturedCompoundIsNodeFreeToDetach (structuredFracturedCollision, node)) { detachableNodes.Insert(node, node); } // remove any node that can be deched fro the secund layer, this codul; be reusive void* neighbors[32]; int count = NewtonFracturedCompoundNeighborNodeList (structuredFracturedCollision, node, neighbors, sizeof (neighbors) / sizeof (neighbors[0])); for (int i = 0; i < count; i ++ ) { if (NewtonFracturedCompoundIsNodeFreeToDetach (structuredFracturedCollision, neighbors[i])) { detachableNodes.Insert(node, node); } } } // now delete the actual nodes dTree<void*, void*>::Iterator iter (detachableNodes) ; for (iter.Begin(); iter; iter ++) { void* const node = iter.GetNode()->GetInfo(); NewtonCompoundCollisionRemoveSubCollision (structuredFracturedCollision, node); } NewtonCompoundCollisionEndAddRemove(structuredFracturedCollision); #endif #if 1 dVector plane (0.0f, 1.0f, 0.0f, 0.0f); NewtonCollision* const crack = NewtonFracturedCompoundPlaneClip (structuredFracturedCollision, &plane[0]); if (crack) { NewtonDestroyCollision (structuredFracturedCollision); } #endif dVector com(0.0f); dVector inertia(0.0f); NewtonConvexCollisionCalculateInertialMatrix (structuredFracturedCollision, &inertia[0], &com[0]); //dFloat mass = 10.0f; //int materialId = 0; //create the rigid body dMatrix matrix (dGetIdentityMatrix()); matrix.m_posit = origin; matrix.m_posit.m_y = 20.0; matrix.m_posit.m_w = 1.0f; NewtonBody* const rigidBody = NewtonCreateDynamicBody (world, structuredFracturedCollision, &matrix[0][0]); // set the mass and center of mass dFloat density = 1.0f; dFloat mass = density * NewtonConvexCollisionCalculateVolume (structuredFracturedCollision); NewtonBodySetMassProperties (rigidBody, mass, structuredFracturedCollision); // set the transform call back function NewtonBodySetTransformCallback (rigidBody, DemoEntity::TransformCallback); // set the force and torque call back function NewtonBodySetForceAndTorqueCallback (rigidBody, PhysicsApplyGravityForce); // create the entity and visual mesh and attach to the body as user data CreateVisualEntity (scene, rigidBody); // assign the wood id // NewtonBodySetMaterialGroupID (rigidBody, materialId); // set a destructor for this rigid body // NewtonBodySetDestructorCallback (rigidBody, PhysicsBodyDestructor); // release the interior texture // ReleaseTexture (internalMaterial); // delete the solid mesh since it no longed needed NewtonMeshDestroy (solidMesh); // destroy the fracture collision NewtonDestroyCollision (structuredFracturedCollision); }
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); } }
void AddDoubleSwingDoors (NewtonWorld* nWorld) { dFloat mass; dFloat Ixx; dFloat Iyy; dFloat Izz; NewtonBody* link0; NewtonBody* link1; CustomHinge* joint; BoxPrimitive* visualObject; NewtonCollision* collision; dVector size (2.0f, 5.0f, 0.5f); // 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; // create 100 tack of 10 boxes each dMatrix location (GetIdentityMatrix()); location.m_posit.m_x = -2.0f; location.m_posit.m_y = 3.0f; location.m_posit.m_z = -2.0f; // create a collision primitive to be shared by all links collision = NewtonCreateBox (nWorld, size.m_x, size.m_y, size.m_z, NULL); // make first wing { // create the a graphic character (use a visualObject as our body visualObject = new BoxPrimitive (location, size); //create the rigid body link1 = NewtonCreateBody (nWorld, collision); // Set Material Id for this object NewtonBodySetMaterialGroupID (link1, woodID); // save the pointer to the graphic object with the body. NewtonBodySetUserData (link1, visualObject); // set a destrutor for this rigid body NewtonBodySetDestructorCallback (link1, PhysicsBodyDestructor); // set the tranform call back function NewtonBodySetTransformCallback (link1, PhysicsSetTransform); // set the force and torque call back funtion NewtonBodySetForceAndTorqueCallback (link1,PhysicsApplyGravityForce); // set the mass matrix NewtonBodySetMassMatrix (link1, mass, Ixx, Iyy, Izz); // set the matrix for tboth the rigid nody and the graphic body NewtonBodySetMatrix (link1, &location[0][0]); PhysicsSetTransform (link1, &location[0][0]); dVector pivot (location.m_posit); dVector pin (location.m_up); pivot.m_x += size.m_x * 0.5f; // connect these two bodies by a ball and sockect joint joint = new CustomHinge (pivot, pin, link1, NULL); joint->EnableLimits (true); joint->SetLimis (-30.0f * 3.1416f/180.0f, 30.0f * 3.1416f/180.0f); } // make second wing { location.m_posit.m_x -= size.m_x; // create the a graphic character (use a visualObject as our body visualObject = new BoxPrimitive (location, size); //create the rigid body link0 = NewtonCreateBody (nWorld, collision); // Set Material Id for this object NewtonBodySetMaterialGroupID (link0, woodID); // save the pointer to the graphic object with the body. NewtonBodySetUserData (link0, visualObject); // set a destrutor for this rigid body NewtonBodySetDestructorCallback (link0, PhysicsBodyDestructor); // set the tranform call back function NewtonBodySetTransformCallback (link0, PhysicsSetTransform); // set the force and torque call back funtion NewtonBodySetForceAndTorqueCallback (link0,PhysicsApplyGravityForce); // set the mass matrix NewtonBodySetMassMatrix (link0, mass, Ixx, Iyy, Izz); // set the matrix for tboth the rigid nody and the graphic body NewtonBodySetMatrix (link0, &location[0][0]); PhysicsSetTransform (link0, &location[0][0]); dVector pivot (location.m_posit); dVector pin (location.m_up); 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, link0, link1); joint->EnableLimits (true); joint->SetLimis (-30.0f * 3.1416f/180.0f, 30.0f * 3.1416f/180.0f); } // release the collision geometry when not need it NewtonReleaseCollision (nWorld, collision); }
// create a rope of boxes void AddRope (NewtonWorld* nWorld) { int i; dFloat mass; dFloat Ixx; dFloat Iyy; dFloat Izz; NewtonBody* link0; NewtonBody* link1; NewtonCustomJoint* joint; NewtonCollision* collision; RenderPrimitive* visualObject; dVector size (2.0f, 0.25f, 0.25f); // calculate a acurate momenet of inertia mass = 2.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; // create 100 tack of 10 boxes each //dMatrix location (GetIdentityMatrix()); dMatrix location (dgRollMatrix(3.1426f * 0.5f)); location.m_posit.m_y = 11.5f; location.m_posit.m_z = -5.0f; // create a collision primitive to be shared by all links collision = NewtonCreateCapsule (nWorld, size.m_y, size.m_x, NULL); link0 = NULL; // create a lon vertical rope with limits for (i = 0; i < 7; i ++) { // create the a graphic character (use a visualObject as our body visualObject = new CapsulePrimitive (location, size.m_y, size.m_x); //create the rigid body link1 = NewtonCreateBody (nWorld, collision); // add some damping to each link NewtonBodySetLinearDamping (link1, 0.2f); dVector angularDamp (0.2f, 0.2f, 0.2f); NewtonBodySetAngularDamping (link1, &angularDamp.m_x); // Set Material Id for this object NewtonBodySetMaterialGroupID (link1, woodID); // save the pointer to the graphic object with the body. NewtonBodySetUserData (link1, visualObject); // set a destrutor for this rigid body NewtonBodySetDestructorCallback (link1, PhysicsBodyDestructor); // set the tranform call back function NewtonBodySetTransformCallback (link1, PhysicsSetTransform); // set the force and torque call back funtion NewtonBodySetForceAndTorqueCallback (link1,PhysicsApplyGravityForce); // set the mass matrix NewtonBodySetMassMatrix (link1, mass, Ixx, Iyy, Izz); // set the matrix for tboth the rigid nody and the graphic body NewtonBodySetMatrix (link1, &location[0][0]); PhysicsSetTransform (link1, &location[0][0]); dVector pivot (location.m_posit); pivot.m_y += (size.m_x - size.m_y) * 0.5f; dFloat coneAngle = 2.0 * 3.1416f / 180.0f; dFloat twistAngle = 2.0 * 3.1416f / 180.0f; dVector pin (location.m_front.Scale (-1.0f)); joint = new CustomConeLimitedBallAndSocket(twistAngle, coneAngle, pin, pivot, link1, link0); link0 = link1; location.m_posit.m_y -= (size.m_x - size.m_y); } // vrete a short horizontal rope with limits location = GetIdentityMatrix(); location.m_posit.m_y = 2.5f; location.m_posit.m_z = -7.0f; link0 = NULL; for (i = 0; i < 3; i ++) { // create the a graphic character (use a visualObject as our body visualObject = new CapsulePrimitive (location, size.m_y, size.m_x); //create the rigid body link1 = NewtonCreateBody (nWorld, collision); // add some damping to each link NewtonBodySetLinearDamping (link1, 0.2f); dVector angularDamp (0.2f, 0.2f, 0.2f); NewtonBodySetAngularDamping (link1, &angularDamp.m_x); // Set Material Id for this object NewtonBodySetMaterialGroupID (link1, woodID); // save the pointer to the graphic object with the body. NewtonBodySetUserData (link1, visualObject); // make sure it is active NewtonWorldUnfreezeBody (nWorld, link1); //NewtonBodySetAutoFreeze (link1, 0); // set a destrutor for this rigid body NewtonBodySetDestructorCallback (link1, PhysicsBodyDestructor); // set the tranform call back function NewtonBodySetTransformCallback (link1, PhysicsSetTransform); // set the force and torque call back funtion NewtonBodySetForceAndTorqueCallback (link1,PhysicsApplyGravityForce); // set the mass matrix NewtonBodySetMassMatrix (link1, mass, Ixx, Iyy, Izz); // set the matrix for tboth the rigid nody and the graphic body NewtonBodySetMatrix (link1, &location[0][0]); PhysicsSetTransform (link1, &location[0][0]); dVector pivot (location.m_posit); pivot.m_x += (size.m_x - size.m_y) * 0.5f; dFloat coneAngle = 10.0 * 3.1416f / 180.0f; dFloat twistAngle = 10.0 * 3.1416f / 180.0f; dVector pin (location.m_front.Scale (-1.0f)); joint = new CustomConeLimitedBallAndSocket(twistAngle, coneAngle, pin, pivot, link1, link0); link0 = link1; location.m_posit.m_x -= (size.m_x - size.m_y); } // release the collision geometry when not need it NewtonReleaseCollision (nWorld, collision); }
// create physics scene void InitScene() { BoxPrimitive* box; BoxPrimitive* floor; NewtonBody* boxBody; NewtonBody* floorBody; NewtonCollision* collision; // create the newton world nWorld = NewtonCreate (PhysicsAlloc, PhysicsFree); // set the linear solver model for faster speed NewtonSetSolverModel (nWorld, 8); // set the adpative friction model for faster speed NewtonSetFrictionModel (nWorld, 1); // Set the termination function atexit(CleanUp); // create the the floor graphic objects dVector size (100.0f, 2.0f, 100.0f); dMatrix location (GetIdentityMatrix()); location.m_posit.m_y = -5.0f; // create a box for floor floor = new BoxPrimitive (location, size, g_floorTexture); // create the the floor collision, and body with default values collision = NewtonCreateBox (nWorld, size.m_x, size.m_y, size.m_z, NULL); floorBody = NewtonCreateBody (nWorld, collision); NewtonReleaseCollision (nWorld, collision); // set the transformation for this rigid body NewtonBodySetMatrix (floorBody, &location[0][0]); // save the pointer to the graphic object with the body. NewtonBodySetUserData (floorBody, floor); // set a destrutor for this rigid body NewtonBodySetDestructorCallback (floorBody, PhysicsBodyDestructor); // set the initial size size = dVector(0.5f, 0.5f, 0.5f); // create the collision collision = NewtonCreateBox (nWorld, size.m_x, size.m_y, size.m_z, NULL); // create 100 stacks of 10 boxes each location.m_posit.m_x = -10.0f; for (int k = 0; k < 10; k ++) { location.m_posit.m_z = 0.0f; for (int j = 0; j < 10; j ++) { location.m_posit.m_y = 2.0f; for (int i = 0; i < 10; i ++) { // create a graphic box box = new BoxPrimitive (location, size); //create the rigid body boxBody = NewtonCreateBody (nWorld, collision); // save the pointer to the graphic object with the body. NewtonBodySetUserData (boxBody, box); // set a destrutor for this rigid body NewtonBodySetDestructorCallback (boxBody, PhysicsBodyDestructor); // set the tranform call back function NewtonBodySetTransformCallback (boxBody, PhysicsSetTransform); // set the force and torque call back funtion NewtonBodySetForceAndTorqueCallback (boxBody, PhysicsApplyForceAndTorque); // set the mass matrix //NewtonBodySetMassMatrix (boxBody, 1.0f, 1.0f / 6.0f, 1.0f / 6.0f, 1.0f / 6.0f); NewtonBodySetMassMatrix (boxBody, 1.0f, 1.0f, 1.0f, 1.0f); // set the matrix for tboth the rigid nody and the graphic body NewtonBodySetMatrix (boxBody, &location[0][0]); PhysicsSetTransform (boxBody, &location[0][0]); location.m_posit.m_y += size.m_y * 2.0f; } location.m_posit.m_z -= size.m_z * 4.0f; } location.m_posit.m_x += size.m_x * 4.0f; } // release the collsion geometry when not need it NewtonReleaseCollision (nWorld, collision); }
BasicCarEntity (DemoEntityManager* const scene, CustomVehicleControllerManager* const manager, const dMatrix& location, const BasciCarParameters& parameters) :DemoEntity (dGetIdentityMatrix(), NULL) ,m_tireaLigmentMatrix (dYawMatrix(3.141592f * 90.0f / 180.0f)) ,m_controller(NULL) ,m_helpKey (true) ,m_gearUpKey (false) ,m_gearDownKey (false) ,m_reverseGear (false) ,m_engineKeySwitch(false) ,m_automaticTransmission(true) ,m_engineKeySwitchCounter(0) ,m_engineOldKeyState(false) ,m_engineRPMOn(false) { // add this entity to the scene for rendering scene->Append(this); // place entity in the world ResetMatrix (*scene, location); NewtonWorld* const world = scene->GetNewton(); // create the vehicle collision shape NewtonCollision* const chassisCollision = CreateChassisCollision (world); // caret the visual mesh form the collision shape DemoMesh* const visualMesh = new DemoMesh ("vehicle chassis", chassisCollision, "metal_30.tga", "metal_30.tga", "metal_30.tga"); SetMesh (visualMesh, dGetIdentityMatrix()); visualMesh->Release(); // create the coordinate system dMatrix chassisMatrix; chassisMatrix.m_front = dVector (1.0f, 0.0f, 0.0f, 0.0f); // this is the vehicle direction of travel chassisMatrix.m_up = dVector (0.0f, 1.0f, 0.0f, 0.0f); // this is the downward vehicle direction chassisMatrix.m_right = chassisMatrix.m_front * chassisMatrix.m_up; // this is in the side vehicle direction (the plane of the wheels) chassisMatrix.m_posit = dVector (0.0f, 0.0f, 0.0f, 1.0f); // create a default vehicle controller m_controller = manager->CreateVehicle (chassisCollision, chassisMatrix, parameters.MASS, dVector (0.0f, DEMO_GRAVITY, 0.0f, 0.0f)); // get body the vehicle rigid body and set the Newton rigid body physics properties NewtonBody* const body = m_controller->GetBody(); // set the user data NewtonBodySetUserData(body, this); // set the transform callback NewtonBodySetTransformCallback (body, DemoEntity::TransformCallback); // set the standard force and torque call back NewtonBodySetForceAndTorqueCallback(body, PhysicsApplyGravityForce); // set the player matrix NewtonBodySetMatrix(body, &location[0][0]); // destroy the collision helper shape NewtonDestroyCollision(chassisCollision); // map the gear to a look up table: gear 0 is reverse, gea 1 is neutral, gear 1 is first, gear 2 is second and so on for (int i = 0; i < int ((sizeof (m_gearMap) / sizeof (m_gearMap[0]))); i ++) { m_gearMap[i] = i; } m_gearMap[0] = 1; m_gearMap[1] = 0; }
void SimulationPostListener(DemoEntityManager* const scene, DemoEntityManager::dListNode* const mynode, dFloat timeStep) { // see if the net force on the body comes fr a high impact collision dFloat breakImpact = 0.0f; for (NewtonJoint* joint = NewtonBodyGetFirstContactJoint(m_myBody); joint; joint = NewtonBodyGetNextContactJoint(m_myBody, joint)) { for (void* contact = NewtonContactJointGetFirstContact(joint); contact; contact = NewtonContactJointGetNextContact(joint, contact)) { dVector contactForce; NewtonMaterial* const material = NewtonContactGetMaterial(contact); dFloat impulseImpact = NewtonMaterialGetContactMaxNormalImpact(material); if (impulseImpact > breakImpact) { breakImpact = impulseImpact; } } } // if the force is bigger than N time Gravities, It is considered a collision force breakImpact *= m_myMassInverse; // breakImpact = 1000.0f; if (breakImpact > BREAK_IMPACT_IN_METERS_PER_SECONDS) { NewtonWorld* const world = NewtonBodyGetWorld(m_myBody); dMatrix bodyMatrix; dVector com(0.0f); dVector veloc(0.0f); dVector omega(0.0f); dFloat Ixx; dFloat Iyy; dFloat Izz; dFloat mass; NewtonBodyGetVelocity(m_myBody, &veloc[0]); NewtonBodyGetOmega(m_myBody, &omega[0]); NewtonBodyGetCentreOfMass(m_myBody, &com[0]); NewtonBodyGetMatrix(m_myBody, &bodyMatrix[0][0]); NewtonBodyGetMass(m_myBody, &mass, &Ixx, &Iyy, &Izz); com = bodyMatrix.TransformVector(com); dMatrix matrix(GetCurrentMatrix()); dQuaternion rotation(matrix); // we need to lock the world before creation a bunch of bodies scene->Lock(m_lock); for (FractureEffect::dListNode* node = m_effect.GetFirst(); node; node = node->GetNext()) { FractureAtom& atom = node->GetInfo(); DemoEntity* const entity = new DemoEntity(dMatrix(rotation, matrix.m_posit), NULL); entity->SetMesh(atom.m_mesh, dGetIdentityMatrix()); scene->Append(entity); int materialId = 0; dFloat debriMass = mass * atom.m_massFraction; //create the rigid body NewtonBody* const rigidBody = NewtonCreateDynamicBody(world, atom.m_collision, &matrix[0][0]); // calculate debris initial velocity dVector center(matrix.TransformVector(atom.m_centerOfMass)); dVector v(veloc + omega.CrossProduct(center - com)); // set initial velocity NewtonBodySetVelocity(rigidBody, &v[0]); NewtonBodySetOmega(rigidBody, &omega[0]); // set the debris mass properties, mass, center of mass, and inertia NewtonBodySetMassProperties(rigidBody, debriMass, atom.m_collision); // save the pointer to the graphic object with the body. NewtonBodySetUserData(rigidBody, entity); // assign the wood id NewtonBodySetMaterialGroupID(rigidBody, materialId); // set continuous collision mode // NewtonBodySetContinuousCollisionMode (rigidBody, continueCollisionMode); // set a destructor for this rigid body NewtonBodySetDestructorCallback(rigidBody, PhysicsBodyDestructor); // set the transform call back function NewtonBodySetTransformCallback(rigidBody, DemoEntity::TransformCallback); // set the force and torque call back function NewtonBodySetForceAndTorqueCallback(rigidBody, PhysicsApplyGravityForce); } NewtonDestroyBody(m_myBody); scene->RemoveEntity(mynode); // unlock the work after done with the effect scene->Unlock(m_lock); } }
Car::Car(const ion::base::String& identifier,NewtonWorld *pWorld,const ion::video::Mesh& srcmesh,const float mass, const float Ixx,const float Iyy,const float Izz):Node(identifier),m_pNewtonChassisCollision(0),m_pBody(0), m_pNewtonworld(pWorld),m_pNewtonJoint(0) { if (pWorld==0) { ion::base::log("Car::Car()",ion::base::Error) << "No NewtonWorld pointer given\n"; return; } if (!srcmesh.isValid()) { ion::base::log("Car::Car()",ion::base::Error) << "Source mesh is invalid\n"; return; } if (!srcmesh.vertexstream().isMapped()) { ion::base::log("Car::Car()",ion::base::Error) << "source mesh \"" << srcmesh.objIdentifier() << " is not mapped!\n"; return; } if ((m_pNewtonChassisCollision!=0) && (m_pNewtonworld!=0)) NewtonReleaseCollision(m_pNewtonworld,m_pNewtonChassisCollision); float *pPoints; { pPoints=new float[3*srcmesh.vertexstream().capacity()]; for (ion_uint32 v=0;v<srcmesh.vertexstream().capacity();++v) { const ion::math::Vector3f &rV=srcmesh.vertexstream().position(v); pPoints[v*3+0]=rV.x(); pPoints[v*3+1]=rV.y(); pPoints[v*3+2]=rV.z(); } } ion::math::Matrix4f c; m_pNewtonworld=pWorld; m_pNewtonChassisCollision=NewtonCreateConvexHull(m_pNewtonworld,srcmesh.vertexstream().capacity(),pPoints,12,c); m_pBody=NewtonCreateBody(m_pNewtonworld,m_pNewtonChassisCollision); NewtonBodySetUserData(m_pBody,this); ion::math::Vector3f origin,inertia; // calculate the moment of inertia and the relative center of mass of the solid NewtonConvexCollisionCalculateInertialMatrix (m_pNewtonChassisCollision, &inertia[0], &origin[0]); float ixx = mass * inertia[0]; float iyy = mass * inertia[1]; float izz = mass * inertia[2]; // set the mass matrix NewtonBodySetMassMatrix (m_pBody, mass, ixx, iyy, izz); origin.y()=-1; NewtonBodySetCentreOfMass (m_pBody, &origin[0]); NewtonBodySetMatrix(m_pBody,localTransform().matrix()); NewtonReleaseCollision(m_pNewtonworld,m_pNewtonChassisCollision); NewtonBodySetTransformCallback (m_pBody, physicsSetTransform); NewtonBodySetForceAndTorqueCallback (m_pBody, physicsApplyForceAndTorque); float updir[3]={0,1,0}; m_pNewtonJoint=NewtonConstraintCreateVehicle(m_pNewtonworld,&updir[0],m_pBody); NewtonVehicleSetTireCallback(m_pNewtonJoint,tireUpdate); delete [] pPoints; }
void SimulationLister(DemoEntityManager* const scene, DemoEntityManager::dListNode* const mynode, dFloat timeStep) { m_delay --; if (m_delay > 0) { return; } // see if the net force on the body comes fr a high impact collision dFloat maxInternalForce = 0.0f; for (NewtonJoint* joint = NewtonBodyGetFirstContactJoint(m_myBody); joint; joint = NewtonBodyGetNextContactJoint(m_myBody, joint)) { for (void* contact = NewtonContactJointGetFirstContact (joint); contact; contact = NewtonContactJointGetNextContact (joint, contact)) { //dVector point; //dVector normal; dVector contactForce; NewtonMaterial* const material = NewtonContactGetMaterial (contact); //NewtonMaterialGetContactPositionAndNormal (material, &point.m_x, &normal.m_x); NewtonMaterialGetContactForce(material, m_myBody, &contactForce[0]); dFloat forceMag = contactForce % contactForce; if (forceMag > maxInternalForce) { maxInternalForce = forceMag; } } } // if the force is bigger than 4 Gravities, It is considered a collision force dFloat maxForce = BREAK_FORCE_IN_GRAVITIES * m_myweight; if (maxInternalForce > (maxForce * maxForce)) { NewtonWorld* const world = NewtonBodyGetWorld(m_myBody); dFloat Ixx; dFloat Iyy; dFloat Izz; dFloat mass; NewtonBodyGetMassMatrix(m_myBody, &mass, &Ixx, &Iyy, &Izz); dVector com; dVector veloc; dVector omega; dMatrix bodyMatrix; NewtonBodyGetVelocity(m_myBody, &veloc[0]); NewtonBodyGetOmega(m_myBody, &omega[0]); NewtonBodyGetCentreOfMass(m_myBody, &com[0]); NewtonBodyGetMatrix(m_myBody, &bodyMatrix[0][0]); com = bodyMatrix.TransformVector (com); dMatrix matrix (GetCurrentMatrix()); dQuaternion rotation (matrix); for (ShatterEffect::dListNode* node = m_effect.GetFirst(); node; node = node->GetNext()) { ShatterAtom& atom = node->GetInfo(); DemoEntity* const entity = new DemoEntity (NULL); entity->SetMesh (atom.m_mesh); entity->SetMatrix(*scene, rotation, matrix.m_posit); entity->InterpolateMatrix (*scene, 1.0f); scene->Append(entity); int materialId = 0; dFloat debriMass = mass * atom.m_massFraction; dFloat Ixx = debriMass * atom.m_momentOfInirtia.m_x; dFloat Iyy = debriMass * atom.m_momentOfInirtia.m_y; dFloat Izz = debriMass * atom.m_momentOfInirtia.m_z; //create the rigid body NewtonBody* const rigidBody = NewtonCreateBody (world, atom.m_collision, &matrix[0][0]); // set the correct center of gravity for this body NewtonBodySetCentreOfMass (rigidBody, &atom.m_centerOfMass[0]); // calculate the center of mas of the debris dVector center (matrix.TransformVector(atom.m_centerOfMass)); // calculate debris initial velocity dVector v (veloc + omega * (center - com)); // set initial velocity NewtonBodySetVelocity(rigidBody, &v[0]); NewtonBodySetOmega(rigidBody, &omega[0]); // set the debrie center of mass NewtonBodySetCentreOfMass (rigidBody, &atom.m_centerOfMass[0]); // set the mass matrix NewtonBodySetMassMatrix (rigidBody, debriMass, Ixx, Iyy, Izz); // activate // NewtonBodyCoriolisForcesMode (blockBoxBody, 1); // save the pointer to the graphic object with the body. NewtonBodySetUserData (rigidBody, entity); // assign the wood id NewtonBodySetMaterialGroupID (rigidBody, materialId); // set continue collision mode // NewtonBodySetContinuousCollisionMode (rigidBody, continueCollisionMode); // set a destructor for this rigid body NewtonBodySetDestructorCallback (rigidBody, PhysicsBodyDestructor); // set the transform call back function NewtonBodySetTransformCallback (rigidBody, DemoEntity::SetTransformCallback); // set the force and torque call back function NewtonBodySetForceAndTorqueCallback (rigidBody, PhysicsApplyGravityForce); } NewtonDestroyBody(world, m_myBody); scene->RemoveEntity (mynode); } };
void CreateScene (NewtonWorld* world, SceneManager* sceneManager) { Entity* floor; NewtonBody* floorBody; NewtonCollision* shape; /* void* materialManager; SoundManager* sndManager; PhysicsMaterialInteration matInterations; sndManager = sceneManager->GetSoundManager(); // Create the material for this scene, and attach it to the Newton World materialManager = CreateMaterialManager (world, sndManager); // add the Material table matInterations.m_restitution = 0.6f; matInterations.m_staticFriction = 0.6f; matInterations.m_kineticFriction = 0.3f; matInterations.m_scrapingSound = NULL; matInterations.m_impactSound = sndManager->LoadSound ("metalMetal.wav"); AddMaterilInteraction (materialManager, m_metal, m_metal, &matInterations); matInterations.m_impactSound = sndManager->LoadSound ("boxBox.wav"); AddMaterilInteraction (materialManager, m_wood, m_wood, &matInterations); matInterations.m_impactSound = sndManager->LoadSound ("metalBox.wav"); AddMaterilInteraction (materialManager, m_metal, m_wood, &matInterations); matInterations.m_impactSound = sndManager->LoadSound ("grass0.wav"); AddMaterilInteraction (materialManager, m_wood, m_grass, &matInterations); matInterations.m_impactSound = sndManager->LoadSound ("boxHit.wav"); AddMaterilInteraction (materialManager, m_wood, m_bricks, &matInterations); matInterations.m_impactSound = sndManager->LoadSound ("grass1.wav"); AddMaterilInteraction (materialManager, m_metal, m_grass, &matInterations); matInterations.m_impactSound = sndManager->LoadSound ("metal.wav"); AddMaterilInteraction (materialManager, m_metal, m_bricks, &matInterations); */ // Create a large body to be the floor floor = sceneManager->CreateEntity(); int materialMap[] = {m_bricks, m_grass, m_wood, m_metal}; #ifdef USE_HEIGHT_FIELD_LEVEL // add scene collision from a level m*esh shape = CreateHeightFieldCollision (world, "h2.raw", materialMap); floorBody = CreateRigidBody (world, floor, shape, 0.0f); NewtonDestroyCollision(shape); // make a visual mesh for the collision data CreateHeightFieldMesh (shape, floor); // set the matrix at the origin dVector boxP0; dVector boxP1; dMatrix matrix (floor->m_curRotation, floor->m_curPosition); NewtonCollisionCalculateAABB (shape, &matrix[0][0], &boxP0.m_x, &boxP1.m_x); // place the origin of the visual mesh at the center of the height field matrix.m_posit = (boxP0 + boxP1).Scale (-0.5f); matrix.m_posit.m_w = 1.0f; floor->m_curPosition = matrix.m_posit; floor->m_prevPosition = matrix.m_posit; // relocate the body; NewtonBodySetMatrix (floorBody, &matrix[0][0]); #else floor->LoadMesh ("LevelMesh.dat"); // add static floor Physics shape = CreateMeshCollision (world, floor, materialMap); floorBody = CreateRigidBody (world, floor, shape, 0.0f); NewtonDestroyCollision(shape); // set the Transformation Matrix for this rigid body dMatrix matrix (floor->m_curRotation, floor->m_curPosition); NewtonBodySetMatrix (floorBody, &matrix[0][0]); #endif // now we will use the properties of this body to set a proper world size. dVector minBox; dVector maxBox; NewtonCollisionCalculateAABB (shape, &matrix[0][0], &minBox[0], &maxBox[0]); // add some extra padding minBox.m_x -= 50.0f; minBox.m_y -= 500.0f; minBox.m_z -= 50.0f; maxBox.m_x += 50.0f; maxBox.m_y += 500.0f; maxBox.m_z += 50.0f; // set the new world size NewtonSetWorldSize (world, &minBox[0], &maxBox[0]); // Create a Body and attach a player controller joint { dFloat y0; Entity* player; NewtonBody* playerBody; NewtonCollision* shape; // find the a floor to place the player y0 = FindFloor (world, 0.0f, 0.0f) + 1.0f; // load the player mesh player = sceneManager->CreateEntity(); player->LoadMesh ("gymnast.dat"); player->m_curPosition.m_y = y0; player->m_prevPosition = player->m_curPosition; // get the bounding Box of the player to get the collision shape dimensions dVector minBox; dVector maxBox; player->GetBBox (minBox, maxBox); // calculate player high and width dFloat padding = 1.0f / 64.0f; // this si the default padding, for teh palye joint, we must subtract it from the shape dFloat playerHigh = (maxBox.m_y - minBox.m_y) - padding; dFloat playerRadius0 = (maxBox.m_z - minBox.m_z) * 0.5f; dFloat playerRadius1 = (maxBox.m_x - minBox.m_x) * 0.5f; dFloat playerRadius = (playerRadius0 > playerRadius1 ? playerRadius0 : playerRadius1) - padding; // No we make and make a upright capsule for the collision mesh dMatrix orientation; orientation.m_front = dVector (0.0f, 1.0f, 0.0f, 0.0f); // this is the player up direction orientation.m_up = dVector (1.0f, 0.0f, 0.0f, 0.0f); // this is the player front direction orientation.m_right = orientation.m_front * orientation.m_up; // this is the player sideway direction orientation.m_posit = dVector (0.0f, 0.0f, 0.0f, 1.0f); // add a body with a box shape //shape = CreateNewtonCapsule (world, player, playerHigh, playerRadius, m_wood, orientation); shape = CreateNewtonCylinder (world, player, playerHigh, playerRadius, m_wood, orientation); playerBody = CreateRigidBody (world, player, shape, 10.0f); NewtonDestroyCollision(shape); // make sure the player does not go to sleep NewtonBodySetAutoSleep (playerBody, 0); // now we will attach a player controller to the body NewtonUserJoint* playerController; // the player can take step up to 0.7 units; dFloat maxStairStepFactor = 0.7f / playerHigh; playerController = CreateCustomPlayerController (&orientation[0][0], playerBody, maxStairStepFactor, padding); // set the Max Slope the player can climb to PLAYER_MAX_SLOPE degree CustomPlayerControllerSetMaxSlope (playerController, PLAYER_MAX_SLOPE * 3.1416f / 180.0f); // now we will append some application data for the application to control the player PlayerController* userControl = (PlayerController*) malloc (sizeof (PlayerController)); userControl->m_isThirdView = 1; userControl->m_point = dVector (0.0f, playerHigh, 0.0f,0.0f); // set the user data for the application to control the player CustomSetUserData (playerController, userControl); // set the destruction call back so that the application can destroy local used data CustomSetDestructorCallback (playerController, PlayerController::Destroy); // set a call back to control the player CustomSetSubmitContraintCallback (playerController, PlayerController::ApplyPlayerInput); // we also need to set override the transform call back so the we can set the Camera userControl->m_setTransformOriginal = NewtonBodyGetTransformCallback(playerBody); NewtonBodySetTransformCallback (playerBody, PlayerController::SetTransform); // we will need some ID to fin this joint in the transform Callback CustomSetJointID (playerController, PLAYER_JOINT_ID); } /* { // add some visual entities. dFloat y0; y0 = FindFloor (world, 0.0f, 0.4f) + 10.5f; for (int i = 0; i < 5; i ++) { Entity* frowny; NewtonBody* frownyBody; NewtonCollision* shape; frowny = sceneManager->CreateEntity(); frowny->LoadMesh ("Frowny.dat"); frowny->m_curPosition.m_z = 0.4f; frowny->m_curPosition.m_y = y0; y0 += 2.0f; frowny->m_prevPosition = frowny->m_curPosition; // add a body with a Convex hull shape shape = CreateNewtonConvex (world, frowny, m_wood); frownyBody = CreateRigidBody (world, frowny, shape, 10.0f); NewtonDestroyCollision(shape); } } */ // set the Camera EyePoint close to the scene action SetCameraEyePoint (dVector (-15.0f, FindFloor (world, -15.0f, 0.0f) + 5.0f, 0.0f)); }
static void CreateDebriPiece (const NewtonBody* sourceBody, NewtonMesh* mesh, dFloat volume) { dFloat Ixx; dFloat Iyy; dFloat Izz; dFloat mass; dFloat shapeVolume; NewtonWorld* world; NewtonBody* rigidBody; NewtonCollision* collision; OGLMesh* meshInstance; SceneManager* system; RenderPrimitive* primitive; dVector inertia; dVector origin; dVector veloc; dVector omega; dMatrix matrix; world = NewtonBodyGetWorld (sourceBody); NewtonBodyGetMatrix (sourceBody, &matrix[0][0]); NewtonBodyGetMassMatrix (sourceBody, &mass, &Ixx, &Iyy, &Izz); // make a visual object meshInstance = new OGLMesh(); meshInstance->BuildFromMesh (mesh); // create a visual geometry primitive = new RenderPrimitive (matrix, meshInstance); meshInstance->Release(); // save the graphics system system = (SceneManager*) NewtonWorldGetUserData(world); system->AddModel (primitive); collision = NewtonCreateConvexHullFromMesh (world, mesh, 0.1f, DEBRI_ID); // calculate the moment of inertia and the relative center of mass of the solid shapeVolume = NewtonConvexCollisionCalculateVolume (collision); NewtonConvexCollisionCalculateInertialMatrix (collision, &inertia[0], &origin[0]); mass = mass * shapeVolume / volume; Ixx = mass * inertia[0]; Iyy = mass * inertia[1]; Izz = mass * inertia[2]; //create the rigid body rigidBody = NewtonCreateBody (world, collision); // set the correct center of gravity for this body NewtonBodySetCentreOfMass (rigidBody, &origin[0]); // set the mass matrix NewtonBodySetMassMatrix (rigidBody, mass, Ixx, Iyy, Izz); // save the pointer to the graphic object with the body. NewtonBodySetUserData (rigidBody, primitive); // assign the wood id // NewtonBodySetMaterialGroupID (rigidBody, NewtonBodyGetMaterialGroupID(source)); // set continue collision mode NewtonBodySetContinuousCollisionMode (rigidBody, 1); // set a destructor for this rigid body NewtonBodySetDestructorCallback (rigidBody, PhysicsBodyDestructor); // set the transform call back function NewtonBodySetTransformCallback (rigidBody, PhysicsSetTransform); // set the force and torque call back function NewtonBodySetForceAndTorqueCallback (rigidBody, PhysicsApplyGravityForce); // set the matrix for both the rigid body and the graphic body NewtonBodySetMatrix (rigidBody, &matrix[0][0]); PhysicsSetTransform (rigidBody, &matrix[0][0], 0); NewtonBodyGetVelocity(sourceBody, &veloc[0]); NewtonBodyGetOmega(sourceBody, &omega[0]); veloc += omega * matrix.RotateVector(origin); // for now so that I can see the body veloc = dVector (0, 0, 0, 0); // omega = dVector (0, 0, 0, 0); NewtonBodySetVelocity(rigidBody, &veloc[0]); NewtonBodySetOmega(rigidBody, &omega[0]); NewtonReleaseCollision(world, collision); }