Main Page | Alphabetical List | Compound List | File List | Compound Members | File Members

PhysicsSystem.c

Go to the documentation of this file.
00001 /****************************************************************************************/
00002 /*  PHYSICSSYSTEM.C                                                                     */
00003 /*                                                                                      */
00004 /*  Author: Jason Wood                                                                  */
00005 /*  Description: Rigid body, constraint based physics system implementation             */
00006 /*                                                                                      */
00007 /*  The contents of this file are subject to the Genesis3D Public License               */
00008 /*  Version 1.01 (the "License"); you may not use this file except in                   */
00009 /*  compliance with the License. You may obtain a copy of the License at                */
00010 /*  http://www.genesis3d.com                                                            */
00011 /*                                                                                      */
00012 /*  Software distributed under the License is distributed on an "AS IS"                 */
00013 /*  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See                */
00014 /*  the License for the specific language governing rights and limitations              */
00015 /*  under the License.                                                                  */
00016 /*                                                                                      */
00017 /*  The Original Code is Genesis3D, released March 25, 1999.                            */
00018 /*Genesis3D Version 1.1 released November 15, 1999                            */
00019 /*  Copyright (C) 1999 WildTangent, Inc. All Rights Reserved           */
00020 /*                                                                                      */
00021 /****************************************************************************************/
00022 #include <stdio.h>
00023 #include <math.h>
00024 #include <assert.h>
00025 #include <string.h>
00026 #include <float.h>
00027 
00028 #include "vec3d.h"
00029 #include "xform3d.h"
00030 #include "ram.h"
00031 #include "matrix33.h"
00032 #include "quatern.h"
00033 
00034 #include "PhysicsObject.h"
00035 #include "PhysicsJoint.h"
00036 #include "PhysicsSystem.h"
00037 
00038 typedef struct LinearSystemStruct
00039 {       
00040         geFloat ** M;
00041         geFloat * X;
00042         geFloat * KVector;
00043 }       LinearSystemStruct;
00044 
00045 typedef struct gePhysicsSystem
00046 {       
00047         int                                                                             sumOfConstraintDimensions;
00048         LinearSystemStruct                                              *linsys;
00049         int                                                                             PhysicsObjectCount;
00050         int                                                                             PhysicsJointCount;
00051         gePhysicsObject                                                 **Objects;
00052         gePhysicsJoint                                                  **Joints;
00053         geFloat physicsScale;
00054 
00055         int sourceConfigIndex, targetConfigIndex;
00056 
00057 }       gePhysicsSystem;
00058 
00059 
00060 static geBoolean gePhysicsSystem_EnforceConstraints(gePhysicsSystem* physsysPtr, geFloat subStepSize);
00061 static geBoolean gePhysicsSystem_SolveForConstraintForces(gePhysicsSystem* physsysPtr);
00062 
00063 static  Matrix33 gePhysicsSystemIdentityMatrix;
00064 
00065 GENESISAPI gePhysicsSystem* GENESISCC gePhysicsSystem_Create(void)
00066 {
00067         gePhysicsSystem* pPhyssys;
00068 
00069         pPhyssys = NULL;
00070         pPhyssys = GE_RAM_ALLOCATE_STRUCT(gePhysicsSystem);
00071         if (pPhyssys == NULL)
00072         {
00073                 return NULL;
00074         }       
00075 
00076         memset(pPhyssys, 0, sizeof(*pPhyssys));
00077 
00078         Matrix33_SetIdentity(&gePhysicsSystemIdentityMatrix);
00079 
00080         pPhyssys->sourceConfigIndex = 0;
00081         pPhyssys->targetConfigIndex = 1;
00082 
00083         return pPhyssys;
00084 }
00085 
00086 GENESISAPI geBoolean    GENESISCC gePhysicsSystem_AddObject(gePhysicsSystem *PS, gePhysicsObject *Object)
00087 {
00088         gePhysicsObject **      NewList;
00089         assert( PS != NULL );
00090 
00091         NewList = geRam_Realloc(PS->Objects, sizeof(*NewList) * (PS->PhysicsObjectCount + 1));
00092         if      (!NewList)
00093                 return GE_FALSE;
00094 
00095         NewList[PS->PhysicsObjectCount] = Object;
00096         PS->PhysicsObjectCount++;
00097         PS->Objects = NewList;
00098 
00099         return GE_TRUE;
00100 }
00101 
00102 GENESISAPI geBoolean    GENESISCC gePhysicsSystem_AddJoint(gePhysicsSystem *PS, gePhysicsJoint *Joint)
00103 {
00104         gePhysicsJoint **       NewList;
00105         int                                     i;
00106         gePhysicsJoint_Kind type;
00107         assert( PS != NULL );
00108         assert( Joint != NULL );
00109 
00110         NewList = geRam_Realloc(PS->Joints, sizeof(*NewList) * (PS->PhysicsJointCount + 1));
00111         if      (!NewList)
00112                 return GE_FALSE;
00113 
00114         NewList[PS->PhysicsJointCount] = Joint;
00115         PS->PhysicsJointCount++;
00116         PS->Joints = NewList;
00117 
00118         // Free any old data
00119         if      (PS->linsys)
00120         {
00121                 assert(PS->linsys->M);
00122                 assert(PS->linsys->X);
00123                 assert(PS->linsys->KVector);
00124 
00125                 for (i = 0; i < PS->sumOfConstraintDimensions; i++)
00126                 {
00127                         assert(PS->linsys->M[i]);
00128                         geRam_Free(PS->linsys->M[i]);
00129                 }
00130 
00131                 geRam_Free(PS->linsys->M);
00132                 geRam_Free(PS->linsys->X);
00133                 geRam_Free(PS->linsys->KVector);
00134                 geRam_Free(PS->linsys);
00135         }
00136 
00137         PS->linsys = GE_RAM_ALLOCATE_STRUCT(LinearSystemStruct);
00138         if (PS->linsys == NULL)
00139         {
00140                 return GE_FALSE;
00141         }
00142 
00144         // compute size of linear system
00145 
00146         PS->sumOfConstraintDimensions = 0;
00147         for (   i = 0; i < PS->PhysicsJointCount; i++)
00148         {
00149                 type = gePhysicsJoint_GetType(NewList[i]);
00150                 switch (type)
00151                 {
00152                         case JT_WORLD:
00153                         case JT_SPHERICAL:
00154                                 PS->sumOfConstraintDimensions += 3;
00155                                 break;
00156 
00157                         default:
00158                                 // shouldn't happen !
00159                                 assert(!"Illegal joint kind");
00160                                 return GE_FALSE;
00161                 }
00162         }
00163 
00164         if (PS->sumOfConstraintDimensions == 0)
00165                 return GE_FALSE;
00166 
00168         // alloc mem for the linear system and handle exceptions
00169 
00170         PS->linsys->M = (geFloat**)geRam_Allocate(PS->sumOfConstraintDimensions * sizeof(geFloat*));
00171 
00172         if (PS->linsys->M == NULL)
00173         {
00174                 return GE_FALSE;
00175         }
00176 
00177         for (i = 0; i < PS->sumOfConstraintDimensions; i++)
00178         {
00179                 PS->linsys->M[i] = (geFloat*)geRam_Allocate(PS->sumOfConstraintDimensions * sizeof(geFloat));
00180 
00181                 if (PS->linsys->M[i] == NULL)
00182                 {
00183                         return GE_FALSE;
00184                 }
00185         }
00186 
00187         PS->linsys->X = (geFloat*)geRam_Allocate(PS->sumOfConstraintDimensions * sizeof(geFloat));
00188 
00189         if (PS->linsys->X == NULL)
00190         {
00191                 return GE_FALSE;
00192         }
00193 
00194         PS->linsys->KVector = (geFloat*)geRam_Allocate(PS->sumOfConstraintDimensions * sizeof(geFloat));
00195 
00196         if (PS->linsys->KVector == NULL)
00197         {
00198                 return GE_FALSE;
00199         }       
00200 
00201         return GE_TRUE;
00202 }
00203 
00204 GENESISAPI geBoolean GENESISCC gePhysicsSystem_Destroy(gePhysicsSystem** ppPhyssys)
00205 {
00206         gePhysicsSystem *pPhyssys;
00207         int                             i;
00208 
00209         pPhyssys = *ppPhyssys;
00210 
00211         geRam_Free(pPhyssys->Objects);
00212         geRam_Free(pPhyssys->Joints);
00213 
00214         // Free any old data
00215         if      (pPhyssys->linsys)
00216         {
00217                 assert(pPhyssys->linsys->M);
00218                 assert(pPhyssys->linsys->X);
00219                 assert(pPhyssys->linsys->KVector);
00220 
00221                 for (i = 0; i < pPhyssys->sumOfConstraintDimensions; i++)
00222                 {
00223                         assert(pPhyssys->linsys->M[i]);
00224                         geRam_Free(pPhyssys->linsys->M[i]);
00225                 }
00226 
00227                 geRam_Free(pPhyssys->linsys->M);
00228                 geRam_Free(pPhyssys->linsys->X);
00229                 geRam_Free(pPhyssys->linsys->KVector);
00230         }
00231 
00232         geRam_Free(pPhyssys->linsys);
00233         geRam_Free(*ppPhyssys);
00234         *ppPhyssys = NULL;
00235 
00236         return GE_TRUE;
00237 }
00238 
00240 // physics stuff follows
00241 
00242 static geFloat fmin(geFloat a, geFloat b)
00243 {
00244         return a < b ? a : b;
00245 }
00246 
00247 GENESISAPI geBoolean GENESISCC gePhysicsSystem_Iterate(gePhysicsSystem* psPtr, geFloat Time)
00248 {
00249         int                             i;
00250 
00251         int numIntegrationSteps;
00252         geFloat minAssemblyRate, subStepSize;
00253         geFloat amountIntegrated = 0.f;
00254 
00255         assert( psPtr != NULL );
00256 
00258         // integrate numIntegrationSteps times during the frame
00259         // this is done to ensure smoother motion and enforce constraint stability
00260 
00261         minAssemblyRate = FLT_MAX;
00262 
00263         if (psPtr->PhysicsJointCount == 0)
00264         {
00265                 numIntegrationSteps = 1;
00266         }
00267 
00268         else
00269                 numIntegrationSteps = 5;
00270 
00271         if (Time > 0.03f) Time = 0.03f;
00272 
00273         subStepSize = Time / numIntegrationSteps;
00274 
00275         for (   amountIntegrated = 0.f;
00276                                 amountIntegrated < Time;
00277                                 amountIntegrated += subStepSize)
00278         {
00279                 for     (i = 0; i < psPtr->PhysicsObjectCount; i++)
00280                 {
00281                         if (!gePhysicsObject_ComputeForces(psPtr->Objects[i], psPtr->sourceConfigIndex))
00282                                 return GE_FALSE;
00283                 }                       
00284 
00286                 // enforce constraints
00287 
00288                 if (psPtr->sumOfConstraintDimensions > 0)
00289                 {
00290                         if (!gePhysicsSystem_EnforceConstraints(psPtr, subStepSize))
00291                                 return GE_FALSE;
00292                 }
00293 
00294                 for     (i = 0; i < psPtr->PhysicsObjectCount; i++)
00295                 {
00296                         if (!gePhysicsObject_Integrate(psPtr->Objects[i], subStepSize, psPtr->sourceConfigIndex))
00297                                 return GE_FALSE;                                                        
00298                 }
00299 
00300                 psPtr->sourceConfigIndex = (psPtr->sourceConfigIndex == 0 ? 1 : 0);
00301                 psPtr->targetConfigIndex = (psPtr->targetConfigIndex == 0 ? 1 : 0);
00302                 
00303                 // let physical object's control fns update themselves          
00304         }
00305 
00306         for     (i = 0; i < psPtr->PhysicsObjectCount; i++)
00307         {
00308                 gePhysicsObject* pod;           
00309                 
00310                 pod = psPtr->Objects[i];
00311                 
00312                 gePhysicsObject_ClearAppliedForce(pod, psPtr->sourceConfigIndex);
00313                 gePhysicsObject_ClearAppliedTorque(pod, psPtr->sourceConfigIndex);
00314                 gePhysicsObject_SetActiveConfig(psPtr->Objects[i], psPtr->sourceConfigIndex);
00315         }
00316 
00317         return GE_TRUE;
00318 }
00319 
00320 static geBoolean gePhysicsSystem_EnforceConstraints(gePhysicsSystem* PS, geFloat subStepSize)
00321 {
00322         geFloat h, hSquared;
00323         geVec3d beta, D0, D1;
00324         geVec3d K;
00325         geVec3d rA, rB;
00326         geVec3d accA, accB;
00327         geVec3d velA, velB;
00328 
00329         Matrix33 tmpMat;
00330         Matrix33 term11, term12, term21, term22;
00331         Matrix33 rStarA, itA, itiA, rStarB, itB, itiB;
00332         Matrix33 rotA, rotB, rotAt, rotBt;
00333 
00334         geVec3d tmpVec;
00335         geVec3d jntLocA, jntLocB;
00336         geVec3d jntLocAWS, jntLocBWS;
00337         geVec3d offsetVecA, offsetVecB;
00338         geVec3d omegaA, LA, omegaB, LB;
00339         geVec3d zeroForceAccelerationA, zeroForceAccelerationB;
00340         geVec3d ptVelocityA, ptVelocityB;
00341         geVec3d alphaA, alphaB;
00342         geVec3d ptAccelerationA, ptAccelerationB;
00343 
00344         geVec3d linearVelocityA, linearVelocityB;
00345         geVec3d angularVelocityA, angularVelocityB;
00346 
00347         geXForm3d xformA, xformB;
00348 
00349         Matrix33 iTensorA, iTensorB;
00350         Matrix33 iTensorInvA, iTensorInvB;
00351 
00352         geVec3d constraintForce;
00353         Matrix33 Mblock;
00354 
00355         int i, j, k, iOffset;
00356         int size;
00357 
00358         int si;
00359 
00360         gePhysicsJoint* jntData;
00361         gePhysicsObject *podA, *podB;
00362 
00363         gePhysicsJoint_Kind type;
00364 
00366         // BEGIN
00367         assert( PS != NULL );
00368 
00369         si = PS->sourceConfigIndex;
00370 
00371         assert(PS != NULL);
00372 
00373         size = PS->sumOfConstraintDimensions;
00374 
00375         for (i = 0; i < size; i++)
00376                 for (j = 0; j < size; j++)
00377                         PS->linsys->M[i][j] = 0.f;
00378 
00379 
00380         for     (i = 0, iOffset = 0; i < PS->PhysicsJointCount; i++)
00381         {
00382                 jntData = PS->Joints[i];
00383                 h = gePhysicsJoint_GetAssemblyRate(jntData);
00384                 hSquared = h * h;
00385 
00387                 // compute joints' actual locations in the world
00388 
00389                 type = gePhysicsJoint_GetType(jntData);
00390 
00391                 switch(type)
00392                 {
00393                         case JT_WORLD:
00394                                 
00395                                 podA = gePhysicsJoint_GetObject1(jntData);
00396                                 
00397                                 assert(podA != NULL);                           
00398 
00399                                 gePhysicsObject_GetLocation(podA, &offsetVecA, si);
00400                                 gePhysicsObject_GetXForm(podA, &xformA, si);
00401                                 gePhysicsJoint_GetLocationA(jntData, &jntLocA);
00402 
00403                                 geXForm3d_Rotate(&xformA, &jntLocA, &rA);
00404                                 geVec3d_Add(&offsetVecA, &rA, &tmpVec);
00405                                 gePhysicsJoint_SetLocationAInWorldSpace(jntData, &tmpVec);
00406 
00407                                 Matrix33_MakeCrossProductMatrix33(&rA, &rStarA);
00408 
00409                                 Matrix33_ExtractFromXForm3d(&xformA, &rotA);
00410                                 Matrix33_GetTranspose(&rotA, &rotAt);
00411 
00412                                 gePhysicsObject_GetInertiaTensor(podA, &iTensorA);
00413                                 gePhysicsObject_GetInertiaTensorInverse(podA, &iTensorInvA);
00414 
00415                                 Matrix33_Multiply(&rotA, &iTensorA, &tmpMat);
00416                                 Matrix33_Multiply(&tmpMat, &rotAt, &itA);
00417 
00418                                 Matrix33_Multiply(&rotA, &iTensorInvA, &tmpMat);
00419                                 Matrix33_Multiply(&tmpMat, &rotAt, &itiA);
00420 
00421                                 gePhysicsObject_GetAngularVelocity(podA, &angularVelocityA, si);
00422 
00423                                 Matrix33_MultiplyVec3d(&rotA, &angularVelocityA, &omegaA);
00424                                 Matrix33_MultiplyVec3d(&itA, &omegaA, &LA);
00425 
00427                                 // create M submatrix
00428 
00429                                 Matrix33_MultiplyScalar(gePhysicsObject_GetOneOverMass(podA), &gePhysicsSystemIdentityMatrix, &term11);
00430                                 Matrix33_Multiply(&rStarA, &itiA, &tmpMat);
00431                                 Matrix33_Multiply(&tmpMat, &rStarA, &term12);
00432                                 Matrix33_Subtract(&term11, &term12, &Mblock);
00433 
00435                                 // compute deviation
00436 
00437                                 geVec3d_CrossProduct(&omegaA, &LA, &zeroForceAccelerationA);
00438                                 geVec3d_CrossProduct(&omegaA, &rA, &ptVelocityA);
00439                                 geVec3d_CrossProduct(&omegaA, &ptVelocityA, &alphaA);
00440                                 geVec3d_Add(&zeroForceAccelerationA, &alphaA, &ptAccelerationA);
00441 
00443                                 // tmpMat holds rStarA * itiA
00444 
00445                                 Matrix33_MultiplyVec3d(&tmpMat, &ptAccelerationA, &beta);
00446 
00447                                 gePhysicsObject_GetLinearVelocity(podA, &linearVelocityA, si);
00448                                 geVec3d_Add(&linearVelocityA, &ptVelocityA, &D1);
00449 
00450                                 gePhysicsJoint_GetLocationAInWorldSpace(jntData, &jntLocAWS);
00451                                 gePhysicsJoint_GetLocationB(jntData, &jntLocB);
00452                                 geVec3d_Subtract(&jntLocAWS, &jntLocB, &D0);
00453 
00455                                 // compute K subvector
00456 
00457                                 geVec3d_Scale(&D1, 2.f / h, &D1);
00458                                 geVec3d_Scale(&D0, 1.f / hSquared, &D0);
00459                                 geVec3d_Add(&beta, &D1, &K);
00460                                 geVec3d_Add(&D0, &K, &K);
00461 
00463                                 // fill linear system appropriately
00464 
00465                                 PS->linsys->KVector[iOffset] = -K.X;
00466                                 PS->linsys->KVector[iOffset + 1] = -K.Y;
00467                                 PS->linsys->KVector[iOffset + 2] = -K.Z;
00468 
00469                                 for (j = 0; j < 3; j++)
00470                                 {
00471                                         for (k = 0; k < 3; k++)
00472                                         {
00473                                                 PS->linsys->M[iOffset + j][iOffset + k] = Mblock.x[j][k];
00474                                         }
00475                                 }
00476 
00477                                 iOffset += 3;
00478                                 break;
00479                         
00480                         case JT_SPHERICAL:
00481 
00483                                  // compute joint locations in world space
00484                                 
00486                                 // for gePhysicsObject A
00487 
00488                                 podA = gePhysicsJoint_GetObject1(jntData);
00489 
00490                                 assert(podA != NULL);
00491 
00492                                 gePhysicsObject_GetLocation(podA, &offsetVecA, si);
00493                                 gePhysicsObject_GetXForm(podA, &xformA, si);
00494                                 gePhysicsJoint_GetLocationA(jntData, &jntLocA);
00495 
00496                                 geXForm3d_Rotate(&xformA, &jntLocA, &rA);                               
00497                                 geVec3d_Add(&offsetVecA, &rA, &tmpVec);
00498                                 gePhysicsJoint_SetLocationAInWorldSpace(jntData, &tmpVec);
00499 
00501                                 // for gePhysicsObject B
00502                                         
00503                                 podB = gePhysicsJoint_GetObject2(jntData);
00504 
00505                                 assert(podB != NULL);
00506 
00507                                 gePhysicsObject_GetLocation(podB, &offsetVecB, si);
00508                                 gePhysicsObject_GetXForm(podB, &xformB, si);
00509                                 gePhysicsJoint_GetLocationB(jntData, &jntLocB);
00510 
00511                                 geXForm3d_Rotate(&xformB, &jntLocB, &rB);                               
00512                                 geVec3d_Add(&offsetVecB, &rB, &tmpVec);
00513                                 gePhysicsJoint_SetLocationBInWorldSpace(jntData, &tmpVec);
00514 
00516                                 // do physics setup
00517 
00519                                 // for gePhysicsObject A                                                                
00520 
00521                                 Matrix33_MakeCrossProductMatrix33(&rA, &rStarA);
00522 
00523                                 Matrix33_ExtractFromXForm3d(&xformA, &rotA);
00524                                 Matrix33_GetTranspose(&rotA, &rotAt);
00525 
00526                                 gePhysicsObject_GetInertiaTensor(podA, &iTensorA);
00527                                 gePhysicsObject_GetInertiaTensorInverse(podA, &iTensorInvA);
00528 
00529                                 Matrix33_Multiply(&rotA, &iTensorA, &tmpMat);
00530                                 Matrix33_Multiply(&tmpMat, &rotAt, &itA);
00531 
00532                                 Matrix33_Multiply(&rotA, &iTensorInvA, &tmpMat);
00533                                 Matrix33_Multiply(&tmpMat, &rotAt, &itiA);
00534 
00535                                 gePhysicsObject_GetAngularVelocity(podA, &angularVelocityA, si);
00536 
00537                                 Matrix33_MultiplyVec3d(&rotA, &angularVelocityA, &omegaA);
00538                                 Matrix33_MultiplyVec3d(&itA, &omegaA, &LA);
00539 
00541                                 // for gePhysicsObject B                                
00542 
00543                                 Matrix33_MakeCrossProductMatrix33(&rB, &rStarB);
00544 
00545                                 Matrix33_ExtractFromXForm3d(&xformB, &rotB);
00546                                 Matrix33_GetTranspose(&rotB, &rotBt);
00547 
00548                                 gePhysicsObject_GetInertiaTensor(podB, &iTensorB);
00549                                 gePhysicsObject_GetInertiaTensorInverse(podB, &iTensorInvB);
00550 
00551                                 Matrix33_Multiply(&rotB, &iTensorB, &tmpMat);
00552                                 Matrix33_Multiply(&tmpMat, &rotBt, &itB);
00553 
00554                                 Matrix33_Multiply(&rotB, &iTensorInvB, &tmpMat);
00555                                 Matrix33_Multiply(&tmpMat, &rotBt, &itiB);
00556 
00557                                 gePhysicsObject_GetAngularVelocity(podB, &angularVelocityB, si);
00558 
00559                                 Matrix33_MultiplyVec3d(&rotB, &angularVelocityB, &omegaB);
00560                                 Matrix33_MultiplyVec3d(&itB, &omegaB, &LB);
00561 
00563                                 // create M submatrix
00564 
00565                                 Matrix33_MultiplyScalar(gePhysicsObject_GetOneOverMass(podA) + 
00566                                         gePhysicsObject_GetOneOverMass(podB), &gePhysicsSystemIdentityMatrix, &term11);
00567 
00568                                 Matrix33_Multiply(&rStarA, &itiA, &tmpMat);
00569                                 Matrix33_Multiply(&tmpMat, &rStarA, &term12);
00570 
00571                                 Matrix33_Multiply(&rStarB, &itiB, &tmpMat);
00572                                 Matrix33_Multiply(&tmpMat, &rStarB, &term22);
00573 
00574                                 Matrix33_Add(&term12, &term22, &term21);
00575         
00576                                 Matrix33_Subtract(&term11, &term21, &Mblock);
00577 
00579                                 // compute deviation
00580 
00581                                 geVec3d_CrossProduct(&omegaA, &LA, &zeroForceAccelerationA);
00582                                 geVec3d_CrossProduct(&omegaA, &rA, &ptVelocityA);
00583                                 geVec3d_CrossProduct(&omegaA, &ptVelocityA, &alphaA);
00584                                 geVec3d_Add(&zeroForceAccelerationA, &alphaA, &ptAccelerationA);
00585 
00586                                 geVec3d_CrossProduct(&omegaB, &LB, &zeroForceAccelerationB);
00587                                 geVec3d_CrossProduct(&omegaB, &rB, &ptVelocityB);
00588                                 geVec3d_CrossProduct(&omegaB, &ptVelocityB, &alphaB);
00589                                 geVec3d_Add(&zeroForceAccelerationB, &alphaB, &ptAccelerationB);
00590 
00591                                 Matrix33_MultiplyVec3d(&itiA, &ptAccelerationA, &tmpVec);
00592                                 Matrix33_MultiplyVec3d(&rStarA, &tmpVec, &accA);
00593 
00594                                 Matrix33_MultiplyVec3d(&itiB, &ptAccelerationB, &tmpVec);
00595                                 Matrix33_MultiplyVec3d(&rStarB, &tmpVec, &accB);                                                        
00596 
00597                                 geVec3d_Subtract(&accA, &accB, &beta);
00598 
00599                                 gePhysicsObject_GetLinearVelocity(podA, &linearVelocityA, si);
00600                                 geVec3d_Add(&linearVelocityA, &ptVelocityA, &velA);
00601                                 gePhysicsObject_GetLinearVelocity(podB, &linearVelocityB, si);
00602                                 geVec3d_Add(&linearVelocityB, &ptVelocityB, &velB);
00603 
00604                                 geVec3d_Subtract(&velA, &velB, &D1);
00605 
00606                                 gePhysicsJoint_GetLocationAInWorldSpace(jntData, &jntLocAWS);
00607                                 gePhysicsJoint_GetLocationBInWorldSpace(jntData, &jntLocBWS);
00608 
00609                                 geVec3d_Subtract(&jntLocAWS, &jntLocBWS, &D0);
00610 
00612                                 // compute K subvector
00613 
00614                                 geVec3d_Scale(&D1, 2.f / h, &D1);
00615                                 geVec3d_Scale(&D0, 1.f / hSquared, &D0);
00616                                 geVec3d_Add(&beta, &D1, &K);
00617                                 geVec3d_Add(&D0, &K, &K);
00618 
00620                                 // fill linear system appropriately
00621 
00622                                 PS->linsys->KVector[iOffset] = -K.X;
00623                                 PS->linsys->KVector[iOffset + 1] = -K.Y;
00624                                 PS->linsys->KVector[iOffset + 2] = -K.Z;
00625 
00626                                 for (j = 0; j < 3; j++)
00627                                 {
00628                                         for (k = 0; k < 3; k++)
00629                                         {
00630                                                 PS->linsys->M[iOffset + j][iOffset + k] = Mblock.x[j][k];
00631                                         }
00632                                 }
00633 
00634                                 iOffset += 3;
00635                                 break;
00636 
00637                         default:
00638                                 assert(!"Illegal joint type");
00639                                 break;
00640                 }       // switch               
00641         } // for
00642 
00643         if (!gePhysicsSystem_SolveForConstraintForces(PS))
00644         {
00645                 return GE_FALSE;
00646         }
00647 
00648         for     (i = 0, iOffset = 0; i < PS->PhysicsJointCount; i++)
00649         {
00650                 jntData = PS->Joints[i];
00651 
00653                 // compute joints' actual locations in the world
00654 
00655                 type = gePhysicsJoint_GetType(jntData);
00656 
00657                 switch(type)
00658                 {
00659                         case JT_WORLD:
00660 
00661                                 podA = gePhysicsJoint_GetObject1(jntData);
00662                                 assert(podA != NULL);
00663 
00664                                 gePhysicsObject_GetXForm(podA, &xformA, si);
00665                                 gePhysicsJoint_GetLocationA(jntData, &jntLocA);
00666                                 geXForm3d_Rotate(&xformA, &jntLocA, &rA);
00667 
00668                                 constraintForce.X = PS->linsys->X[iOffset];
00669                                 constraintForce.Y = PS->linsys->X[iOffset + 1];
00670                                 constraintForce.Z = PS->linsys->X[iOffset + 2];
00671 
00672                                 gePhysicsObject_ApplyGlobalFrameForce(podA, &constraintForce, &rA, GE_FALSE, si);
00673 
00674                                 iOffset += 3;
00675 
00676                                 break;
00677 
00678                         case JT_SPHERICAL:
00679 
00680                                 podA = gePhysicsJoint_GetObject1(jntData);
00681                                 assert(podA != NULL);
00682 
00683                                 gePhysicsObject_GetXForm(podA, &xformA, si);
00684                                 gePhysicsJoint_GetLocationA(jntData, &jntLocA);
00685                                 geXForm3d_Rotate(&xformA, &jntLocA, &rA);
00686 
00687                                 constraintForce.X = PS->linsys->X[iOffset];
00688                                 constraintForce.Y = PS->linsys->X[iOffset + 1];
00689                                 constraintForce.Z = PS->linsys->X[iOffset + 2];
00690 
00691                                 gePhysicsObject_ApplyGlobalFrameForce(podA, &constraintForce, &rA, GE_FALSE, si);
00692 
00694                                 // apply -ve force to gePhysicsObject B
00695 
00696                                 podB = gePhysicsJoint_GetObject2(jntData);
00697                                 assert(podB != NULL);
00698 
00699                                 gePhysicsObject_GetXForm(podB, &xformB, si);
00700                                 gePhysicsJoint_GetLocationB(jntData, &jntLocB);
00701                                 geXForm3d_Rotate(&xformB, &jntLocB, &rB);
00702 
00703                                 constraintForce.X = -constraintForce.X;
00704                                 constraintForce.Y = -constraintForce.Y;
00705                                 constraintForce.Z = -constraintForce.Z;
00706 
00707                                 gePhysicsObject_ApplyGlobalFrameForce(podB, &constraintForce, &rB, GE_FALSE, si);
00708 
00709                                 iOffset += 3;
00710 
00711                                 break;
00712 
00713                         default:
00714                                 break;
00715                 } // switch
00716         } // for
00717 
00718         return GE_TRUE;
00719 }
00720 
00721 static int imin(int a, int b)
00722 {
00723         return a < b ? a : b;
00724 }
00725 
00726 static geBoolean gePhysicsSystem_SolveForConstraintForces(gePhysicsSystem* PS)
00727 {
00728         int i, j, k, n;
00729         int ixend1, ixend2;
00730         geFloat num;
00731         geFloat** M;
00732         geFloat* b;
00733         geFloat* x;
00734 
00735         assert(PS != NULL);
00736         
00737         b = PS->linsys->KVector;
00738         x = PS->linsys->X;
00739         M = PS->linsys->M;
00740 
00741         assert(b != NULL);
00742         assert(x != NULL);
00743         assert(M != NULL);
00744 
00745         n = PS->sumOfConstraintDimensions;
00746 
00747         for (i = 0; i < n; i++)
00748         {
00749                 assert(M[i] != NULL);
00750 
00751                 if ((geFloat)fabs(M[i][i]) < (geFloat)(1e-5))
00752                 {
00753                         return GE_FALSE;
00754                 }
00755 
00756                 num = 1 / M[i][i];
00757 
00758                 for (j = i; j < n; j++)
00759                         M[i][j] *= num;
00760 
00761                 b[i] *= num;
00762                 
00763                                 
00764 
00765                 ixend1 = imin(n, i + 3);
00766 
00767                 for (j = i + 1; j < ixend1; j++)
00768                 {
00769                         num = M[j][i];
00770 
00771                         ixend2 = imin(n, i + 2);
00772 
00773                         for (k = i; k < ixend2; k++)
00774                         {
00775                                 M[i][k] -= num * M[i][k];
00776                         }
00777 
00778                         b[j] -= num * b[i];
00779                 }                               
00780         }
00781 
00783         // backsubstitute
00784 
00785         for (i = n - 1; i >= 0; i--)
00786         {
00787                 x[i] = b[i];
00788 
00789                 ixend1 = imin(n, i + 2);
00790 
00791                 for (j = i + 1; j < ixend1; j++)
00792                 {
00793                         x[i] -= M[i][j] * x[j];
00794                 }
00795         }
00796 
00797         return GE_TRUE;
00798 }
00799 
00800 GENESISAPI int GENESISCC gePhysicsSystem_GetSourceConfigIndex(const gePhysicsSystem* pSys)
00801 {
00802         assert(pSys != NULL);
00803 
00804         return pSys->sourceConfigIndex;
00805 }
00806 
00807 GENESISAPI gePhysicsObject** GENESISCC gePhysicsSystem_GetPhysicsObjects(const gePhysicsSystem* pSys)
00808 {
00809         assert(pSys != NULL);
00810 
00811         return pSys->Objects;
00812 }
00813 
00814 GENESISAPI gePhysicsJoint** GENESISCC gePhysicsSystem_GetPhysicsJoints(const gePhysicsSystem* pSys)
00815 {
00816         assert(pSys != NULL);
00817 
00818         return pSys->Joints;
00819 }
00820 
00821 GENESISAPI int GENESISCC gePhysicsSystem_GetNumPhysicsObjects(const gePhysicsSystem* pSys)
00822 {
00823         assert(pSys != NULL);
00824 
00825         return pSys->PhysicsObjectCount;
00826 }
00827 
00828 GENESISAPI int GENESISCC gePhysicsSystem_GetNumPhysicsJoints(const gePhysicsSystem* pSys)
00829 {
00830         assert(pSys != NULL);
00831 
00832         return pSys->PhysicsJointCount;
00833 }
00834 
00835 GENESISAPI int GENESISCC gePhysicsSystem_GetSumOfConstraintDimensions(const gePhysicsSystem* pSys)
00836 {
00837         assert(pSys != NULL);
00838 
00839         return pSys->sumOfConstraintDimensions;
00840 }
00841 

Generated on Tue Sep 30 12:36:09 2003 for GTestAndEngine by doxygen 1.3.2