Update all files to store and use FrameId instead of raw pointers
parent
3a0aa4301b
commit
4f1eaa41d3
12
src/Beam.cpp
12
src/Beam.cpp
|
@ -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());
|
||||
|
|
81
src/Body.cpp
81
src/Body.cpp
|
@ -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)
|
||||
|
|
21
src/Body.h
21
src/Body.h
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
156
src/Frame.cpp
156
src/Frame.cpp
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
46
src/Frame.h
46
src/Frame.h
|
@ -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
|
||||
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
#include "FrameId.h"
|
||||
|
||||
bool IsIdValid(FrameId fId) { return fId >= 0; }
|
|
@ -5,4 +5,6 @@ typedef int FrameId;
|
|||
|
||||
constexpr FrameId noFrameId = -1;
|
||||
|
||||
extern bool IsIdValid(FrameId fId);
|
||||
|
||||
#endif // FRAMEID_H_INCLUDED
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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))) {
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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;
|
||||
|
|
28
src/Sfx.cpp
28
src/Sfx.cpp
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
11
src/Sfx.h
11
src/Sfx.h
|
@ -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);
|
||||
|
||||
|
|
35
src/Ship.cpp
35
src/Ship.cpp
|
@ -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()) {
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
305
src/Space.cpp
305
src/Space.cpp
|
@ -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);
|
||||
}
|
||||
|
|
16
src/Space.h
16
src/Space.h
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue