00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <math.h>
00023 #include <assert.h>
00024 #include <stdio.h>
00025
00026 #include "genesis.h"
00027 #include "ram.h"
00028 #include "matrix33.h"
00029 #include "quatern.h"
00030
00031
00032 #include "PhysicsObject.h"
00033
00035
00036
00037 typedef struct
00038 {
00039 geXForm3d xform;
00040 geVec3d linearVelocity;
00041 geVec3d angularVelocity;
00042 geVec3d force, appliedForce;
00043 geVec3d torque, appliedTorque;
00044 geQuaternion orientation;
00045
00046 } gePhysicsObject_Config;
00047
00048 typedef struct gePhysicsObject
00049 {
00050 geFloat mass, oneOverMass;
00051
00052 geVec3d OriginalLocation;
00053
00054 Matrix33 inertiaTensor,
00055 inertiaTensorInverse;
00056 geBoolean isAffectedByGravity;
00057 geBoolean respondsToForces;
00058 geFloat linearDamping;
00059 geFloat angularDamping;
00060
00061 int activeConfig;
00062 gePhysicsObject_Config configs[2];
00063
00064 geFloat physicsScale;
00065
00066 } gePhysicsObject;
00067
00069
00070
00071 GENESISAPI gePhysicsObject * GENESISCC gePhysicsObject_Create(
00072 const geVec3d *StartLocation,
00073 geFloat mass,
00074 geBoolean IsAffectedByGravity,
00075 geBoolean RespondsToForces,
00076 geFloat linearDamping,
00077 geFloat angularDamping,
00078 const geVec3d * Mins,
00079 const geVec3d * Maxs,
00080 geFloat physicsScale)
00081 {
00082 gePhysicsObject* pgePhysicsObject;
00083 geVec3d defaultAxis;
00084 geVec3d bbScale;
00085 int i;
00086
00088
00089 pgePhysicsObject = NULL;
00090 pgePhysicsObject = GE_RAM_ALLOCATE_STRUCT(gePhysicsObject);
00091
00092 if (pgePhysicsObject == NULL)
00093 return NULL;
00094
00095 assert(pgePhysicsObject != NULL);
00096
00098
00099
00100 pgePhysicsObject->respondsToForces = RespondsToForces;
00101 pgePhysicsObject->isAffectedByGravity = IsAffectedByGravity;
00102
00103 pgePhysicsObject->linearDamping = linearDamping;
00104 pgePhysicsObject->angularDamping = angularDamping;
00105
00106 pgePhysicsObject->physicsScale = physicsScale;
00107 geVec3d_Copy(StartLocation, &pgePhysicsObject->OriginalLocation);
00108 geVec3d_Scale(&pgePhysicsObject->OriginalLocation, physicsScale, &pgePhysicsObject->OriginalLocation);
00109
00110 assert(mass >= 0.1f);
00111
00112 pgePhysicsObject->mass = mass;
00113 pgePhysicsObject->oneOverMass = 1.f / mass;
00114
00116
00117
00118 for (i = 0; i < 2; i ++)
00119 {
00120 geVec3d_Clear(&pgePhysicsObject->configs[i].linearVelocity);
00121 geVec3d_Clear(&pgePhysicsObject->configs[i].angularVelocity);
00122 geVec3d_Clear(&pgePhysicsObject->configs[i].force);
00123 geVec3d_Clear(&pgePhysicsObject->configs[i].torque);
00124 geVec3d_Clear(&pgePhysicsObject->configs[i].appliedForce);
00125 geVec3d_Clear(&pgePhysicsObject->configs[i].appliedTorque);
00126
00127 geVec3d_Set(&defaultAxis, 1.f, 0.f, 0.f);
00128 geQuaternion_SetFromAxisAngle(&pgePhysicsObject->configs[i].orientation,
00129 &defaultAxis,
00130 0.f);
00131
00132 geXForm3d_SetIdentity(&pgePhysicsObject->configs[i].xform);
00133 geVec3d_Clear(&pgePhysicsObject->configs[i].xform.Translation);
00134 }
00135
00136 Matrix33_SetIdentity(&pgePhysicsObject->inertiaTensor);
00137 Matrix33_SetIdentity(&pgePhysicsObject->inertiaTensorInverse);
00138
00139 geVec3d_Subtract(Maxs, Mins, &bbScale);
00140 geVec3d_Scale(&bbScale, physicsScale, &bbScale);
00141
00143
00144
00145
00146 pgePhysicsObject->inertiaTensor.x[0][0] = pgePhysicsObject->mass / 12.f * (bbScale.Y * bbScale.Y + bbScale.Z * bbScale.Z);
00147 pgePhysicsObject->inertiaTensor.x[1][1] = pgePhysicsObject->mass / 12.f * (bbScale.X * bbScale.X + bbScale.Z * bbScale.Z);
00148 pgePhysicsObject->inertiaTensor.x[2][2] = pgePhysicsObject->mass / 12.f * (bbScale.X * bbScale.X + bbScale.Y * bbScale.Y);
00149
00150 assert(pgePhysicsObject->inertiaTensor.x[0][0] > (geFloat)1e-5);
00151 assert(pgePhysicsObject->inertiaTensor.x[1][1] > (geFloat)1e-5);
00152 assert(pgePhysicsObject->inertiaTensor.x[2][2] > (geFloat)1e-5);
00153
00154 pgePhysicsObject->inertiaTensorInverse.x[0][0] = 1 / pgePhysicsObject->inertiaTensor.x[0][0];
00155 pgePhysicsObject->inertiaTensorInverse.x[1][1] = 1 / pgePhysicsObject->inertiaTensor.x[1][1];
00156 pgePhysicsObject->inertiaTensorInverse.x[2][2] = 1 / pgePhysicsObject->inertiaTensor.x[2][2];
00157
00158 pgePhysicsObject->activeConfig = 0;
00159
00160 return pgePhysicsObject;
00161 }
00162
00163 GENESISAPI geBoolean GENESISCC gePhysicsObject_Destroy(gePhysicsObject** pPhysob)
00164 {
00165 assert(pPhysob != NULL);
00166 assert(*pPhysob != NULL);
00167
00168 geRam_Free(*pPhysob);
00169 *pPhysob = NULL;
00170
00171 return GE_TRUE;
00172 }
00173
00175
00176
00177
00178 GENESISAPI geBoolean GENESISCC gePhysicsObject_ApplyGlobalFrameForce(gePhysicsObject* pod, geVec3d* force, geVec3d* radiusVector, geBoolean isAppliedForce,
00179 int configIndex)
00180 {
00181 gePhysicsObject_Config* pConfig;
00182 geVec3d torqueToAdd;
00183
00184 assert(pod != NULL);
00185 assert(force != NULL);
00186 assert(radiusVector != NULL);
00187 assert( configIndex >= 0 );
00188 assert( configIndex < 2 );
00189
00190 pConfig = &pod->configs[configIndex];
00191
00192 if (! isAppliedForce)
00193 {
00194 geVec3d_Add(force, &pConfig->force, &pConfig->force);
00195
00196 geVec3d_CrossProduct(radiusVector, force, &torqueToAdd);
00197 geVec3d_Add(&torqueToAdd, &pConfig->torque, &pConfig->torque);
00198 }
00199
00200 else
00201 {
00202 geVec3d_Add(force, &pConfig->appliedForce, &pConfig->appliedForce);
00203
00204 geVec3d_CrossProduct(radiusVector, force, &torqueToAdd);
00205 geVec3d_Add(&torqueToAdd, &pConfig->appliedTorque, &pConfig->appliedTorque);
00206 }
00207
00208 return GE_TRUE;
00209 }
00210
00211
00212 GENESISAPI geBoolean GENESISCC gePhysicsObject_ApplyGlobalFrameImpulse(
00213 gePhysicsObject* pPhysob,
00214 geVec3d* pImpulse,
00215 geVec3d* pRadVec,
00216 int configIndex)
00217 {
00218 gePhysicsObject_Config* pConfig;
00219 Matrix33 R, Rt;
00220 geVec3d rCrossRW, rCrossRL, dv, dw;
00221 assert( pPhysob != NULL );
00222 assert( pImpulse != NULL );
00223 assert( pRadVec != NULL );
00224 assert( configIndex >= 0 );
00225 assert( configIndex < 2 );
00226
00227 pConfig = &pPhysob->configs[configIndex];
00228
00229 geVec3d_Scale(pImpulse, pPhysob->oneOverMass, &dv);
00230 geVec3d_Add(&dv, &pConfig->linearVelocity, &pConfig->linearVelocity);
00231
00232 geVec3d_CrossProduct(pRadVec, pImpulse, &rCrossRW);
00233
00234 Matrix33_ExtractFromXForm3d(&pConfig->xform, &R);
00235 Matrix33_GetTranspose(&R, &Rt);
00236
00237 Matrix33_MultiplyVec3d(&Rt, &rCrossRW, &rCrossRL);
00238 Matrix33_MultiplyVec3d(&pPhysob->inertiaTensorInverse, &rCrossRL, &dw);
00239 geVec3d_Add(&dw, &pConfig->angularVelocity, &pConfig->angularVelocity);
00240
00241 return GE_TRUE;
00242 }
00243
00244 GENESISAPI geBoolean GENESISCC gePhysicsObject_ComputeForces(gePhysicsObject* pod, int configIndex)
00245 {
00246 gePhysicsObject_Config* pConfig = &pod->configs[configIndex];
00247 assert( configIndex >= 0 );
00248 assert( configIndex < 2 );
00249 assert( pod != NULL );
00250
00251
00252 geVec3d_Scale(&pConfig->linearVelocity, 1.f - pod->linearDamping, &pConfig->linearVelocity);
00253 geVec3d_Scale(&pConfig->angularVelocity, 1.f - pod->angularDamping, &pConfig->angularVelocity);
00254
00255
00256 geVec3d_Clear(&pConfig->force);
00257 geVec3d_Clear(&pConfig->torque);
00258
00259
00260 if (pod->isAffectedByGravity)
00261 geVec3d_Set(&pConfig->force, 0.f, PHYSICSOBJECT_GRAVITY * pod->mass, 0.f);
00262
00263
00264 if (! pod->respondsToForces) return GE_TRUE;
00265
00266 geVec3d_Add(&pConfig->appliedForce, &pConfig->force, &pConfig->force);
00267 geVec3d_Add(&pConfig->appliedTorque, &pConfig->torque, &pConfig->torque);
00268
00269 return GE_TRUE;
00270 }
00271
00273
00274
00275 GENESISAPI geBoolean GENESISCC gePhysicsObject_Integrate(
00276 gePhysicsObject* pod,
00277 geFloat dt,
00278 int sourceConfigIndex)
00279 {
00280 gePhysicsObject_Config* pSourceConfig, *pTargetConfig;
00281 geVec3d tau;
00282 geVec3d a, dv;
00283 geVec3d angularMomentum, angularAcceleration;
00284 geVec3d omega_x_L, term1, dtTimesOmega;
00285 Matrix33 R, Rt;
00286
00287 geFloat qmag;
00288 geQuaternion qdot;
00289 geFloat G[3][4], Gt[4][3];
00290 int i, j;
00291 static int M[]={0x696C6345,0x21657370};
00292 geFloat dt2 = 0.5f * (dt * dt);
00293
00294 assert( sourceConfigIndex >= 0 );
00295 assert( sourceConfigIndex < 2 );
00296 assert( pod != NULL );
00297
00299
00300 pSourceConfig = &pod->configs[sourceConfigIndex];
00301 pTargetConfig = &pod->configs[1 - sourceConfigIndex];
00302
00303 geVec3d_Scale(&pSourceConfig->force, pod->oneOverMass, &a);
00304 geVec3d_Scale(&a, dt, &dv);
00305 geVec3d_Add(&pSourceConfig->linearVelocity, &dv, &pTargetConfig->linearVelocity);
00306
00308
00309 Matrix33_MultiplyVec3d(&pod->inertiaTensor, &pSourceConfig->angularVelocity, &angularMomentum);
00310 geVec3d_CrossProduct(&pSourceConfig->angularVelocity, &angularMomentum, &omega_x_L);
00311
00313
00314
00315 Matrix33_ExtractFromXForm3d(&pSourceConfig->xform, &R);
00316 Matrix33_GetTranspose(&R, &Rt);
00317 Matrix33_MultiplyVec3d(&Rt, &pSourceConfig->torque, &tau);
00318
00319 geVec3d_Subtract(&tau, &omega_x_L, &term1);
00320
00321 Matrix33_MultiplyVec3d(&pod->inertiaTensorInverse, &term1, &angularAcceleration);
00322
00323 geXForm3d_Rotate(&pSourceConfig->xform, &pSourceConfig->angularVelocity, &dtTimesOmega);
00324 geVec3d_Scale(&dtTimesOmega, dt, &dtTimesOmega);
00325
00326 G[0][0] = -pSourceConfig->orientation.X;
00327 G[0][1] = pSourceConfig->orientation.W;
00328 G[0][2] = -pSourceConfig->orientation.Z;
00329 G[0][3] = pSourceConfig->orientation.Y;
00330
00331 G[1][0] = -pSourceConfig->orientation.Y;
00332 G[1][1] = pSourceConfig->orientation.Z;
00333 G[1][2] = pSourceConfig->orientation.W;
00334 G[1][3] = -pSourceConfig->orientation.X;
00335
00336 G[2][0] = -pSourceConfig->orientation.Z;
00337 G[2][1] = -pSourceConfig->orientation.Y;
00338 G[2][2] = pSourceConfig->orientation.X;
00339 G[2][3] = pSourceConfig->orientation.W;
00340
00341 for (i = 0; i < 3; i++)
00342 for (j = 0; j < 4; j++)
00343 Gt[j][i] = 0.5f * G[i][j];
00344
00345 qdot.W = Gt[0][0] * dtTimesOmega.X + Gt[0][1] * dtTimesOmega.Y + Gt[0][2] * dtTimesOmega.Z;
00346 qdot.X = Gt[1][0] * dtTimesOmega.X + Gt[1][1] * dtTimesOmega.Y + Gt[1][2] * dtTimesOmega.Z;
00347 qdot.Y = Gt[2][0] * dtTimesOmega.X + Gt[2][1] * dtTimesOmega.Y + Gt[2][2] * dtTimesOmega.Z;
00348 qdot.Z = Gt[3][0] * dtTimesOmega.X + Gt[3][1] * dtTimesOmega.Y + Gt[3][2] * dtTimesOmega.Z;
00349
00350 pTargetConfig->orientation.W = pSourceConfig->orientation.W + qdot.W;
00351 pTargetConfig->orientation.X = pSourceConfig->orientation.X + qdot.X;
00352 pTargetConfig->orientation.Y = pSourceConfig->orientation.Y + qdot.Y;
00353 pTargetConfig->orientation.Z = pSourceConfig->orientation.Z + qdot.Z;
00354
00355 qmag = geQuaternion_Normalize(&pTargetConfig->orientation);
00356 geQuaternion_ToMatrix(&pTargetConfig->orientation, &pTargetConfig->xform);
00357
00358 pTargetConfig->angularVelocity.X = pSourceConfig->angularVelocity.X + dt * angularAcceleration.X;
00359 pTargetConfig->angularVelocity.Y = pSourceConfig->angularVelocity.Y + dt * angularAcceleration.Y;
00360 pTargetConfig->angularVelocity.Z = pSourceConfig->angularVelocity.Z + dt * angularAcceleration.Z;
00361
00363
00364 pTargetConfig->xform.Translation.X =
00365 pSourceConfig->xform.Translation.X + dt * pSourceConfig->linearVelocity.X + dt2 * a.X;
00366 pTargetConfig->xform.Translation.Y =
00367 pSourceConfig->xform.Translation.Y + dt * pSourceConfig->linearVelocity.Y + dt2 * a.Y;
00368 pTargetConfig->xform.Translation.Z =
00369 pSourceConfig->xform.Translation.Z + dt * pSourceConfig->linearVelocity.Z + dt2 * a.Z;
00370
00371 return GE_TRUE;
00372 }
00373
00374 GENESISAPI geFloat GENESISCC gePhysicsObject_GetMass(const gePhysicsObject* po)
00375 {
00376 assert(po != NULL);
00377
00378 return po->mass;
00379 }
00380
00381 GENESISAPI void GENESISCC gePhysicsObject_SetMass(gePhysicsObject* po, geFloat mass)
00382 {
00383 assert(po != NULL);
00384
00385 po->mass = mass;
00386
00387 #pragma message("TODO: set i tensor")
00388 }
00389
00390 GENESISAPI geFloat GENESISCC gePhysicsObject_GetOneOverMass(const gePhysicsObject* po)
00391 {
00392 assert(po != NULL);
00393
00394 return po->oneOverMass;
00395 }
00396
00397 GENESISAPI void GENESISCC gePhysicsObject_GetXForm( const gePhysicsObject* po,
00398 geXForm3d* xform,
00399 int configIndex)
00400 {
00401 assert(po != NULL);
00402 assert(xform != NULL);
00403 assert( configIndex >= 0 );
00404 assert( configIndex < 2 );
00405
00406 geXForm3d_Copy(&po->configs[configIndex].xform, xform);
00407 }
00408
00409 GENESISAPI void GENESISCC gePhysicsObject_SetXForm( gePhysicsObject* po,
00410 const geXForm3d* xform,
00411 int configIndex)
00412 {
00413 assert(po != NULL);
00414 assert(xform != NULL);
00415 assert( configIndex >= 0 );
00416 assert( configIndex < 2 );
00417
00418 geXForm3d_Copy(xform, &po->configs[configIndex].xform);
00419 }
00420
00421 GENESISAPI void GENESISCC gePhysicsObject_GetXFormInEditorSpace(const gePhysicsObject* po,
00422 geXForm3d* xform,
00423 int configIndex)
00424 {
00425 assert(po != NULL);
00426 assert(xform != NULL);
00427 assert( configIndex >= 0 );
00428 assert( configIndex < 2 );
00429
00430 geXForm3d_Copy(&po->configs[configIndex].xform, xform);
00431 geVec3d_Scale(&xform->Translation, 1 / po->physicsScale, &xform->Translation);
00432 }
00433
00434 GENESISAPI void GENESISCC gePhysicsObject_GetOriginalLocation(const gePhysicsObject* po, geVec3d* loc)
00435 {
00436 assert(po != NULL);
00437 assert(loc != NULL);
00438
00439 geVec3d_Copy(&po->OriginalLocation, loc);
00440 }
00441
00442 GENESISAPI void GENESISCC gePhysicsObject_SetOriginalLocation(gePhysicsObject* po, const geVec3d* loc)
00443 {
00444 assert(po != NULL);
00445 assert(loc != NULL);
00446
00447 geVec3d_Copy(loc, &po->OriginalLocation);
00448 }
00449
00451
00452 GENESISAPI void GENESISCC gePhysicsObject_GetLocation( const gePhysicsObject *po,
00453 geVec3d *Location,
00454 int configIndex)
00455 {
00456 assert(po != NULL);
00457 assert(Location != NULL);
00458 assert( configIndex >= 0 );
00459 assert( configIndex < 2 );
00460
00461 geVec3d_Add(&po->configs[configIndex].xform.Translation, &po->OriginalLocation, Location);
00462 }
00463
00464
00465 GENESISAPI void GENESISCC gePhysicsObject_GetLocationInEditorSpace(const gePhysicsObject* po,
00466 geVec3d* loc,
00467 int configIndex)
00468 {
00469 assert(po != NULL);
00470 assert(loc != NULL);
00471 assert( configIndex >= 0 );
00472 assert( configIndex < 2 );
00473
00474 geVec3d_Add(&po->OriginalLocation, &po->configs[configIndex].xform.Translation, loc);
00475 geVec3d_Scale(loc, 1 / po->physicsScale, loc);
00476 }
00477
00478 GENESISAPI void GENESISCC gePhysicsObject_GetLinearVelocity(const gePhysicsObject* po,
00479 geVec3d* vel,
00480 int configIndex)
00481 {
00482 assert(po != NULL);
00483 assert(vel != NULL);
00484 assert( configIndex >= 0 );
00485 assert( configIndex < 2 );
00486
00487 geVec3d_Copy(&po->configs[configIndex].linearVelocity, vel);
00488 }
00489
00490 GENESISAPI void GENESISCC gePhysicsObject_SetLinearVelocity(gePhysicsObject* po,
00491 const geVec3d* vel,
00492 int configIndex)
00493 {
00494 assert(po != NULL);
00495 assert(vel != NULL);
00496 assert( configIndex >= 0 );
00497 assert( configIndex < 2 );
00498
00499 geVec3d_Copy(vel, &po->configs[configIndex].linearVelocity);
00500 }
00501
00502 GENESISAPI void GENESISCC gePhysicsObject_GetAngularVelocity(const gePhysicsObject* po,
00503 geVec3d* vel,
00504 int configIndex)
00505 {
00506 assert(po != NULL);
00507 assert(vel != NULL);
00508 assert( configIndex >= 0 );
00509 assert( configIndex < 2 );
00510
00511 geVec3d_Copy(&po->configs[configIndex].angularVelocity, vel);
00512 }
00513
00514 GENESISAPI void GENESISCC gePhysicsObject_SetAngularVelocity(gePhysicsObject* po,
00515 const geVec3d* vel,
00516 int configIndex)
00517 {
00518 assert(po != NULL);
00519 assert(vel != NULL);
00520 assert( configIndex >= 0 );
00521 assert( configIndex < 2 );
00522
00523 geVec3d_Copy(vel, &po->configs[configIndex].angularVelocity);
00524 }
00525
00526 GENESISAPI void GENESISCC gePhysicsObject_GetForce( const gePhysicsObject* po,
00527 geVec3d* force,
00528 int configIndex)
00529 {
00530 assert(po != NULL);
00531 assert(force != NULL);
00532 assert( configIndex >= 0 );
00533 assert( configIndex < 2 );
00534
00535 geVec3d_Copy(&po->configs[configIndex].force, force);
00536 }
00537
00538 GENESISAPI void GENESISCC gePhysicsObject_SetForce( gePhysicsObject* po,
00539 const geVec3d* force,
00540 int configIndex)
00541 {
00542 assert(po != NULL);
00543 assert(force != NULL);
00544 assert( configIndex >= 0 );
00545 assert( configIndex < 2 );
00546
00547 geVec3d_Copy(force, &po->configs[configIndex].force);
00548 }
00549
00550 GENESISAPI void GENESISCC gePhysicsObject_GetTorque(const gePhysicsObject* po,
00551 geVec3d* torque,
00552 int configIndex)
00553 {
00554 assert(po != NULL);
00555 assert(torque != NULL);
00556 assert( configIndex >= 0 );
00557 assert( configIndex < 2 );
00558
00559 geVec3d_Copy(&po->configs[configIndex].torque, torque);
00560 }
00561
00562 GENESISAPI void GENESISCC gePhysicsObject_SetTorque(gePhysicsObject* po,
00563 const geVec3d* torque,
00564 int configIndex)
00565 {
00566 assert(po != NULL);
00567 assert(torque != NULL);
00568 assert( configIndex >= 0 );
00569 assert( configIndex < 2 );
00570
00571 geVec3d_Copy(torque, &po->configs[configIndex].torque);
00572 }
00573
00574 GENESISAPI void GENESISCC gePhysicsObject_GetAppliedForce( const gePhysicsObject* po,
00575 geVec3d* force,
00576 int configIndex)
00577 {
00578 assert(po != NULL);
00579 assert(force != NULL);
00580 assert( configIndex >= 0 );
00581 assert( configIndex < 2 );
00582
00583 geVec3d_Copy(&po->configs[configIndex].appliedForce, force);
00584 }
00585
00586 GENESISAPI void GENESISCC gePhysicsObject_SetAppliedForce( gePhysicsObject* po,
00587 const geVec3d* force,
00588 int configIndex)
00589 {
00590 assert(po != NULL);
00591 assert(force != NULL);
00592 assert( configIndex >= 0 );
00593 assert( configIndex < 2 );
00594
00595 geVec3d_Copy(force, &po->configs[configIndex].appliedForce);
00596 }
00597
00598 GENESISAPI void GENESISCC gePhysicsObject_GetAppliedTorque( const gePhysicsObject* po,
00599 geVec3d* torque,
00600 int configIndex)
00601 {
00602 assert(po != NULL);
00603 assert(torque != NULL);
00604 assert( configIndex >= 0 );
00605 assert( configIndex < 2 );
00606
00607 geVec3d_Copy(&po->configs[configIndex].appliedTorque, torque);
00608 }
00609
00610 GENESISAPI void GENESISCC gePhysicsObject_SetAppliedTorque( gePhysicsObject* po,
00611 const geVec3d* torque,
00612 int configIndex)
00613 {
00614 assert(po != NULL);
00615 assert(torque != NULL);
00616 assert( configIndex >= 0 );
00617 assert( configIndex < 2 );
00618
00619 geVec3d_Copy(torque, &po->configs[configIndex].appliedTorque);
00620 }
00621
00622 GENESISAPI void GENESISCC gePhysicsObject_ClearForce(gePhysicsObject* po, int configIndex)
00623 {
00624 assert(po != NULL);
00625 assert( configIndex >= 0 );
00626 assert( configIndex < 2 );
00627
00628 geVec3d_Clear(&po->configs[configIndex].force);
00629 }
00630
00631 GENESISAPI void GENESISCC gePhysicsObject_ClearTorque(gePhysicsObject* po, int configIndex)
00632 {
00633 assert(po != NULL);
00634 assert( configIndex >= 0 );
00635 assert( configIndex < 2 );
00636
00637 geVec3d_Clear(&po->configs[configIndex].torque);
00638 }
00639
00640 GENESISAPI void GENESISCC gePhysicsObject_ClearAppliedForce(gePhysicsObject* po, int configIndex)
00641 {
00642 assert(po != NULL);
00643 assert( configIndex >= 0 );
00644 assert( configIndex < 2 );
00645
00646 geVec3d_Clear(&po->configs[configIndex].appliedForce);
00647 }
00648
00649 GENESISAPI void GENESISCC gePhysicsObject_ClearAppliedTorque(gePhysicsObject* po, int configIndex)
00650 {
00651 assert(po != NULL);
00652 assert( configIndex >= 0 );
00653 assert( configIndex < 2 );
00654
00655 geVec3d_Clear(&po->configs[configIndex].appliedTorque);
00656 }
00657
00658 GENESISAPI void GENESISCC gePhysicsObject_IncForce( gePhysicsObject* po,
00659 const geVec3d* forceInc,
00660 int configIndex)
00661 {
00662 assert(po != NULL);
00663 assert(forceInc != NULL);
00664 assert( configIndex >= 0 );
00665 assert( configIndex < 2 );
00666
00667 geVec3d_Add(&po->configs[configIndex].force, forceInc, &po->configs[configIndex].force);
00668 }
00669
00670 GENESISAPI void GENESISCC gePhysicsObject_IncTorque(gePhysicsObject* po,
00671 const geVec3d* torqueInc,
00672 int configIndex)
00673 {
00674 assert(po != NULL);
00675 assert(torqueInc != NULL);
00676 assert( configIndex >= 0 );
00677 assert( configIndex < 2 );
00678
00679 geVec3d_Add(&po->configs[configIndex].torque, torqueInc, &po->configs[configIndex].torque);
00680 }
00681
00682 GENESISAPI void GENESISCC gePhysicsObject_IncAppliedForce( gePhysicsObject* po,
00683 const geVec3d* forceInc,
00684 int configIndex)
00685 {
00686 assert(po != NULL);
00687 assert(forceInc != NULL);
00688 assert( configIndex >= 0 );
00689 assert( configIndex < 2 );
00690
00691 geVec3d_Add(&po->configs[configIndex].appliedForce, forceInc, &po->configs[configIndex].appliedForce);
00692 }
00693
00694 GENESISAPI void GENESISCC gePhysicsObject_IncAppliedTorque(gePhysicsObject* po,
00695 const geVec3d* torqueInc, int configIndex)
00696 {
00697 assert(po != NULL);
00698 assert(torqueInc != NULL);
00699 assert( configIndex >= 0 );
00700 assert( configIndex < 2 );
00701
00702 geVec3d_Add(&po->configs[configIndex].appliedTorque, torqueInc, &po->configs[configIndex].appliedTorque);
00703 }
00704
00705 GENESISAPI void GENESISCC gePhysicsObject_GetOrientation( const gePhysicsObject* po,
00706 geQuaternion* orient, int configIndex)
00707 {
00708 assert(po != NULL);
00709 assert(orient != NULL);
00710 assert( configIndex >= 0 );
00711 assert( configIndex < 2 );
00712
00713 geQuaternion_Copy(&po->configs[configIndex].orientation, orient);
00714 }
00715
00716 GENESISAPI void GENESISCC gePhysicsObject_SetOrientation(gePhysicsObject* po,
00717 const geQuaternion* orient,
00718 int configIndex)
00719 {
00720 assert(po != NULL);
00721 assert(orient != NULL);
00722 assert( configIndex >= 0 );
00723 assert( configIndex < 2 );
00724
00725 geQuaternion_Copy(orient, &po->configs[configIndex].orientation);
00726 }
00727
00728
00729 GENESISAPI void GENESISCC gePhysicsObject_GetInertiaTensor(const gePhysicsObject* po, Matrix33* iTensor)
00730 {
00731 assert(po != NULL);
00732 assert(iTensor != NULL);
00733
00734 Matrix33_Copy(&po->inertiaTensor, iTensor);
00735 }
00736
00737 GENESISAPI void GENESISCC gePhysicsObject_GetInertiaTensorInverse(const gePhysicsObject* po, Matrix33* iTensorInv)
00738 {
00739 assert(po != NULL);
00740 assert(iTensorInv != NULL);
00741
00742 Matrix33_Copy(&po->inertiaTensorInverse, iTensorInv);
00743 }
00744
00745 GENESISAPI void GENESISCC gePhysicsObject_GetInertiaTensorInPhysicsSpace(
00746 const gePhysicsObject* pPhysob,
00747 Matrix33* pITensor,
00748 int configIndex)
00749 {
00750 Matrix33 R, Rt, RJ;
00751
00752 assert(pPhysob != NULL);
00753 assert(pITensor != NULL);
00754 assert( configIndex >= 0 );
00755 assert( configIndex < 2 );
00756
00757 Matrix33_ExtractFromXForm3d(&pPhysob->configs[configIndex].xform, &R);
00758 Matrix33_GetTranspose(&R, &Rt);
00759
00760 Matrix33_Multiply(&R, &pPhysob->inertiaTensor, &RJ);
00761 Matrix33_Multiply(&RJ, &Rt, pITensor);
00762 }
00763
00764 GENESISAPI void GENESISCC gePhysicsObject_GetInertiaTensorInverseInPhysicsSpace(
00765 const gePhysicsObject* pPhysob,
00766 Matrix33* pITensorInv,
00767 int configIndex)
00768 {
00769 Matrix33 R, Rt, RJi;
00770
00771 assert(pPhysob != NULL);
00772 assert(pITensorInv != NULL);
00773 assert( configIndex >= 0 );
00774 assert( configIndex < 2 );
00775
00776 Matrix33_ExtractFromXForm3d(&pPhysob->configs[configIndex].xform, &R);
00777 Matrix33_GetTranspose(&R, &Rt);
00778
00779 Matrix33_Multiply(&R, &pPhysob->inertiaTensorInverse, &RJi);
00780 Matrix33_Multiply(&RJi, &Rt, pITensorInv);
00781 }
00782
00783 GENESISAPI geBoolean GENESISCC gePhysicsObject_IsAffectedByGravity(const gePhysicsObject* po)
00784 {
00785 assert(po != NULL);
00786
00787 return po->isAffectedByGravity;
00788 }
00789
00790 GENESISAPI void GENESISCC gePhysicsObject_SetIsAffectedByGravity(gePhysicsObject* po, geBoolean flag)
00791 {
00792 assert(po != NULL);
00793
00794 po->isAffectedByGravity = flag;
00795 }
00796
00797 GENESISAPI geBoolean GENESISCC gePhysicsObject_RespondsToForces(const gePhysicsObject* po)
00798 {
00799 assert(po != NULL);
00800
00801 return po->respondsToForces;
00802 }
00803
00804 GENESISAPI void GENESISCC gePhysicsObject_SetRespondsToForces(gePhysicsObject* po, geBoolean flag)
00805 {
00806 assert(po != NULL);
00807
00808 po->respondsToForces = flag;
00809 }
00810
00811 GENESISAPI geFloat GENESISCC gePhysicsObject_GetLinearDamping(const gePhysicsObject* po)
00812 {
00813 assert(po != NULL);
00814
00815 return po->linearDamping;
00816 }
00817
00818 GENESISAPI void GENESISCC gePhysicsObject_SetLinearDamping(gePhysicsObject* po, geFloat linearDamping)
00819 {
00820 assert(po != NULL);
00821 assert(linearDamping >= 0.f && linearDamping <= 1.f);
00822
00823 po->linearDamping = linearDamping;
00824 }
00825
00826 GENESISAPI geFloat GENESISCC gePhysicsObject_GetAngularDamping(const gePhysicsObject* po)
00827 {
00828 assert(po != NULL);
00829
00830 return po->angularDamping;
00831 }
00832
00833 GENESISAPI void GENESISCC gePhysicsObject_SetAngularDamping(gePhysicsObject* po, geFloat angularDamping)
00834 {
00835 assert(po != NULL);
00836 assert(angularDamping >= 0.f && angularDamping <= 1.f);
00837
00838 po->angularDamping = angularDamping;
00839 }
00840
00841 GENESISAPI void GENESISCC gePhysicsObject_SetActiveConfig(gePhysicsObject* pPhysob, int configIndex)
00842 {
00843 assert(pPhysob != NULL);
00844 pPhysob->activeConfig = configIndex;
00845 }
00846
00847 GENESISAPI int GENESISCC gePhysicsObject_GetActiveConfig(gePhysicsObject* pPhysob)
00848 {
00849 assert(pPhysob != NULL);
00850 return pPhysob->activeConfig;
00851 }
00852
00853 GENESISAPI void GENESISCC gePhysicsObject_SetPhysicsScale(gePhysicsObject* pPhysob, geFloat scale)
00854 {
00855 assert(pPhysob != NULL);
00856 pPhysob->physicsScale = scale;
00857 }
00858
00859 GENESISAPI geFloat GENESISCC gePhysicsObject_GetPhysicsScale(gePhysicsObject* pPhysob)
00860 {
00861 assert(pPhysob != NULL);
00862 return pPhysob->physicsScale;
00863 }
00864