• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

src/physic/src/Physic.cpp

Go to the documentation of this file.
00001 #include "../pch.h"
00002 
00003 NxUserAllocatorDefault nxAllocator;
00004 
00005 Physic::Physic(void)
00006 {
00007         sdk = 0;
00008         scene = 0;
00009         forceField = 0;
00010         forceFieldActor = 0;
00011         includeShape = 0;
00012         excludeShape = 0;
00013         includeGroup = 0;
00014         excludeGroup = 0;
00015         explosionTime = 0.f;
00016         explosion = false;
00017         initialized = false;
00018 }
00019 
00020 Physic::~Physic(void)
00021 {
00022         uninit();
00023 }
00024 
00025 bool Physic::init(void)
00026 {
00027         if(initialized)
00028                 return false;
00029 
00030         // initialize PhysX SDK
00031         sdk = NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION);
00032         if(sdk == 0)
00033                 return printf("%s", "Could not create physix SDK class."), uninit(), false;
00034         sdk->setParameter(NX_SKIN_WIDTH, 0.001f);
00035 
00036         // initialize PhysX Scene
00037         // If HW simulation is not available, try
00038         // to create a SW scene. If this failes to
00039         // return an error.
00040         NxSceneDesc sceneDesc;
00041         sceneDesc.gravity = NxVec3(0.f,-9.8f,0.f);
00042         sceneDesc.simType = NX_SIMULATION_HW;// NX_SIMULATION_SW;
00043         scene = sdk->createScene(sceneDesc);
00044         if(scene == 0){
00045                 printf("%s", "PhysX hardware simulation is not posible.");
00046                 sceneDesc.simType = NX_SIMULATION_SW;
00047                 scene = sdk->createScene(sceneDesc);
00048                 if(scene == 0)
00049                         return printf("%s", "PhysX Scene could not be created."), uninit(), false;
00050         }
00051 
00052         // set the default material
00053         NxMaterial* defaultMaterial = scene->getMaterialFromIndex(0); 
00054         defaultMaterial->setRestitution(0.5f);
00055         defaultMaterial->setStaticFriction(0.7f);
00056         defaultMaterial->setDynamicFriction(0.5f);
00057 
00058         // prepare force field
00059         NxActorDesc actorDesc;
00060         NxBodyDesc bodyDesc;
00061         bodyDesc.flags |= NX_BF_KINEMATIC;
00062         bodyDesc.massSpaceInertia = NxVec3(1, 1, 1);
00063         bodyDesc.mass = 1.0f;
00064         actorDesc.body = &bodyDesc;
00065         forceFieldActor = scene->createActor(actorDesc);
00066 
00067         NxForceFieldDesc ffDesc;
00068         NxForceFieldLinearKernelDesc linearKernelDesc;
00069         NxForceFieldLinearKernel* linearKernel;
00070 
00071         //constant force of 100 outwards
00072         linearKernelDesc.constant = NxVec3(10000, 0, 0);
00073 
00074         //The forces do not depend on where the objects are positioned
00075         NxMat33 m;
00076         m.zero();
00077         linearKernelDesc.positionMultiplier = m;
00078         linearKernelDesc.noise = NxVec3(0.1f,0.1f,0.1f); //adds a random noise on the forces to make the objects a little more chaotic
00079 
00080         //Set target velocity along the radius to 20
00081         linearKernelDesc.velocityTarget = NxVec3(20,0,0);
00082         //Acts with a force relative to the current velocity to reach the
00083         //target velocities. 0 means that those components won't be affected
00084         m.diagonal(NxVec3(1,0,0));
00085         linearKernelDesc.velocityMultiplier = m;
00086 
00087         // create linear kernel
00088         linearKernel = scene->createForceFieldLinearKernel(linearKernelDesc);
00089         ffDesc.kernel = linearKernel;
00090         
00091         //Attach the force field to an actor (kinematic) so that we can move it around 
00092         // (spawn the explosions in different places)
00093         ffDesc.actor = forceFieldActor;
00094 
00095         //Create the force field around origo
00096         ffDesc.pose.id();
00097         ffDesc.coordinates = NX_FFC_SPHERICAL;
00098         ffDesc.flags = 0;
00099 
00100         forceField = scene->createForceField(ffDesc);
00101 
00102         //Attach an include shape, we will animate the size of this later on, so that it grows (like a slow explosion)
00103         // inclusion group
00104         NxForceFieldShapeGroupDesc sgInclDesc;
00105         includeGroup = scene->createForceFieldShapeGroup(sgInclDesc);
00106         NxForceFieldShape* shape = NULL;
00107         NxSphereForceFieldShapeDesc s;
00108         s.radius = 0.1f;
00109         s.pose.t = NxVec3(0, 0, 0);
00110         includeShape = includeGroup->createShape(s);
00111 
00112         // exclude group
00113         NxForceFieldShapeGroupDesc sgExclDesc;
00114         sgExclDesc.flags = NX_FFSG_EXCLUDE_GROUP;
00115         excludeGroup = scene->createForceFieldShapeGroup(sgExclDesc);
00116         NxSphereForceFieldShapeDesc exclude;
00117         exclude.radius = 0.2f;
00118         exclude.pose.t = NxVec3(0, 0, 0);
00119         excludeShape = excludeGroup->createShape(exclude);
00120 
00121         forceField->addShapeGroup(*excludeGroup);
00122 
00123         initialized = true;
00124         return true;
00125 }
00126 
00127 void Physic::uninit(void)
00128 {
00129         if(sdk)
00130         {
00131                 if (forceField != 0)
00132                 {
00133                         scene->releaseForceField(*forceField);
00134                         forceField = 0;
00135                 }
00136                 if(scene)
00137                 {
00138                         sdk->releaseScene(*scene);
00139                         scene = 0;
00140                 }
00141                 sdk->release();
00142                 sdk = 0;
00143                 forceFieldActor = 0;
00144                 includeShape = 0;
00145                 excludeShape = 0;
00146                 includeGroup = 0;
00147                 excludeGroup = 0;
00148         }
00149         initialized = false;
00150 }
00151 
00152 pIBody Physic::createDummy(float3 position, float3 rotation)
00153 {
00154         pBody body = new Body(position, rotation);
00155         body->setActor(0);
00156         return body;
00157 }
00158 
00159 pIBody Physic::createSphere(float3 position, float3 rotation, float radius, float density, ushort colGroup, int material, bool dynamic)
00160 {
00161         NxBodyDesc bodyDesc;
00162         NxSphereShapeDesc sphereDesc;
00163         NxActorDesc actorDesc;
00164         pBody body = new Body(position, rotation);
00165 
00166         // set sphere parameters
00167         sphereDesc.radius = radius;
00168         //sphereDesc.group = colGroup;
00169         sphereDesc.localPose.id();
00170 
00171         // set actor parameters
00172         if(dynamic){
00173                 actorDesc.userData = body;
00174                 actorDesc.body = &bodyDesc;
00175         }else{
00176                 actorDesc.userData = 0;
00177         }
00178         actorDesc.shapes.pushBack(&sphereDesc);
00179         actorDesc.density = density;
00180         actorDesc.globalPose.setRowMajor44(body->getTransformation().m16);
00181 
00182         // create actor
00183         NxActor* actor = scene->createActor(actorDesc);
00184 
00185         body->setActor(actor);
00186         return body;
00187 }
00188 
00189 pIBody Physic::createBox(float3 position, float3 rotation, float width, float height, float depth, float density, ushort colGroup, int material, bool dynamic)
00190 {
00191         NxBodyDesc bodyDesc;
00192         NxBoxShapeDesc boxDesc;
00193         NxActorDesc actorDesc;
00194         pBody body = new Body(position, rotation);
00195 
00196         // set box parameters
00197         boxDesc.dimensions.set(width/2, height/2, depth/2);
00198         //boxDesc.group = colGroup;
00199         boxDesc.localPose.id();
00200 
00201         // set actor parameters
00202         if(dynamic){
00203                 actorDesc.userData = body;
00204                 actorDesc.body = &bodyDesc;
00205         }else{
00206                 actorDesc.userData = 0;
00207         }
00208         actorDesc.shapes.pushBack(&boxDesc);
00209         actorDesc.density = density;
00210         actorDesc.globalPose.setRowMajor44(body->getTransformation().m16);
00211 
00212         // create actor
00213         NxActor* actor = scene->createActor(actorDesc);
00214 
00215         body->setActor(actor);
00216         return body;
00217 }
00218 
00219 pIBody Physic::createMesh(float3 position, float3 rotation,
00220                 float* vertices,  int vertexSize, int numVertices,
00221                 ushort* indices, int numIndices, float density,
00222                 ushort colGroup, int material, bool dynamic)
00223 {
00224         NxBodyDesc bodyDesc;
00225         NxTriangleMeshShapeDesc triMeshShapeDesc;
00226         NxTriangleMeshDesc triMeshDesc;
00227         NxTriangleMesh* triMesh;
00228         NxActorDesc actorDesc;
00229         pBody body = new Body(position, rotation);
00230 
00231         // cook mesh
00232         if(NxInitCooking() == false){
00233                 printf("%s", "NxInitCooking failed.\n");
00234                 return 0;
00235         }
00236         MemoryWriteBuffer buf;
00237         triMeshDesc.numVertices = numVertices;
00238         triMeshDesc.pointStrideBytes = vertexSize;
00239         triMeshDesc.points = vertices;
00240         triMeshDesc.flags = 0;
00241         triMeshDesc.numTriangles = numIndices/3;
00242         triMeshDesc.triangles = indices;
00243         triMeshDesc.triangleStrideBytes = sizeof(ushort)*3;
00244         triMeshDesc.flags = NX_MF_16_BIT_INDICES;
00245 
00246         if(NxCookTriangleMesh(triMeshDesc, buf) == false){
00247                 printf("%s", "NxCookTriangleMesh failed.\n");
00248                 NxCloseCooking();
00249                 return 0;
00250         }
00251 
00252         triMesh = sdk->createTriangleMesh(MemoryReadBuffer(buf.data));
00253         triMeshShapeDesc.meshData = triMesh;
00254         triMeshShapeDesc.group = colGroup;
00255         triMeshShapeDesc.localPose.id();
00256         triMeshShapeDesc.userData = 0;
00257         triMeshShapeDesc.meshPagingMode = NX_MESH_PAGING_AUTO;
00258 
00259         NxCloseCooking();
00260 
00261         // set actor parameters
00262         if(dynamic){
00263                 actorDesc.userData = body;
00264                 actorDesc.body = &bodyDesc;
00265         }else{
00266                 actorDesc.userData = 0;
00267         }
00268         actorDesc.shapes.pushBack(&triMeshShapeDesc);
00269         actorDesc.density = density;
00270         actorDesc.globalPose.setRowMajor44(body->getTransformation().m16);
00271 
00272         // create actor
00273         NxActor* actor = scene->createActor(actorDesc);
00274 
00275         body->setActor(actor);
00276         return body;
00277 }
00278 
00279 void Physic::createExplosion(float3 pos)
00280 {
00281         if(explosion)
00282                 return;
00283         forceField->addShapeGroup(*includeGroup);
00284         NxMat34 pose;
00285         pose.id();
00286         pose.t = NxVec3(pos.x, pos.y, pos.z);
00287         forceFieldActor->setGlobalPose(pose); // to set FF, could also get rid of that indirection
00288         includeShape->setPose(pose);
00289         excludeShape->setPose(pose);
00290         explosionTime = 0.0f;
00291         explosion = true;
00292 }
00293 
00294 void Physic::freeBody(pIBody& body)
00295 {
00296         if(body){
00297                 scene->releaseActor(((pBody)body)->getActor());
00298                 delete body;
00299                 body = 0;
00300         }
00301 }
00302 
00303 void Physic::update(float dt)
00304 {
00305         pBody body;
00306 
00307         if(explosion){
00308                 includeShape->isSphere()->setRadius((explosionTime+0.2f) * 20.f);
00309                 excludeShape->isSphere()->setRadius((explosionTime+0.1f) * 20.f);
00310 
00311                 explosionTime += dt;
00312                 if(explosionTime > 1.f){
00313                         explosion = false;
00314                         explosionTime = 0.f;
00315 
00316                         forceField->removeShapeGroup(*includeGroup);
00317 
00318                         includeShape->isSphere()->setRadius(0.1f);
00319                         excludeShape->isSphere()->setRadius(0.2f);
00320                 }
00321         }
00322 
00323         // for all scenes
00324         const NxU32 numScenes = sdk->getNbScenes();
00325         for(NxU32 i=0; i<numScenes; i++)
00326         {
00327                 // simulate the scene
00328                 NxScene* scene = sdk->getScene(i);
00329                 scene->simulate(dt);
00330                 scene->flushStream();
00331 
00332                 // wait until all results are available
00333                 while(!scene->fetchResults(NX_RIGID_BODY_FINISHED, false));
00334 
00335                 // for all actors in the scene
00336                 const NxU32 numActors = scene->getNbActors();
00337                 NxActor** actors = scene->getActors();
00338                 for(NxU32 j=0; j<numActors; j++)
00339                 {
00340                         if(body = (pBody)actors[j]->userData)
00341                         {
00342                                 // update position and rotation
00343                                 toFloat4x4(actors[j]->getGlobalPose(), body->getTransformation());
00344                         }
00345                 }
00346         }
00347 }

Generated on Fri Jun 18 2010 17:48:39 for Cannonball by  doxygen 1.7.0