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
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
00037
00038
00039
00040 NxSceneDesc sceneDesc;
00041 sceneDesc.gravity = NxVec3(0.f,-9.8f,0.f);
00042 sceneDesc.simType = NX_SIMULATION_HW;
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
00053 NxMaterial* defaultMaterial = scene->getMaterialFromIndex(0);
00054 defaultMaterial->setRestitution(0.5f);
00055 defaultMaterial->setStaticFriction(0.7f);
00056 defaultMaterial->setDynamicFriction(0.5f);
00057
00058
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
00072 linearKernelDesc.constant = NxVec3(10000, 0, 0);
00073
00074
00075 NxMat33 m;
00076 m.zero();
00077 linearKernelDesc.positionMultiplier = m;
00078 linearKernelDesc.noise = NxVec3(0.1f,0.1f,0.1f);
00079
00080
00081 linearKernelDesc.velocityTarget = NxVec3(20,0,0);
00082
00083
00084 m.diagonal(NxVec3(1,0,0));
00085 linearKernelDesc.velocityMultiplier = m;
00086
00087
00088 linearKernel = scene->createForceFieldLinearKernel(linearKernelDesc);
00089 ffDesc.kernel = linearKernel;
00090
00091
00092
00093 ffDesc.actor = forceFieldActor;
00094
00095
00096 ffDesc.pose.id();
00097 ffDesc.coordinates = NX_FFC_SPHERICAL;
00098 ffDesc.flags = 0;
00099
00100 forceField = scene->createForceField(ffDesc);
00101
00102
00103
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
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
00167 sphereDesc.radius = radius;
00168
00169 sphereDesc.localPose.id();
00170
00171
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
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
00197 boxDesc.dimensions.set(width/2, height/2, depth/2);
00198
00199 boxDesc.localPose.id();
00200
00201
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
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
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
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
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);
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
00324 const NxU32 numScenes = sdk->getNbScenes();
00325 for(NxU32 i=0; i<numScenes; i++)
00326 {
00327
00328 NxScene* scene = sdk->getScene(i);
00329 scene->simulate(dt);
00330 scene->flushStream();
00331
00332
00333 while(!scene->fetchResults(NX_RIGID_BODY_FINISHED, false));
00334
00335
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
00343 toFloat4x4(actors[j]->getGlobalPose(), body->getTransformation());
00344 }
00345 }
00346 }
00347 }