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 #ifndef PHY_SPACE_H
00028 #define PHY_SPACE_H
00029
00030 #include <PVLE/Export.h>
00031 #include <PVLE/Physics/AbstractGeom.h>
00032 #include <PVLE/Physics/Geom.h>
00033 #include <set>
00034 #include <algorithm>
00035
00036 #pragma warning(push)
00037 #pragma warning(disable : 4345) // For SpaceTypeInfo ONLY - Stupid warning about the fact that SimpleData is POD type in boost::variant.
00038
00039
00040 #include <boost/variant/variant.hpp>
00041 #include <boost/variant/get.hpp>
00042
00043 #pragma warning(pop)
00044
00045
00046 class C3DPhy;
00047
00048 namespace Physics {
00049
00050
00051
00052
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 #pragma warning(push)
00073 #pragma warning(disable : 4345) // For SpaceTypeInfo ONLY - Stupid warning about the fact that SimpleData is POD type in boost::variant.
00074
00078 class SpaceTypeInfo {
00079 public:
00080 enum ESpaceType { SIMPLE, HASH, QUAD, SWEEP_AND_PRUNE };
00081
00083 SpaceTypeInfo(ESpaceType type = SIMPLE) { setType(type); }
00084
00086 inline ESpaceType getType() const { return type; }
00087
00088 void setType(ESpaceType type) {
00089 this->type = type;
00090 if (type == SIMPLE) setTypeSimple();
00091 else if (type == HASH) setTypeHash();
00092 else if (type == QUAD) setTypeQuad();
00093 else if (type == SWEEP_AND_PRUNE) setTypeSweepAndPrune();
00094 }
00095
00097 struct HashData {
00098 UINT minLevel, maxLevel;
00099 };
00100
00102 struct QuadData {
00103 osg::Vec3 worldBox, center;
00104 UINT level;
00105 };
00106
00109 enum ESAPAxesOrder {
00110 SAP_AXES_XYZ = dSAP_AXES_XYZ,
00111 SAP_AXES_XZY = dSAP_AXES_XZY,
00112 SAP_AXES_YXZ = dSAP_AXES_YXZ,
00113 SAP_AXES_YZX = dSAP_AXES_YZX,
00114 SAP_AXES_ZXY = dSAP_AXES_ZXY,
00115 SAP_AXES_ZYX = dSAP_AXES_ZYX
00116 };
00117
00119 struct SweepAndPruneData {
00120 ESAPAxesOrder axisOrder;
00121 };
00122
00124 inline HashData & getHashData() { ASSERT(type == HASH); return boost::get<HashData>(data); }
00126 inline const HashData & getHashData() const { ASSERT(type == HASH); return boost::get<HashData>(data); }
00128 inline QuadData & getQuadData() { ASSERT(type == QUAD); return boost::get<QuadData>(data); }
00130 inline const QuadData & getQuadData() const { ASSERT(type == QUAD); return boost::get<QuadData>(data); }
00132 inline SweepAndPruneData & getSweepAndPruneData() { ASSERT(type == SWEEP_AND_PRUNE); return boost::get<SweepAndPruneData>(data); }
00134 inline const SweepAndPruneData & getSweepAndPruneData() const { ASSERT(type == SWEEP_AND_PRUNE); return boost::get<SweepAndPruneData>(data); }
00135
00136
00137 inline void setTypeSimple() {
00138 type = SIMPLE;
00139 data = SimpleData();
00140 }
00141
00142 inline HashData & setTypeHash() {
00143 type = HASH;
00144 HashData hash;
00145
00146 hash.minLevel = 1;
00147 hash.maxLevel = 4;
00148 data = hash;
00149 return getHashData();
00150 }
00151
00152 inline QuadData & setTypeQuad() {
00153 type = QUAD;
00154 QuadData quad;
00155
00156 quad.worldBox = osg::Vec3(1e7, 1e7, 1e7);
00157 quad.center = osg::Vec3(0,0,0);
00158 quad.level = 4;
00159 data = quad;
00160 return getQuadData();
00161 }
00162
00163 inline SweepAndPruneData & setTypeSweepAndPrune() {
00164 type = SWEEP_AND_PRUNE;
00165 SweepAndPruneData sap;
00166
00167 sap.axisOrder = SAP_AXES_XYZ;
00168 data = sap;
00169 return getSweepAndPruneData();
00170 }
00171
00172 protected:
00173 ESpaceType type;
00174
00175
00176 struct SimpleData {};
00177
00178 boost::variant<HashData, QuadData, SweepAndPruneData, SimpleData> data;
00179 };
00180
00181
00182 #pragma warning(pop)
00183
00184
00185
00186 class Visitor;
00187
00194 class PVLE_EXPORT Space : public AbstractGeom {
00195 public:
00197 Space() : collided(false) { init(); }
00199 Space(const SpaceTypeInfo & spaceTypeInfo) : collided(false), typeInfo(spaceTypeInfo) { init(); }
00201 Space(const osg::Vec3 & worldBox) : collided(false) { typeInfo.setTypeQuad().worldBox = worldBox; init(); }
00202
00203 Space(const Space & v, UINT opts = COPY_ALL, IGeomCollisionContainer * pGeomsContainer = NULL, TDuplicatedBodiesMap * pDuplicatedBodies = NULL);
00204
00205
00206
00207 virtual Space * asSpace() { return this; }
00208 virtual const Space * asSpace() const { return this; }
00209
00210 typedef std::set<osg::ref_ptr<AbstractGeom> > TListGeoms;
00211 TListGeoms::const_iterator getGeomsBegin() const { return vGeoms.begin(); }
00212 TListGeoms::const_iterator getGeomsEnd() const { return vGeoms.end(); }
00213
00214 #ifdef ENABLE_PHYSICS_EXTRA_WRAPPING
00215 UINT nbGeoms() const { ASSERT(vGeoms.size() == dSpaceGetNumGeoms(reinterpret_cast<dSpaceID>(id))); return vGeoms.size(); }
00216 #endif
00217 bool isInSpace(AbstractGeom * pAbstractGeom) const;
00218
00220 void add(AbstractGeom * pAbstractGeom);
00222 void add(C3DPhy & r3DPhy);
00223
00225 void remove(AbstractGeom * pAbstractGeom);
00226 void removeAll();
00227 void remove(C3DPhy & r3DPhy);
00228
00229 virtual void accept(Visitor & v);
00230 virtual void traverse(Visitor & v);
00231
00232 SpaceTypeInfo::ESpaceType getType() const {
00233 return typeInfo.getType();
00234
00235 };
00236
00237 #ifdef ENABLE_PHYSICS_EXTRA_WRAPPING
00238 int getSublevel() const { return dSpaceGetSublevel(reinterpret_cast<dSpaceID>(id)); }
00239 void getSublevel(int subLevel) { return dSpaceSetSublevel(reinterpret_cast<dSpaceID>(id), subLevel); }
00240 #endif
00241
00242 operator dSpaceID() { return reinterpret_cast<dSpaceID>(id); }
00243 operator const dSpaceID() const { return reinterpret_cast<dSpaceID>(id); }
00244
00245 protected:
00246 friend class World;
00247
00248 TListGeoms vGeoms;
00249
00250 bool collided;
00251
00252 SpaceTypeInfo typeInfo;
00253
00254 virtual ~Space();
00255
00256 private:
00257 void init();
00258 void initSimple();
00259 void initHash(UINT minLevel, UINT maxLevel);
00260 void initQuad(osg::Vec3 worldBox, osg::Vec3 center = osg::Vec3(0,0,0), UINT level = 4);
00261 void initSweepAndPrune(int axesOrder);
00262 };
00263
00264
00265 }
00266
00267 #endif // PHY_SPACE_H