00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include <PVLE/Physics/World.h>
00028 #include <PVLE/Physics/Body.h>
00029 #include <PVLE/Physics/Geom.h>
00030 #include <PVLE/Physics/Space.h>
00031 #include <PVLE/Physics/Contact.h>
00032 #include <PVLE/Physics/GeometryHandlers.h>
00033 #include <PVLE/Physics/Visitor.h>
00034 #include <PVLE/Util/Assert.h>
00035 #include <PVLE/Config.h>
00036
00037 namespace Physics {
00038
00039 Geom::Geom(GeometryHandler * pGeometryHandler, const SurfaceParams & surfaceParams) :
00040 pGeomH(pGeometryHandler), pContainer(NULL), surface(surfaceParams), gameplayDensity(2000)
00041 {
00042 id = pGeomH->create(0);
00043 dGeomSetData(id, this);
00044 }
00045
00046 void Geom::accept(Visitor & v) { v.apply(*this); }
00047 void Geom::traverse(Visitor & v) {
00048 if (pBody.valid()) v.apply(*pBody);
00049 }
00050
00051
00052 #ifdef PVLE_PHYSICS_KEEP_DEPRECATED_TRANSFORMS
00053 Geom::Geom() :
00054 pContainer(NULL), gameplayDensity(2000)
00055 {}
00056 #endif
00057
00058 Geom::Geom(const Geom & v, UINT opts, IGeomCollisionContainer * pContainer, TDuplicatedBodiesMap * pDuplicatedBodies) :
00059 pGeomH(NULL), pContainer(pContainer)
00060 {
00061 pGeomH = v.pGeomH->clone();
00062 id = pGeomH->create(0);
00063 dGeomSetData(id, this);
00064
00065 dGeomSetPosition(id, dGeomGetPositionV(v));
00066 dGeomSetQuaternion(id, dGeomGetQuaternionV(v));
00067 if (dGeomIsEnabled(v)) dGeomEnable(*this); else dGeomDisable(*this);
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 if (opts & COPY_BODIES) {
00080 const Body * pOriginalBody = v.pBody.get();
00081 if (!pOriginalBody) {
00082
00083 setBody(NULL);
00084 } else {
00085
00086 if (!pDuplicatedBodies) {
00087
00088 setBody(new Body(*pOriginalBody));
00089 } else {
00090
00091 TDuplicatedBodiesMap::iterator it = pDuplicatedBodies->find(pOriginalBody);
00092 if (it != pDuplicatedBodies->end()) setBody(it->second);
00093 else {
00094
00095 setBody(new Body(*pOriginalBody));
00096 if (pDuplicatedBodies) pDuplicatedBodies->insert( TDuplicatedBody(pOriginalBody, pBody.get()) );
00097 }
00098 }
00099
00100
00101 ASSERT(pBody.valid());
00102 setOffsetMatrix(v.getOffsetMatrix());
00103 }
00104 }
00105
00106 surface = v.surface;
00107 gameplayDensity = v.gameplayDensity;
00108
00109 setMatrix(v.getMatrix());
00110 }
00111
00112
00113 void Geom::setBody(Body * pBody) {
00114 this->pBody = pBody;
00115 if (!pBody) {
00116 dGeomSetBody(id, 0);
00117 return;
00118 }
00119
00120 dGeomSetBody(id, pBody->id);
00121 applyHints();
00122 }
00123
00124
00125 void Geom::resetAndApplyHints() {
00126 if (!pBody) return;
00127 dBodySetAutoDisableDefaults(*pBody);
00128 applyHints();
00129 }
00130
00131
00132 void Geom::applyHints() {
00133
00134 ASSERT(pGeomH.valid() && pBody.valid());
00135 UINT flag = pGeomH->getADOverrideFlag();
00136 if (flag & GeometryHandler::AD_FLAG) dBodySetAutoDisableFlag(*pBody, pGeomH->getADFlag() ? 1 : 0);
00137 if (flag & GeometryHandler::AD_LINEAR) dBodySetAutoDisableLinearThreshold(*pBody, pGeomH->getADLinearThreshold());
00138 if (flag & GeometryHandler::AD_ANGULAR) dBodySetAutoDisableAngularThreshold(*pBody, pGeomH->getADAngularThreshold());
00139 if (flag & GeometryHandler::AD_STEPS) dBodySetAutoDisableSteps(*pBody, pGeomH->getADSteps());
00140 if (flag & GeometryHandler::AD_TIME) dBodySetAutoDisableTime(*pBody, pGeomH->getADTime());
00141 if (flag & GeometryHandler::AD_SAMPLES_COUNT) dBodySetAutoDisableAverageSamplesCount(*pBody, pGeomH->getADSamplesCount());
00142 }
00143
00144
00145 UINT Geom::collide(Geom * pGeom, UINT nbMaxContacts, Contact * pContacts) {
00146 return dCollide(id, pGeom->id, nbMaxContacts, &(pContacts[0].geom), sizeof(Contact));
00147 }
00148
00149 }