virtual const void InitRigiBody(const NewtonBody* const body, const char* const bodyName) const { dMatrix matrix; DemoEntityManager* const scene = (DemoEntityManager*)NewtonWorldGetUserData(NewtonBodyGetWorld(body)); NewtonCollision* const collision = NewtonBodyGetCollision(body); DemoMesh* const mesh = new DemoMesh("ragdoll", collision, "smilli.tga", "smilli.tga", "smilli.tga"); NewtonBodyGetMatrix(body, &matrix[0][0]); DemoEntity* const entity = new DemoEntity(matrix, NULL); entity->SetNameID (bodyName); entity->SetMesh(mesh, dGetIdentityMatrix()); scene->Append(entity); mesh->Release(); // save the pointer to the graphic object with the body. NewtonBodySetUserData(body, entity); // assign the wood id NewtonBodySetMaterialGroupID(body, m_material); //set continuous collision mode //NewtonBodySetContinuousCollisionMode (rigidBody, continueCollisionMode); // set a destructor for this rigid body NewtonBodySetDestructorCallback(body, PhysicsBodyDestructor); // set the transform call back function NewtonBodySetTransformCallback(body, DemoEntity::TransformCallback); // set the force and torque call back function NewtonBodySetForceAndTorqueCallback(body, PhysicsApplyGravityForce); }
static void AddShatterEntity (DemoEntityManager* const scene, DemoMesh* const visualMesh, NewtonCollision* const collision, const ShatterEffect& shatterEffect, dVector location) { dQuaternion rotation; SimpleShatterEffectEntity* const entity = new SimpleShatterEffectEntity (visualMesh, shatterEffect); entity->SetMatrix(*scene, rotation, location); entity->InterpolateMatrix (*scene, 1.0f); scene->Append(entity); dVector origin; dVector inertia; NewtonConvexCollisionCalculateInertialMatrix (collision, &inertia[0], &origin[0]); float mass = 10.0f; int materialId = 0; dFloat Ixx = mass * inertia[0]; dFloat Iyy = mass * inertia[1]; dFloat Izz = mass * inertia[2]; //create the rigid body dMatrix matrix (GetIdentityMatrix()); matrix.m_posit = location; NewtonWorld* const world = scene->GetNewton(); NewtonBody* const rigidBody = NewtonCreateBody (world, collision, &matrix[0][0]); entity->m_myBody = rigidBody; entity->m_myweight = dAbs (mass * DEMO_GRAVITY); // set the correct center of gravity for this body NewtonBodySetCentreOfMass (rigidBody, &origin[0]); // set the mass matrix NewtonBodySetMassMatrix (rigidBody, mass, 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); }
void iPhysics::setMaterial(iPhysicsBody* body, int64 materialID) { con_assert(body != nullptr, "zero pointer"); if (body != nullptr) { NewtonBodySetMaterialGroupID(static_cast<const NewtonBody*>(body->_newtonBody), materialID); } }
void cPhysicsBodyNewton::SetMaterial(iPhysicsMaterial *a_pMaterial) { m_pMaterial = a_pMaterial; if (a_pMaterial == NULL) return; cPhysicsMaterialNewton *pNewtonMat = static_cast<cPhysicsMaterialNewton*>(m_pMaterial); NewtonBodySetMaterialGroupID(m_pNewtonBody, pNewtonMat->GetId()); }
PuckEntity (DemoEntityManager* const scene, int materialID) :DemoEntity (dGetIdentityMatrix(), NULL) ,m_launched(false) { scene->Append(this); NewtonWorld* const world = scene->GetNewton(); dVector puckSize(WEIGHT_DIAMETER, WEIGHT_HEIGHT, 0.0f, 0.0f); // create the shape and visual mesh as a common data to be re used NewtonCollision* const collision = CreateConvexCollision (world, dGetIdentityMatrix(), puckSize, _CYLINDER_PRIMITIVE, materialID); // correction: make the puck an upright cylinder, this makes everything simpler dMatrix collisionAligmentMatrix (dRollMatrix(3.141592f/2.0f)); NewtonCollisionSetMatrix(collision, &collisionAligmentMatrix[0][0]); DemoMesh* const geometry = new DemoMesh("cylinder_1", collision, "smilli.tga", "smilli.tga", "smilli.tga"); //dMatrix matrix = dRollMatrix(3.141592f/2.0f); dMatrix matrix (dGetIdentityMatrix()); matrix.m_posit.m_x = -TABLE_LENGTH*0.5f+WEIGHT_DIAMETER; matrix.m_posit.m_z = -11.8f; //matrix.m_posit.m_z += 4.0f; matrix.m_posit.m_y = 5.0f; m_puckBody = CreateSimpleSolid (scene, geometry, WEIGHT_MASS, matrix, collision, materialID); // Set moment of inertia // correction: this is deprecated, NewtonBodySetMassProperties produce the exact result //dVector I; //dFloat Mass = WEIGHT_MASS; //dFloat Radius = WEIGHT_RADIUS; //dFloat Height = WEIGHT_HEIGHT; //I.m_x = I.m_z = Mass*(3.0f*Radius*Radius+Height*Height)/12.0f; //I.m_y = Mass*Radius*Radius/2.0f; //NewtonBodySetMassMatrix(gPuckBody,Mass, I.m_x, I.m_y, I.m_z); NewtonBodySetMassProperties(m_puckBody, WEIGHT_MASS, NewtonBodyGetCollision(m_puckBody)); NewtonBodySetMaterialGroupID(m_puckBody, materialID); // remember to make continuous collision work with auto sleep mode, right now this is no working NewtonBodySetContinuousCollisionMode(m_puckBody, 1); NewtonBodySetAutoSleep(m_puckBody, 1); // Set callbacks NewtonBodySetForceAndTorqueCallback(m_puckBody, NewtonRigidBodySetForceCB); // do not forget to release the assets geometry->Release(); NewtonDestroyCollision (collision); }
NewtonBody* CreateSimpleBody (NewtonWorld* const world, void* const userData, dFloat mass, const dMatrix& matrix, NewtonCollision* const collision, int materialId) { // calculate the moment of inertia and the relative center of mass of the solid // dVector origin; // dVector inertia; // NewtonConvexCollisionCalculateInertialMatrix (collision, &inertia[0], &origin[0]); // dFloat Ixx = mass * inertia[0]; // dFloat Iyy = mass * inertia[1]; // dFloat Izz = mass * inertia[2]; //create the rigid body NewtonBody* const rigidBody = NewtonCreateDynamicBody (world, collision, &matrix[0][0]); // set the correct center of gravity for this body (these function are for legacy) // NewtonBodySetCentreOfMass (rigidBody, &origin[0]); // NewtonBodySetMassMatrix (rigidBody, mass, Ixx, Iyy, Izz); // use a more convenient function for setting mass and inertia matrix NewtonBodySetMassProperties (rigidBody, mass, collision); // save the pointer to the graphic object with the body. NewtonBodySetUserData (rigidBody, userData); // 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); // set the matrix for both the rigid body and the graphic body //NewtonBodySetMatrix (rigidBody, &matrix[0][0]); //PhysicsSetTransform (rigidBody, &matrix[0][0], 0); //dVector xxx (0, -9.8f * mass, 0.0f, 0.0f); //NewtonBodySetForce (rigidBody, &xxx[0]); // force the body to be active of inactive // NewtonBodySetAutoSleep (rigidBody, sleepMode); return rigidBody; }
static void AddFracturedEntity(DemoEntityManager* const scene, DemoMesh* const visualMesh, NewtonCollision* const collision, const FractureEffect& fractureEffect, const dVector& location) { dQuaternion rotation; SimpleFracturedEffectEntity* const entity = new SimpleFracturedEffectEntity(visualMesh, fractureEffect); entity->SetMatrix(*scene, rotation, location); entity->InterpolateMatrix(*scene, 1.0f); scene->Append(entity); dVector origin(0.0f); dVector inertia(0.0f); NewtonConvexCollisionCalculateInertialMatrix(collision, &inertia[0], &origin[0]); dFloat mass = 10.0f; int materialId = 0; //create the rigid body dMatrix matrix(dGetIdentityMatrix()); matrix.m_posit = location; NewtonWorld* const world = scene->GetNewton(); NewtonBody* const rigidBody = NewtonCreateDynamicBody(world, collision, &matrix[0][0]); entity->m_myBody = rigidBody; entity->m_myMassInverse = 1.0f / mass; // set the correct center of gravity for this body //NewtonBodySetCentreOfMass (rigidBody, &origin[0]); // set the mass matrix NewtonBodySetMassProperties(rigidBody, mass, 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); }
/* ============= CMod_PhysicsAddEntity ============= */ void CMod_PhysicsAddEntity(sharedEntity_t * gEnt) { NewtonCollision* collision = NULL; NewtonBody* body = NULL; std::map<int, bspCmodel>::iterator it = bspModels.find (gEnt->s.modelindex); if ( it == bspModels.end() ) { return; } vec3_t inertia, com; dMatrix matrix (GetIdentityMatrix()); bspCmodel* bmodel = &it->second; collision = NewtonCreateConvexHull (g_world, bmodel->vertices.size(), &bmodel->vertices[0].m_x, sizeof (dVector), 0.0f, &matrix[0][0]); body = NewtonCreateBody (g_world, collision); NewtonConvexCollisionCalculateVolume (collision); NewtonReleaseCollision (g_world, collision); bmodel->rigidBody = body; NewtonBodySetMaterialGroupID (body, defaultMaterialGroup); NewtonBodySetUserData (body, (void*)gEnt); NewtonBodySetDestructorCallback (body, PhysicsEntityDie); NewtonBodySetContinuousCollisionMode (body, 0); NewtonBodySetForceAndTorqueCallback (body, PhysicsEntityThink); NewtonBodySetTransformCallback (body, PhysicsEntitySetTransform); NewtonConvexCollisionCalculateInertialMatrix (collision, &inertia[0], &com[0]); NewtonBodySetCentreOfMass (body, &com[0]); VectorScale (inertia, 10.0f, inertia); // The inertia needs to be scaled by the mass. NewtonBodySetMassMatrix (body, 10.f, inertia[0], inertia[1], inertia[2]); matrix.m_posit.m_x = gEnt->s.origin[0] * UNITS_PER_METRE; matrix.m_posit.m_y = gEnt->s.origin[1] * UNITS_PER_METRE; matrix.m_posit.m_z = gEnt->s.origin[2] * UNITS_PER_METRE; NewtonBodySetMatrix (body, &matrix[0][0]); gEnt->s.pos.trType = TR_INTERPOLATE; VectorCopy (gEnt->s.origin, gEnt->s.pos.trBase); VectorCopy (gEnt->s.origin, gEnt->r.currentOrigin); gEnt->s.apos.trType = TR_INTERPOLATE; VectorCopy (gEnt->s.angles, gEnt->s.apos.trBase); VectorCopy (gEnt->s.angles, gEnt->r.currentAngles); }
Error PhysicsWorld::create(AllocAlignedCallback allocCb, void* allocCbData) { Error err = ErrorCode::NONE; m_alloc = HeapAllocator<U8>(allocCb, allocCbData); // Set allocators gAlloc = &m_alloc; NewtonSetMemorySystem(newtonAlloc, newtonFree); // Initialize world m_world = NewtonCreate(); if(!m_world) { ANKI_LOGE("NewtonCreate() failed"); return ErrorCode::FUNCTION_FAILED; } // Set the simplified solver mode (faster but less accurate) NewtonSetSolverModel(m_world, 1); // Create scene collision m_sceneCollision = NewtonCreateSceneCollision(m_world, 0); Mat4 trf = Mat4::getIdentity(); m_sceneBody = NewtonCreateDynamicBody(m_world, m_sceneCollision, &trf[0]); NewtonBodySetMaterialGroupID(m_sceneBody, NewtonMaterialGetDefaultGroupID(m_world)); NewtonDestroyCollision(m_sceneCollision); // destroy old scene m_sceneCollision = NewtonBodyGetCollision(m_sceneBody); // Set the post update listener NewtonWorldAddPostListener(m_world, "world", this, postUpdateCallback, destroyCallback); // Set callbacks NewtonMaterialSetCollisionCallback(m_world, NewtonMaterialGetDefaultGroupID(m_world), NewtonMaterialGetDefaultGroupID(m_world), nullptr, onAabbOverlapCallback, onContactCallback); return err; }
void CreateScene (NewtonWorld* world, SceneManager* sceneManager) { Entity* floor; Entity* smilly; Entity* frowny; NewtonBody* floorBody; NewtonBody* smillyBody; NewtonBody* frownyBody; NewtonCollision* shape; // Create the material for this scene CreateMateials (world, sceneManager); // Create a large body to be the floor floor = sceneManager->CreateEntity(); // add scene collision from a level mesh shape = CreateHeightFieldCollision (world, "h2.raw", 0); floorBody = CreateRigidBody (world, floor, shape, 0.0f); NewtonReleaseCollision (world, 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]); // now we will use the properties of this body to set a proper world size. NewtonCollisionCalculateAABB (shape, &matrix[0][0], &boxP0.m_x, &boxP1.m_x); // add some extra padding boxP0.m_x -= 50.0f; boxP0.m_y -= 500.0f; boxP0.m_z -= 50.0f; boxP1.m_x += 50.0f; boxP1.m_y += 500.0f; boxP1.m_z += 50.0f; // set the new world size NewtonSetWorldSize (world, &boxP0[0], &boxP1[0]); // assign an Material ID to this body NewtonBodySetMaterialGroupID (floorBody, g_floorMaterial); // add some visual entities. dFloat y0 = FindFloor (world, 0.0f, 0.0f) + 10.0f; for (int i = 0; i < 5; i ++) { smilly = sceneManager->CreateEntity(); smilly->LoadMesh ("Smilly.dat"); smilly->m_curPosition.m_y = y0; y0 += 2.0f; smilly->m_prevPosition = smilly->m_curPosition; // add a body with a box shape shape = CreateNewtonBox (world, smilly, 0); smillyBody = CreateRigidBody (world, smilly, shape, 10.0f); NewtonReleaseCollision (world, shape); // assign an Material ID to this body NewtonBodySetMaterialGroupID (smillyBody, g_metalMaterial); } // add some visual entities. y0 = FindFloor (world, 0.0f, 0.4f) + 10.5f; for (int i = 0; i < 5; i ++) { 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, 0); frownyBody = CreateRigidBody (world, frowny, shape, 10.0f); NewtonReleaseCollision (world, shape); // assign an Material ID to this body NewtonBodySetMaterialGroupID (frownyBody, g_woodMaterial); } // set the Camera EyePoint close to the scene action InitCamera (dVector (-15.0f, FindFloor (world, -15.0f, 0.0f) + 5.0f, 0.0f), dVector (1.0f, 0.0f, 0.0f)); }
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 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 physics scene void PuckSlide (DemoEntityManager* const scene) { scene->CreateSkyBox(); NewtonWorld* const world = scene->GetNewton(); int materialGroupIDs[SB_NUM_MATERIALS]; // Create groups for (int i = 0; i < SB_NUM_MATERIALS; i++) { materialGroupIDs[i] = NewtonMaterialCreateGroupID(world); } // Setup the material data NewtonMaterialSetDefaultSoftness(world, materialGroupIDs[SBMaterial_WEIGHT], materialGroupIDs[SBMaterial_SURFACE], 0.15f); NewtonMaterialSetDefaultElasticity(world, materialGroupIDs[SBMaterial_WEIGHT], materialGroupIDs[SBMaterial_SURFACE], 0.30f); NewtonMaterialSetDefaultFriction(world, materialGroupIDs[SBMaterial_WEIGHT], materialGroupIDs[SBMaterial_SURFACE], 0.05f, 0.04f); // setup callbacks for collisions between two material groups NewtonMaterialSetCollisionCallback(world,materialGroupIDs[SBMaterial_WEIGHT],materialGroupIDs[SBMaterial_SURFACE],NULL,PhysicsNewton_CollisionPuckSurfaceCB); /////// // Add table { dVector tableSize(TABLE_LENGTH, TABLE_HEIGHT, TABLE_WIDTH, 0.0f); // create the shape and visual mesh as a common data to be re used NewtonCollision* const collision = CreateConvexCollision (world, dGetIdentityMatrix(), tableSize, _BOX_PRIMITIVE, materialGroupIDs[SBMaterial_SURFACE]); DemoMesh* const geometry = new DemoMesh("cylinder_1", collision, "wood_3.tga", "wood_3.tga", "wood_3.tga"); dMatrix matrix = dGetIdentityMatrix(); matrix.m_posit.m_x = 0.0f; matrix.m_posit.m_z = 0.0f; matrix.m_posit.m_y = 0.0f; NewtonBody* const tableBody = CreateSimpleSolid (scene, geometry, 0.0, matrix, collision, materialGroupIDs[SBMaterial_SURFACE]); // this is deprecated, use NewtonBodySetMassProperties //NewtonBodySetMassMatrix(tableBody, 0.0f, 1.0f, 1.0f, 1.0f); NewtonBodySetMassProperties(tableBody, 0.0f, NewtonBodyGetCollision(tableBody)); NewtonBodySetMaterialGroupID(tableBody, materialGroupIDs[SBMaterial_SURFACE]); // it is not wise to se static body to continuous collision mode //NewtonBodySetContinuousCollisionMode(tableBody, 1); // do not forget to release the assets geometry->Release(); // the collision need to be destroy, the body is using an instance no a reference NewtonDestroyCollision (collision); } /////// // Add puck { new PuckEntity (scene, materialGroupIDs[SBMaterial_WEIGHT]); } // place camera into position dMatrix camMatrix (dPitchMatrix(20.0f * 3.1416f /180.0f)); dQuaternion rot (camMatrix); dVector origin (CAMERA_Z, CAMERA_Y, CAMERA_X, 0.0f); scene->SetCameraMatrix(rot, origin); }
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); } }
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ void PhysicsActor::setMaterial(PhysicsActor::pPhysicsMaterial_type _material) { m_material = _material; NewtonBodySetMaterialGroupID(m_pActor, m_material->getMaterialID()); }
/*************************** Auteur : Loïc Teyssier Usage : Charge les modeles des caisses, leur attribue un matériau et une fonction de rappel de collision. ***************************/ CMiniJeuCaisse::CMiniJeuCaisse(NewtonWorld *world, int matPerso) : CMiniJeu(4) { m_nWorld = world; m_sNameElem = "caisse(s)"; // TIMER : int seconde = 1000; // 1 seconde = 1000 ms int timerInterval = seconde / 60; // l'intervalle entre deux images t_TimerCaisse = new QTimer(this); connect(t_TimerCaisse, SIGNAL(timeout()), this, SLOT(timeOutSlotCaisse())); t_TimerCaisse->start( timerInterval ); // Caisses : m_Caisse1 = new C3DModel(); m_Caisse2 = new C3DModel(); m_Caisse3 = new C3DModel(); m_Caisse4 = new C3DModel(); m_JeuLoader = new CLoad3DS(); m_JeuLoader->Import3DS(m_Caisse1,"Models/caisse1.3ds"); delete m_JeuLoader; m_JeuLoader = new CLoad3DS(); m_JeuLoader->Import3DS(m_Caisse2,"Models/caisse2.3ds"); delete m_JeuLoader; m_JeuLoader = new CLoad3DS(); m_JeuLoader->Import3DS(m_Caisse3,"Models/caisse3.3ds"); delete m_JeuLoader; m_JeuLoader = new CLoad3DS(); m_JeuLoader->Import3DS(m_Caisse4,"Models/caisse4.3ds"); delete m_JeuLoader; m_Caisse1->LoadTextures(); m_Caisse2->LoadTextures(); m_Caisse3->LoadTextures(); m_Caisse4->LoadTextures(); m_Caisse1->Initialiser(world,true,200.0); m_Caisse2->Initialiser(world,true,200.0); m_Caisse3->Initialiser(world,true,200.0); m_Caisse4->Initialiser(world,true,200.0); int matCaisse1 = NewtonMaterialCreateGroupID(world); int matCaisse2 = NewtonMaterialCreateGroupID(world); int matCaisse3 = NewtonMaterialCreateGroupID(world); int matCaisse4 = NewtonMaterialCreateGroupID(world); NewtonBodySetMaterialGroupID(m_Caisse1->GetBody(),matCaisse1); NewtonBodySetMaterialGroupID(m_Caisse2->GetBody(),matCaisse2); NewtonBodySetMaterialGroupID(m_Caisse3->GetBody(),matCaisse3); NewtonBodySetMaterialGroupID(m_Caisse4->GetBody(),matCaisse4); NewtonMaterialSetCollisionCallback (world, matCaisse1, matPerso , NULL, ContactBegin, ContactProcessCaisse1, ContactEnd); NewtonMaterialSetCollisionCallback (world, matCaisse2, matPerso , NULL, ContactBegin, ContactProcessCaisse2, ContactEnd); NewtonMaterialSetCollisionCallback (world, matCaisse3, matPerso , NULL, ContactBegin, ContactProcessCaisse3, ContactEnd); NewtonMaterialSetCollisionCallback (world, matCaisse4, matPerso , NULL, ContactBegin, ContactProcessCaisse4, ContactEnd); g_colC.c1 = true; g_colC.c2 = true; g_colC.c3 = true; g_colC.c4 = true; }
// 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); }
bool Physics::buildStaticGeometry( osg::Group* p_root, const std::string& levelFile ) { NewtonCollision* p_collision = NULL; // check if a serialization file exists, if so then load it. otherwise build the static geometry on the fly. assert( levelFile.length() && "internal error: missing levelFile name!" ); std::string file = cleanPath( levelFile ); std::vector< std::string > path; explode( file, "/", &path ); file = yaf3d::Application::get()->getMediaPath() + YAF3DPHYSICS_MEDIA_FOLDER + path[ path.size() - 1 ] + YAF3DPHYSICS_SERIALIZE_POSTFIX; std::ifstream serializationfile; serializationfile.open( file.c_str(), std::ios_base::binary | std::ios_base::in ); if ( !serializationfile ) { log_warning << "Physics: no serialization file for physics static geometry exists, building on-the-fly ..." << std::endl; p_collision = NewtonCreateTreeCollision( _p_world, levelCollisionCallback ); NewtonTreeCollisionBeginBuild( p_collision ); // build the collision faces //-------------------------- // start timer osg::Timer_t start_tick = osg::Timer::instance()->tick(); //! iterate through all geometries and create their collision faces PhysicsVisitor physVisitor( osg::NodeVisitor::TRAVERSE_ALL_CHILDREN, p_collision ); p_root->accept( physVisitor ); // stop timer and give out the time messure osg::Timer_t end_tick = osg::Timer::instance()->tick(); log_debug << "Physics: elapsed time for building physics collision faces = "<< osg::Timer::instance()->delta_s( start_tick, end_tick ) << std::endl; log_debug << "Physics: total num of evaluated primitives: " << physVisitor.getNumPrimitives() << std::endl; log_debug << "Physics: total num of vertices: " << physVisitor.getNumVertices() << std::endl; //-------------------------- // finalize tree building with optimization off ( because the meshes are already optimized by // osg _and_ Newton has currently problems with optimization ) NewtonTreeCollisionEndBuild( p_collision, 0 /* 1 */); } else { log_debug << "Physics: loading serialization file for physics static geometry: '" << file << "' ..." << std::endl; // start timer osg::Timer_t start_tick = osg::Timer::instance()->tick(); p_collision = NewtonCreateTreeCollisionFromSerialization( _p_world, NULL, deserializationCallback, &serializationfile ); assert( p_collision && "internal error, something went wrong during physics deserialization!" ); // stop timer and give out the time messure osg::Timer_t end_tick = osg::Timer::instance()->tick(); log_debug << "Physics: elapsed time for deserializing physics collision faces = "<< osg::Timer::instance()->delta_s( start_tick, end_tick ) << std::endl; serializationfile.close(); } _p_body = NewtonCreateBody( _p_world, p_collision ); // release collision object NewtonReleaseCollision( _p_world, p_collision ); // set Material Id for this object NewtonBodySetMaterialGroupID( _p_body, getMaterialId( "level" ) ); osg::Matrixf mat; mat.identity(); NewtonBodySetMatrix( _p_body, mat.ptr() ); // calculate the world bbox and world size float bmin[ 4 ], bmax[ 4 ]; NewtonCollisionCalculateAABB( p_collision, mat.ptr(), bmin, bmax ); bmin[ 0 ] -= 10.0f; bmin[ 1 ] -= 10.0f; bmin[ 2 ] -= 10.0f; bmin[ 3 ] = 1.0f; bmax[ 0 ] += 10.0f; bmax[ 1 ] += 10.0f; bmax[ 2 ] += 10.0f; bmax[ 3 ] = 1.0f; NewtonSetWorldSize( _p_world, bmin, bmax ); return true; }
void CEffectsGame::CreateScene() { pScene->CreateSkybox("clear"); NewtonBody *bFloor = AddBox(pScene, pWorld, Vector3(0,-0.5,0), Vector3(1000,1,1000), Vector3()); NewtonCollision *col = NewtonCreateTreeCollision(pWorld, 0); NewtonTreeCollisionBeginBuild(col); Vector3 v[4] = { Vector3(-1000,0.5f,-1000), Vector3(-1000,0.5f,+1000), Vector3(+1000,0.5f,+1000), Vector3(+1000,0.5f,-1000) }; NewtonTreeCollisionAddFace(col, 4, &v[0][0], sizeof(Vector3), 1); NewtonTreeCollisionEndBuild(col, 0); NewtonBodySetCollision(bFloor, col); CObject3D *f = (CObject3D*)NewtonBodyGetUserData(bFloor); f->visible = false; NewtonBodySetMaterialGroupID(bFloor, gLevelChunksMaterialID); // floor static CTexture *floorTex = new CTexture("textures/512.png"); CMaterial *floorMat = new CMaterial(); floorMat->features = EShaderFeature::LIGHT | EShaderFeature::FOG | EShaderFeature::SHADOW | EShaderFeature::TEXTURE; CPlaneGeometry *floorGeom = new CPlaneGeometry(1000,1000); CObject3D *floor = new CMesh( floorGeom, floorMat ); floor->geometry->materials.AddToTail(floorMat); floorMat->pTexture = floorTex; floorGeom->SetTextureScale(40,40); floor->SetPosition(-500, 0, -500); pScene->Add(floor); pLevel = new CLevel(pScene, pWorld); pLevel->Create(32,80,32); int width = 24; int depth = 24; int storeys = 8; int storyHeight = 8; for (int y=0; y<storeys*storyHeight; y++) for (int x=0; x<width; x++) for (int z=0; z<depth; z++) { int block = 0; if (x==0 || z==0 || x==width-1 || z==depth-1) block = 1; if (y%storyHeight == storyHeight-1) block = 1; if (x>5 && z>5 && x<width-5 && z<depth-5) block = 0; if (y%storyHeight > 2 && y%storyHeight <= 4) { if (x%8 >= 2 && x%8 < 7) block = 0; if (z%8 >= 2 && z%8 < 7) block = 0; } if ((x==5 && z==5) || (x==width-5 && z==depth-5) || (x==5 && z==depth-5) || (x==width-5 && z==5) ) block = 4; if (block > 0) block = 4; pLevel->GetTile(x,y,z)->type = block; } int sx = 55; int sz = 55; pLevel->Recreate(); for (int x=0; x<pLevel->chunksX; x++) for (int y=0; y<pLevel->chunksY; y++) for (int z=0; z<pLevel->chunksZ; z++) { pLevel->GetChunk(x,y,z)->RecreateCollision(); } // once the map has been created, creatie bodies that will collide /*for (int x=0; x<pLevel->sizeX; x++) for (int y=0; y<pLevel->sizeY; y++) for (int z=0; z<pLevel->sizeZ; z++) { if (pLevel->GetTile(x,y,z)->type == 0) continue; CObject3D *o = new CObject3D(); o->SetPosition(Vector3(x+0.5, y+0.5, z+0.5)); NewtonBody *box = CPhysics::CreateBox(pWorld, o, 1,1,1, 0); NewtonBodySetFreezeState(box, 1); delete o; }*/ // let's create a collision tree for each chunk /* for (int x=0; x<pLevel->chunksX; x++) for (int y=0; y<pLevel->chunksY; y++) for (int z=0; z<pLevel->chunksZ; z++) { NewtonCollision * col = NewtonCreateTreeCollision(pWorld, 0); NewtonTreeCollisionBeginBuild(col); CArray<Vector3> &verts = pLevel->GetChunk(x,y,z)->pMesh->geometry->vertices; for (int i=0; i<pLevel->GetChunk(x,y,z)->pMesh->geometry->faces.Size(); i++) { Face3 face = pLevel->GetChunk(x,y,z)->pMesh->geometry->faces[i]; Vector3 v[] = { verts[face.a], verts[face.b], verts[face.c] }; NewtonTreeCollisionAddFace(col, 3, &v[0][0], sizeof(Vector3), 1); } NewtonTreeCollisionEndBuild(col, 1); // create body float m[16] = { 1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1 }; NewtonBody *body = NewtonCreateBody(pWorld, col, &m[0]); NewtonReleaseCollision(pWorld, col); NewtonBody } */ /* CreateBuilding(0,0,0, 3,8,3); CreateBuilding(20,0,-10, 2,4,6); CreateBuilding(-5,0,-20, 5,2,3); */ // point light that will circle the building pLight = new CPointLight(Vector3(), SRGBA(255,200,50)); pLight->range = 8.0f; pLight->overbright = true; pScene->Add(pLight); pScene->fog = new SFog( SRGBA(172,201,241, 255), 200, 500); // point light at 0,1,0 CLight *pLight = new CPointLight(Vector3(0,1,0), RED);//SRGBA(255,233,155,255)); //pScene->Add( pLight ); pLight->specular = pLight->color;//SRGBA(255,255,255,100); pLight->range = 1; pLight->intensity = 1; // directional Sun light CDirectionalLight *pDirLight = new CDirectionalLight(Vector3(0,0,0), SRGBA(255,225,175,255)); pDirLight->SetPosition(+70,90,-70); pDirLight->LookAt(Vector3()); pDirLight->UpdateMatrixWorld(true); pDirLight->shadowNear = 20; pDirLight->shadowFar = 200; pDirLight->castShadow = true; float aspect = (float)gEngine.width / gEngine.height; pDirLight->width = 200.0f; pDirLight->height = pDirLight->width / aspect; pScene->Add( pDirLight ); // ambient light pScene->ambientColor = SRGBA(200,200,255,255); pCamera->LookAt(Vector3()); }
int CustomMultiBodyVehicle::AddSingleSuspensionTire ( void* userData, const dVector& localPosition, dFloat mass, dFloat radius, dFloat width, dFloat suspensionLength, dFloat springConst, dFloat springDamper) { dFloat Ixx; dFloat Iyy; dFloat Izz; dMatrix carMatrix; NewtonBody* tire; NewtonWorld* world; NewtonCollision *collision; world = NewtonBodyGetWorld(GetBody0()); // create the tire RogidBody collision = NewtonCreateChamferCylinder(world, radius, width, 0, NULL); //create the rigid body tire = NewtonCreateBody (world, collision); // release the collision NewtonReleaseCollision (world, collision); // save the user data NewtonBodySetUserData (tire, userData); // set the material group id for vehicle NewtonBodySetMaterialGroupID (tire, 0); // NewtonBodySetMaterialGroupID (tire, woodID); // set the force and torque call back function NewtonBodySetForceAndTorqueCallback (tire, NewtonBodyGetForceAndTorqueCallback (GetBody0())); // body part do not collision NewtonBodySetJointRecursiveCollision (tire, 0); // calculate the moment of inertia and the relative center of mass of the solid dVector origin; dVector inertia; NewtonConvexCollisionCalculateInertialMatrix (collision, &inertia[0], &origin[0]); Ixx = mass * inertia[0]; Iyy = mass * inertia[1]; Izz = mass * inertia[2]; // set the mass matrix NewtonBodySetMassMatrix (tire, mass, Ixx, Iyy, Izz); // calculate the tire local base pose matrix dMatrix tireMatrix; tireMatrix.m_front = m_localFrame.m_right; tireMatrix.m_up = m_localFrame.m_up; tireMatrix.m_right = tireMatrix.m_front * tireMatrix.m_up; tireMatrix.m_posit = localPosition; NewtonBodyGetMatrix(GetBody0(), &carMatrix[0][0]); tireMatrix = tireMatrix * carMatrix; // set the matrix for both the rigid body and the graphic body NewtonBodySetMatrix (tire, &tireMatrix[0][0]); // add a single tire m_tires[m_tiresCount] = new CustomMultiBodyVehicleTire (GetBody0(), tire, suspensionLength, springConst, springDamper, radius); m_tiresCount ++; return m_tiresCount - 1; }