1 // Copyright © 2008-2021 Pioneer Developers. See AUTHORS.txt for details 2 // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt 3 4 #ifndef _FRAME_H 5 #define _FRAME_H 6 7 #include "FrameId.h" 8 9 #include "IterationProxy.h" 10 #include "JsonFwd.h" 11 #include "matrix3x3.h" 12 #include "matrix4x4.h" 13 #include "vector3.h" 14 #include <list> 15 #include <string> 16 17 class Body; 18 class CollisionSpace; 19 class Geom; 20 class SystemBody; 21 class SfxManager; 22 class Space; 23 24 struct CollisionContact; 25 26 // Frame of reference. 27 28 class Frame { 29 // Used to avoid direct instantiation of Frames: use factory methods instead. 30 // TODO: Find a better way, as checking it at compile time 31 struct Dummy; 32 33 public: 34 Frame() = delete; 35 Frame(const Dummy &d, FrameId parent, const char *label, unsigned int flags = FLAG_DEFAULT, double radius = 0.0); 36 // Used *only* for Camera frame: 37 // it doesn't set up CollisionSpace, and use default values for label, flags and radius 38 Frame(const Dummy &d, FrameId parent); 39 40 Frame(const Frame &) = delete; 41 Frame(Frame &&) noexcept; 42 Frame &operator=(Frame &&); 43 44 ~Frame(); 45 46 enum { FLAG_DEFAULT = (0), 47 FLAG_ROTATING = (1 << 1), 48 FLAG_HAS_ROT = (1 << 2) }; 49 50 static FrameId CreateFrame(FrameId parent, const char *label, unsigned int flags = FLAG_DEFAULT, double radius = 0.0); 51 static FrameId FromJson(const Json &jsonObj, Space *space, FrameId parent, double at_time); 52 53 // Used to speed up creation/deletion of Frame for camera 54 static FrameId CreateCameraFrame(FrameId parent); 55 static void DeleteCameraFrame(FrameId camera); 56 57 static void ToJson(Json &jsonObj, FrameId fId, Space *space); 58 static void PostUnserializeFixup(FrameId fId, Space *space); 59 60 static void DeleteFrames(); 61 62 static Frame *GetFrame(FrameId FId); 63 GetId()64 FrameId GetId() const { return m_thisId; } 65 GetLabel()66 const std::string &GetLabel() const { return m_label; } SetLabel(const char * label)67 void SetLabel(const char *label) { m_label = label; } 68 SetPosition(const vector3d & pos)69 void SetPosition(const vector3d &pos) { m_pos = pos; } GetPosition()70 vector3d GetPosition() const { return m_pos; } 71 void SetInitialOrient(const matrix3x3d &m, double time); 72 void SetOrient(const matrix3x3d &m, double time); GetOrient()73 const matrix3x3d &GetOrient() const { return m_orient; } GetInterpOrient()74 const matrix3x3d &GetInterpOrient() const { return m_interpOrient; } SetVelocity(const vector3d & vel)75 void SetVelocity(const vector3d &vel) { m_vel = vel; } GetVelocity()76 vector3d GetVelocity() const { return m_vel; } SetAngSpeed(const double angspeed)77 void SetAngSpeed(const double angspeed) { m_angSpeed = angspeed; } GetAngSpeed()78 double GetAngSpeed() const { return m_angSpeed; } SetRadius(double radius)79 void SetRadius(double radius) { m_radius = radius; } GetRadius()80 double GetRadius() const { return m_radius; } IsRotFrame()81 bool IsRotFrame() const { return m_flags & FLAG_ROTATING; } HasRotFrame()82 bool HasRotFrame() const { return m_flags & FLAG_HAS_ROT; } 83 GetParent()84 FrameId GetParent() const { return m_parent; } GetNonRotFrame()85 FrameId GetNonRotFrame() const { return IsRotFrame() ? m_parent : m_thisId; } GetRotFrame()86 FrameId GetRotFrame() const { return HasRotFrame() ? m_children.front() : m_thisId; } 87 SetBodies(SystemBody * s,Body * b)88 void SetBodies(SystemBody *s, Body *b) 89 { 90 m_sbody = s; 91 m_astroBody = b; 92 } GetSystemBody()93 SystemBody *GetSystemBody() const { return m_sbody; } GetBody()94 Body *GetBody() const { return m_astroBody; } 95 AddChild(FrameId fId)96 void AddChild(FrameId fId) { m_children.push_back(fId); } 97 void RemoveChild(FrameId fId); HasChildren()98 bool HasChildren() const { return !m_children.empty(); } GetNumChildren()99 unsigned GetNumChildren() const { return static_cast<Uint32>(m_children.size()); } GetChildren()100 IterationProxy<std::vector<FrameId>> GetChildren() { return MakeIterationProxy(m_children); } GetChildren()101 const IterationProxy<const std::vector<FrameId>> GetChildren() const { return MakeIterationProxy(m_children); } 102 103 void AddGeom(Geom *); 104 void RemoveGeom(Geom *); 105 void AddStaticGeom(Geom *); 106 void RemoveStaticGeom(Geom *); 107 // TODO: Should be a Planet or there's a needs for a Body? 108 void SetPlanetGeom(double radius, Body *); 109 CollisionSpace *GetCollisionSpace() const; 110 111 static void UpdateOrbitRails(double time, double timestep); 112 static void CollideFrames(void (*callback)(CollisionContact *)); 113 void UpdateInterpTransform(double alpha); 114 void ClearMovement(); 115 116 // For an object in a rotating frame, relative to non-rotating frames it 117 // must attain this velocity within rotating frame to be stationary. GetStasisVelocity(const vector3d & pos)118 vector3d GetStasisVelocity(const vector3d &pos) const { return -vector3d(0, m_angSpeed, 0).Cross(pos); } 119 120 vector3d GetPositionRelTo(FrameId relTo) const; 121 vector3d GetVelocityRelTo(FrameId relTo) const; 122 matrix3x3d GetOrientRelTo(FrameId relTo) const; 123 matrix4x4d GetTransformRelTo(FrameId relTo) const; 124 125 // Same as above except it does interpolation between 126 // physics ticks so rendering is smooth above physics hz 127 vector3d GetInterpPositionRelTo(FrameId relTo) const; 128 matrix3x3d GetInterpOrientRelTo(FrameId relTo) const; 129 matrix4x4d GetInterpTransformRelTo(FrameId relTo) const; 130 131 static void GetFrameTransform(FrameId fFrom, FrameId fTo, matrix4x4d &m); 132 133 std::unique_ptr<SfxManager> m_sfx; // the last survivor. actually m_children is pretty grim too. 134 135 private: 136 FrameId m_thisId; 137 138 void UpdateRootRelativeVars(); 139 140 FrameId m_parent; // if parent is null then frame position is absolute 141 std::vector<FrameId> m_children; // child frames, first may be rotating 142 SystemBody *m_sbody; // points to SBodies in Pi::current_system 143 Body *m_astroBody; // if frame contains a star or planet or something 144 145 vector3d m_pos; 146 vector3d m_oldPos; 147 vector3d m_interpPos; 148 matrix3x3d m_initialOrient; 149 matrix3x3d m_orient; 150 matrix3x3d m_interpOrient; 151 vector3d m_vel; // note we don't use this to move frame. rather, 152 // orbital rails determine velocity. 153 double m_angSpeed; // this however *is* directly applied (for rotating frames) 154 double m_oldAngDisplacement; 155 std::string m_label; 156 double m_radius; 157 int m_flags; 158 int m_collisionSpace; 159 160 vector3d m_rootVel; // velocity, position and orient relative to root frame 161 vector3d m_rootPos; // updated by UpdateOrbitRails 162 matrix3x3d m_rootOrient; 163 vector3d m_rootInterpPos; // interp position and orient relative to root frame 164 matrix3x3d m_rootInterpOrient; // updated by UpdateInterpTransform 165 166 int m_astroBodyIndex; // deserialisation 167 168 static std::vector<Frame> s_frames; 169 static std::vector<CollisionSpace> s_collisionSpaces; 170 171 // A trick in order to avoid a direct call of ctor or dtor: use factory methods instead 172 struct Dummy { DummyDummy173 Dummy() : 174 madeWithFactory(false) 175 {} 176 bool madeWithFactory; 177 }; 178 179 Dummy d; 180 }; 181 182 #endif /* _FRAME_H */ 183