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

PhysicsJoint.c

Go to the documentation of this file.
00001 /****************************************************************************************/
00002 /*  PHYSICSJOINT.H                                                                      */
00003 /*                                                                                      */
00004 /*  Author: Jason Wood                                                                  */
00005 /*  Description: Rigid body joint 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 <math.h>
00023 #include <assert.h>
00024 
00025 #include "vec3d.h"
00026 #include "xform3d.h"
00027 #include "ram.h"
00028 #include "matrix33.h"
00029 #include "quatern.h"
00030 
00031 #include "PhysicsObject.h"
00032 #include "PhysicsJoint.h"
00033 
00034 typedef struct gePhysicsJoint
00035 {
00036         gePhysicsJoint_Kind     Type;
00037         geVec3d                         locationA;
00038         geVec3d                         locationB;
00039         geVec3d                         locationAInWorldSpace;
00040         geVec3d                         locationBInWorldSpace;
00041         gePhysicsObject *               Object1;
00042         gePhysicsObject *               Object2;
00043         geFloat                         assemblyRate;
00044 }       gePhysicsJoint;
00045 
00046 #define JOINT_ASSEMBLY_RATE_MULTIPLIER (4.f)
00047 
00048 GENESISAPI gePhysicsJoint * GENESISCC gePhysicsJoint_Create(gePhysicsJoint_Kind Kind, const geVec3d *Location, 
00049         geFloat assemblyRate, gePhysicsObject *PS1, gePhysicsObject *PS2, geFloat physicsScale)
00050 {
00051         gePhysicsJoint* pPhysjnt;
00052         geVec3d         POLocation;
00053         geVec3d         physicsSpaceLocation;
00054 
00055         pPhysjnt = NULL;
00056         pPhysjnt = GE_RAM_ALLOCATE_STRUCT(gePhysicsJoint);
00057         if (pPhysjnt == NULL)
00058         {
00059                 return NULL;
00060         }
00061 
00063         // make sure the joint makes sense
00064 
00065         pPhysjnt->Type = Kind;
00066         pPhysjnt->assemblyRate = assemblyRate * JOINT_ASSEMBLY_RATE_MULTIPLIER;
00067         pPhysjnt->Object1 = PS1;
00068         pPhysjnt->Object2 = PS2;
00069 
00070         geVec3d_Scale(Location, physicsScale, &physicsSpaceLocation);
00071 
00072         switch (Kind)
00073         {
00074                 case JT_WORLD:
00075                         if (PS1 == NULL)
00076                         {
00077                                 /*
00078                                 GenVSI_Error(VSI, 
00079                                         GE_FALSE, 
00080                                         "Joint_Spawn: World joint needs non-NULL gePhysicsObject1 field.\n");
00081                                 */
00082                                 return NULL;
00083                         }
00084                         #if 0
00085                         if (pJoint->Next == pJoint)
00086                         {
00087                                 /*
00088                                 GenVSI_Error(VSI, 
00089                                         GE_FALSE, 
00090                                         "Joint_Spawn: Next field points to parent.\n");
00091                                 */
00092                                 return NULL;
00093                         }
00094                         #endif
00095                         
00096                         gePhysicsObject_GetLocation(PS1, &POLocation, 0);
00097 
00098                         geVec3d_Subtract(&physicsSpaceLocation,
00099                                 &POLocation,
00100                                 &pPhysjnt->locationA);
00101                         geVec3d_Copy(&physicsSpaceLocation, &pPhysjnt->locationB);
00102                         break;
00103 
00104                 case JT_SPHERICAL:
00105                         if (PS1 == NULL || PS2 == NULL)
00106                         {
00107                                 /*
00108                                 GenVSI_Error(VSI, 
00109                                         GE_FALSE, 
00110                                         "Joint_Spawn: Spherical joint needs 2 non-NULL gePhysicsObjects.\n");
00111                                 */
00112                                 return NULL;
00113                         }
00114                         #if 0
00115                         if (pJoint->Next == pJoint)
00116                         {
00117                                 /*
00118                                 GenVSI_Error(VSI, 
00119                                         GE_FALSE, 
00120                                         "Joint_Spawn: Next field points to parent.\n");
00121                                 */
00122                         }
00123                         #endif
00124                         if (PS1 == PS2)
00125                         {
00126                                 /*
00127                                 GenVSI_Error(VSI, 
00128                                         GE_FALSE, 
00129                                         "Joint_Spawn: Spherical joint: need 2 distinct gePhysicsObjects.\n");
00130                                 */
00131                                 return NULL;
00132                         }
00133 
00134                         gePhysicsObject_GetLocation(PS1, &POLocation, 0);
00135                         geVec3d_Subtract(&physicsSpaceLocation,
00136                                 &POLocation,
00137                                 &pPhysjnt->locationA);
00138 
00139                         gePhysicsObject_GetLocation(PS2, &POLocation, 0);
00140                         geVec3d_Subtract(&physicsSpaceLocation,
00141                                 &POLocation,
00142                                 &pPhysjnt->locationB);
00143                         break;
00144 
00145                 default:
00146                         /*
00147                         GenVSI_Error(VSI, 
00148                                 GE_FALSE, 
00149                                 "Joint_Spawn: unsupported joint type %d.\n", ij->jointType);
00150                         */
00151                         return NULL;
00152         }
00153 
00154         return pPhysjnt;
00155 }
00156 
00157 GENESISAPI geBoolean GENESISCC gePhysicsJoint_Destroy(gePhysicsJoint** ppPhysjnt)
00158 {
00159         assert(ppPhysjnt != NULL);
00160         assert(*ppPhysjnt != NULL);
00161 
00162         geRam_Free(*ppPhysjnt);
00163 
00164         *ppPhysjnt = NULL;
00165 
00166         return GE_TRUE;
00167 }
00168 
00169 GENESISAPI gePhysicsJoint_Kind GENESISCC gePhysicsJoint_GetType(const gePhysicsJoint* pPhysjnt)
00170 {
00171         assert(pPhysjnt != NULL);
00172 
00173         return pPhysjnt->Type;
00174 }
00175 
00176 GENESISAPI void GENESISCC gePhysicsJoint_GetLocationA(const gePhysicsJoint* pPhysjnt, geVec3d* pLoc)
00177 {
00178         assert(pPhysjnt != NULL);
00179         assert(pLoc != NULL);
00180         
00181         geVec3d_Copy(&pPhysjnt->locationA, pLoc);
00182 }
00183 
00184 GENESISAPI void GENESISCC gePhysicsJoint_GetLocationB(const gePhysicsJoint* pPhysjnt, geVec3d* pLoc)
00185 {
00186         assert(pPhysjnt != NULL);
00187         assert(pLoc != NULL);
00188         
00189         geVec3d_Copy(&pPhysjnt->locationB, pLoc);
00190 }
00191 
00192 GENESISAPI void GENESISCC gePhysicsJoint_SetLocationA(gePhysicsJoint* pPhysjnt, const geVec3d* pLoc)
00193 {
00194         assert(pPhysjnt != NULL);
00195         assert(pLoc != NULL);
00196         
00197         geVec3d_Copy(pLoc, &pPhysjnt->locationA);
00198 }
00199 
00200 GENESISAPI void GENESISCC gePhysicsJoint_SetLocationB(gePhysicsJoint* pPhysjnt, const geVec3d* pLoc)
00201 {
00202         assert(pPhysjnt != NULL);
00203         assert(pLoc != NULL);
00204         
00205         geVec3d_Copy(pLoc, &pPhysjnt->locationB);
00206 }
00207 
00208 GENESISAPI void GENESISCC gePhysicsJoint_GetLocationAInWorldSpace(const gePhysicsJoint* pPhysjnt, geVec3d* pLoc)
00209 {
00210         assert(pPhysjnt != NULL);
00211         assert(pLoc != NULL);
00212         
00213         geVec3d_Copy(&pPhysjnt->locationAInWorldSpace, pLoc);
00214 }
00215 
00216 GENESISAPI void GENESISCC gePhysicsJoint_GetLocationBInWorldSpace(const gePhysicsJoint* pPhysjnt, geVec3d* pLoc)
00217 {
00218         assert(pPhysjnt != NULL);
00219         assert(pLoc != NULL);
00220         
00221         geVec3d_Copy(&pPhysjnt->locationBInWorldSpace, pLoc);
00222 }
00223 
00224 GENESISAPI void GENESISCC gePhysicsJoint_SetLocationAInWorldSpace(gePhysicsJoint* pPhysjnt, const geVec3d* pLoc)
00225 {
00226         assert(pPhysjnt != NULL);
00227         assert(pLoc != NULL);
00228         
00229         geVec3d_Copy(pLoc, &pPhysjnt->locationAInWorldSpace);
00230 }
00231 
00232 GENESISAPI void GENESISCC gePhysicsJoint_SetLocationBInWorldSpace(gePhysicsJoint* pPhysjnt, const geVec3d* pLoc)
00233 {
00234         assert(pPhysjnt != NULL);
00235         assert(pLoc != NULL);
00236         
00237         geVec3d_Copy(pLoc, &pPhysjnt->locationBInWorldSpace);
00238 }
00239 
00240 GENESISAPI gePhysicsObject* GENESISCC gePhysicsJoint_GetObject1(const gePhysicsJoint* pPhysjnt)
00241 {
00242         assert(pPhysjnt != NULL);
00243 
00244         return pPhysjnt->Object1;
00245 }
00246 
00247 GENESISAPI gePhysicsObject* GENESISCC gePhysicsJoint_GetObject2(const gePhysicsJoint* pPhysjnt)
00248 {
00249         assert(pPhysjnt != NULL);
00250 
00251         return pPhysjnt->Object2;
00252 }
00253 
00254 GENESISAPI geFloat GENESISCC gePhysicsJoint_GetAssemblyRate(const gePhysicsJoint* pPhysjnt)
00255 {
00256         assert(pPhysjnt != NULL);
00257 
00258         return pPhysjnt->assemblyRate;
00259 }
00260 
00261 GENESISAPI void GENESISCC gePhysicsJoint_SetAssemblyRate(gePhysicsJoint* pPhysjnt, geFloat assemblyRate)
00262 {
00263         assert(pPhysjnt != NULL);
00264         assert(assemblyRate >= (geFloat)(1e-5));
00265 
00266         pPhysjnt->assemblyRate = assemblyRate;
00267 }
00268 

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