Pioneer
Loading...
Searching...
No Matches
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"
11#include "matrix3x3.h"
12#include "vector3.h"
13#include <string>
14
15class Space;
16class Camera;
17class Frame;
18class SystemBody;
19
20namespace Graphics {
21 class Renderer;
22}
23struct 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.
28enum class ObjectType { // <enum name=PhysicsObjectType scope='ObjectType' public>
29 // only creating enum strings for types that are exposed to Lua
30 BODY,
32 DYNAMICBODY, // <enum skip>
33 SHIP,
34 PLAYER,
36 TERRAINBODY, // <enum skip>
37 PLANET,
38 STAR,
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
57class Body : public DeleteEmitter, public PropertiedObject {
58public:
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; }
175 vector3d GetInterpPositionRelTo(const Body *relTo) 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 {
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
198private:
199 uint64_t m_components = 0;
200
201protected:
202 virtual void SaveToJson(Json &jsonObj, Space *space);
203 unsigned int m_flags = 0;
204
205 // Interpolated draw orientation-position
208
209private:
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
T * AddComponent()
Definition Body.h:151
virtual vector3d GetTargetIndicatorPosition() const
Definition Body.cpp:313
vector3d GetPositionRelTo(FrameId) const
Definition Body.cpp:201
const matrix3x3d & GetOrient() const
Definition Body.h:73
virtual void PostLoadFixup(Space *space)
Definition Body.h:68
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
T * GetComponent() const
Definition Body.h:144
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
const matrix3x3d & GetInterpOrient() const
Definition Body.h:172
void UpdateFrame()
Definition Body.cpp:285
uint64_t GetComponentList() const
Definition Body.h:162
virtual void StaticUpdate(const float timeStep)
Definition Body.h:99
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
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
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
const std::string & GetLabel() const
Definition Body.h:120
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