00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef _BASECOLLISIONHULL_
00019 #define _BASECOLLISIONHULL_
00020
00021 #include <boost/shared_ptr.hpp>
00022
00023 #include "contrib/xercesc/dom/DOM.hpp"
00024
00025 #include "game/BaseCollisionShape.h"
00026 #include "game/CircleCollisionShape.h"
00027 #include "game/PolygonCollisionShape.h"
00028
00029 #include "util/AbstractStreamedObject.h"
00030 #include "util/Attribute.h"
00031 #include "util/Macros.h"
00032
00033 #define DEFAULT_COLLISIONHULL_CONSTRUCTOR(class_name, initialization_list) \
00034 class_name##(const std::string & type) \
00035 :BaseCollisionHull(type) initialization_list \
00036 {\
00037 }
00038
00039 typedef std::vector<BaseCollisionShape*> CollisionShapeVector;
00040
00041 class ResourceCache;
00042
00043 class BaseCollisionHull : public AbstractStreamedObject
00044 {
00045 private:
00046
00047 CollisionShapeVector m_shapes;
00048
00049 ResourceCache* m_pResourceCache;
00050
00051 std::string m_type;
00052
00053 protected:
00054 void PushShape(BaseCollisionShape* pShape);
00055 void ClearShapes();
00056 public:
00057 BaseCollisionHull(const std::string & type)
00058 :m_type(type), m_pResourceCache(0)
00059 {
00060 }
00061
00062 BaseCollisionHull(const std::string & type, ResourceCache* pResourceCache)
00063 :m_type(type), m_pResourceCache(pResourceCache)
00064 {
00065 }
00066
00067 virtual ~BaseCollisionHull()
00068 {
00069 ClearShapes();
00070 }
00071
00072 const CollisionShapeVector & GetShapes() const { return m_shapes; }
00073
00074 void SetMaterial(const Material & material);
00075
00076 ResourceCache* GetResourceCache() const { return m_pResourceCache; }
00077 void SetResourceCache(ResourceCache* pResourceCache) { m_pResourceCache = pResourceCache; }
00078
00079 const std::string & GetType() const { return m_type; }
00080
00081 template<class T>
00082 T* CreateShape(const COLLISIONSHAPETYPE type);
00083
00084 virtual void ParseShapes() = 0;
00085 virtual bool FromAttribute(const Attribute * pRoot) = 0;
00086
00087 virtual void ToStream(std::ostream& stream) const;
00088 virtual void FromStream(std::istream& stream);
00089 };
00090
00091 typedef boost::shared_ptr<BaseCollisionHull> BaseCollisionHullPtr;
00092
00093 inline void BaseCollisionHull::SetMaterial(const Material & material)
00094 {
00095 FOREACH2(CollisionShapeVector, i, m_shapes)
00096 {
00097 (*i)->SetMaterial(material);
00098 }
00099 }
00100
00101 template<class T>
00102 inline T* BaseCollisionHull::CreateShape(const COLLISIONSHAPETYPE type)
00103 {
00104 BaseCollisionShape* pNewShape = 0;
00105 switch(type)
00106 {
00107 case COLLISIONSHAPETYPE_CIRCLE:
00108 {
00109 pNewShape = new CircleCollisionShape();
00110 }
00111 break;
00112 case COLLISIONSHAPETYPE_POLYGON:
00113 {
00114 pNewShape = new PolygonCollisionShape();
00115 }
00116 break;
00117 default:
00118 assert(false && "Invalid collision shape type!");
00119 }
00120 PushShape(pNewShape);
00121 return reinterpret_cast<T*>(pNewShape);
00122 }
00123
00124
00125 inline void BaseCollisionHull::PushShape(BaseCollisionShape* pShape)
00126 {
00127 m_shapes.push_back(pShape);
00128 }
00129
00130 inline void BaseCollisionHull::ClearShapes()
00131 {
00132 FOREACH(CollisionShapeVector, i, m_shapes)
00133 {
00134 delete *i;
00135 }
00136
00137 m_shapes.clear();
00138 }
00139
00140 inline void BaseCollisionHull::ToStream(std::ostream& stream) const
00141 {
00142 stream << m_shapes.size() << " ";
00143
00144 FOREACH(CollisionShapeVector, i, m_shapes)
00145 {
00146 stream << (*i)->GetType() << " ";
00147 (*i)->ToStream(stream);
00148 }
00149 }
00150
00151 inline void BaseCollisionHull::FromStream(std::istream& stream)
00152 {
00153 ClearShapes();
00154
00155 int nNumShapes = 0;
00156 stream >> nNumShapes;
00157
00158 for(int i = 0; i < nNumShapes; ++i)
00159 {
00160 int nType = 0;
00161 stream >> nType;
00162
00163 BaseCollisionShape* pNewShape = CreateShape<BaseCollisionShape>((COLLISIONSHAPETYPE)nType);
00164
00165 pNewShape->FromStream(stream);
00166 }
00167 }
00168
00169
00170 #endif