00001
00002
00003
00004
00005 #pragma once
00006 #include <ode/ode.h>
00007 #include <flatland/shapes.hpp>
00008 #include <flatland/flatland.hpp>
00009 #include <list>
00010 #include <stack>
00011
00012 using Flatland::vec2;
00013 using Flatland::Dynamic;
00014 using Flatland::Static;
00015 using Flatland::round;
00016
00017 namespace Demo
00018 {
00019 class Space;
00020
00021
00022 typedef unsigned int Texture;
00023
00024 struct RawColor { float r, g, b, a; };
00025
00026
00027 struct Color
00028 {
00029 Color() {}
00030 Color(float theta);
00031 void IncreaseBrightness(float factor);
00032 void DecreaseBrightness(float factor);
00033 static Color Blend(const Color &a, const Color &b, float mu);
00034 Color(RawColor raw) : raw(raw) {}
00035 operator RawColor() { return raw; }
00036 operator RawColor() const { return raw; }
00037 Color(float r, float g, float b, float a) : r(r), g(g), b(b), a(a) {}
00038 Color(const float *f) : r(f[0]), g(f[1]), b(f[2]), a(f[3]) {}
00039 union
00040 {
00041 struct { float r, g, b, a; };
00042 RawColor raw;
00043 };
00044 static Color Transparent, Black, White, PaleYellow, PaleGreen, PaleRed, Red, Green, Blue;
00045 };
00046
00047
00048 struct ObjectProperties
00049 {
00050 float outlineThickness;
00051 RawColor fillColor;
00052 RawColor altFillColor;
00053 RawColor outlineColor;
00054 bool offset;
00055 };
00056
00057
00058 class Object
00059 {
00060 public:
00061 Object() : properties(defaults) {}
00062 virtual ~Object() {}
00063 virtual void Draw() const = 0;
00064 virtual Flatland::Object *GetFlatlandObject() { return 0; }
00065 virtual void Insert(Space &space);
00066 virtual void InsertFront(Space &space);
00067 public:
00068 ObjectProperties &Property() { return properties; }
00069 const ObjectProperties &Property() const { return properties; }
00070 static ObjectProperties &Default() { return defaults; }
00071 static void PushProperties() { defaultStack.push(defaults); }
00072 static void PopProperties() { defaults = defaultStack.top(); defaultStack.pop(); }
00073 private:
00074 ObjectProperties properties;
00075 static ObjectProperties defaults;
00076 static std::stack<ObjectProperties> defaultStack;
00077 };
00078
00079 class Block : public Object
00080 {
00081 public:
00082 Block(vec2 center, float width, float height);
00083 void Draw() const;
00084 Flatland::Object *GetFlatlandObject() { return &object; }
00085 private:
00086 Dynamic<Flatland::Block> object;
00087 };
00088
00089 class Wall : public Object
00090 {
00091 public:
00092 Wall(vec2 center, float width, float height);
00093 Wall(float left, float top, float right, float bottom);
00094 void Draw() const;
00095 Flatland::Object *GetFlatlandObject() { return &object; }
00096 private:
00097 Static<Flatland::Block> object;
00098 };
00099
00100 class Line : public Object
00101 {
00102 public:
00103 Line(vec2 a, vec2 b);
00104 void Draw() const;
00105 Flatland::Object *GetFlatlandObject() { return &object; }
00106 private:
00107 Static<Flatland::Line> object;
00108 };
00109
00110 class RopeSegment : public Object
00111 {
00112 public:
00113 RopeSegment(vec2 a, vec2 b);
00114 void Draw() const {}
00115 vec2 Origin() const { return object.GetGeometry().Origin(); }
00116 vec2 End() const { return object.GetGeometry().End(); }
00117 Flatland::Object *GetFlatlandObject() { return &object; }
00118 private:
00119 Dynamic<Flatland::Line> object;
00120 };
00121
00122 typedef std::vector<RopeSegment*> RopeVector;
00123
00124 class Rope : public Object
00125 {
00126 public:
00127 Rope(vec2 start, vec2 end, float length, float tautness);
00128 RopeSegment *front() { return segments.front(); }
00129 RopeSegment *back() { return segments.back(); }
00130 void Draw() const;
00131 void Terrainify(float bottom);
00132 void Insert(Space &space);
00133 private:
00134 vec2 start, end;
00135 RopeVector segments;
00136 float bottom;
00137 bool terrain;
00138 };
00139
00140 class Terrain : public Object
00141 {
00142 public:
00143 Terrain(vec2 start, float bottom, bool borders = false, bool borderVisibility = true);
00144 void Add(const vec2 &v);
00145 void Insert(Space &space);
00146 void Draw() const;
00147 Flatland::Object *GetFlatlandObject() { return &object; }
00148 Line *InsertWestBorder(Space &space) const;
00149 Line *InsertEastBorder(Space &space) const;
00150 Line *InsertSouthBorder(Space &space) const;
00151 private:
00152 Static<Flatland::Terrain> object;
00153 float bottom;
00154 bool borders;
00155 bool borderVisibility;
00156 };
00157
00158 class Ball : public Object
00159 {
00160 public:
00161 Ball(vec2 center, float radius);
00162 void Draw() const;
00163 Flatland::Object *GetFlatlandObject() { return &object; }
00164 private:
00165 Dynamic<Flatland::Circle> object;
00166 };
00167
00168 class Point : public Object
00169 {
00170 public:
00171 Point(vec2 center);
00172 void Draw() const;
00173 Flatland::Object *GetFlatlandObject() { return &object; }
00174 static const float Size;
00175 private:
00176 Dynamic<Flatland::Circle> object;
00177 };
00178
00179 class Wheel : public Object
00180 {
00181 public:
00182 Wheel(vec2 center, float radius);
00183 void Draw() const;
00184 void SetTexture(Texture t) { texture = t; }
00185 Flatland::Object *GetFlatlandObject() { return &object; }
00186 private:
00187 Dynamic<Flatland::Circle> object;
00188 Texture texture;
00189 };
00190
00191 class Catapult : public Object
00192 {
00193 public:
00194 Catapult(vec2 center, float width, float height, vec2 hinge);
00195 void Rotate(float theta);
00196 Point *InsertSouthEastAnchor(Space &space);
00197 Point *InsertSouthWestAnchor(Space &space);
00198 Point *InsertNorthEastAnchor(Space &space);
00199 Point *InsertNorthWestAnchor(Space &space);
00200 void Draw() const {}
00201 void Insert(Space &space);
00202 private:
00203 Point *hinge;
00204 Block *arm;
00205 };
00206
00207 class Composite : public Object
00208 {
00209 public:
00210 Composite(vec2 centroid);
00211 void Draw() const;
00212 Flatland::Object *GetFlatlandObject() { return &object; }
00213 virtual void Insert(Space &space);
00214 virtual void InsertFront(Space &space);
00215 void Add(Flatland::Geometry *geometry);
00216 private:
00217 Dynamic<Flatland::Composite> object;
00218 };
00219
00220 class Beam : public Composite
00221 {
00222 public:
00223 Beam(vec2 start, vec2 end, float thickness);
00224 void Insert(Space &space);
00225 void InsertFront(Space &space);
00226 private:
00227 float theta;
00228 };
00229
00230 typedef std::list<Object*> OList;
00231
00232
00233
00234 class Space
00235 {
00236 public:
00237 ~Space();
00238 size_t size() const { return list.size(); }
00239 Space &operator<<(Object *o) { list.push_back(o); return *this; }
00240 typedef OList::const_iterator const_iterator;
00241 const_iterator begin() const { return list.begin(); }
00242 const_iterator end() const { return list.end(); }
00243 void pop() { delete *m; m = list.erase(m); }
00244 void push_back(Object *o) { list.push_back(o); }
00245 void push_front(Object *o) { list.push_front(o); }
00246 void mark() { m = --list.end(); }
00247 private:
00248 OList list;
00249 OList::iterator m;
00250 };
00251
00252 void DrawContact(const dContact &contact);
00253
00254 class App
00255 {
00256 public:
00257 App(int width, int height);
00258 void InitGl();
00259 void InitOde();
00260 virtual void Draw() const;
00261 Space &GetSpace() { return space; }
00262 Flatland::World &GetWorld() { return world; }
00263 void Clear() const;
00264 void DrawScene() const;
00265 void Step(float delta);
00266 void SetTarget(const vec2 &target) { velocity = (target - center) / 100; }
00267 void UpdateCenter() { center += velocity; }
00268 void Resize(int width, int height);
00269 vec2 Center() const { return center; }
00270 void Zoom(float factor);
00271 dJointID Glue(Object *a, Object *b);
00272 dJointID Anchor(Object *a, Object *b, vec2 p, float mu = 0, float erp = 0.01);
00273 dJointID Anchor(Object *a, vec2 p, float mu = 0, float erp = 0.01);
00274 dJointID AnchorAxis(Object *a, vec2 axis);
00275 static Texture LoadTexture(int width, int height, const void *data);
00276 static Texture LoadTexture(const char *filename);
00277 static int TextureWidth(Texture id);
00278 static int TextureHeight(Texture id);
00279 static void GetImageData(const char *filename, void *data);
00280 static void GetImageSize(const char *filename, int &width, int &height);
00281 static void Blit(Texture id, float left, float top, Color color = Color::White, bool flip = false);
00282 static App &GetSingleton();
00283 protected:
00284 Space space;
00285 Flatland::World world;
00286 vec2 center;
00287 vec2 velocity;
00288 vec2 target;
00289 static App *singleton;
00290 float zoom;
00291 int width, height;
00292 };
00293
00294 void glColor(const Color &color);
00295 void glVertex(const vec2 &v);
00296
00297 void Draw(const Flatland::Geometry &g, const ObjectProperties &properties);
00298 void DrawCircle(const Flatland::Geometry &g, const ObjectProperties &properties);
00299 void DrawQuad(const Flatland::Geometry &g, const ObjectProperties &properties);
00300 }
00301