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
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
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
00079
00080
00081
00082 return NULL;
00083 }
00084 #if 0
00085 if (pJoint->Next == pJoint)
00086 {
00087
00088
00089
00090
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
00109
00110
00111
00112 return NULL;
00113 }
00114 #if 0
00115 if (pJoint->Next == pJoint)
00116 {
00117
00118
00119
00120
00121
00122 }
00123 #endif
00124 if (PS1 == PS2)
00125 {
00126
00127
00128
00129
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
00148
00149
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