Pioneer
Body.h
Go to the documentation of this file.
1 // Copyright © 2008-2023 Pioneer Developers. See AUTHORS.txt for details
2 // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt
3 
4 #ifndef _BODY_H
5 #define _BODY_H
6 
7 #include "BodyComponent.h"
8 #include "DeleteEmitter.h"
9 #include "FrameId.h"
10 #include "lua/PropertiedObject.h"
11 #include "matrix3x3.h"
12 #include "vector3.h"
13 #include <string>
14 
15 class Space;
16 class Camera;
17 class Frame;
18 class SystemBody;
19 
20 namespace Graphics {
21  class Renderer;
22 }
23 struct CollisionContact;
24 
25 // ObjectType is used as a form of RTTI for Body and its children.
26 // Think carefully before adding more entries; we'd like to switch
27 // to a composition-based system instead.
28 enum class ObjectType { // <enum name=PhysicsObjectType scope='ObjectType' public>
29  // only creating enum strings for types that are exposed to Lua
30  BODY,
31  MODELBODY,
32  DYNAMICBODY, // <enum skip>
33  SHIP,
34  PLAYER,
36  TERRAINBODY, // <enum skip>
37  PLANET,
38  STAR,
39  CARGOBODY,
40  PROJECTILE, // <enum skip>
41  MISSILE,
42  HYPERSPACECLOUD // <enum skip>
43 };
44 
45 #define OBJDEF(__thisClass, __parentClass, __TYPE) \
46  static constexpr ObjectType StaticType() { return ObjectType::__TYPE; } \
47  static constexpr ObjectType SuperType() { return __parentClass::StaticType(); } \
48  virtual ObjectType GetType() const override { return ObjectType::__TYPE; } \
49  virtual bool IsType(ObjectType c) const override \
50  { \
51  if (__thisClass::GetType() == (c)) \
52  return true; \
53  else \
54  return __parentClass::IsType(c); \
55  }
56 
57 class Body : public DeleteEmitter, public PropertiedObject {
58 public:
59  static constexpr ObjectType StaticType() { return ObjectType::BODY; }
60  virtual ObjectType GetType() const { return ObjectType::BODY; }
61  virtual bool IsType(ObjectType c) const { return GetType() == c; }
62 
63  Body();
64  Body(const Json &jsonObj, Space *space);
65  virtual ~Body();
66  void ToJson(Json &jsonObj, Space *space);
67  static Body *FromJson(const Json &jsonObj, Space *space);
68  virtual void PostLoadFixup(Space *space){};
69 
70  virtual void SetPosition(const vector3d &p) { m_pos = p; }
71  vector3d GetPosition() const { return m_pos; }
72  virtual void SetOrient(const matrix3x3d &r) { m_orient = r; }
73  const matrix3x3d &GetOrient() const { return m_orient; }
74  virtual void SetVelocity(const vector3d &v) { assert(0); }
75  virtual vector3d GetVelocity() const { return vector3d(0.0); }
76  virtual void SetAngVelocity(const vector3d &v) { assert(0); }
77  virtual vector3d GetAngVelocity() const { return vector3d(0.0); }
78 
79  void SetPhysRadius(double r) { m_physRadius = r; }
80  double GetPhysRadius() const { return m_physRadius; }
81  void SetClipRadius(double r) { m_clipRadius = r; }
82  double GetClipRadius() const { return m_clipRadius; }
83  virtual double GetMass() const
84  {
85  assert(0);
86  return 0;
87  }
88 
89  // return true if to do collision response and apply damage
90  virtual bool OnCollision(Body *o, Uint32 flags, double relVel) { return false; }
91  // Attacker may be null
92  virtual bool OnDamage(Body *attacker, float kgDamage, const CollisionContact &contactData) { return false; }
93  // Override to clear any pointers you hold to the body
94  virtual void NotifyRemoved(const Body *const removedBody) {}
95 
96  // before all bodies have had TimeStepUpdate (their moving step),
97  // StaticUpdate() is called. Good for special collision testing (Projectiles)
98  // as you can't test for collisions if different objects are on different 'steps'
99  virtual void StaticUpdate(const float timeStep) {}
100  virtual void TimeStepUpdate(const float timeStep) {}
101  virtual void Render(Graphics::Renderer *r, const Camera *camera, const vector3d &viewCoords, const matrix4x4d &viewTransform) = 0;
102 
103  virtual void SetFrame(FrameId f) { m_frame = f; }
104  FrameId GetFrame() const { return m_frame; }
105  void SwitchToFrame(FrameId newFrame);
106  void UpdateFrame(); // check for frame switching
107 
108  vector3d GetVelocityRelTo(const Body *) const;
111  vector3d GetPositionRelTo(const Body *) const;
113 
114  // Should return pointer in Pi::currentSystem
115  virtual const SystemBody *GetSystemBody() const { return nullptr; }
116  // for putting on planet surface, oriented +y up
117  void OrientOnSurface(double radius, double latitude, double longitude);
118 
119  virtual void SetLabel(const std::string &label);
120  const std::string &GetLabel() const { return m_label; }
121 
122  unsigned int GetFlags() const { return m_flags; }
123  // TODO(sturnclaw) use this sparingly, the flags interface is rather fragile and needs work
124  void SetFlag(unsigned int flag, bool enable)
125  {
126  if (enable)
127  m_flags |= flag;
128  else
129  m_flags &= ~flag;
130  }
131 
132  // Check if a specific component is present. This involves a lookup through std::map
133  // so it's not quite as efficient as it should be.
134  template <typename T>
135  bool HasComponent() const
136  {
137  return m_components & (uint64_t(1) << uint8_t(BodyComponentDB::GetComponentType<T>()->componentIndex));
138  }
139 
140  // Return a pointer to the component of type T attached to this instance or nullptr.
141  // This returns a non-const pointer for simplicity as the component is technically
142  // not part of the object.
143  template <typename T>
144  T *GetComponent() const
145  {
146  auto *type = BodyComponentDB::GetComponentType<T>();
147  return m_components & (uint64_t(1) << uint8_t(type->componentIndex)) ? type->get(this) : nullptr;
148  }
149 
150  template <typename T>
152  {
153  auto *type = BodyComponentDB::GetComponentType<T>();
154  if (m_components & (uint64_t(1) << uint8_t(type->componentIndex)))
155  return type->get(this);
156 
157  m_components |= (uint64_t(1) << uint8_t(type->componentIndex));
158  return type->newComponent(this);
159  }
160 
161  // Returns the bitset of components attached to this body. Prefer using HasComponent<> or GetComponent<> instead.
162  uint64_t GetComponentList() const { return m_components; }
163 
164  // Only Space::KillBody() should call this method.
165  void MarkDead() { m_dead = true; }
166  bool IsDead() const { return m_dead; }
167 
168  // all Bodies are in space... except where they're not (Ships hidden in hyperspace clouds)
169  virtual bool IsInSpace() const { return true; }
170 
171  // Interpolated between physics ticks.
172  const matrix3x3d &GetInterpOrient() const { return m_interpOrient; }
174  vector3d GetInterpPositionRelTo(FrameId relToId) const;
175  vector3d GetInterpPositionRelTo(const Body *relTo) const;
176  matrix3x3d GetInterpOrientRelTo(FrameId relToId) const;
177 
178  // should set m_interpolatedTransform to the smoothly interpolated value
179  // (interpolated by 0 <= alpha <=1) between the previous and current physics tick
180  virtual void UpdateInterpTransform(double alpha)
181  {
184  }
185 
186  // TODO: abstract this functionality into a component of some fashion
187  // Return the position in body-local coordinates where the target indicator should be displayed.
188  // Usually equal to the center of the body == vector3d(0, 0, 0)
189  virtual vector3d GetTargetIndicatorPosition() const;
190 
191  enum {
193  FLAG_LABEL_HIDDEN = (1 << 1),
194  FLAG_DRAW_LAST = (1 << 2), // causes the body drawn after other bodies in the z-sort
195  FLAG_DRAW_EXCLUDE = (1 << 3) // do not draw this body, intended for e.g. when camera is inside
196  };
197 
198 private:
199  uint64_t m_components = 0;
200 
201 protected:
202  virtual void SaveToJson(Json &jsonObj, Space *space);
203  unsigned int m_flags = 0;
204 
205  // Interpolated draw orientation-position
208 
209 private:
210  vector3d m_pos;
211  matrix3x3d m_orient;
212  FrameId m_frame; // frame of reference
213  std::string m_label;
214  bool m_dead; // Checked in destructor to make sure body has been marked dead.
215  double m_clipRadius;
216  double m_physRadius;
217 };
218 
219 #endif /* _BODY_H */
ObjectType
Definition: Body.h:28
nlohmann::json Json
Definition: Json.h:8
Definition: Body.h:57
void OrientOnSurface(double radius, double latitude, double longitude)
Definition: Body.cpp:260
virtual vector3d GetTargetIndicatorPosition() const
Definition: Body.cpp:313
vector3d GetPositionRelTo(FrameId) const
Definition: Body.cpp:201
virtual void PostLoadFixup(Space *space)
Definition: Body.h:68
const matrix3x3d & GetOrient() const
Definition: Body.h:73
virtual void TimeStepUpdate(const float timeStep)
Definition: Body.h:100
void SetPhysRadius(double r)
Definition: Body.h:79
virtual void SetOrient(const matrix3x3d &r)
Definition: Body.h:72
vector3d GetInterpPositionRelTo(FrameId relToId) const
Definition: Body.cpp:210
double GetPhysRadius() const
Definition: Body.h:80
virtual vector3d GetVelocity() const
Definition: Body.h:75
virtual void Render(Graphics::Renderer *r, const Camera *camera, const vector3d &viewCoords, const matrix4x4d &viewTransform)=0
virtual void NotifyRemoved(const Body *const removedBody)
Definition: Body.h:94
static constexpr ObjectType StaticType()
Definition: Body.h:59
virtual void SetVelocity(const vector3d &v)
Definition: Body.h:74
virtual void SetPosition(const vector3d &p)
Definition: Body.h:70
vector3d GetPosition() const
Definition: Body.h:71
vector3d GetVelocityRelTo(const Body *) const
Definition: Body.cpp:255
virtual void SaveToJson(Json &jsonObj, Space *space)
Definition: Body.cpp:74
void SwitchToFrame(FrameId newFrame)
Definition: Body.cpp:269
virtual bool OnDamage(Body *attacker, float kgDamage, const CollisionContact &contactData)
Definition: Body.h:92
virtual double GetMass() const
Definition: Body.h:83
vector3d m_interpPos
Definition: Body.h:206
virtual bool IsInSpace() const
Definition: Body.h:169
virtual bool OnCollision(Body *o, Uint32 flags, double relVel)
Definition: Body.h:90
matrix3x3d GetInterpOrientRelTo(FrameId relToId) const
Definition: Body.cpp:237
Body()
Definition: Body.cpp:21
vector3d GetInterpPosition() const
Definition: Body.h:173
void ToJson(Json &jsonObj, Space *space)
Definition: Body.cpp:113
void UpdateFrame()
Definition: Body.cpp:285
const std::string & GetLabel() const
Definition: Body.h:120
uint64_t GetComponentList() const
Definition: Body.h:162
virtual void StaticUpdate(const float timeStep)
Definition: Body.h:99
T * GetComponent() const
Definition: Body.h:144
virtual void UpdateInterpTransform(double alpha)
Definition: Body.h:180
void SetFlag(unsigned int flag, bool enable)
Definition: Body.h:124
static Body * FromJson(const Json &jsonObj, Space *space)
Definition: Body.cpp:134
void MarkDead()
Definition: Body.h:165
const matrix3x3d & GetInterpOrient() const
Definition: Body.h:172
virtual void SetAngVelocity(const vector3d &v)
Definition: Body.h:76
bool HasComponent() const
Definition: Body.h:135
virtual ~Body()
Definition: Body.cpp:59
virtual void SetLabel(const std::string &label)
Definition: Body.cpp:318
T * AddComponent()
Definition: Body.h:151
unsigned int m_flags
Definition: Body.h:203
matrix3x3d GetOrientRelTo(FrameId) const
Definition: Body.cpp:229
virtual vector3d GetAngVelocity() const
Definition: Body.h:77
virtual const SystemBody * GetSystemBody() const
Definition: Body.h:115
@ FLAG_CAN_MOVE_FRAME
Definition: Body.h:192
@ FLAG_LABEL_HIDDEN
Definition: Body.h:193
@ FLAG_DRAW_EXCLUDE
Definition: Body.h:195
@ FLAG_DRAW_LAST
Definition: Body.h:194
void SetClipRadius(double r)
Definition: Body.h:81
double GetClipRadius() const
Definition: Body.h:82
bool IsDead() const
Definition: Body.h:166
unsigned int GetFlags() const
Definition: Body.h:122
matrix3x3d m_interpOrient
Definition: Body.h:207
virtual ObjectType GetType() const
Definition: Body.h:60
virtual void SetFrame(FrameId f)
Definition: Body.h:103
FrameId GetFrame() const
Definition: Body.h:104
virtual bool IsType(ObjectType c) const
Definition: Body.h:61
Definition: Camera.h:80
Definition: DeleteEmitter.h:16
Definition: Frame.h:28
Definition: Renderer.h:44
Definition: PropertiedObject.h:11
Definition: Space.h:19
Definition: SystemBody.h:19
Definition: Background.h:14
Definition: CollisionContact.h:9
Definition: FrameId.h:9
vector3< double > vector3d
Definition: vector3.h:290