179 lines
6.3 KiB
C++
179 lines
6.3 KiB
C++
// Copyright © 2008-2021 Pioneer Developers. See AUTHORS.txt for details
|
|
// Licensed under the terms of the GPL v3. See licenses/GPL-3.txt
|
|
|
|
#ifndef _BODY_H
|
|
#define _BODY_H
|
|
|
|
#include "DeleteEmitter.h"
|
|
#include "FrameId.h"
|
|
#include "lua/PropertiedObject.h"
|
|
#include "matrix3x3.h"
|
|
#include "vector3.h"
|
|
#include <string>
|
|
|
|
class Space;
|
|
class Camera;
|
|
class Frame;
|
|
class SystemBody;
|
|
|
|
namespace Graphics {
|
|
class Renderer;
|
|
}
|
|
struct CollisionContact;
|
|
|
|
// ObjectType is used as a form of RTTI for Body and its children.
|
|
// Think carefully before adding more entries; we'd like to switch
|
|
// to a composition-based system instead.
|
|
enum class ObjectType { // <enum name=PhysicsObjectType scope='ObjectType' public>
|
|
// only creating enum strings for types that are exposed to Lua
|
|
BODY,
|
|
MODELBODY,
|
|
DYNAMICBODY, // <enum skip>
|
|
SHIP,
|
|
PLAYER,
|
|
SPACESTATION,
|
|
TERRAINBODY, // <enum skip>
|
|
PLANET,
|
|
STAR,
|
|
CARGOBODY,
|
|
PROJECTILE, // <enum skip>
|
|
MISSILE,
|
|
HYPERSPACECLOUD // <enum skip>
|
|
};
|
|
|
|
#define OBJDEF(__thisClass, __parentClass, __TYPE) \
|
|
virtual ObjectType GetType() const override { return ObjectType::__TYPE; } \
|
|
virtual bool IsType(ObjectType c) const override \
|
|
{ \
|
|
if (__thisClass::GetType() == (c)) \
|
|
return true; \
|
|
else \
|
|
return __parentClass::IsType(c); \
|
|
}
|
|
|
|
class Body : public DeleteEmitter, public PropertiedObject {
|
|
public:
|
|
virtual ObjectType GetType() const { return ObjectType::BODY; }
|
|
virtual bool IsType(ObjectType c) const { return GetType() == c; }
|
|
|
|
Body();
|
|
Body(const Json &jsonObj, Space *space);
|
|
virtual ~Body();
|
|
void ToJson(Json &jsonObj, Space *space);
|
|
static Body *FromJson(const Json &jsonObj, Space *space);
|
|
virtual void PostLoadFixup(Space *space){};
|
|
|
|
virtual void SetPosition(const vector3d &p) { m_pos = p; }
|
|
vector3d GetPosition() const { return m_pos; }
|
|
virtual void SetOrient(const matrix3x3d &r) { m_orient = r; }
|
|
const matrix3x3d &GetOrient() const { return m_orient; }
|
|
virtual void SetVelocity(const vector3d &v) { assert(0); }
|
|
virtual vector3d GetVelocity() const { return vector3d(0.0); }
|
|
|
|
void SetPhysRadius(double r) { m_physRadius = r; }
|
|
double GetPhysRadius() const { return m_physRadius; }
|
|
void SetClipRadius(double r) { m_clipRadius = r; }
|
|
double GetClipRadius() const { return m_clipRadius; }
|
|
virtual double GetMass() const
|
|
{
|
|
assert(0);
|
|
return 0;
|
|
}
|
|
|
|
// return true if to do collision response and apply damage
|
|
virtual bool OnCollision(Body *o, Uint32 flags, double relVel) { return false; }
|
|
// Attacker may be null
|
|
virtual bool OnDamage(Body *attacker, float kgDamage, const CollisionContact &contactData) { return false; }
|
|
// Override to clear any pointers you hold to the body
|
|
virtual void NotifyRemoved(const Body *const removedBody) {}
|
|
|
|
// before all bodies have had TimeStepUpdate (their moving step),
|
|
// StaticUpdate() is called. Good for special collision testing (Projectiles)
|
|
// as you can't test for collisions if different objects are on different 'steps'
|
|
virtual void StaticUpdate(const float timeStep) {}
|
|
virtual void TimeStepUpdate(const float timeStep) {}
|
|
virtual void Render(Graphics::Renderer *r, const Camera *camera, const vector3d &viewCoords, const matrix4x4d &viewTransform) = 0;
|
|
|
|
virtual void SetFrame(FrameId f) { m_frame = f; }
|
|
FrameId GetFrame() const { return m_frame; }
|
|
void SwitchToFrame(FrameId newFrame);
|
|
void UpdateFrame(); // check for frame switching
|
|
|
|
vector3d GetVelocityRelTo(const Body *) const;
|
|
vector3d GetVelocityRelTo(FrameId) const;
|
|
vector3d GetPositionRelTo(FrameId) const;
|
|
vector3d GetPositionRelTo(const Body *) const;
|
|
matrix3x3d GetOrientRelTo(FrameId) const;
|
|
|
|
// Should return pointer in Pi::currentSystem
|
|
virtual const SystemBody *GetSystemBody() const { return nullptr; }
|
|
// for putting on planet surface, oriented +y up
|
|
void OrientOnSurface(double radius, double latitude, double longitude);
|
|
|
|
virtual void SetLabel(const std::string &label);
|
|
const std::string &GetLabel() const { return m_label; }
|
|
|
|
unsigned int GetFlags() const { return m_flags; }
|
|
// TODO(sturnclaw) use this sparingly, the flags interface is rather fragile and needs work
|
|
void SetFlag(unsigned int flag, bool enable)
|
|
{
|
|
if (enable)
|
|
m_flags |= flag;
|
|
else
|
|
m_flags &= ~flag;
|
|
}
|
|
|
|
// Only Space::KillBody() should call this method.
|
|
void MarkDead() { m_dead = true; }
|
|
bool IsDead() const { return m_dead; }
|
|
|
|
// all Bodies are in space... except where they're not (Ships hidden in hyperspace clouds)
|
|
virtual bool IsInSpace() const { return true; }
|
|
|
|
// Interpolated between physics ticks.
|
|
const matrix3x3d &GetInterpOrient() const { return m_interpOrient; }
|
|
vector3d GetInterpPosition() const { return m_interpPos; }
|
|
vector3d GetInterpPositionRelTo(FrameId relToId) const;
|
|
vector3d GetInterpPositionRelTo(const Body *relTo) const;
|
|
matrix3x3d GetInterpOrientRelTo(FrameId relToId) const;
|
|
|
|
// should set m_interpolatedTransform to the smoothly interpolated value
|
|
// (interpolated by 0 <= alpha <=1) between the previous and current physics tick
|
|
virtual void UpdateInterpTransform(double alpha)
|
|
{
|
|
m_interpOrient = GetOrient();
|
|
m_interpPos = GetPosition();
|
|
}
|
|
|
|
// TODO: abstract this functionality into a component of some fashion
|
|
// Return the position in body-local coordinates where the target indicator should be displayed.
|
|
// Usually equal to the center of the body == vector3d(0, 0, 0)
|
|
virtual vector3d GetTargetIndicatorPosition() const;
|
|
|
|
enum {
|
|
FLAG_CAN_MOVE_FRAME = (1 << 0),
|
|
FLAG_LABEL_HIDDEN = (1 << 1),
|
|
FLAG_DRAW_LAST = (1 << 2), // causes the body drawn after other bodies in the z-sort
|
|
FLAG_DRAW_EXCLUDE = (1 << 3) // do not draw this body, intended for e.g. when camera is inside
|
|
};
|
|
|
|
protected:
|
|
virtual void SaveToJson(Json &jsonObj, Space *space);
|
|
unsigned int m_flags;
|
|
|
|
// Interpolated draw orientation-position
|
|
vector3d m_interpPos;
|
|
matrix3x3d m_interpOrient;
|
|
|
|
private:
|
|
vector3d m_pos;
|
|
matrix3x3d m_orient;
|
|
FrameId m_frame; // frame of reference
|
|
std::string m_label;
|
|
bool m_dead; // Checked in destructor to make sure body has been marked dead.
|
|
double m_clipRadius;
|
|
double m_physRadius;
|
|
};
|
|
|
|
#endif /* _BODY_H */
|