#ifndef _PHYSICS_BODY_ #define _PHYSICS_BODY_ #include #include #define DB_SET_VECTOR2D(j,xIndex,yIndex) void j(const wgd::Vector2D &v) { \ if (getID()[xIndex] == Null) getID().set(xIndex, wgd::DB::createObject()); \ if (getID()[yIndex] == Null) getID().set(yIndex, wgd::DB::createObject()); \ OID x = v.x; \ OID y = v.y; \ dtx &tx = *dtx::New(); \ tx.Begin(getID()); \ tx.Set(xIndex, x); \ tx.Set(yIndex, y); \ tx.End(); \ tx.Execute(dtx::FREE | dtx::SYNC); } #define DB_GET_VECTOR2D(j,xIndex,yIndex) wgd::Vector2D j() { \ OID x,y; \ dtx &tx = *dtx::New(); \ tx.Variable(dtx::VAR1, x); \ tx.Variable(dtx::VAR2, y); \ tx.Begin(getID()); \ tx.Get(xIndex, dtx::VAR1); \ tx.Get(yIndex, dtx::VAR2); \ tx.End(); \ tx.Execute(dtx::FREE | dtx::SYNC); \ return wgd::Vector2D(x,y); } class Body : public wgd::Instance { public: Body(const wgd::InstanceID &); virtual void update(); virtual void draw(); virtual float getMinX () = 0; virtual float getMaxX () = 0; virtual float getMinY () = 0; virtual float getMaxY () = 0; virtual bool contains (const wgd::Vector2D& p) = 0; virtual void collision () { setColour(wgd::Colour(1, 0, 0)); }; void impulse (const wgd::Vector3D& impulse, const wgd::Vector3D& point); virtual float getMomentOfInertia () const = 0; VINSTANCE(Instance, "body"); float getX () const { return cache_position.x; } //DB_GET_FLOAT(getX, wgd::ix::x); DB_SET_FLOAT(setX, wgd::ix::x); float getY () const { return cache_position.y; } //DB_GET_FLOAT(getY, wgd::ix::y); DB_SET_FLOAT(setY, wgd::ix::y); DB_GET_FLOAT(getRotation, wgd::ix::roll); DB_SET_FLOAT(setRotation, wgd::ix::roll); #if 0 DB_GET_FLOAT(getVX, "vx"); DB_SET_FLOAT(setVX, "vx"); DB_GET_FLOAT(getVY, "vy"); DB_SET_FLOAT(setVY, "vy"); DB_GET_VECTOR2D(getVelocity, "vx", "vy"); DB_SET_VECTOR2D(setVelocity, "vx", "vy"); DB_GET_FLOAT(getRotationVel, "vrot"); DB_SET_FLOAT(setRotationVel, "vrot"); DB_GET_BOOL(selected, "selected"); DB_SET_BOOL(selected, "selected"); DB_GET_FLOAT(getDensity, "density"); DB_SET_FLOAT(setDensity, "density"); DB_GET_FLOAT(getRadius, "radius"); DB_SET_FLOAT(setRadius, "radius"); #else private: bool m_selected; wgd::Vector2D velocity; float vrot; float density; float radius; public: float getVX () const { return velocity.x; } void setVX (float f) { velocity.x = f; } float getVY () const { return velocity.y; } void setVY (float f) { velocity.y = f; } wgd::Vector2D getVelocity () const { return velocity; } void setVelocity (const wgd::Vector2D& v) { velocity = v; } float getRotationVel () const { return vrot; } void setRotationVel (float f) { vrot = f; } bool selected () const { return m_selected; } void selected (bool b) { m_selected = b; } float getDensity () const { return density; } void setDensity (float f) { density = f; } float getRadius () const { return radius; } void setRadius (float f) { radius = f; } #endif float getMass () const { return getArea() * getDensity(); } virtual float getArea () const = 0; virtual wgd::Vector2D getNormal (int i) const { return wgd::Vector2D(); } virtual wgd::Vector2D getVertex (int i) const { return position(); } virtual int getVertexCount () const { return 1; } virtual wgd::Vector2D getExtremePoint (const wgd::Vector2D& dir, int& i) const = 0; float getRadiusSq () const { const float r = getRadius(); return r * r; }; DB_GET_COLOUR(getInternalColour, "colour"); DB_SET_COLOUR(setColour, "colour"); wgd::Colour getColour () { if (selected()) { return wgd::Colour::lerp(getInternalColour(), wgd::Colour(0, 0, 0), 0.25); } else { return getInternalColour(); } } DOSTE_BEGINEVENTS_INHERIT(wgd::Instance); DOSTE_EVENT(402, positionChanged); DOSTE_EVENT(403, positionChanged); DOSTE_ENDEVENTS; private: void positionChanged (WGD_HANDLER) { cache_position = position(); } wgd::Vector2D cache_position; }; #endif