Update all files to store and use FrameId instead of raw pointers

master
mike-f1 2019-10-07 18:12:28 +02:00
parent 3a0aa4301b
commit 4f1eaa41d3
45 changed files with 671 additions and 537 deletions

View File

@ -216,7 +216,7 @@ double Beam::GetRadius() const
return sqrt(m_length * m_length);
}
static void MiningLaserSpawnTastyStuff(Frame *f, const SystemBody *asteroid, const vector3d &pos)
static void MiningLaserSpawnTastyStuff(FrameId fId, const SystemBody *asteroid, const vector3d &pos)
{
lua_State *l = Lua::manager->GetLuaState();
@ -240,7 +240,7 @@ static void MiningLaserSpawnTastyStuff(Frame *f, const SystemBody *asteroid, con
lua_pop(l, 1);
LUA_DEBUG_END(l, 0);
cargo->SetFrame(f);
cargo->SetFrame(fId);
cargo->SetPosition(pos);
const double x = Pi::rng.Double();
vector3d dir = pos.Normalized();
@ -257,7 +257,9 @@ void Beam::StaticUpdate(const float timeStep)
return;
CollisionContact c;
GetFrame()->GetCollisionSpace()->TraceRay(GetPosition(), m_dir.Normalized(), m_length, &c, static_cast<ModelBody *>(m_parent)->GetGeom());
Frame *frame = Frame::GetFrame(GetFrame());
frame->GetCollisionSpace()->TraceRay(GetPosition(), m_dir.Normalized(), m_length, &c, static_cast<ModelBody *>(m_parent)->GetGeom());
if (c.userData1) {
Object *o = static_cast<Object *>(c.userData1);
@ -277,8 +279,8 @@ void Beam::StaticUpdate(const float timeStep)
if (m_mining) {
// need to test for terrain hit
if (GetFrame()->GetBody() && GetFrame()->GetBody()->IsType(Object::PLANET)) {
Planet *const planet = static_cast<Planet *>(GetFrame()->GetBody());
if (frame->GetBody() && frame->GetBody()->IsType(Object::PLANET)) {
Planet *const planet = static_cast<Planet *>(frame->GetBody());
const SystemBody *b = planet->GetSystemBody();
vector3d pos = GetPosition();
double terrainHeight = planet->GetTerrainHeight(pos.Normalized());

View File

@ -24,7 +24,7 @@ Body::Body() :
m_interpOrient(matrix3x3d::Identity()),
m_pos(0.0),
m_orient(matrix3x3d::Identity()),
m_frame(nullptr),
m_frame(noFrameId),
m_dead(false),
m_clipRadius(0.0),
m_physRadius(0.0)
@ -37,13 +37,13 @@ Body::Body(const Json &jsonObj, Space *space) :
m_flags(0),
m_interpPos(0.0),
m_interpOrient(matrix3x3d::Identity()),
m_frame(nullptr)
m_frame(noFrameId)
{
try {
Json bodyObj = jsonObj["body"];
Properties().LoadFromJson(bodyObj);
m_frame = Frame::FindFrame(bodyObj["index_for_frame"]);
m_frame = bodyObj["index_for_frame"];
m_label = bodyObj["label"];
Properties().Set("label", m_label);
m_dead = bodyObj["dead"];
@ -66,7 +66,7 @@ void Body::SaveToJson(Json &jsonObj, Space *space)
Json bodyObj = Json::object(); // Create JSON object to contain body data.
Properties().SaveToJson(bodyObj);
bodyObj["index_for_frame"] = (m_frame != nullptr ? m_frame->GetId() : noFrameId);
bodyObj["index_for_frame"] = (m_frame >= 0 ? m_frame : noFrameId);
bodyObj["label"] = m_label;
bodyObj["dead"] = m_dead;
@ -139,17 +139,21 @@ Body *Body::FromJson(const Json &jsonObj, Space *space)
return nullptr;
}
vector3d Body::GetPositionRelTo(const Frame *relTo) const
vector3d Body::GetPositionRelTo(FrameId relToId) const
{
vector3d fpos = m_frame->GetPositionRelTo(relTo);
matrix3x3d forient = m_frame->GetOrientRelTo(relTo);
Frame *frame = Frame::GetFrame(m_frame);
vector3d fpos = frame->GetPositionRelTo(relToId);
matrix3x3d forient = frame->GetOrientRelTo(relToId);
return forient * GetPosition() + fpos;
}
vector3d Body::GetInterpPositionRelTo(const Frame *relTo) const
vector3d Body::GetInterpPositionRelTo(FrameId relToId) const
{
vector3d fpos = m_frame->GetInterpPositionRelTo(relTo);
matrix3x3d forient = m_frame->GetInterpOrientRelTo(relTo);
Frame *frame = Frame::GetFrame(m_frame);
vector3d fpos = frame->GetInterpPositionRelTo(relToId);
matrix3x3d forient = frame->GetInterpOrientRelTo(relToId);
return forient * GetInterpPosition() + fpos;
}
@ -163,24 +167,30 @@ vector3d Body::GetInterpPositionRelTo(const Body *relTo) const
return GetInterpPositionRelTo(relTo->m_frame) - relTo->GetInterpPosition();
}
matrix3x3d Body::GetOrientRelTo(const Frame *relTo) const
matrix3x3d Body::GetOrientRelTo(FrameId relToId) const
{
matrix3x3d forient = m_frame->GetOrientRelTo(relTo);
Frame *frame = Frame::GetFrame(m_frame);
matrix3x3d forient = frame->GetOrientRelTo(relToId);
return forient * GetOrient();
}
matrix3x3d Body::GetInterpOrientRelTo(const Frame *relTo) const
matrix3x3d Body::GetInterpOrientRelTo(FrameId relToId) const
{
matrix3x3d forient = m_frame->GetInterpOrientRelTo(relTo);
Frame *frame = Frame::GetFrame(m_frame);
matrix3x3d forient = frame->GetInterpOrientRelTo(relToId);
return forient * GetInterpOrient();
}
vector3d Body::GetVelocityRelTo(const Frame *relTo) const
vector3d Body::GetVelocityRelTo(FrameId relToId) const
{
matrix3x3d forient = m_frame->GetOrientRelTo(relTo);
Frame *frame = Frame::GetFrame(m_frame);
matrix3x3d forient = frame->GetOrientRelTo(relToId);
vector3d vel = GetVelocity();
if (m_frame != relTo) vel -= m_frame->GetStasisVelocity(GetPosition());
return forient * vel + m_frame->GetVelocityRelTo(relTo);
if (m_frame != relToId) vel -= frame->GetStasisVelocity(GetPosition());
return forient * vel + frame->GetVelocityRelTo(relToId);
}
vector3d Body::GetVelocityRelTo(const Body *relTo) const
@ -197,15 +207,18 @@ void Body::OrientOnSurface(double radius, double latitude, double longitude)
SetOrient(matrix3x3d::FromVectors(right, up));
}
void Body::SwitchToFrame(Frame *newFrame)
void Body::SwitchToFrame(FrameId newFrameId)
{
const vector3d vel = GetVelocityRelTo(newFrame); // do this first because it uses position
const vector3d fpos = m_frame->GetPositionRelTo(newFrame);
const matrix3x3d forient = m_frame->GetOrientRelTo(newFrame);
const Frame *newFrame = Frame::GetFrame(newFrameId);
const Frame *frame = Frame::GetFrame(m_frame);
const vector3d vel = GetVelocityRelTo(newFrameId); // do this first because it uses position
const vector3d fpos = frame->GetPositionRelTo(newFrameId);
const matrix3x3d forient = frame->GetOrientRelTo(newFrameId);
SetPosition(forient * GetPosition() + fpos);
SetOrient(forient * GetOrient());
SetVelocity(vel + newFrame->GetStasisVelocity(GetPosition()));
SetFrame(newFrame);
SetFrame(newFrameId);
LuaEvent::Queue("onFrameChanged", this);
}
@ -214,29 +227,33 @@ void Body::UpdateFrame()
{
if (!(m_flags & FLAG_CAN_MOVE_FRAME)) return;
const Frame *frame = Frame::GetFrame(m_frame);
// falling out of frames
if (m_frame->GetRadius() < GetPosition().Length()) {
Frame *newFrame = GetFrame()->GetParent();
if (frame->GetRadius() < GetPosition().Length()) {
FrameId parent = frame->GetParent();
Frame *newFrame = Frame::GetFrame(parent);
if (newFrame) { // don't fall out of root frame
Output("%s leaves frame %s\n", GetLabel().c_str(), GetFrame()->GetLabel().c_str());
SwitchToFrame(newFrame);
Output("%s leaves frame %s\n", GetLabel().c_str(), frame->GetLabel().c_str());
SwitchToFrame(parent);
return;
}
}
// entering into frames
for (Frame *kid : m_frame->GetChildren()) {
for (FrameId kid : frame->GetChildren()) {
Frame *kid_frame = Frame::GetFrame(kid);
const vector3d pos = GetPositionRelTo(kid);
if (pos.Length() >= kid->GetRadius()) continue;
if (pos.Length() >= kid_frame->GetRadius()) continue;
SwitchToFrame(kid);
Output("%s enters frame %s\n", GetLabel().c_str(), kid->GetLabel().c_str());
Output("%s enters frame %s\n", GetLabel().c_str(), kid_frame->GetLabel().c_str());
break;
}
}
vector3d Body::GetTargetIndicatorPosition(const Frame *relTo) const
vector3d Body::GetTargetIndicatorPosition(FrameId relToId) const
{
return GetInterpPositionRelTo(relTo);
return GetInterpPositionRelTo(relToId);
}
void Body::SetLabel(const std::string &label)

View File

@ -4,6 +4,7 @@
#ifndef _BODY_H
#define _BODY_H
#include "FrameId.h"
#include "Object.h"
#include "PropertiedObject.h"
#include "matrix3x3.h"
@ -61,16 +62,16 @@ public:
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(Frame *f) { m_frame = f; }
Frame *GetFrame() const { return m_frame; }
void SwitchToFrame(Frame *newFrame);
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(const Frame *) const;
vector3d GetPositionRelTo(const Frame *) const;
vector3d GetVelocityRelTo(FrameId) const;
vector3d GetPositionRelTo(FrameId) const;
vector3d GetPositionRelTo(const Body *) const;
matrix3x3d GetOrientRelTo(const Frame *) const;
matrix3x3d GetOrientRelTo(FrameId) const;
// Should return pointer in Pi::currentSystem
virtual const SystemBody *GetSystemBody() const { return nullptr; }
@ -90,9 +91,9 @@ public:
// Interpolated between physics ticks.
const matrix3x3d &GetInterpOrient() const { return m_interpOrient; }
vector3d GetInterpPosition() const { return m_interpPos; }
vector3d GetInterpPositionRelTo(const Frame *relTo) const;
vector3d GetInterpPositionRelTo(FrameId relToId) const;
vector3d GetInterpPositionRelTo(const Body *relTo) const;
matrix3x3d GetInterpOrientRelTo(const Frame *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
@ -103,7 +104,7 @@ public:
}
// where to draw targeting indicators - usually equal to GetInterpolatedPositionRelTo
virtual vector3d GetTargetIndicatorPosition(const Frame *relTo) const;
virtual vector3d GetTargetIndicatorPosition(FrameId relToId) const;
enum { FLAG_CAN_MOVE_FRAME = (1 << 0),
FLAG_LABEL_HIDDEN = (1 << 1),
@ -120,7 +121,7 @@ protected:
private:
vector3d m_pos;
matrix3x3d m_orient;
Frame *m_frame; // frame of reference
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;

View File

@ -29,44 +29,46 @@ CameraContext::CameraContext(float width, float height, float fovAng, float zNea
m_zNear(zNear),
m_zFar(zFar),
m_frustum(m_width, m_height, m_fovAng, m_zNear, m_zFar),
m_frame(nullptr),
m_frame(noFrameId),
m_pos(0.0),
m_orient(matrix3x3d::Identity()),
m_camFrame(nullptr)
m_camFrame(noFrameId)
{
}
CameraContext::~CameraContext()
{
if (m_camFrame)
if (m_camFrame != noFrameId)
EndFrame();
}
void CameraContext::BeginFrame()
{
assert(m_frame);
assert(!m_camFrame);
assert(IsIdValid(m_frame));
assert(!IsIdValid(m_camFrame));
// make temporary camera frame
m_camFrame = Frame::CreateFrame(m_frame, "camera", Frame::FLAG_ROTATING, 0.0);
Frame *camFrame = Frame::GetFrame(m_camFrame);
// move and orient it to the camera position
m_camFrame->SetOrient(m_orient, Pi::game ? Pi::game->GetTime() : 0.0);
m_camFrame->SetPosition(m_pos);
camFrame->SetOrient(m_orient, Pi::game ? Pi::game->GetTime() : 0.0);
camFrame->SetPosition(m_pos);
// make sure old orient and interpolated orient (rendering orient) are not rubbish
m_camFrame->ClearMovement();
m_camFrame->UpdateInterpTransform(1.0); // update root-relative pos/orient
camFrame->ClearMovement();
camFrame->UpdateInterpTransform(1.0); // update root-relative pos/orient
}
void CameraContext::EndFrame()
{
assert(m_frame);
assert(m_camFrame);
assert(IsIdValid(m_frame));
assert(IsIdValid(m_camFrame));
m_frame->RemoveChild(m_camFrame);
Frame *frame = Frame::GetFrame(m_frame);
frame->RemoveChild(m_camFrame);
Frame::DeleteFrame(m_camFrame);
m_camFrame = nullptr;
m_camFrame = noFrameId;
}
void CameraContext::ApplyDrawTransforms(Graphics::Renderer *r)
@ -113,7 +115,7 @@ static void position_system_lights(Frame *camFrame, Frame *frame, std::vector<Ca
SystemBody *body = frame->GetSystemBody();
// IsRotFrame check prevents double counting
if (body && !frame->IsRotFrame() && (body->GetSuperType() == SystemBody::SUPERTYPE_STAR)) {
vector3d lpos = frame->GetPositionRelTo(camFrame);
vector3d lpos = frame->GetPositionRelTo(camFrame->GetId());
const double dist = lpos.Length() / AU;
lpos *= 1.0 / dist; // normalize
@ -125,14 +127,15 @@ static void position_system_lights(Frame *camFrame, Frame *frame, std::vector<Ca
lights.push_back(Camera::LightSource(frame->GetBody(), light));
}
for (Frame *kid : frame->GetChildren()) {
position_system_lights(camFrame, kid, lights);
for (FrameId kid : frame->GetChildren()) {
Frame *kid_f = Frame::GetFrame(kid);
position_system_lights(camFrame, kid_f, lights);
}
}
void Camera::Update()
{
Frame *camFrame = m_context->GetCamFrame();
FrameId camFrame = m_context->GetCamFrame();
// evaluate each body and determine if/where/how to draw it
m_sortedBodies.clear();
@ -143,8 +146,9 @@ void Camera::Update()
// determine position and transform for draw
// Frame::GetFrameTransform(b->GetFrame(), camFrame, attrs.viewTransform); // doesn't use interp coords, so breaks in some cases
attrs.viewTransform = b->GetFrame()->GetInterpOrientRelTo(camFrame);
attrs.viewTransform.SetTranslate(b->GetFrame()->GetInterpPositionRelTo(camFrame));
Frame *f = Frame::GetFrame(b->GetFrame());
attrs.viewTransform = f->GetInterpOrientRelTo(camFrame);
attrs.viewTransform.SetTranslate(f->GetInterpPositionRelTo(camFrame));
attrs.viewCoords = attrs.viewTransform * b->GetInterpPosition();
// cull off-screen objects
@ -203,18 +207,22 @@ void Camera::Draw(const Body *excludeBody, ShipCockpit *cockpit)
{
PROFILE_SCOPED()
Frame *camFrame = m_context->GetCamFrame();
FrameId camFrameId = m_context->GetCamFrame();
FrameId rootFrameId = Pi::game->GetSpace()->GetRootFrame();
Frame *camFrame = Frame::GetFrame(camFrameId);
Frame *rootFrame = Frame::GetFrame(rootFrameId);
m_renderer->ClearScreen();
matrix4x4d trans2bg;
Frame::GetFrameTransform(Pi::game->GetSpace()->GetRootFrame(), camFrame, trans2bg);
Frame::GetFrameTransform(rootFrameId, camFrameId, trans2bg);
trans2bg.ClearToRotOnly();
// Pick up to four suitable system light sources (stars)
m_lightSources.clear();
m_lightSources.reserve(4);
position_system_lights(camFrame, Pi::game->GetSpace()->GetRootFrame(), m_lightSources);
position_system_lights(camFrame, rootFrame, m_lightSources);
if (m_lightSources.empty()) {
// no lights means we're somewhere weird (eg hyperspace). fake one
@ -224,12 +232,13 @@ void Camera::Draw(const Body *excludeBody, ShipCockpit *cockpit)
//fade space background based on atmosphere thickness and light angle
float bgIntensity = 1.f;
if (camFrame->GetParent() && camFrame->GetParent()->IsRotFrame()) {
Frame *camParent = Frame::GetFrame(camFrame->GetParent());
if ( camParent && camParent->IsRotFrame()) {
//check if camera is near a planet
Body *camParentBody = camFrame->GetParent()->GetBody();
Body *camParentBody = camParent->GetBody();
if (camParentBody && camParentBody->IsType(Object::PLANET)) {
Planet *planet = static_cast<Planet *>(camParentBody);
const vector3f relpos(planet->GetInterpPositionRelTo(camFrame));
const vector3f relpos(planet->GetInterpPositionRelTo(camFrameId));
double altitude(relpos.Length());
double pressure, density;
planet->GetAtmosphericState(altitude, &pressure, &density);
@ -279,7 +288,7 @@ void Camera::Draw(const Body *excludeBody, ShipCockpit *cockpit)
attrs->body->Render(m_renderer, this, attrs->viewCoords, attrs->viewTransform);
}
SfxManager::RenderAll(m_renderer, Pi::game->GetSpace()->GetRootFrame(), camFrame);
SfxManager::RenderAll(m_renderer, rootFrameId, camFrameId);
// NB: Do any screen space rendering after here:
// Things like the cockpit and AR features like hudtrails, space dust etc.
@ -288,7 +297,7 @@ void Camera::Draw(const Body *excludeBody, ShipCockpit *cockpit)
// XXX only here because it needs a frame for lighting calc
// should really be in WorldView, immediately after camera draw
if (cockpit)
cockpit->RenderCockpit(m_renderer, this, camFrame);
cockpit->RenderCockpit(m_renderer, this, camFrameId);
}
void Camera::CalcShadows(const int lightNum, const Body *b, std::vector<Shadow> &shadowsOut) const

View File

@ -5,6 +5,7 @@
#define _CAMERA_H
#include "Color.h"
#include "FrameId.h"
#include "graphics/Frustum.h"
#include "graphics/Light.h"
#include "matrix4x4.h"
@ -32,7 +33,7 @@ public:
float GetZFar() const { return m_zFar; }
// frame to position the camera relative to
void SetCameraFrame(Frame *frame) { m_frame = frame; }
void SetCameraFrame(FrameId frame) { m_frame = frame; }
// camera position relative to the frame origin
void SetCameraPosition(const vector3d &pos) { m_pos = pos; }
@ -48,7 +49,7 @@ public:
void EndFrame();
// valid between BeginFrame and EndFrame
Frame *GetCamFrame() const
FrameId GetCamFrame() const
{
assert(m_camFrame);
return m_camFrame;
@ -66,11 +67,11 @@ private:
Graphics::Frustum m_frustum;
Frame *m_frame;
FrameId m_frame;
vector3d m_pos;
matrix3x3d m_orient;
Frame *m_camFrame;
FrameId m_camFrame;
};
class Camera {

View File

@ -4,6 +4,7 @@
#include "CameraController.h"
#include "AnimationCurves.h"
#include "Frame.h"
#include "Game.h"
#include "GameSaveError.h"
#include "MathUtil.h"
@ -374,9 +375,10 @@ void FlyByCameraController::Update()
vector3d ship_pos = ship->GetInterpPosition();
vector3d camerap;
if (GetPosition() == vector3d(0, 0, 0) || m_old_frame != ship->GetFrame()) {
Frame *shipFrame = Frame::GetFrame(ship->GetFrame());
if (GetPosition() == vector3d(0, 0, 0) || m_old_frame != shipFrame) {
m_old_pos = ship_pos;
m_old_frame = ship->GetFrame();
m_old_frame = shipFrame;
}
m_flybyOrient.Renormalize();

View File

@ -64,7 +64,8 @@ void CityOnPlanet::AddStaticGeomsToCollisionSpace()
for (unsigned int i = 0; i < m_buildings.size(); i++) {
if (i & skipMask) {
} else {
m_frame->AddStaticGeom(m_buildings[i].geom);
Frame *f = Frame::GetFrame(m_frame);
f->AddStaticGeom(m_buildings[i].geom);
m_enabledBuildings.push_back(m_buildings[i]);
// Update building types
++(m_buildingCounts[m_buildings[i].instIndex]);
@ -79,7 +80,8 @@ void CityOnPlanet::RemoveStaticGeomsFromCollisionSpace()
{
m_enabledBuildings.clear();
for (unsigned int i = 0; i < m_buildings.size(); i++) {
m_frame->RemoveStaticGeom(m_buildings[i].geom);
Frame *f = Frame::GetFrame(m_frame);
f->RemoveStaticGeom(m_buildings[i].geom);
}
}
@ -190,7 +192,8 @@ CityOnPlanet::~CityOnPlanet()
{
// frame may be null (already removed from
for (unsigned int i = 0; i < m_buildings.size(); i++) {
m_frame->RemoveStaticGeom(m_buildings[i].geom);
Frame *f = Frame::GetFrame(m_frame);
f->RemoveStaticGeom(m_buildings[i].geom);
delete m_buildings[i].geom;
}
}

View File

@ -5,6 +5,7 @@
#define _CITYONPLANET_H
#include "CollMesh.h"
#include "FrameId.h"
#include "Object.h"
#include "Random.h"
@ -53,7 +54,7 @@ private:
};
Planet *m_planet;
Frame *m_frame;
FrameId m_frame;
std::vector<BuildingDef> m_buildings;
std::vector<BuildingDef> m_enabledBuildings;
std::vector<Uint32> m_buildingCounts;

View File

@ -181,17 +181,18 @@ void DynamicBody::SetMass(double mass)
m_angInertia = (2 / 5.0) * m_mass * m_massRadius * m_massRadius;
}
void DynamicBody::SetFrame(Frame *f)
void DynamicBody::SetFrame(FrameId fId)
{
ModelBody::SetFrame(f);
ModelBody::SetFrame(fId);
// external forces will be wrong after frame transition
m_externalForce = m_gravityForce = m_atmosForce = vector3d(0.0);
}
double DynamicBody::CalcAtmosphericDrag(double velSqr, double area, double coeff) const
{
Body *body = GetFrame()->GetBody();
if (!body || !GetFrame()->IsRotFrame() || !body->IsType(Object::PLANET))
Frame *f = Frame::GetFrame(GetFrame());
Body *body = f->GetBody();
if (!body || !f->IsRotFrame() || !body->IsType(Object::PLANET))
return 0.0;
Planet *planet = static_cast<Planet *>(body);
double pressure, density;
@ -213,8 +214,9 @@ vector3d DynamicBody::CalcAtmosphericForce() const
void DynamicBody::CalcExternalForce()
{
// gravity
if (!GetFrame()) return; // no external force if not in a frame
Body *body = GetFrame()->GetBody();
Frame *f = Frame::GetFrame(GetFrame());
if (!f) return; // no external force if not in a frame
Body *body = f->GetBody();
if (body && !body->IsType(Object::SPACESTATION)) { // they ought to have mass though...
vector3d b1b2 = GetPosition();
double m1m2 = GetMass() * body->GetMass();
@ -226,7 +228,7 @@ void DynamicBody::CalcExternalForce()
m_gravityForce = m_externalForce;
// atmospheric drag
if (body && GetFrame()->IsRotFrame() && body->IsType(Object::PLANET)) {
if (body && f->IsRotFrame() && body->IsType(Object::PLANET)) {
vector3d fAtmoForce = CalcAtmosphericForce();
// make this a bit less daft at high time accel
@ -243,8 +245,8 @@ void DynamicBody::CalcExternalForce()
m_atmosForce = vector3d(0.0);
// centrifugal and coriolis forces for rotating frames
if (GetFrame()->IsRotFrame()) {
vector3d angRot(0, GetFrame()->GetAngSpeed(), 0);
if (f->IsRotFrame()) {
vector3d angRot(0, f->GetAngSpeed(), 0);
m_externalForce -= m_mass * angRot.Cross(angRot.Cross(GetPosition())); // centrifugal
m_externalForce -= 2 * m_mass * angRot.Cross(GetVelocity()); // coriolis
}
@ -362,12 +364,13 @@ bool DynamicBody::OnCollision(Object *o, Uint32 flags, double relVel)
// return parameters for orbit of any body, gives both elliptic and hyperbolic trajectories
Orbit DynamicBody::ComputeOrbit() const
{
const Frame *frame = this->GetFrame()->GetNonRotFrame();
const double mass = frame->GetSystemBody()->GetMass();
FrameId nrFrameId = Frame::GetFrame(GetFrame())->GetNonRotFrame();
const Frame *nrFrame = Frame::GetFrame(nrFrameId);
const double mass = nrFrame->GetSystemBody()->GetMass();
// current velocity and position with respect to non-rotating frame
const vector3d vel = this->GetVelocityRelTo(frame);
const vector3d pos = this->GetPositionRelTo(frame);
const vector3d vel = GetVelocityRelTo(nrFrameId);
const vector3d pos = GetPositionRelTo(nrFrameId);
return Orbit::FromBodyState(pos, vel, mass);
}

View File

@ -25,7 +25,7 @@ public:
virtual vector3d GetVelocity() const override;
virtual void SetVelocity(const vector3d &v) override;
virtual void SetFrame(Frame *f) override;
virtual void SetFrame(FrameId fId) override;
vector3d GetAngVelocity() const;
void SetAngVelocity(const vector3d &v);
virtual bool OnCollision(Object *o, Uint32 flags, double relVel) override;

View File

@ -12,7 +12,7 @@
std::list<Frame> Frame::s_frames;
Frame::Frame(const Dummy &d, Frame *parent, const char *label, unsigned int flags, double radius):
Frame::Frame(const Dummy &d, FrameId parent, const char *label, unsigned int flags, double radius):
m_sbody(nullptr),
m_astroBody(nullptr),
m_parent(parent),
@ -31,12 +31,16 @@ Frame::Frame(const Dummy &d, Frame *parent, const char *label, unsigned int flag
ClearMovement();
m_collisionSpace = new CollisionSpace();
if (m_parent) m_parent->AddChild(this);
if (IsIdValid(m_parent)) Frame::GetFrame(m_parent)->AddChild(m_thisId);
if (label) m_label = label;
}
void Frame::ToJson(Json &frameObj, Frame *f, Space *space)
void Frame::ToJson(Json &frameObj, FrameId fId, Space *space)
{
Frame *f = Frame::GetFrame(fId);
assert(f != nullptr);
frameObj["frameId"] = f->m_thisId;
frameObj["flags"] = f->m_flags;
frameObj["radius"] = f->m_radius;
@ -48,7 +52,7 @@ void Frame::ToJson(Json &frameObj, Frame *f, Space *space)
frameObj["index_for_astro_body"] = space->GetIndexForBody(f->m_astroBody);
Json childFrameArray = Json::array(); // Create JSON array to contain child frame data.
for (Frame *kid : f->GetChildren()) {
for (FrameId kid : f->GetChildren()) {
Json childFrameArrayEl = Json::object(); // Create JSON object to contain child frame.
Frame::ToJson(childFrameArrayEl, kid, space);
childFrameArray.push_back(childFrameArrayEl); // Append child frame object to array.
@ -57,30 +61,46 @@ void Frame::ToJson(Json &frameObj, Frame *f, Space *space)
frameObj["child_frames"] = childFrameArray; // Add child frame array to frame object.
// Add sfx array to supplied object.
SfxManager::ToJson(frameObj, f);
SfxManager::ToJson(frameObj, f->m_thisId);
}
Frame *Frame::CreateFrame(Frame *parent, const char *label, unsigned int flags, double radius)
Frame::~Frame()
{
if (!d.madeWithFactory) {
Error("Frame instance deletion outside 'DeleteFrame'\n");
}
// Delete this Frame and recurse deleting children
delete m_collisionSpace;
for (FrameId kid : m_children) {
DeleteFrame(kid);
}
}
FrameId Frame::CreateFrame(FrameId parent, const char *label, unsigned int flags, double radius)
{
Dummy dummy;
dummy.madeWithFactory = true;
s_frames.emplace_back(dummy, parent, label, flags, radius);
return &s_frames.back();
return (s_frames.size() - 1);
}
Frame *Frame::FromJson(const Json &frameObj, Space *space, Frame *parent, double at_time)
FrameId Frame::FromJson(const Json &frameObj, Space *space, FrameId parent, double at_time)
{
Dummy dummy;
dummy.madeWithFactory = true;
// Set parent to nullptr here in order to avoid this frame
// being a child twice (due to ctor calling AddChild)
s_frames.emplace_back(dummy, nullptr, nullptr);
s_frames.emplace_back(dummy, noFrameId, nullptr);
Frame *f = &s_frames.back();
f->m_parent = parent;
if (parent != noFrameId)
f->m_parent = Frame::GetFrame(parent)->GetId();
else
f->m_parent = noFrameId;
f->d.madeWithFactory = false;
try {
@ -104,7 +124,8 @@ Frame *Frame::FromJson(const Json &frameObj, Space *space, Frame *parent, double
Json childFrameArray = frameObj["child_frames"];
f->m_children.reserve(childFrameArray.size());
for (unsigned int i = 0; i < childFrameArray.size(); ++i) {
f->m_children.push_back(FromJson(childFrameArray[i], space, f, at_time));
FrameId kidId = FromJson(childFrameArray[i], space, f->m_thisId, at_time);
f->m_children.push_back(kidId);
}
} else {
f->m_children.clear();
@ -115,26 +136,26 @@ Frame *Frame::FromJson(const Json &frameObj, Space *space, Frame *parent, double
throw SavedGameCorruptException();
}
SfxManager::FromJson(frameObj, f);
SfxManager::FromJson(frameObj, f->m_thisId);
f->ClearMovement();
return f;
return f->GetId();
}
void Frame::DeleteFrame(Frame *tobedeleted)
void Frame::DeleteFrame(FrameId tobedeleted)
{
tobedeleted->d.madeWithFactory = true;
Frame *f = GetFrame(tobedeleted);
f->d.madeWithFactory = true;
// Find Frame and delete it, let dtor delete its children
for (std::list<Frame>::const_iterator it = s_frames.begin(); it != s_frames.end(); it++) {
if (tobedeleted == &(*it)) {
if (f == &(*it)) {
s_frames.erase(it);
break;
}
}
tobedeleted->d.madeWithFactory = false;
}
Frame *Frame::FindFrame(FrameId FId)
Frame *Frame::GetFrame(FrameId FId)
{
for (Frame &elem : s_frames) {
if (elem.m_thisId == FId) return &elem;
@ -142,30 +163,22 @@ Frame *Frame::FindFrame(FrameId FId)
return nullptr;
}
void Frame::PostUnserializeFixup(Frame *f, Space *space)
void Frame::PostUnserializeFixup(FrameId fId, Space *space)
{
Frame *f = Frame::GetFrame(fId);
f->UpdateRootRelativeVars();
f->m_astroBody = space->GetBodyByIndex(f->m_astroBodyIndex);
for (Frame *kid : f->GetChildren())
for (FrameId kid : f->GetChildren())
PostUnserializeFixup(kid, space);
}
Frame::~Frame()
{
if (!d.madeWithFactory) {
Error("Frame instance deletion outside 'DeleteFrame'\n");
}
// Delete this Frame and recurse deleting children
delete m_collisionSpace;
for (Frame *kid : m_children) {
DeleteFrame(kid);
}
}
void Frame::RemoveChild(Frame *f)
void Frame::RemoveChild(FrameId fId)
{
PROFILE_SCOPED()
const std::vector<Frame *>::iterator it = std::find(m_children.begin(), m_children.end(), f);
if (fId == noFrameId) return;
Frame *f = Frame::GetFrame(fId);
if (f == nullptr) return;
const std::vector<FrameId>::iterator it = std::find(m_children.begin(), m_children.end(), fId);
if (it != m_children.end())
m_children.erase(it);
}
@ -180,9 +193,11 @@ void Frame::SetPlanetGeom(double radius, Body *obj)
}
// doesn't consider stasis velocity
vector3d Frame::GetVelocityRelTo(const Frame *relTo) const
vector3d Frame::GetVelocityRelTo(FrameId relToId) const
{
if (this == relTo) return vector3d(0, 0, 0); // early-out to avoid unnecessary computation
if (m_thisId == relToId) return vector3d(0, 0, 0); // early-out to avoid unnecessary computation
const Frame *relTo = Frame::GetFrame(relToId);
vector3d diff = m_rootVel - relTo->m_rootVel;
if (relTo->IsRotFrame())
return diff * relTo->m_rootOrient;
@ -190,12 +205,15 @@ vector3d Frame::GetVelocityRelTo(const Frame *relTo) const
return diff;
}
vector3d Frame::GetPositionRelTo(const Frame *relTo) const
vector3d Frame::GetPositionRelTo(FrameId relToId) const
{
// early-outs for simple cases, required for accuracy in large systems
if (this == relTo) return vector3d(0, 0, 0);
if (GetParent() == relTo) return m_pos; // relative to parent
if (relTo->GetParent() == this) { // relative to child
if (m_thisId == relToId) return vector3d(0, 0, 0);
const Frame *relTo = Frame::GetFrame(relToId);
if (GetParent() == relToId) return m_pos; // relative to parent
if (relTo->GetParent() == m_thisId) { // relative to child
if (!relTo->IsRotFrame())
return -relTo->m_pos;
else
@ -216,12 +234,14 @@ vector3d Frame::GetPositionRelTo(const Frame *relTo) const
return diff;
}
vector3d Frame::GetInterpPositionRelTo(const Frame *relTo) const
vector3d Frame::GetInterpPositionRelTo(FrameId relToId) const
{
const Frame *relTo = Frame::GetFrame(relToId);
// early-outs for simple cases, required for accuracy in large systems
if (this == relTo) return vector3d(0, 0, 0);
if (GetParent() == relTo) return m_interpPos; // relative to parent
if (relTo->GetParent() == this) { // relative to child
if (m_thisId == relToId) return vector3d(0, 0, 0);
if (GetParent() == relTo->GetId()) return m_interpPos; // relative to parent
if (relTo->GetParent() == m_thisId) { // relative to child
if (!relTo->IsRotFrame())
return -relTo->m_interpPos;
else
@ -241,16 +261,16 @@ vector3d Frame::GetInterpPositionRelTo(const Frame *relTo) const
return diff;
}
matrix3x3d Frame::GetOrientRelTo(const Frame *relTo) const
matrix3x3d Frame::GetOrientRelTo(FrameId relToId) const
{
if (this == relTo) return matrix3x3d::Identity();
return relTo->m_rootOrient.Transpose() * m_rootOrient;
if (m_thisId == relToId) return matrix3x3d::Identity();
return Frame::GetFrame(relToId)->m_rootOrient.Transpose() * m_rootOrient;
}
matrix3x3d Frame::GetInterpOrientRelTo(const Frame *relTo) const
matrix3x3d Frame::GetInterpOrientRelTo(FrameId relToId) const
{
if (this == relTo) return matrix3x3d::Identity();
return relTo->m_rootInterpOrient.Transpose() * m_rootInterpOrient;
if (m_thisId == relToId) return matrix3x3d::Identity();
return Frame::GetFrame(relToId)->m_rootInterpOrient.Transpose() * m_rootInterpOrient;
/* if (IsRotFrame()) {
if (relTo->IsRotFrame()) return m_interpOrient * relTo->m_interpOrient.Transpose();
else return m_interpOrient;
@ -272,21 +292,24 @@ void Frame::UpdateInterpTransform(double alpha)
} else
m_interpOrient = m_orient;
if (!m_parent)
Frame *parent = Frame::GetFrame(m_parent);
if (!parent)
ClearMovement();
else {
m_rootInterpPos = m_parent->m_rootInterpOrient * m_interpPos + m_parent->m_rootInterpPos;
m_rootInterpOrient = m_parent->m_rootInterpOrient * m_interpOrient;
m_rootInterpPos = parent->m_rootInterpOrient * m_interpPos + parent->m_rootInterpPos;
m_rootInterpOrient = parent->m_rootInterpOrient * m_interpOrient;
}
for (Frame *kid : m_children)
kid->UpdateInterpTransform(alpha);
for (FrameId kid : m_children) {
Frame *kidFrame = Frame::GetFrame(kid);
kidFrame->UpdateInterpTransform(alpha);
}
}
void Frame::GetFrameTransform(const Frame *fFrom, const Frame *fTo, matrix4x4d &m)
void Frame::GetFrameTransform(const FrameId fFromId, const FrameId fToId, matrix4x4d &m)
{
matrix3x3d forient = fFrom->GetOrientRelTo(fTo);
vector3d fpos = fFrom->GetPositionRelTo(fTo);
matrix3x3d forient = Frame::GetFrame(fFromId)->GetOrientRelTo(fToId);
vector3d fpos = Frame::GetFrame(fFromId)->GetPositionRelTo(fToId);
m = forient;
m.SetTranslate(fpos);
}
@ -307,7 +330,7 @@ void Frame::UpdateOrbitRails(double time, double timestep)
m_oldAngDisplacement = m_angSpeed * timestep;
// update frame position and velocity
if (m_parent && m_sbody && !IsRotFrame()) {
if (IsIdValid(m_parent) && m_sbody && !IsRotFrame()) {
m_pos = m_sbody->GetOrbit().OrbitalPosAtTime(time);
vector3d pos2 = m_sbody->GetOrbit().OrbitalPosAtTime(time + timestep);
m_vel = (pos2 - m_pos) / timestep;
@ -324,8 +347,10 @@ void Frame::UpdateOrbitRails(double time, double timestep)
}
UpdateRootRelativeVars(); // update root-relative pos/vel/orient
for (Frame *kid : m_children)
kid->UpdateOrbitRails(time, timestep);
for (FrameId kid : m_children) {
Frame *kidFrame = Frame::GetFrame(kid);
kidFrame->UpdateOrbitRails(time, timestep);
}
}
void Frame::SetInitialOrient(const matrix3x3d &m, double time)
@ -355,12 +380,13 @@ void Frame::SetOrient(const matrix3x3d &m, double time)
void Frame::UpdateRootRelativeVars()
{
// update pos & vel relative to parent frame
if (!m_parent) {
Frame *parent = Frame::GetFrame(m_parent);
if (!parent) {
m_rootPos = m_rootVel = vector3d(0, 0, 0);
m_rootOrient = matrix3x3d::Identity();
} else {
m_rootPos = m_parent->m_rootOrient * m_pos + m_parent->m_rootPos;
m_rootVel = m_parent->m_rootOrient * m_vel + m_parent->m_rootVel;
m_rootOrient = m_parent->m_rootOrient * m_orient;
m_rootPos = parent->m_rootOrient * m_pos + parent->m_rootPos;
m_rootVel = parent->m_rootOrient * m_vel + parent->m_rootVel;
m_rootOrient = parent->m_rootOrient * m_orient;
}
}

View File

@ -30,22 +30,22 @@ class Frame {
public:
Frame() = delete;
Frame(const Dummy &d, Frame *parent, const char *label, unsigned int flags = FLAG_DEFAULT, double radius = 0.0);
Frame(const Dummy &d, FrameId parent, const char *label, unsigned int flags = FLAG_DEFAULT, double radius = 0.0);
~Frame();
enum { FLAG_DEFAULT = (0),
FLAG_ROTATING = (1 << 1),
FLAG_HAS_ROT = (1 << 2) };
static Frame *CreateFrame(Frame *parent, const char *label, unsigned int flags = FLAG_DEFAULT, double radius = 0.0);
static Frame *FromJson(const Json &jsonObj, Space *space, Frame *parent, double at_time);
static FrameId CreateFrame(FrameId parent, const char *label, unsigned int flags = FLAG_DEFAULT, double radius = 0.0);
static FrameId FromJson(const Json &jsonObj, Space *space, FrameId parent, double at_time);
static void ToJson(Json &jsonObj, Frame *f, Space *space);
static void PostUnserializeFixup(Frame *f, Space *space);
static void ToJson(Json &jsonObj, FrameId fId, Space *space);
static void PostUnserializeFixup(FrameId fId, Space *space);
static void DeleteFrame(Frame *tobedeleted);
static void DeleteFrame(FrameId tobedeleted);
static Frame *FindFrame(FrameId FId);
static Frame *GetFrame(FrameId FId);
FrameId GetId() const {return m_thisId; }
@ -67,11 +67,9 @@ public:
bool IsRotFrame() const { return m_flags & FLAG_ROTATING; }
bool HasRotFrame() const { return m_flags & FLAG_HAS_ROT; }
Frame *GetParent() const { return m_parent; }
const Frame *GetNonRotFrame() const { return IsRotFrame() ? m_parent : this; }
Frame *GetNonRotFrame() { return IsRotFrame() ? m_parent : this; }
const Frame *GetRotFrame() const { return HasRotFrame() ? m_children.front() : this; }
Frame *GetRotFrame() { return HasRotFrame() ? m_children.front() : this; }
FrameId GetParent() const { return m_parent; }
FrameId GetNonRotFrame() { return IsRotFrame() ? m_parent : m_thisId; }
FrameId GetRotFrame() { return HasRotFrame() ? m_children.front() : m_thisId; }
void SetBodies(SystemBody *s, Body *b)
{
@ -81,12 +79,12 @@ public:
SystemBody *GetSystemBody() const { return m_sbody; }
Body *GetBody() const { return m_astroBody; }
void AddChild(Frame *f) { m_children.push_back(f); }
void RemoveChild(Frame *f);
void AddChild(FrameId fId) { m_children.push_back(fId); }
void RemoveChild(FrameId fId);
bool HasChildren() const { return !m_children.empty(); }
unsigned GetNumChildren() const { return static_cast<Uint32>(m_children.size()); }
IterationProxy<std::vector<Frame *>> GetChildren() { return MakeIterationProxy(m_children); }
const IterationProxy<const std::vector<Frame *>> GetChildren() const { return MakeIterationProxy(m_children); }
IterationProxy<std::vector<FrameId>> GetChildren() { return MakeIterationProxy(m_children); }
const IterationProxy<const std::vector<FrameId>> GetChildren() const { return MakeIterationProxy(m_children); }
void AddGeom(Geom *);
void RemoveGeom(Geom *);
@ -104,16 +102,16 @@ public:
// must attain this velocity within rotating frame to be stationary.
vector3d GetStasisVelocity(const vector3d &pos) const { return -vector3d(0, m_angSpeed, 0).Cross(pos); }
vector3d GetPositionRelTo(const Frame *relTo) const;
vector3d GetVelocityRelTo(const Frame *relTo) const;
matrix3x3d GetOrientRelTo(const Frame *relTo) const;
vector3d GetPositionRelTo(FrameId relTo) const;
vector3d GetVelocityRelTo(FrameId relTo) const;
matrix3x3d GetOrientRelTo(FrameId relTo) const;
// Same as above except it does interpolation between
// physics ticks so rendering is smooth above physics hz
vector3d GetInterpPositionRelTo(const Frame *relTo) const;
matrix3x3d GetInterpOrientRelTo(const Frame *relTo) const;
vector3d GetInterpPositionRelTo(FrameId relTo) const;
matrix3x3d GetInterpOrientRelTo(FrameId relTo) const;
static void GetFrameTransform(const Frame *fFrom, const Frame *fTo, matrix4x4d &m);
static void GetFrameTransform(FrameId fFrom, FrameId fTo, matrix4x4d &m);
std::unique_ptr<SfxManager> m_sfx; // the last survivor. actually m_children is pretty grim too.
@ -122,8 +120,8 @@ private:
void UpdateRootRelativeVars();
Frame *m_parent; // if parent is null then frame position is absolute
std::vector<Frame *> m_children; // child frames, first may be rotating
FrameId m_parent; // if parent is null then frame position is absolute
std::vector<FrameId> m_children; // child frames, first may be rotating
SystemBody *m_sbody; // points to SBodies in Pi::current_system
Body *m_astroBody; // if frame contains a star or planet or something

3
src/FrameId.cpp Normal file
View File

@ -0,0 +1,3 @@
#include "FrameId.h"
bool IsIdValid(FrameId fId) { return fId >= 0; }

View File

@ -5,4 +5,6 @@ typedef int FrameId;
constexpr FrameId noFrameId = -1;
extern bool IsIdValid(FrameId fId);
#endif // FRAMEID_H_INCLUDED

View File

@ -4,6 +4,7 @@
#include "HudTrail.h"
#include "Body.h"
#include "Frame.h"
#include "Pi.h"
#include "graphics/Renderer.h"
#include "graphics/RenderState.h"
@ -31,14 +32,15 @@ void HudTrail::Update(float time)
m_updateTime += time;
if (m_updateTime > UPDATE_INTERVAL) {
m_updateTime = 0.f;
const Frame *bodyFrame = m_body->GetFrame();
FrameId bodyFrameId = m_body->GetFrame();
const Frame *bodyFrame = Frame::GetFrame(bodyFrameId);
if (!m_currentFrame) {
m_currentFrame = bodyFrame;
if (m_currentFrame < 0) {
m_currentFrame = bodyFrameId;
m_trailPoints.clear();
}
if (bodyFrame == m_currentFrame)
if (bodyFrameId == m_currentFrame)
m_trailPoints.push_back(m_body->GetInterpPosition());
}
@ -82,7 +84,7 @@ void HudTrail::Render(Graphics::Renderer *r)
}
}
void HudTrail::Reset(const Frame *newFrame)
void HudTrail::Reset(FrameId newFrame)
{
m_currentFrame = newFrame;
m_trailPoints.clear();

View File

@ -5,6 +5,7 @@
#define _HUDTRAIL_H
#include "Color.h"
#include "FrameId.h"
#include "matrix4x4.h"
#include "graphics/Drawables.h"
@ -24,14 +25,14 @@ public:
HudTrail(Body *b, const Color &);
void Update(float time);
void Render(Graphics::Renderer *r);
void Reset(const Frame *newFrame);
void Reset(const FrameId newFrame);
void SetColor(const Color &c) { m_color = c; }
void SetTransform(const matrix4x4d &t) { m_transform = t; }
private:
Body *m_body;
const Frame *m_currentFrame;
FrameId m_currentFrame;
float m_updateTime;
Color m_color;
matrix4x4d m_transform;

View File

@ -405,7 +405,7 @@ static int l_body_attr_frame_body(lua_State *l)
return 1;
}
Frame *f = b->GetFrame();
Frame *f = Frame::GetFrame(b->GetFrame());
LuaObject<Body>::PushToLua(f->GetBody());
return 1;
}
@ -434,7 +434,7 @@ static int l_body_attr_frame_rotating(lua_State *l)
return 1;
}
Frame *f = b->GetFrame();
Frame *f = Frame::GetFrame(b->GetFrame());
lua_pushboolean(l, f->IsRotFrame());
return 1;
}
@ -548,7 +548,7 @@ static int l_body_get_ground_position(lua_State *l)
return 1;
}
Frame *f = b->GetFrame();
Frame *f = Frame::GetFrame(b->GetFrame());
if (!f->IsRotFrame())
return 0;

View File

@ -515,13 +515,14 @@ static int l_get_gps(lua_State *l)
Player *player = LuaObject<Player>::CheckFromLua(1);
vector3d pos = Pi::player->GetPosition();
double center_dist = pos.Length();
auto frame = player->GetFrame();
if (frame) {
Body *astro = frame->GetBody();
FrameId playerFrameId = player->GetFrame();
Frame *playerFrame = Frame::GetFrame(playerFrameId);
if (IsIdValid(playerFrameId)) {
Body *astro = Frame::GetFrame(playerFrameId)->GetBody();
if (astro && astro->IsType(Object::TERRAINBODY)) {
TerrainBody *terrain = static_cast<TerrainBody *>(astro);
if (!frame->IsRotFrame())
frame = frame->GetRotFrame();
if (!playerFrame->IsRotFrame())
playerFrame = Frame::GetFrame(playerFrame->GetRotFrame());
vector3d surface_pos = pos.Normalized();
double radius = 0.0;
if (center_dist <= 3.0 * terrain->GetMaxFeatureRadius()) {

View File

@ -938,7 +938,8 @@ static int l_ship_get_set_speed_target(lua_State *l)
Ship *s = LuaObject<Ship>::CheckFromLua(1);
Body *t = s->GetController()->GetSetSpeedTarget();
if (s->GetType() == Object::Type::PLAYER && t == nullptr) {
Frame *f = s->GetFrame();
FrameId fId = s->GetFrame();
Frame *f = Frame::GetFrame(fId);
if (f)
t = f->GetBody();
}

View File

@ -225,7 +225,9 @@ static int l_space_spawn_ship_near(lua_State *l)
Body *thing = _maybe_wrap_ship_with_cloud(ship, path, due);
// XXX protect against spawning inside the body
Frame *newframe = nearbody->GetFrame();
FrameId newframeId = nearbody->GetFrame();
Frame *newframe = Frame::GetFrame(newframeId);
const vector3d newPosition = (MathUtil::RandomPointOnSphere(min_dist, max_dist) * 1000.0) + nearbody->GetPosition();
// If the frame is rotating and the chosen position is too far, use non-rotating parent.
@ -233,10 +235,10 @@ static int l_space_spawn_ship_near(lua_State *l)
// rotating frame in the next update
if (newframe->IsRotFrame() && newframe->GetRadius() < newPosition.Length()) {
assert(newframe->GetParent());
newframe = newframe->GetParent();
newframe = Frame::GetFrame(newframe->GetParent());
}
thing->SetFrame(newframe);
thing->SetFrame(newframe->GetId());
;
thing->SetPosition(newPosition);
thing->SetVelocity(newVelocity);
@ -505,7 +507,7 @@ static int l_space_spawn_ship_landed_near(lua_State *l)
assert(ship);
// XXX protect against spawning inside the body
Frame *newframe = nearbody->GetFrame()->GetRotFrame();
Frame *newframe = Frame::GetFrame(Frame::GetFrame(nearbody->GetFrame())->GetRotFrame());
if (!newframe->IsRotFrame())
luaL_error(l, "Body must be in rotating frame");
SystemBody *sbody = newframe->GetSystemBody();
@ -696,7 +698,9 @@ static int l_space_attr_root_system_body(lua_State *l)
LUA_DEBUG_START(l);
LuaObject<SystemBody>::PushToLua(Pi::game->GetSpace()->GetRootFrame()->GetSystemBody());
FrameId rootId = Pi::game->GetSpace()->GetRootFrame();
Frame *root = Frame::GetFrame(rootId);
LuaObject<SystemBody>::PushToLua(root->GetSystemBody());
LUA_DEBUG_END(l, 1);

View File

@ -92,7 +92,7 @@ ModelBody::ModelBody(const Json &jsonObj, Space *space) :
ModelBody::~ModelBody()
{
SetFrame(0); // Will remove geom from frame if necessary.
SetFrame(noFrameId); // Will remove geom from frame if necessary.
DeleteGeoms();
//delete instanced model
@ -120,12 +120,13 @@ void ModelBody::SetStatic(bool isStatic)
m_isStatic = isStatic;
if (!m_geom) return;
Frame *f = Frame::GetFrame(GetFrame());
if (m_isStatic) {
GetFrame()->RemoveGeom(m_geom);
GetFrame()->AddStaticGeom(m_geom);
f->RemoveGeom(m_geom);
f->AddStaticGeom(m_geom);
} else {
GetFrame()->RemoveStaticGeom(m_geom);
GetFrame()->AddGeom(m_geom);
f->RemoveStaticGeom(m_geom);
f->AddGeom(m_geom);
}
}
@ -140,8 +141,9 @@ void ModelBody::SetColliding(bool colliding)
void ModelBody::RebuildCollisionMesh()
{
Frame *f = Frame::GetFrame(GetFrame());
if (m_geom) {
if (GetFrame()) RemoveGeomsFromFrame(GetFrame());
if (f) RemoveGeomsFromFrame(f);
DeleteGeoms();
}
@ -167,7 +169,7 @@ void ModelBody::RebuildCollisionMesh()
m_dynGeoms.push_back(dynG);
}
if (GetFrame()) AddGeomsToFrame(GetFrame());
if (f) AddGeomsToFrame(f);
}
void ModelBody::SetModel(const char *modelName)
@ -193,9 +195,6 @@ void ModelBody::SetPosition(const vector3d &p)
{
Body::SetPosition(p);
MoveGeoms(GetOrient(), p);
// for rebuild of static objects in collision space
if (m_isStatic) SetFrame(GetFrame());
}
void ModelBody::SetOrient(const matrix3x3d &m)
@ -205,16 +204,18 @@ void ModelBody::SetOrient(const matrix3x3d &m)
MoveGeoms(m2, GetPosition());
}
void ModelBody::SetFrame(Frame *f)
void ModelBody::SetFrame(FrameId fId)
{
if (f == GetFrame()) return;
if (fId == GetFrame()) return;
//remove collision geoms from old frame
if (GetFrame()) RemoveGeomsFromFrame(GetFrame());
Frame *f = Frame::GetFrame(GetFrame());
if (f) RemoveGeomsFromFrame(f);
Body::SetFrame(f);
Body::SetFrame(fId);
//add collision geoms to new frame
f = Frame::GetFrame(GetFrame());
if (f) AddGeomsToFrame(f);
}
@ -247,14 +248,16 @@ void ModelBody::AddGeomsToFrame(Frame *f)
void ModelBody::RemoveGeomsFromFrame(Frame *f)
{
if (f == nullptr) return;
if (m_isStatic) {
GetFrame()->RemoveStaticGeom(m_geom);
f->RemoveStaticGeom(m_geom);
} else {
GetFrame()->RemoveGeom(m_geom);
f->RemoveGeom(m_geom);
}
for (auto it = m_dynGeoms.begin(); it != m_dynGeoms.end(); ++it)
GetFrame()->RemoveGeom(*it);
f->RemoveGeom(*it);
}
void ModelBody::MoveGeoms(const matrix4x4d &m, const vector3d &p)
@ -296,7 +299,7 @@ void ModelBody::CalcLighting(double &ambient, double &direct, const Camera *came
const double minAmbient = 0.05;
ambient = minAmbient;
direct = 1.0;
Body *astro = GetFrame()->GetBody();
Body *astro = Frame::GetFrame(GetFrame())->GetBody();
if (!(astro && astro->IsType(Object::PLANET)))
return;

View File

@ -6,6 +6,7 @@
#include "Body.h"
#include "CollMesh.h"
#include "FrameId.h"
class Shields;
class Geom;
@ -29,7 +30,7 @@ public:
virtual ~ModelBody();
void SetPosition(const vector3d &p) override;
void SetOrient(const matrix3x3d &r) override;
virtual void SetFrame(Frame *f) override;
virtual void SetFrame(FrameId fId) override;
// Colliding: geoms are checked against collision space
void SetColliding(bool colliding);
bool IsColliding() const { return m_colliding; }

View File

@ -1426,7 +1426,7 @@ void Pi::MainLoop()
for (Body *b : game->GetSpace()->GetBodies()) {
b->UpdateInterpTransform(Pi::GetGameTickAlpha());
}
game->GetSpace()->GetRootFrame()->UpdateInterpTransform(Pi::GetGameTickAlpha());
Frame::GetFrame(game->GetSpace()->GetRootFrame())->UpdateInterpTransform(Pi::GetGameTickAlpha());
currentView->Update();
currentView->Draw3D();

View File

@ -306,9 +306,9 @@ int Player::GetManeuverTime() const
vector3d Player::GetManeuverVelocity() const
{
const Frame *frame = GetFrame();
Frame *frame = Frame::GetFrame(GetFrame());
if (frame->IsRotFrame())
frame = frame->GetNonRotFrame();
frame = Frame::GetFrame(frame->GetNonRotFrame());
const SystemBody *systemBody = frame->GetSystemBody();
if (Pi::planner->GetOffsetVel().ExactlyEqual(vector3d(0, 0, 0))) {

View File

@ -220,7 +220,7 @@ double Projectile::GetRadius() const
return sqrt(m_length * m_length + m_width * m_width);
}
void MiningLaserSpawnTastyStuff(Frame *f, const SystemBody *asteroid, const vector3d &pos)
void MiningLaserSpawnTastyStuff(FrameId fId, const SystemBody *asteroid, const vector3d &pos)
{
lua_State *l = Lua::manager->GetLuaState();
@ -244,7 +244,7 @@ void MiningLaserSpawnTastyStuff(Frame *f, const SystemBody *asteroid, const vect
lua_pop(l, 1);
LUA_DEBUG_END(l, 0);
cargo->SetFrame(f);
cargo->SetFrame(fId);
cargo->SetPosition(pos);
const double x = Pi::rng.Double();
vector3d dir = pos.Normalized();
@ -259,7 +259,8 @@ void Projectile::StaticUpdate(const float timeStep)
CollisionContact c;
// Collision spaces don't store velocity, so dirvel-only is still wrong but less awful than dirvel+basevel
vector3d vel = m_dirVel * timeStep;
GetFrame()->GetCollisionSpace()->TraceRay(GetPosition(), vel.Normalized(), vel.Length(), &c);
Frame *frame = Frame::GetFrame(GetFrame());
frame->GetCollisionSpace()->TraceRay(GetPosition(), vel.Normalized(), vel.Length(), &c);
if (c.userData1) {
Object *o = static_cast<Object *>(c.userData1);
@ -279,7 +280,7 @@ void Projectile::StaticUpdate(const float timeStep)
if (m_mining) // mining lasers can break off chunks of terrain
{
// need to test for terrain hit
Planet *const planet = static_cast<Planet *>(GetFrame()->GetBody()); // cache the value even for the if statement
Planet *const planet = static_cast<Planet *>(frame->GetBody()); // cache the value even for the if statement
if (planet && planet->IsType(Object::PLANET)) {
vector3d pos = GetPosition();
double terrainHeight = planet->GetTerrainHeight(pos.Normalized());

View File

@ -138,7 +138,7 @@ void Sensors::Update(float time)
it->distance = m_owner->GetPositionRelTo(it->body).Length();
it->trail->Update(time);
} else {
it->trail->Reset(nullptr);
it->trail->Reset(noFrameId);
}
it->fresh = false;
++it;

View File

@ -128,8 +128,9 @@ SfxManager::SfxManager()
}
}
void SfxManager::ToJson(Json &jsonObj, const Frame *f)
void SfxManager::ToJson(Json &jsonObj, const FrameId fId)
{
Frame *f = Frame::GetFrame(fId);
Json sfxArray = Json::array(); // Create JSON array to contain sfx data.
if (f->m_sfx) {
@ -148,10 +149,12 @@ void SfxManager::ToJson(Json &jsonObj, const Frame *f)
jsonObj["sfx_array"] = sfxArray; // Add sfx array to supplied object.
}
void SfxManager::FromJson(const Json &jsonObj, Frame *f)
void SfxManager::FromJson(const Json &jsonObj, FrameId fId)
{
Json sfxArray = jsonObj["sfx_array"].get<Json::array_t>();
Frame *f = Frame::GetFrame(fId);
if (sfxArray.size()) f->m_sfx.reset(new SfxManager);
for (unsigned int i = 0; i < sfxArray.size(); ++i) {
Sfx inst(sfxArray[i]);
@ -159,8 +162,10 @@ void SfxManager::FromJson(const Json &jsonObj, Frame *f)
}
}
SfxManager *SfxManager::AllocSfxInFrame(Frame *f)
SfxManager *SfxManager::AllocSfxInFrame(FrameId fId)
{
Frame *f = Frame::GetFrame(fId);
if (!f->m_sfx) {
f->m_sfx.reset(new SfxManager);
}
@ -201,9 +206,12 @@ void SfxManager::AddThrustSmoke(const Body *b, const float speed, const vector3d
sfxman->AddInstance(sfx);
}
void SfxManager::TimeStepAll(const float timeStep, Frame *f)
void SfxManager::TimeStepAll(const float timeStep, FrameId fId)
{
PROFILE_SCOPED()
Frame *f = Frame::GetFrame(fId);
if (f->m_sfx) {
for (size_t t = TYPE_EXPLOSION; t < TYPE_NONE; t++) {
for (size_t i = 0; i < f->m_sfx->GetNumberInstances(SFX_TYPE(t)); i++) {
@ -214,7 +222,7 @@ void SfxManager::TimeStepAll(const float timeStep, Frame *f)
f->m_sfx->Cleanup();
}
for (Frame *kid : f->GetChildren()) {
for (FrameId kid : f->GetChildren()) {
TimeStepAll(timeStep, kid);
}
}
@ -235,12 +243,14 @@ void SfxManager::Cleanup()
}
}
void SfxManager::RenderAll(Renderer *renderer, Frame *f, const Frame *camFrame)
void SfxManager::RenderAll(Renderer *renderer, FrameId fId, FrameId camFrameId)
{
Frame *f = Frame::GetFrame(fId);
PROFILE_SCOPED()
if (f->m_sfx) {
matrix4x4d ftran;
Frame::GetFrameTransform(f, camFrame, ftran);
Frame::GetFrameTransform(fId, camFrameId, ftran);
for (size_t t = TYPE_EXPLOSION; t < TYPE_NONE; t++) {
const size_t numInstances = f->m_sfx->GetNumberInstances(SFX_TYPE(t));
@ -292,8 +302,8 @@ void SfxManager::RenderAll(Renderer *renderer, Frame *f, const Frame *camFrame)
}
}
for (Frame *kid : f->GetChildren()) {
RenderAll(renderer, kid, camFrame);
for (FrameId kid : f->GetChildren()) {
RenderAll(renderer, kid, camFrameId);
}
}

View File

@ -4,6 +4,7 @@
#ifndef _SFX_H
#define _SFX_H
#include "FrameId.h"
#include "graphics/Material.h"
#include "JsonFwd.h"
@ -54,10 +55,10 @@ public:
static void Add(const Body *, SFX_TYPE);
static void AddExplosion(Body *);
static void AddThrustSmoke(const Body *b, float speed, const vector3d &adjustpos);
static void TimeStepAll(const float timeStep, Frame *f);
static void RenderAll(Graphics::Renderer *r, Frame *f, const Frame *camFrame);
static void ToJson(Json &jsonObj, const Frame *f);
static void FromJson(const Json &jsonObj, Frame *f);
static void TimeStepAll(const float timeStep, FrameId f);
static void RenderAll(Graphics::Renderer *r, FrameId f, const FrameId camFrame);
static void ToJson(Json &jsonObj, const FrameId f);
static void FromJson(const Json &jsonObj, FrameId f);
//create shared models
static void Init(Graphics::Renderer *r);
@ -92,7 +93,7 @@ private:
};
// methods
static SfxManager *AllocSfxInFrame(Frame *f);
static SfxManager *AllocSfxInFrame(FrameId f);
static vector2f CalculateOffset(const enum SFX_TYPE, const Sfx &);
static bool SplitMaterialData(const std::string &spec, MaterialData &output);

View File

@ -889,8 +889,12 @@ void Ship::Blastoff()
if (m_flightState != LANDED) return;
vector3d up = GetPosition().Normalized();
assert(GetFrame()->GetBody()->IsType(Object::PLANET));
const double planetRadius = 2.0 + static_cast<Planet *>(GetFrame()->GetBody())->GetTerrainHeight(up);
Frame *f = Frame::GetFrame(GetFrame());
assert(f->GetBody()->IsType(Object::PLANET));
const double planetRadius = 2.0 + static_cast<Planet *>(f->GetBody())->GetTerrainHeight(up);
SetVelocity(vector3d(0, 0, 0));
SetAngVelocity(vector3d(0, 0, 0));
SetFlightState(FLYING);
@ -898,7 +902,7 @@ void Ship::Blastoff()
SetPosition(up * planetRadius - GetAabb().min.y * up);
SetThrusterState(1, 1.0); // thrust upwards
LuaEvent::Queue("onShipTakeOff", this, GetFrame()->GetBody());
LuaEvent::Queue("onShipTakeOff", this, f->GetBody());
}
void Ship::TestLanded()
@ -906,10 +910,13 @@ void Ship::TestLanded()
m_testLanded = false;
if (m_launchLockTimeout > 0.0f) return;
if (m_wheelState < 1.0f) return;
if (GetFrame()->GetBody()->IsType(Object::PLANET)) {
Frame *f = Frame::GetFrame(GetFrame());
if (f->GetBody()->IsType(Object::PLANET)) {
double speed = GetVelocity().Length();
vector3d up = GetPosition().Normalized();
const double planetRadius = static_cast<Planet *>(GetFrame()->GetBody())->GetTerrainHeight(up);
const double planetRadius = static_cast<Planet *>(f->GetBody())->GetTerrainHeight(up);
if (speed < MAX_LANDING_SPEED) {
// check player is sortof sensibly oriented for landing
@ -926,7 +933,7 @@ void Ship::TestLanded()
ClearThrusterState();
SetFlightState(LANDED);
Sound::BodyMakeNoise(this, "Rough_Landing", 1.0f);
LuaEvent::Queue("onShipLanded", this, GetFrame()->GetBody());
LuaEvent::Queue("onShipLanded", this, f->GetBody());
onLanded.emit();
}
}
@ -937,8 +944,10 @@ void Ship::SetLandedOn(Planet *p, float latitude, float longitude)
{
m_wheelTransition = 0;
m_wheelState = 1.0f;
Frame *f = p->GetFrame()->GetRotFrame();
SetFrame(f);
Frame *f_non_rot = Frame::GetFrame(p->GetFrame());
Frame *f = Frame::GetFrame(f_non_rot->GetRotFrame());
SetFrame(f_non_rot->GetRotFrame());
vector3d up = vector3d(cos(latitude) * sin(longitude), sin(latitude), cos(latitude) * cos(longitude));
const double planetRadius = p->GetTerrainHeight(up);
SetPosition(up * (planetRadius - GetAabb().min.y));
@ -952,9 +961,9 @@ void Ship::SetLandedOn(Planet *p, float latitude, float longitude)
onLanded.emit();
}
void Ship::SetFrame(Frame *f)
void Ship::SetFrame(FrameId fId)
{
DynamicBody::SetFrame(f);
DynamicBody::SetFrame(fId);
m_sensors->ResetTrails();
}
@ -1181,7 +1190,8 @@ void Ship::StaticUpdate(const float timeStep)
}
if (m_flightState == FLYING) {
Body *astro = GetFrame()->GetBody();
Frame *frame = Frame::GetFrame(GetFrame());
Body *astro = frame->GetBody();
if (astro && astro->IsType(Object::PLANET)) {
Planet *p = static_cast<Planet *>(astro);
double dist = GetPosition().Length();
@ -1204,7 +1214,8 @@ void Ship::StaticUpdate(const float timeStep)
int capacity = 0;
Properties().Get("fuel_scoop_cap", capacity);
if (m_flightState == FLYING && capacity > 0) {
Body *astro = GetFrame()->GetBody();
Frame *frame = Frame::GetFrame(GetFrame());
Body *astro = frame->GetBody();
if (astro && astro->IsType(Object::PLANET)) {
Planet *p = static_cast<Planet *>(astro);
if (p->GetSystemBody()->IsScoopable()) {

View File

@ -65,7 +65,7 @@ public:
Ship(const ShipType::Id &shipId);
virtual ~Ship();
virtual void SetFrame(Frame *f) override;
virtual void SetFrame(FrameId fId) override;
void SetController(ShipController *c); //deletes existing
ShipController *GetController() const { return m_controller; }

View File

@ -665,8 +665,9 @@ static double MaxEffectRad(Body *body, Propulsion *prop)
}
// returns acceleration due to gravity at that point
static double GetGravityAtPos(Frame *targframe, const vector3d &posoff)
static double GetGravityAtPos(FrameId targframeId, const vector3d &posoff)
{
Frame *targframe = Frame::GetFrame(targframeId);
Body *body = targframe->GetBody();
if (!body || body->IsType(Object::SPACESTATION)) return 0;
double rsqr = posoff.LengthSqr();
@ -675,31 +676,33 @@ static double GetGravityAtPos(Frame *targframe, const vector3d &posoff)
}
// gets position of (target + offset in target's frame) in frame
static vector3d GetPosInFrame(Frame *frame, Frame *target, const vector3d &offset)
static vector3d GetPosInFrame(FrameId frameId, FrameId targetId, const vector3d &offset)
{
return target->GetOrientRelTo(frame) * offset + target->GetPositionRelTo(frame);
Frame *target = Frame::GetFrame(targetId);
return target->GetOrientRelTo(frameId) * offset + target->GetPositionRelTo(frameId);
}
static vector3d GetVelInFrame(Frame *frame, Frame *target, const vector3d &offset)
static vector3d GetVelInFrame(FrameId frameId, FrameId targetId, const vector3d &offset)
{
vector3d vel = vector3d(0.0);
if (target != frame && target->IsRotFrame()) {
Frame* target = Frame::GetFrame(targetId);
if (targetId != frameId && target->IsRotFrame()) {
// double ang = Pi::game->GetTimeStep() * target->GetAngSpeed();
// vector3d newpos = offset * matrix3x3d::RotateYMatrix(ang);
// vel = (newpos - offset) / Pi::game->GetTimeStep();
vel = -target->GetStasisVelocity(offset); // stasis velocity not accurate enough
}
return target->GetOrientRelTo(frame) * vel + target->GetVelocityRelTo(frame);
return target->GetOrientRelTo(frameId) * vel + target->GetVelocityRelTo(frameId);
}
// generates from (0,0,0) to spos, in plane of target
// formula uses similar triangles
// shiptarg in ship's frame
// output in targframe
static vector3d GenerateTangent(DynamicBody *dBody, Frame *targframe, const vector3d &shiptarg, double alt)
static vector3d GenerateTangent(DynamicBody *dBody, FrameId targframeId, const vector3d &shiptarg, double alt)
{
vector3d spos = dBody->GetPositionRelTo(targframe);
vector3d targ = GetPosInFrame(targframe, dBody->GetFrame(), shiptarg);
vector3d spos = dBody->GetPositionRelTo(targframeId);
vector3d targ = GetPosInFrame(targframeId, dBody->GetFrame(), shiptarg);
double a = spos.Length(), b = alt;
if (b * 1.02 > a) {
spos *= b * 1.02 / a;
@ -723,7 +726,7 @@ static int CheckCollision(DynamicBody *dBody, const vector3d &pathdir, double pa
assert(prop != nullptr);
// ship is in obstructor's frame anyway, so is tpos
if (pathdist < 100.0) return 0;
Body *body = dBody->GetFrame()->GetBody();
Body *body = Frame::GetFrame(dBody->GetFrame())->GetBody();
if (!body) return 0;
vector3d spos = dBody->GetPosition();
double tlen = tpos.Length(), slen = spos.Length();
@ -776,22 +779,26 @@ static int CheckCollision(DynamicBody *dBody, const vector3d &pathdir, double pa
// ok, need thing to step down through bodies and find closest approach
// modify targpos directly to aim short of dangerous bodies
static bool ParentSafetyAdjust(DynamicBody *dBody, Frame *targframe, vector3d &targpos, vector3d &targvel)
static bool ParentSafetyAdjust(DynamicBody *dBody, FrameId targframeId, vector3d &targpos, vector3d &targvel)
{
Body *body = 0;
Frame *frame = targframe->GetNonRotFrame();
Body *body = nullptr;
FrameId frameId = Frame::GetFrame(targframeId)->GetNonRotFrame();
Frame *frame = Frame::GetFrame(frameId);
while (frame) {
if (dBody->GetFrame()->GetNonRotFrame() == frame) break; // ship in frame, stop
Frame *bFrame = Frame::GetFrame(dBody->GetFrame());
if (bFrame->GetNonRotFrame() == frameId) break; // ship in frame, stop
if (frame->GetBody()) body = frame->GetBody(); // ignore grav points?
double sdist = dBody->GetPositionRelTo(frame).Length();
double sdist = dBody->GetPositionRelTo(frameId).Length();
if (sdist < frame->GetRadius()) break; // ship inside frame, stop
// we should always be inside the root frame, so if we're not inside 'frame'
// then it must not be the root frame (ie, it must have a parent)
assert(frame->GetParent());
Frame *parent = Frame::GetFrame(frame->GetParent());
assert(parent);
frame = frame->GetParent()->GetNonRotFrame(); // check next frame down
frameId = parent->GetNonRotFrame();
frame = Frame::GetFrame(frameId); // check next frame down
}
if (!body) return false;
@ -812,7 +819,7 @@ static bool ParentSafetyAdjust(DynamicBody *dBody, Frame *targframe, vector3d &t
// tandir is normal vector from planet to target pos or dir
static bool CheckSuicide(DynamicBody *dBody, const vector3d &tandir)
{
Body *body = dBody->GetFrame()->GetBody();
Body *body = Frame::GetFrame(dBody->GetFrame())->GetBody();
if (dBody->Have(DynamicBody::PROPULSION)) return false;
Propulsion *prop = dBody->GetPropulsion();
assert(prop != nullptr);
@ -842,15 +849,15 @@ void AICmdFlyTo::GetStatusText(char *str)
m_target->GetLabel().c_str(), m_dist, m_state);
else
snprintf(str, 255, "FlyTo: %s, dist %.1fkm, endvel %.1fkm/s, state %i",
m_targframe->GetLabel().c_str(), m_posoff.Length() / 1000.0, m_endvel / 1000.0, m_state);
Frame::GetFrame(m_targframeId)->GetLabel().c_str(), m_posoff.Length() / 1000.0, m_endvel / 1000.0, m_state);
}
void AICmdFlyTo::PostLoadFixup(Space *space)
{
AICommand::PostLoadFixup(space);
m_target = space->GetBodyByIndex(m_targetIndex);
m_targframe = Frame::FindFrame(m_targframeIndex);
m_lockhead = true;
m_frameId = m_target ? m_target->GetFrame() : noFrameId;
// Ensure needed sub-system:
m_prop.Reset(m_dBody->GetPropulsion());
assert(m_prop != nullptr);
@ -862,7 +869,7 @@ AICmdFlyTo::AICmdFlyTo(DynamicBody *dBody, Body *target) :
{
m_prop.Reset(dBody->GetPropulsion());
assert(m_prop != nullptr);
m_frame = 0;
m_frameId = noFrameId;
m_state = -6;
m_lockhead = true;
m_endvel = 0;
@ -876,27 +883,27 @@ AICmdFlyTo::AICmdFlyTo(DynamicBody *dBody, Body *target) :
if (target->IsType(Object::SPACESTATION) && static_cast<SpaceStation *>(target)->IsGroundStation()) {
m_posoff = target->GetPosition() + VICINITY_MIN * target->GetOrient().VectorY();
// m_posoff += 500.0 * target->GetOrient().VectorX();
m_targframe = target->GetFrame();
m_target = 0;
m_targframeId = target->GetFrame();
m_target = nullptr;
} else {
m_target = target;
m_targframe = 0;
m_targframeId = noFrameId;
}
if (dBody->GetPositionRelTo(target).Length() <= VICINITY_MIN) m_targframe = 0;
if (dBody->GetPositionRelTo(target).Length() <= VICINITY_MIN) m_targframeId = noFrameId;
}
// Specified pos, endvel should be > 0
AICmdFlyTo::AICmdFlyTo(DynamicBody *dBody, Frame *targframe, const vector3d &posoff, double endvel, bool tangent) :
AICmdFlyTo::AICmdFlyTo(DynamicBody *dBody, FrameId targframe, const vector3d &posoff, double endvel, bool tangent) :
AICommand(dBody, CMD_FLYTO),
m_target(nullptr),
m_targframe(targframe),
m_targframeId(targframe),
m_posoff(posoff),
m_endvel(endvel),
m_tangent(tangent),
m_state(-6),
m_lockhead(true),
m_frame(nullptr)
m_frameId(noFrameId)
{
m_prop.Reset(dBody->GetPropulsion());
assert(m_prop != nullptr);
@ -908,7 +915,7 @@ AICmdFlyTo::AICmdFlyTo(const Json &jsonObj) :
try {
m_targetIndex = jsonObj["index_for_target"];
m_dist = jsonObj["dist"];
m_targframeIndex = jsonObj["index_for_target_frame"];
m_targframeId = jsonObj["target_frame"];
m_posoff = jsonObj["pos_off"];
m_endvel = jsonObj["end_vel"];
m_tangent = jsonObj["tangent"];
@ -927,7 +934,7 @@ void AICmdFlyTo::SaveToJson(Json &jsonObj)
AICommand::SaveToJson(aiCommandObj);
aiCommandObj["index_for_target"] = Pi::game->GetSpace()->GetIndexForBody(m_target);
aiCommandObj["dist"] = m_dist;
aiCommandObj["index_for_target_frame"] = (m_targframe != nullptr ? m_targframe->GetId() : noFrameId);
aiCommandObj["target_frame"] = m_targframeId;
aiCommandObj["pos_off"] = m_posoff;
aiCommandObj["end_vel"] = m_endvel;
aiCommandObj["tangent"] = m_tangent;
@ -956,7 +963,7 @@ bool AICmdFlyTo::TimeStepUpdate()
// may be an exploration probe ;-)
return false;
}
if (!m_target && !m_targframe) return true; // deleted object
if (!m_target && !IsIdValid(m_targframeId)) return true; // deleted object
// generate base target pos (with vicinity adjustment) & vel
double timestep = Pi::game->GetTimeStep();
@ -966,11 +973,11 @@ bool AICmdFlyTo::TimeStepUpdate()
targpos -= (targpos - m_dBody->GetPosition()).NormalizedSafe() * m_dist;
targvel = m_target->GetVelocityRelTo(m_dBody->GetFrame());
} else {
targpos = GetPosInFrame(m_dBody->GetFrame(), m_targframe, m_posoff);
targvel = GetVelInFrame(m_dBody->GetFrame(), m_targframe, m_posoff);
targpos = GetPosInFrame(m_dBody->GetFrame(), m_targframeId, m_posoff);
targvel = GetVelInFrame(m_dBody->GetFrame(), m_targframeId, m_posoff);
}
Frame *targframe = m_target ? m_target->GetFrame() : m_targframe;
ParentSafetyAdjust(m_dBody, targframe, targpos, targvel);
FrameId targframeId = m_target ? m_target->GetFrame() : m_targframeId;
ParentSafetyAdjust(m_dBody, targframeId, targpos, targvel);
vector3d relpos = targpos - m_dBody->GetPosition();
vector3d reldir = relpos.NormalizedSafe();
vector3d relvel = targvel - m_dBody->GetVelocity();
@ -983,20 +990,21 @@ bool AICmdFlyTo::TimeStepUpdate()
#endif
// frame switch stuff - clear children/collision state
if (m_frame != m_dBody->GetFrame()) {
if (m_frameId != m_dBody->GetFrame()) {
if (m_child) {
m_child.reset();
}
if (m_tangent && m_frame) return true; // regen tangent on frame switch
if (m_tangent && IsIdValid(m_frameId)) return true; // regen tangent on frame switch
m_reldir = reldir; // for +vel termination condition
m_frame = m_dBody->GetFrame();
m_frameId = m_dBody->GetFrame();
}
// TODO: collision needs to be processed according to vdiff, not reldir?
Body *body = m_frame->GetBody();
Body *body = Frame::GetFrame(m_frameId)->GetBody();
double erad = MaxEffectRad(body, m_prop.Get());
if ((m_target && body != m_target) || (m_targframe && (!m_tangent || body != m_targframe->GetBody()))) {
Frame *targframe = Frame::GetFrame(targframeId);
if ((m_target && body != m_target) || (targframe && (!m_tangent || body != targframe->GetBody()))) {
int coll = CheckCollision(m_dBody, reldir, targdist, targpos, m_endvel, erad);
if (coll == 0) { // no collision
if (m_child) {
@ -1006,7 +1014,7 @@ bool AICmdFlyTo::TimeStepUpdate()
double ang = m_prop->AIFaceDirection(m_dBody->GetPosition());
m_prop->AIMatchVel(ang < 0.05 ? 1000.0 * m_dBody->GetPosition().Normalized() : vector3d(0.0));
} else { // same thing for 2/3/4
if (!m_child) m_child.reset(new AICmdFlyAround(m_dBody, m_frame->GetBody(), erad * 1.05, 0.0));
if (!m_child) m_child.reset(new AICmdFlyAround(m_dBody, Frame::GetFrame(m_frameId)->GetBody(), erad * 1.05, 0.0));
static_cast<AICmdFlyAround *>(m_child.get())->SetTargPos(targpos);
ProcessChild();
}
@ -1030,7 +1038,7 @@ bool AICmdFlyTo::TimeStepUpdate()
// target ship acceleration adjustment
if (m_target && m_target->IsType(Object::SHIP)) {
Ship *targship = static_cast<Ship *>(m_target);
matrix3x3d orient = m_target->GetFrame()->GetOrientRelTo(m_frame);
matrix3x3d orient = Frame::GetFrame(m_target->GetFrame())->GetOrientRelTo(m_frameId);
vector3d targaccel = orient * targship->GetLastForce() / m_target->GetMass();
// fudge: targets accelerating towards you are usually going to flip
if (targaccel.Dot(reldir) < 0.0 && !targship->IsDecelerating()) targaccel *= 0.5;
@ -1068,8 +1076,8 @@ bool AICmdFlyTo::TimeStepUpdate()
if (ispeed > curspeed && curspeed > 0.9 * fuelspeed) ispeed = curspeed;
// Don't exit a frame faster than some fraction of radius
// double maxframespeed = 0.2 * m_frame->GetRadius() / timestep;
// if (m_frame->GetParent() && ispeed > maxframespeed) ispeed = maxframespeed;
// double maxframespeed = 0.2 * m_frameId->GetRadius() / timestep;
// if (m_frameId->GetParent() && ispeed > maxframespeed) ispeed = maxframespeed;
// cap perpspeed according to what's needed now
perpspeed = std::min(perpspeed, 2.0 * sidefactor * timestep);
@ -1167,7 +1175,7 @@ AICmdDock::AICmdDock(DynamicBody *dBody, SpaceStation *target) :
double grav = GetGravityAtPos(m_target->GetFrame(), m_target->GetPosition());
if (m_prop->GetAccelUp() < grav) {
m_dBody->AIMessage(Ship::AIERROR_GRAV_TOO_HIGH);
m_target = 0; // bail out on next timestep call
m_target = nullptr; // bail out on next timestep call
}
}
@ -1238,8 +1246,8 @@ bool AICmdDock::TimeStepUpdate()
}
// if we're not close to target, do a flyto first
double targdist = m_target->GetPositionRelTo(ship).Length();
if (targdist > 16000.0) {
double targdist = m_target->GetPositionRelTo(ship).LengthSqr();
if (targdist > 16000.0 * 16000.0) {
m_child.reset(new AICmdFlyTo(m_dBody, m_target));
ProcessChild();
return false;
@ -1324,7 +1332,7 @@ bool AICmdDock::TimeStepUpdate()
#ifdef DEBUG_AUTOPILOT
Output("AICmdDock dist = %.1f, speed = %.1f, ythrust = %.2f, state = %i\n",
targdist, relvel.Length(), m_ship->GetLinThrusterState().y, m_state);
sqrt(targdist), relvel.Length(), m_ship->GetLinThrusterState().y, m_state);
#endif
return false;
@ -1384,7 +1392,9 @@ void AICmdFlyAround::Setup(Body *obstructor, double alt, double vel, int mode)
// drag within frame because orbits are impossible otherwise
// timestep code also doesn't work correctly for ex-frame cases, should probably be fixed
alt = std::min(alt, 0.95 * obstructor->GetFrame()->GetNonRotFrame()->GetRadius());
Frame *obsFrame = Frame::GetFrame(obstructor->GetFrame());
Frame *nonRot = Frame::GetFrame(obsFrame->GetNonRotFrame());
alt = std::min(alt, 0.95 * nonRot->GetRadius());
// generate suitable velocity if none provided
double minacc = (mode == 2) ? 0 : m_prop->GetAccelMin();
@ -1493,16 +1503,16 @@ bool AICmdFlyAround::TimeStepUpdate()
// if too far away, fly to tangent
if (obsdist > 1.1 * m_alt) {
double v;
Frame *obsframe = m_obstructor->GetFrame()->GetNonRotFrame();
vector3d tangent = GenerateTangent(m_dBody, obsframe, targpos, m_alt);
vector3d tpos_obs = GetPosInFrame(obsframe, m_dBody->GetFrame(), targpos);
FrameId obsframeId = Frame::GetFrame(m_obstructor->GetFrame())->GetNonRotFrame();
vector3d tangent = GenerateTangent(m_dBody, obsframeId, targpos, m_alt);
vector3d tpos_obs = GetPosInFrame(obsframeId, m_dBody->GetFrame(), targpos);
if (m_targmode)
v = m_vel;
else if (relpos.LengthSqr() < obsdist + tpos_obs.LengthSqr())
v = 0.0;
else
v = MaxVel((tpos_obs - tangent).Length(), tpos_obs.Length());
m_child.reset(new AICmdFlyTo(m_dBody, obsframe, tangent, v, true));
m_child.reset(new AICmdFlyTo(m_dBody, obsframeId, tangent, v, true));
ProcessChild();
return false;
}
@ -1632,7 +1642,7 @@ bool AICmdFormation::TimeStepUpdate()
vector3d reldir = (targdist < 1e-16) ? vector3d(1, 0, 0) : relpos / targdist;
// adjust for target acceleration
matrix3x3d forient = m_target->GetFrame()->GetOrientRelTo(m_dBody->GetFrame());
matrix3x3d forient = Frame::GetFrame(m_target->GetFrame())->GetOrientRelTo(m_dBody->GetFrame());
vector3d targaccel = forient * m_target->GetLastForce() / m_target->GetMass();
relvel -= targaccel * Pi::game->GetTimeStep();
double maxdecel = m_prop->GetAccelFwd() + targaccel.Dot(reldir);

View File

@ -8,10 +8,10 @@
#include "JsonFwd.h"
#include "DynamicBody.h"
#include "FrameId.h"
#include "FixedGuns.h"
#include "ship/Propulsion.h"
class Frame;
class Ship;
class Space;
class SpaceStation;
@ -119,7 +119,7 @@ private:
class AICmdFlyTo : public AICommand {
public:
virtual bool TimeStepUpdate();
AICmdFlyTo(DynamicBody *dBody, Frame *targframe, const vector3d &posoff, double endvel, bool tangent);
AICmdFlyTo(DynamicBody *dBody, FrameId targframeId, const vector3d &posoff, double endvel, bool tangent);
AICmdFlyTo(DynamicBody *dBody, Body *target);
virtual void GetStatusText(char *str);
@ -132,16 +132,16 @@ public:
private:
Body *m_target; // target for vicinity. Either this or targframe is 0
double m_dist; // vicinity distance
Frame *m_targframe; // target frame for waypoint
FrameId m_targframeId; // target frame for waypoint
vector3d m_posoff; // offset in target frame
double m_endvel; // target speed in direction of motion at end of path, positive only
bool m_tangent; // true if path is to a tangent of the target frame's body
int m_state;
bool m_lockhead;
int m_targetIndex, m_targframeIndex; // used during deserialisation
int m_targetIndex; // used during deserialisation
vector3d m_reldir; // target direction relative to ship at last frame change
Frame *m_frame; // last frame of ship
FrameId m_frameId; // last frame of ship
};
class AICmdFlyAround : public AICommand {

View File

@ -181,13 +181,13 @@ void ShipCockpit::Update(const Player *player, float timeStep)
}
}
void ShipCockpit::RenderCockpit(Graphics::Renderer *renderer, const Camera *camera, Frame *frame)
void ShipCockpit::RenderCockpit(Graphics::Renderer *renderer, const Camera *camera, FrameId frameId)
{
PROFILE_SCOPED()
renderer->ClearDepthBuffer();
SetFrame(frame);
SetFrame(frameId);
Render(renderer, camera, m_translate, m_transform);
SetFrame(nullptr);
SetFrame(noFrameId);
}
void ShipCockpit::OnActivated(const Player *player)

View File

@ -24,7 +24,7 @@ public:
virtual void Render(Graphics::Renderer *r, const Camera *camera, const vector3d &viewCoords, const matrix4x4d &viewTransform) override;
void Update(const Player *player, float timeStep);
void RenderCockpit(Graphics::Renderer *renderer, const Camera *camera, Frame *frame);
void RenderCockpit(Graphics::Renderer *renderer, const Camera *camera, FrameId frameId);
void OnActivated(const Player *player);
void resetInternalCameraController(void);

View File

@ -75,7 +75,7 @@ Space::Space(Game *game, RefCountedPtr<Galaxy> galaxy, Space *oldSpace) :
{
m_background.reset(new Background::Container(Pi::renderer, Pi::rng));
m_rootFrame.reset(Frame::CreateFrame(nullptr, Lang::SYSTEM, Frame::FLAG_DEFAULT, FLT_MAX));
m_rootFrameId = Frame::CreateFrame(noFrameId, Lang::SYSTEM, Frame::FLAG_DEFAULT, FLT_MAX);
GenSectorCache(galaxy, &game->GetHyperspaceDest());
}
@ -98,15 +98,16 @@ Space::Space(Game *game, RefCountedPtr<Galaxy> galaxy, const SystemPath &path, S
CityOnPlanet::SetCityModelPatterns(m_starSystem->GetPath());
m_rootFrame.reset(Frame::CreateFrame(nullptr, Lang::SYSTEM, Frame::FLAG_DEFAULT, FLT_MAX));
m_rootFrameId = Frame::CreateFrame(noFrameId, Lang::SYSTEM, Frame::FLAG_DEFAULT, FLT_MAX);
std::vector<vector3d> positionAccumulator;
GenBody(m_game->GetTime(), m_starSystem->GetRootBody().Get(), m_rootFrame.get(), positionAccumulator);
m_rootFrame->UpdateOrbitRails(m_game->GetTime(), m_game->GetTimeStep());
GenBody(m_game->GetTime(), m_starSystem->GetRootBody().Get(), m_rootFrameId, positionAccumulator);
Frame::GetFrame(m_rootFrameId)->UpdateOrbitRails(m_game->GetTime(), m_game->GetTimeStep());
//DebugDumpFrames(false);
GenSectorCache(galaxy, &path);
//DebugDumpFrames();
}
Space::Space(Game *game, RefCountedPtr<Galaxy> galaxy, const Json &jsonObj, double at_time) :
@ -134,7 +135,7 @@ Space::Space(Game *game, RefCountedPtr<Galaxy> galaxy, const Json &jsonObj, doub
CityOnPlanet::SetCityModelPatterns(m_starSystem->GetPath());
if (!spaceObj.count("frame")) throw SavedGameCorruptException();
m_rootFrame.reset(Frame::FromJson(spaceObj["frame"], this, nullptr, at_time));
m_rootFrameId = Frame::FromJson(spaceObj["frame"], this, noFrameId, at_time);
try {
Json bodyArray = spaceObj["bodies"].get<Json::array_t>();
@ -146,7 +147,7 @@ Space::Space(Game *game, RefCountedPtr<Galaxy> galaxy, const Json &jsonObj, doub
RebuildBodyIndex();
Frame::PostUnserializeFixup(m_rootFrame.get(), this);
Frame::PostUnserializeFixup(m_rootFrameId, this);
for (Body *b : m_bodies)
b->PostLoadFixup(this);
@ -161,7 +162,7 @@ Space::~Space()
for (std::list<Body *>::iterator i = m_bodies.begin(); i != m_bodies.end(); ++i)
KillBody(*i);
UpdateBodies();
Frame::DeleteFrame(m_rootFrame.get());
Frame::DeleteFrame(m_rootFrameId);
}
void Space::RefreshBackground()
@ -183,7 +184,7 @@ void Space::ToJson(Json &jsonObj)
StarSystem::ToJson(spaceObj, m_starSystem.Get());
Json frameObj({});
Frame::ToJson(frameObj, m_rootFrame.get(), this);
Frame::ToJson(frameObj, m_rootFrameId, this);
spaceObj["frame"] = frameObj;
Json bodyArray = Json::array(); // Create JSON array to contain body data.
@ -394,25 +395,26 @@ Body *Space::FindBodyForPath(const SystemPath *path) const
return 0;
}
static Frame *find_frame_with_sbody(Frame *f, const SystemBody *b)
static FrameId find_frame_with_sbody(FrameId fId, const SystemBody *b)
{
Frame *f = Frame::GetFrame(fId);
if (f->GetSystemBody() == b)
return f;
return fId;
else {
for (Frame *kid : f->GetChildren()) {
Frame *found = find_frame_with_sbody(kid, b);
if (found) return found;
for (FrameId kid : f->GetChildren()) {
FrameId found = find_frame_with_sbody(kid, b);
if (IsIdValid(found)) return found;
}
}
return 0;
return noFrameId;
}
Frame *Space::GetFrameWithSystemBody(const SystemBody *b) const
FrameId Space::GetFrameWithSystemBody(const SystemBody *b) const
{
return find_frame_with_sbody(m_rootFrame.get(), b);
return find_frame_with_sbody(m_rootFrameId, b);
}
static void RelocateStarportIfNecessary(SystemBody *sbody, Frame *frame, Planet *planet, vector3d &pos, matrix3x3d &rot, const std::vector<vector3d> &prevPositions)
static void RelocateStarportIfNecessary(SystemBody *sbody, Planet *planet, vector3d &pos, matrix3x3d &rot, const std::vector<vector3d> &prevPositions)
{
const double radius = planet->GetSystemBody()->GetRadius();
@ -537,110 +539,6 @@ static void RelocateStarportIfNecessary(SystemBody *sbody, Frame *frame, Planet
}
}
static Frame *MakeFrameFor(const double at_time, SystemBody *sbody, Body *b, Frame *f, std::vector<vector3d> &prevPositions)
{
if (!sbody->GetParent()) {
if (b) b->SetFrame(f);
f->SetBodies(sbody, b);
return f;
}
if (sbody->GetType() == SystemBody::TYPE_GRAVPOINT) {
Frame *orbFrame = Frame::CreateFrame(f,
sbody->GetName().c_str(),
Frame::FLAG_DEFAULT,
sbody->GetMaxChildOrbitalDistance() * 1.1
);
orbFrame->SetBodies(sbody, b);
return orbFrame;
}
SystemBody::BodySuperType supertype = sbody->GetSuperType();
if ((supertype == SystemBody::SUPERTYPE_GAS_GIANT) ||
(supertype == SystemBody::SUPERTYPE_ROCKY_PLANET)) {
// for planets we want an non-rotating frame for a few radii
// and a rotating frame with no radius to contain attached objects
double frameRadius = std::max(4.0 * sbody->GetRadius(), sbody->GetMaxChildOrbitalDistance() * 1.05);
Frame *orbFrame = Frame::CreateFrame(f,
sbody->GetName().c_str(),
Frame::FLAG_HAS_ROT,
frameRadius
);
orbFrame->SetBodies(sbody, b);
//Output("\t\t\t%s has frame size %.0fkm, body radius %.0fkm\n", sbody->name.c_str(),
// (frameRadius ? frameRadius : 10*sbody->GetRadius())*0.001f,
// sbody->GetRadius()*0.001f);
assert(sbody->IsRotating() != 0);
// rotating frame has atmosphere radius or feature height, whichever is larger
Frame *rotFrame = Frame::CreateFrame(orbFrame,
sbody->GetName().c_str(),
Frame::FLAG_ROTATING,
b->GetPhysRadius()
);
rotFrame->SetBodies(sbody, b);
matrix3x3d rotMatrix = matrix3x3d::RotateX(sbody->GetAxialTilt());
double angSpeed = 2.0 * M_PI / sbody->GetRotationPeriod();
rotFrame->SetAngSpeed(angSpeed);
if (sbody->HasRotationPhase())
rotMatrix = rotMatrix * matrix3x3d::RotateY(sbody->GetRotationPhaseAtStart());
rotFrame->SetInitialOrient(rotMatrix, at_time);
b->SetFrame(rotFrame);
return orbFrame;
} else if (supertype == SystemBody::SUPERTYPE_STAR) {
// stars want a single small non-rotating frame
// bigger than it's furtherest orbiting body.
// if there are no orbiting bodies use a frame of several radii.
Frame *orbFrame = Frame::CreateFrame(f, sbody->GetName().c_str());
orbFrame->SetBodies(sbody, b);
const double bodyRadius = sbody->GetEquatorialRadius();
double frameRadius = std::max(10.0 * bodyRadius, sbody->GetMaxChildOrbitalDistance() * 1.1);
// Respect the frame of other stars in the multi-star system. We still make sure that the frame ends outside
// the body. For a minimum separation of 1.236 radii, nothing will overlap (see StarSystem::StarSystem()).
if (sbody->GetParent() && frameRadius > AU * 0.11 * sbody->GetOrbMin())
frameRadius = std::max(1.1 * bodyRadius, AU * 0.11 * sbody->GetOrbMin());
orbFrame->SetRadius(frameRadius);
b->SetFrame(orbFrame);
return orbFrame;
} else if (sbody->GetType() == SystemBody::TYPE_STARPORT_ORBITAL) {
// space stations want non-rotating frame to some distance
Frame *orbFrame = Frame::CreateFrame(f,
sbody->GetName().c_str(),
Frame::FLAG_DEFAULT,
20000.0
);
orbFrame->SetBodies(sbody, b);
b->SetFrame(orbFrame);
return orbFrame;
} else if (sbody->GetType() == SystemBody::TYPE_STARPORT_SURFACE) {
// just put body into rotating frame of planet, not in its own frame
// (because collisions only happen between objects in same frame,
// and we want collisions on starport and on planet itself)
Frame *rotFrame = f->GetRotFrame();
b->SetFrame(rotFrame);
assert(rotFrame->IsRotFrame());
assert(rotFrame->GetBody()->IsType(Object::PLANET));
matrix3x3d rot;
vector3d pos;
Planet *planet = static_cast<Planet *>(rotFrame->GetBody());
RelocateStarportIfNecessary(sbody, rotFrame, planet, pos, rot, prevPositions);
sbody->SetOrbitPlane(rot);
b->SetPosition(pos * planet->GetTerrainHeight(pos));
b->SetOrient(rot);
// accumulate for testing against
prevPositions.push_back(pos);
return rotFrame;
} else {
assert(0);
}
return 0;
}
// used to define a cube centred on your current location
static const int sectorRadius = 5;
@ -765,7 +663,120 @@ void Space::UpdateStarSystemCache(const SystemPath *here)
m_starSystemCache->FillCache(paths);
}
void Space::GenBody(const double at_time, SystemBody *sbody, Frame *f, std::vector<vector3d> &posAccum)
static FrameId MakeFramesFor(const double at_time, SystemBody *sbody, Body *b, FrameId fId, std::vector<vector3d> &prevPositions)
{
Frame *f = Frame::GetFrame(fId);
if (!sbody->GetParent()) {
if (b) b->SetFrame(fId);
Frame *f = Frame::GetFrame(fId);
f->SetBodies(sbody, b);
return fId;
}
if (sbody->GetType() == SystemBody::TYPE_GRAVPOINT) {
FrameId orbFrameId = Frame::CreateFrame(fId,
sbody->GetName().c_str(),
Frame::FLAG_DEFAULT,
sbody->GetMaxChildOrbitalDistance() * 1.1
);
Frame *orbFrame = Frame::GetFrame(orbFrameId);
orbFrame->SetBodies(sbody, b);
return orbFrameId;
}
SystemBody::BodySuperType supertype = sbody->GetSuperType();
if ((supertype == SystemBody::SUPERTYPE_GAS_GIANT) ||
(supertype == SystemBody::SUPERTYPE_ROCKY_PLANET)) {
// for planets we want an non-rotating frame for a few radii
// and a rotating frame with no radius to contain attached objects
double frameRadius = std::max(4.0 * sbody->GetRadius(), sbody->GetMaxChildOrbitalDistance() * 1.05);
FrameId orbFrameId = Frame::CreateFrame(fId,
sbody->GetName().c_str(),
Frame::FLAG_HAS_ROT,
frameRadius
);
Frame *orbFrame = Frame::GetFrame(orbFrameId);
orbFrame->SetBodies(sbody, b);
//Output("\t\t\t%s has frame size %.0fkm, body radius %.0fkm\n", sbody->name.c_str(),
// (frameRadius ? frameRadius : 10*sbody->GetRadius())*0.001f,
// sbody->GetRadius()*0.001f);
assert(sbody->IsRotating() != 0);
// rotating frame has atmosphere radius or feature height, whichever is larger
FrameId rotFrameId = Frame::CreateFrame(orbFrameId,
sbody->GetName().c_str(),
Frame::FLAG_ROTATING,
b->GetPhysRadius()
);
Frame *rotFrame = Frame::GetFrame(rotFrameId);
rotFrame->SetBodies(sbody, b);
matrix3x3d rotMatrix = matrix3x3d::RotateX(sbody->GetAxialTilt());
double angSpeed = 2.0 * M_PI / sbody->GetRotationPeriod();
rotFrame->SetAngSpeed(angSpeed);
if (sbody->HasRotationPhase())
rotMatrix = rotMatrix * matrix3x3d::RotateY(sbody->GetRotationPhaseAtStart());
rotFrame->SetInitialOrient(rotMatrix, at_time);
b->SetFrame(rotFrameId);
return orbFrameId;
} else if (supertype == SystemBody::SUPERTYPE_STAR) {
// stars want a single small non-rotating frame
// bigger than it's furtherest orbiting body.
// if there are no orbiting bodies use a frame of several radii.
FrameId orbFrameId = Frame::CreateFrame(fId, sbody->GetName().c_str());
Frame *orbFrame = Frame::GetFrame(orbFrameId);
orbFrame->SetBodies(sbody, b);
const double bodyRadius = sbody->GetEquatorialRadius();
double frameRadius = std::max(10.0 * bodyRadius, sbody->GetMaxChildOrbitalDistance() * 1.1);
// Respect the frame of other stars in the multi-star system. We still make sure that the frame ends outside
// the body. For a minimum separation of 1.236 radii, nothing will overlap (see StarSystem::StarSystem()).
if (sbody->GetParent() && frameRadius > AU * 0.11 * sbody->GetOrbMin())
frameRadius = std::max(1.1 * bodyRadius, AU * 0.11 * sbody->GetOrbMin());
orbFrame->SetRadius(frameRadius);
b->SetFrame(orbFrameId);
return orbFrameId;
} else if (sbody->GetType() == SystemBody::TYPE_STARPORT_ORBITAL) {
// space stations want non-rotating frame to some distance
FrameId orbFrameId = Frame::CreateFrame(fId,
sbody->GetName().c_str(),
Frame::FLAG_DEFAULT,
20000.0
);
Frame *orbFrame = Frame::GetFrame(orbFrameId);
orbFrame->SetBodies(sbody, b);
b->SetFrame(orbFrameId);
return orbFrameId;
} else if (sbody->GetType() == SystemBody::TYPE_STARPORT_SURFACE) {
// just put body into rotating frame of planet, not in its own frame
// (because collisions only happen between objects in same frame,
// and we want collisions on starport and on planet itself)
FrameId rotFrameId = Frame::GetFrame(fId)->GetRotFrame();
b->SetFrame(rotFrameId);
Frame *rotFrame = Frame::GetFrame(rotFrameId);
assert(rotFrame->IsRotFrame());
assert(rotFrame->GetBody()->IsType(Object::PLANET));
matrix3x3d rot;
vector3d pos;
Planet *planet = static_cast<Planet *>(rotFrame->GetBody());
RelocateStarportIfNecessary(sbody, planet, pos, rot, prevPositions);
sbody->SetOrbitPlane(rot);
b->SetPosition(pos * planet->GetTerrainHeight(pos));
b->SetOrient(rot);
// accumulate for testing against
prevPositions.push_back(pos);
return rotFrameId;
} else {
assert(0);
}
return 0;
}
void Space::GenBody(const double at_time, SystemBody *sbody, FrameId fId, std::vector<vector3d> &posAccum)
{
Body *b = nullptr;
@ -787,10 +798,10 @@ void Space::GenBody(const double at_time, SystemBody *sbody, Frame *f, std::vect
b->SetPosition(vector3d(0, 0, 0));
AddBody(b);
}
f = MakeFrameFor(at_time, sbody, b, f, posAccum);
fId = MakeFramesFor(at_time, sbody, b, fId, posAccum);
for (SystemBody *kid : sbody->GetChildren()) {
GenBody(at_time, kid, f, posAccum);
GenBody(at_time, kid, fId, posAccum);
}
}
@ -937,8 +948,8 @@ static void CollideWithTerrain(Body *body, float timeStep)
if (!dynBody->IsMoving())
return;
Frame *f = body->GetFrame();
if (!f || !f->GetBody() || f != f->GetBody()->GetFrame())
Frame *f = Frame::GetFrame(body->GetFrame());
if (!f || !f->GetBody() || f->GetId() != f->GetBody()->GetFrame())
return;
if (!f->GetBody()->IsType(Object::TERRAINBODY))
return;
@ -957,14 +968,12 @@ static void CollideWithTerrain(Body *body, float timeStep)
hitCallback(&c);
}
void Space::FrameDeleter::operator()(Frame* frame) {
Frame::DeleteFrame(frame);
};
void Space::CollideFrame(Frame *f)
void Space::CollideFrame(FrameId fId)
{
Frame *f = Frame::GetFrame(fId);
f->GetCollisionSpace()->Collide(&hitCallback);
for (Frame *kid : f->GetChildren())
for (FrameId kid : f->GetChildren())
CollideFrame(kid);
}
@ -978,7 +987,7 @@ void Space::TimeStep(float step)
m_bodyIndexValid = m_sbodyIndexValid = false;
// XXX does not need to be done this often
CollideFrame(m_rootFrame.get());
CollideFrame(m_rootFrameId);
for (Body *b : m_bodies)
CollideWithTerrain(b, step);
@ -991,7 +1000,7 @@ void Space::TimeStep(float step)
for (Body *b : m_bodies)
b->StaticUpdate(step);
m_rootFrame->UpdateOrbitRails(m_game->GetTime(), m_game->GetTimeStep());
Frame::GetFrame(m_rootFrameId)->UpdateOrbitRails(m_game->GetTime(), m_game->GetTimeStep());
for (Body *b : m_bodies)
b->TimeStepUpdate(step);
@ -1033,19 +1042,21 @@ void Space::UpdateBodies()
static char space[256];
static void DebugDumpFrame(Frame *f, bool details, unsigned int indent)
static void DebugDumpFrame(FrameId fId, bool details, unsigned int indent)
{
Output("%.*s%p (%s)\n", indent, space, static_cast<void *>(f), f->GetLabel().c_str());
if (f->GetParent())
Output("%.*s parent %p (%s)\n", indent, space, static_cast<void *>(f->GetParent()), f->GetParent()->GetLabel().c_str());
if (f->GetBody())
Output("%.*s body %p (%s)\n", indent, space, static_cast<void *>(f->GetBody()), f->GetBody()->GetLabel().c_str());
if (Body *b = f->GetBody())
Output("%.*s bodyFor %p (%s)\n", indent, space, static_cast<void *>(b), b->GetLabel().c_str());
Output("%.*s distance %f radius %f", indent, space, f->GetPosition().Length(), f->GetRadius());
Output("%s\n", f->IsRotFrame() ? " [rotating]" : "[non rotating]");
Frame *f = Frame::GetFrame(fId);
Frame *parent = Frame::GetFrame(f->GetParent());
for (Frame *kid : f->GetChildren())
Output("%.*s%2i) %p (%s)%s\n", indent, space, fId, static_cast<void *>(f), f->GetLabel().c_str(), f->IsRotFrame() ? " [rotating]" : " [non rotating]");
if (IsIdValid(f->GetParent()))
Output("%.*s parent %p (%s)\n", indent + 3, space, static_cast<void *>(parent), parent->GetLabel().c_str());
if (f->GetBody())
Output("%.*s body %p (%s)\n", indent + 3, space, static_cast<void *>(f->GetBody()), f->GetBody()->GetLabel().c_str());
if (Body *b = f->GetBody())
Output("%.*s bodyFor %p (%s)\n", indent + 3, space, static_cast<void *>(b), b->GetLabel().c_str());
Output("%.*s distance: %f radius: %f children: %u\n", indent + 3, space, f->GetPosition().Length(), f->GetRadius(), f->GetNumChildren());
for (FrameId kid : f->GetChildren())
DebugDumpFrame(kid, details, indent + 2);
}
@ -1054,5 +1065,5 @@ void Space::DebugDumpFrames(bool details)
memset(space, ' ', sizeof(space));
Output("Frame structure for '%s':\n", m_starSystem->GetName().c_str());
DebugDumpFrame(m_rootFrame.get(), details, 2);
DebugDumpFrame(m_rootFrameId, details, 3);
}

View File

@ -5,6 +5,7 @@
#define _SPACE_H
#include "Background.h"
#include "FrameId.h"
#include "IterationProxy.h"
#include "Object.h"
#include "RefCounted.h"
@ -41,7 +42,7 @@ public:
RefCountedPtr<StarSystem> GetStarSystem() const { return m_starSystem; }
Frame *GetRootFrame() const { return m_rootFrame.get(); }
FrameId GetRootFrame() const { return m_rootFrameId; }
void AddBody(Body *);
void RemoveBody(Body *);
@ -87,20 +88,15 @@ public:
private:
void GenSectorCache(RefCountedPtr<Galaxy> galaxy, const SystemPath *here);
void UpdateStarSystemCache(const SystemPath *here);
void GenBody(const double at_time, SystemBody *b, Frame *f, std::vector<vector3d> &posAccum);
void GenBody(const double at_time, SystemBody *b, FrameId fId, std::vector<vector3d> &posAccum);
// make sure SystemBody* is in Pi::currentSystem
Frame *GetFrameWithSystemBody(const SystemBody *b) const;
FrameId GetFrameWithSystemBody(const SystemBody *b) const;
void UpdateBodies();
void CollideFrame(Frame *f);
void CollideFrame(FrameId fId);
struct FrameDeleter {
/* Implemented in *cpp: prevent including Frame.h */
void operator()(Frame* frame);
};
std::unique_ptr<Frame, FrameDeleter> m_rootFrame;
FrameId m_rootFrameId;
RefCountedPtr<SectorCache::Slave> m_sectorCache;
RefCountedPtr<StarSystemCache::Slave> m_starSystemCache;

View File

@ -722,7 +722,7 @@ static const double SQRMAXCITYDIST = 1e5 * 1e5;
void SpaceStation::Render(Graphics::Renderer *r, const Camera *camera, const vector3d &viewCoords, const matrix4x4d &viewTransform)
{
Body *b = GetFrame()->GetBody();
Body *b = Frame::GetFrame(GetFrame())->GetBody();
assert(b);
if (!b->IsType(Object::PLANET)) {
@ -780,7 +780,7 @@ bool SpaceStation::AllocateStaticSlot(int &slot)
return false;
}
vector3d SpaceStation::GetTargetIndicatorPosition(const Frame *relTo) const
vector3d SpaceStation::GetTargetIndicatorPosition(FrameId relToId) const
{
// return the next waypoint if permission has been granted for player,
// and the docking point's position once the docking anim starts
@ -793,11 +793,11 @@ vector3d SpaceStation::GetTargetIndicatorPosition(const Frame *relTo) const
PiVerify(m_type->GetDockAnimPositionOrient(i, m_type->NumDockingStages(),
1.0f, vector3d(0.0), dport, m_shipDocking[i].ship));
vector3d v = GetInterpPositionRelTo(relTo);
return v + GetInterpOrientRelTo(relTo) * dport.pos;
vector3d v = GetInterpPositionRelTo(relToId);
return v + GetInterpOrientRelTo(relToId) * dport.pos;
}
}
return GetInterpPositionRelTo(relTo);
return GetInterpPositionRelTo(relToId);
}
bool SpaceStation::IsPortLocked(const int bay) const

View File

@ -69,7 +69,7 @@ public:
bool AllocateStaticSlot(int &slot);
// use docking bay position, if player has been granted permission
virtual vector3d GetTargetIndicatorPosition(const Frame *relTo) const override;
virtual vector3d GetTargetIndicatorPosition(FrameId relToId) const override;
// need this now because stations rotate in their frame
virtual void UpdateInterpTransform(double alpha) override;

View File

@ -58,7 +58,7 @@ void SpeedLines::Update(float time)
// don't show if
// vel < 100m/s
// in rotating frame (near station or planet surface)
if (absVel < 100.f || m_ship->GetFrame()->IsRotFrame()) {
if (absVel < 100.f || Frame::GetFrame(m_ship->GetFrame())->IsRotFrame()) {
m_visible = false;
return;
}

View File

@ -66,8 +66,9 @@ void TransferPlanner::AddStartTime(double timeStep)
m_startTime += m_factor * timeStep;
double deltaT = m_startTime - Pi::game->GetTime();
if (deltaT > 0.) {
Frame *frame = Pi::player->GetFrame()->GetNonRotFrame();
Orbit playerOrbit = Orbit::FromBodyState(Pi::player->GetPositionRelTo(frame), Pi::player->GetVelocityRelTo(frame), frame->GetSystemBody()->GetMass());
FrameId frameId = Frame::GetFrame(Pi::player->GetFrame())->GetNonRotFrame();
Frame *frame = Frame::GetFrame(frameId);
Orbit playerOrbit = Orbit::FromBodyState(Pi::player->GetPositionRelTo(frameId), Pi::player->GetVelocityRelTo(frameId), frame->GetSystemBody()->GetMass());
m_position = playerOrbit.OrbitalPosAtTime(deltaT);
m_velocity = playerOrbit.OrbitalVelocityAtTime(frame->GetSystemBody()->GetMass(), deltaT);
@ -78,14 +79,14 @@ void TransferPlanner::AddStartTime(double timeStep)
void TransferPlanner::ResetStartTime()
{
m_startTime = 0;
Frame *frame = Pi::player->GetFrame();
Frame *frame = Frame::GetFrame(Pi::player->GetFrame());
if (!frame || GetOffsetVel().ExactlyEqual(vector3d(0., 0., 0.))) {
m_position = vector3d(0., 0., 0.);
m_velocity = vector3d(0., 0., 0.);
} else {
frame = frame->GetNonRotFrame();
m_position = Pi::player->GetPositionRelTo(frame);
m_velocity = Pi::player->GetVelocityRelTo(frame);
frame = Frame::GetFrame(frame->GetNonRotFrame());
m_position = Pi::player->GetPositionRelTo(frame->GetId());
m_velocity = Pi::player->GetVelocityRelTo(frame->GetId());
}
}
@ -128,7 +129,7 @@ std::string TransferPlanner::printDeltaTime()
void TransferPlanner::AddDv(BurnDirection d, double dv)
{
if (m_position.ExactlyEqual(vector3d(0., 0., 0.))) {
Frame *frame = Pi::player->GetFrame()->GetNonRotFrame();
FrameId frame = Frame::GetFrame(Pi::player->GetFrame())->GetNonRotFrame();
m_position = Pi::player->GetPositionRelTo(frame);
m_velocity = Pi::player->GetVelocityRelTo(frame);
m_startTime = Pi::game->GetTime();
@ -753,9 +754,9 @@ void SystemView::PutBody(const SystemBody *b, const vector3d &offset, const matr
PutLabel(b, offset);
}
Frame *frame = Pi::player->GetFrame();
Frame *frame = Frame::GetFrame(Pi::player->GetFrame());
if (frame->IsRotFrame())
frame = frame->GetNonRotFrame();
frame = Frame::GetFrame(frame->GetNonRotFrame());
// display the players orbit(?)
if (frame->GetSystemBody() == b && frame->GetSystemBody()->GetMass() > 0) {
@ -1024,13 +1025,15 @@ void SystemView::DrawShips(const double t, const vector3d &offset)
for (auto s = m_contacts.begin(); s != m_contacts.end(); s++) {
vector3d pos = offset;
if ((*s).first->GetFlightState() != Ship::FlightState::FLYING) {
Frame *frame = Pi::game->GetSpace()->GetRootFrame();
pos += (*s).first->GetPositionRelTo(frame) * double(m_zoom);
FrameId frameId = Pi::game->GetSpace()->GetRootFrame();
pos += (*s).first->GetPositionRelTo(frameId) * double(m_zoom);
} else {
Frame *frame = (*s).first->GetFrame();
FrameId frameId = (*s).first->GetFrame();
vector3d bpos = vector3d(0., 0., 0.);
if (frame != Pi::game->GetSpace()->GetRootFrame())
if (frameId != Pi::game->GetSpace()->GetRootFrame()) {
Frame *frame = Frame::GetFrame(frameId);
bpos += frame->GetPositionRelTo(Pi::game->GetSpace()->GetRootFrame());
}
pos += (bpos + (*s).second.OrbitalPosAtTime(t)) * double(m_zoom);
}
const bool isNavTarget = Pi::player->GetNavTarget() == (*s).first;

View File

@ -123,14 +123,18 @@ void TerrainBody::Render(Graphics::Renderer *renderer, const Camera *camera, con
renderer->ClearDepthBuffer();
}
void TerrainBody::SetFrame(Frame *f)
void TerrainBody::SetFrame(FrameId fId)
{
if (GetFrame()) {
GetFrame()->SetPlanetGeom(0, 0);
}
Body::SetFrame(f);
Frame *f = Frame::GetFrame(GetFrame());
if (f) {
GetFrame()->SetPlanetGeom(0, 0);
f->SetPlanetGeom(0, nullptr);
}
Body::SetFrame(fId);
f = Frame::GetFrame(fId);
if (f) {
f->SetPlanetGeom(0, nullptr);
}
}

View File

@ -24,7 +24,7 @@ public:
virtual void Render(Graphics::Renderer *r, const Camera *camera, const vector3d &viewCoords, const matrix4x4d &viewTransform) override;
virtual void SubRender(Graphics::Renderer *r, const matrix4x4d &modelView, const vector3d &camPos) {}
virtual void SetFrame(Frame *f) override;
virtual void SetFrame(FrameId fId) override;
virtual bool OnCollision(Object *b, Uint32 flags, double relVel) override { return true; }
virtual double GetMass() const override { return m_mass; }
double GetTerrainHeight(const vector3d &pos) const;

View File

@ -302,8 +302,11 @@ void WorldView::Update()
UpdateProjectedObjects();
const Frame *playerFrame = Pi::player->GetFrame();
const Frame *camFrame = m_cameraContext->GetCamFrame();
FrameId playerFrameId = Pi::player->GetFrame();
FrameId camFrameId = m_cameraContext->GetCamFrame();
const Frame *playerFrame = Frame::GetFrame(playerFrameId);
const Frame *camFrame = Frame::GetFrame(camFrameId);
//speedlines and contact trails need camFrame for transform, so they
//must be updated here
@ -311,7 +314,7 @@ void WorldView::Update()
m_speedLines->Update(m_game->GetTimeStep());
matrix4x4d trans;
Frame::GetFrameTransform(playerFrame, camFrame, trans);
Frame::GetFrameTransform(playerFrameId, camFrameId, trans);
if (m_speedLines.get() && Pi::AreSpeedLinesDisplayed()) {
m_speedLines->Update(m_game->GetTimeStep());
@ -324,13 +327,13 @@ void WorldView::Update()
if (Pi::AreHudTrailsDisplayed()) {
matrix4x4d trans;
Frame::GetFrameTransform(playerFrame, camFrame, trans);
Frame::GetFrameTransform(playerFrameId, camFrameId, trans);
for (auto it = Pi::player->GetSensors()->GetContacts().begin(); it != Pi::player->GetSensors()->GetContacts().end(); ++it)
it->trail->SetTransform(trans);
} else {
for (auto it = Pi::player->GetSensors()->GetContacts().begin(); it != Pi::player->GetSensors()->GetContacts().end(); ++it)
it->trail->Reset(playerFrame);
it->trail->Reset(playerFrameId);
}
UIView::Update();
@ -416,7 +419,7 @@ static inline bool project_to_screen(const vector3d &in, vector3d &out, const Gr
void WorldView::UpdateProjectedObjects()
{
const Frame *cam_frame = m_cameraContext->GetCamFrame();
const Frame *cam_frame = Frame::GetFrame(m_cameraContext->GetCamFrame());
matrix3x3d cam_rot = cam_frame->GetOrient();
// later we might want non-ship enemies (e.g., for assaults on military bases)
@ -427,7 +430,7 @@ void WorldView::UpdateProjectedObjects()
if (enemy) {
const vector3d targpos = enemy->GetInterpPositionRelTo(Pi::player) * cam_rot;
const double dist = targpos.Length();
const vector3d targScreenPos = enemy->GetInterpPositionRelTo(cam_frame);
const vector3d targScreenPos = enemy->GetInterpPositionRelTo(cam_frame->GetId());
UpdateIndicator(m_combatTargetIndicator, targScreenPos);
@ -875,21 +878,21 @@ static double wrapAngleToPositive(const double theta)
*/
std::tuple<double, double, double> WorldView::CalculateHeadingPitchRoll(PlaneType pt)
{
auto frame = Pi::player->GetFrame();
FrameId frameId = Pi::player->GetFrame();
if (pt == ROTATIONAL)
frame = frame->GetRotFrame();
frameId = Frame::GetFrame(frameId)->GetRotFrame();
else if (pt == PARENT)
frame = frame->GetNonRotFrame();
frameId = Frame::GetFrame(frameId)->GetNonRotFrame();
// construct a frame of reference aligned with the ground plane
// and with lines of longitude and latitude
const vector3d up = Pi::player->GetPositionRelTo(frame).NormalizedSafe();
const vector3d up = Pi::player->GetPositionRelTo(frameId).NormalizedSafe();
const vector3d north = projectVecOntoPlane(vector3d(0, 1, 0), up).NormalizedSafe();
const vector3d east = north.Cross(up);
// find the direction that the ship is facing
const auto shpRot = Pi::player->GetOrientRelTo(frame);
const auto shpRot = Pi::player->GetOrientRelTo(frameId);
const vector3d hed = -shpRot.VectorZ();
const vector3d right = shpRot.VectorX();
const vector3d groundHed = projectVecOntoPlane(hed, up).NormalizedSafe();
@ -929,7 +932,7 @@ vector3d WorldView::WorldSpaceToScreenSpace(const Body *body) const
{
if (body->IsType(Object::PLAYER) && shipView.GetCamType() == ShipViewController::CAM_INTERNAL)
return vector3d(0, 0, 0);
const Frame *cam_frame = m_cameraContext->GetCamFrame();
const FrameId cam_frame = m_cameraContext->GetCamFrame();
vector3d pos = body->GetInterpPositionRelTo(cam_frame);
return projectToScreenSpace(pos, m_cameraContext);
}
@ -937,7 +940,7 @@ vector3d WorldView::WorldSpaceToScreenSpace(const Body *body) const
// needs to run inside m_cameraContext->Begin/EndFrame();
vector3d WorldView::WorldSpaceToScreenSpace(const vector3d &position) const
{
const Frame *cam_frame = m_cameraContext->GetCamFrame();
const Frame *cam_frame = Frame::GetFrame(m_cameraContext->GetCamFrame());
matrix3x3d cam_rot = cam_frame->GetInterpOrient();
vector3d pos = position * cam_rot;
return projectToScreenSpace(pos, m_cameraContext);
@ -947,7 +950,7 @@ vector3d WorldView::WorldSpaceToScreenSpace(const vector3d &position) const
vector3d WorldView::ShipSpaceToScreenSpace(const vector3d &pos) const
{
matrix3x3d orient = Pi::player->GetInterpOrient();
const Frame *cam_frame = m_cameraContext->GetCamFrame();
const Frame *cam_frame = Frame::GetFrame(m_cameraContext->GetCamFrame());
matrix3x3d cam_rot = cam_frame->GetInterpOrient();
vector3d camspace = orient * pos * cam_rot;
return projectToScreenSpace(camspace, m_cameraContext, false);
@ -964,7 +967,7 @@ vector3d WorldView::GetTargetIndicatorScreenPosition(const Body *body) const
{
if (body->IsType(Object::PLAYER) && shipView.GetCamType() == ShipViewController::CAM_INTERNAL)
return vector3d(0, 0, 0);
const Frame *cam_frame = m_cameraContext->GetCamFrame();
FrameId cam_frame = m_cameraContext->GetCamFrame();
vector3d pos = body->GetTargetIndicatorPosition(cam_frame);
return projectToScreenSpace(pos, m_cameraContext);
}
@ -973,7 +976,7 @@ vector3d WorldView::GetTargetIndicatorScreenPosition(const Body *body) const
vector3d WorldView::GetMouseDirection() const
{
// orientation according to mouse
const Frame *cam_frame = m_cameraContext->GetCamFrame();
const Frame *cam_frame = Frame::GetFrame(m_cameraContext->GetCamFrame());
matrix3x3d cam_rot = cam_frame->GetInterpOrient();
vector3d mouseDir = Pi::player->GetPlayerController()->GetMouseDir() * cam_rot;
if (shipView.GetCamType() == ShipViewController::CAM_INTERNAL && shipView.m_internalCameraController->GetMode() == InternalCameraController::MODE_REAR)

View File

@ -184,7 +184,7 @@ void PlayerShipController::StaticUpdate(const float timeStep)
// AIMatchVel(vector3d(0.0)); // just in case autopilot doesn't...
// actually this breaks last timestep slightly in non-relative target cases
m_ship->AIMatchAngVelObjSpace(vector3d(0.0));
if (m_ship->GetFrame()->IsRotFrame())
if (Frame::GetFrame(m_ship->GetFrame())->IsRotFrame())
SetFlightControlState(CONTROL_FIXSPEED);
else
SetFlightControlState(CONTROL_MANUAL);
@ -209,7 +209,7 @@ void PlayerShipController::CheckControlsLock()
vector3d PlayerShipController::GetMouseDir() const
{
// translate from system to local frame
return m_mouseDir * m_ship->GetFrame()->GetOrient();
return m_mouseDir * Frame::GetFrame(m_ship->GetFrame())->GetOrient();
}
// mouse wraparound control function
@ -241,7 +241,7 @@ void PlayerShipController::PollControls(const float timeStep, const bool force_r
// have to use this function. SDL mouse position event is bugged in windows
if (Pi::input.MouseButtonState(SDL_BUTTON_RIGHT)) {
// use ship rotation relative to system, unchanged by frame transitions
matrix3x3d rot = m_ship->GetOrientRelTo(m_ship->GetFrame()->GetNonRotFrame());
matrix3x3d rot = m_ship->GetOrientRelTo(Frame::GetFrame(m_ship->GetFrame())->GetNonRotFrame());
if (!m_mouseActive && !m_disableMouseFacing) {
m_mouseDir = -rot.VectorZ();
m_mouseX = m_mouseY = 0;

View File

@ -131,7 +131,7 @@ void AmbientSounds::Update()
// lets try something random for the time being
if (!s_planetSurfaceNoise.IsPlaying()) {
const SystemBody *sbody = Pi::player->GetFrame()->GetSystemBody();
const SystemBody *sbody = Frame::GetFrame(Pi::player->GetFrame())->GetSystemBody();
assert(sbody);
const char *sample = 0;
@ -149,8 +149,9 @@ void AmbientSounds::Update()
}
} else if (s_planetSurfaceNoise.IsPlaying()) {
// s_planetSurfaceNoise.IsPlaying() - if we are out of the atmosphere then stop playing
if (Pi::player->GetFrame()->IsRotFrame()) {
const Body *astro = Pi::player->GetFrame()->GetBody();
Frame *playerFrame = Frame::GetFrame(Pi::player->GetFrame());
if (playerFrame->IsRotFrame()) {
const Body *astro = playerFrame->GetBody();
if (astro->IsType(Object::PLANET)) {
const double dist = Pi::player->GetPosition().Length();
double pressure, density;
@ -187,7 +188,7 @@ void AmbientSounds::Update()
}
// when all the sounds are in we can use the body we are in frame of reference to
if (!s_starNoise.IsPlaying()) {
Frame *f = Pi::player->GetFrame();
Frame *f = Frame::GetFrame(Pi::player->GetFrame());
if (!f) return; // When player has no frame (game abort) then get outta here!!
const SystemBody *sbody = f->GetSystemBody();
const char *sample = 0;
@ -220,14 +221,16 @@ void AmbientSounds::Update()
s_starNoise.VolumeAnimate(.3f * v_env, .3f * v_env, .05f, .05f);
} else {
// go up orbital hierarchy tree to see if we can find a sound
f = f->GetParent();
if (f == 0) break;
FrameId parent = f->GetParent();
f = Frame::GetFrame(parent);
if (f == nullptr) break;
}
}
}
const Body *astro = Pi::player->GetFrame()->GetBody();
if (astro && Pi::player->GetFrame()->IsRotFrame() && (astro->IsType(Object::PLANET))) {
Frame *playerFrame = Frame::GetFrame(Pi::player->GetFrame());
const Body *astro = playerFrame->GetBody();
if (astro && playerFrame->IsRotFrame() != noFrameId && (astro->IsType(Object::PLANET))) {
double dist = Pi::player->GetPosition().Length();
double pressure, density;
static_cast<const Planet *>(astro)->GetAtmosphericState(dist, &pressure, &density);