[Add] Initial work on rotating frames. Woop, our sun moves now.

This commit is contained in:
Allanis 2017-12-26 17:24:03 +00:00
parent ec3a81ed35
commit 5f51ee9cb1
12 changed files with 132 additions and 44 deletions

View File

@ -17,7 +17,9 @@ Body::~Body(void) {
/* f == NULL, then absolute position within system. */
vector3d Body::GetPositionRelTo(const Frame* relTo) {
return m_frame->GetPosRelativeToOtherFrame(relTo) + GetPosition();
matrix4x4d m;
Frame::GetFrameTransform(m_frame, relTo, m);
return m * GetPosition();
}
const vector3d& Body::GetProjectedPos(void) const {

View File

@ -18,6 +18,8 @@ public:
virtual void SetVelocity(vector3d v) { assert(0); }
virtual vector3d GetVelocity(void) { assert(0); return vector3d(0.0); }
virtual double GetRadius(void) const = 0 ;
virtual void SetRotMatrix(const matrix4x4d& r) {};
virtual void GetRotMatrix(matrix4x4d& m) {};
virtual void Render(const Frame* camFrame) = 0;
virtual void SetFrame(Frame* f) { m_frame = f; }
/* return true if to we do collision response and apply damage. */

View File

@ -24,6 +24,8 @@ void Frame::Init(Frame* parent, const char* label, unsigned int flags) {
m_radius = 0;
m_pos = vector3d(0.0f);
m_vel = vector3d(0.0);
m_angVel = vector3d(0.0);
m_orient = matrix4x4d::Identity();
m_dSpaceID = dHashSpaceCreate(0);
if(m_parent) {
m_parent->m_children.push_back(this);
@ -36,23 +38,40 @@ Frame::~Frame(void) {
for(std::list<Frame*>::iterator i = m_children.begin(); i != m_children.end(); ++i) delete *i;
}
vector3d Frame::GetFramePosRelativeToOther(const Frame* frame, const Frame* relTo) {
vector3d pos = vector3d(0,0,0);
void Frame::ApplyLeavingTransform(matrix4x4d& m) const {
m = matrix4x4d::Translation(m_pos) * m_orient * m;
}
const Frame* f = frame;
void Frame::ApplyEnteringTransform(matrix4x4d& m) const {
m = m * m_orient.InverseOf() * matrix4x4d::Translation(-m_pos);
}
void Frame::GetFrameTransform(const Frame* fFrom, const Frame* fTo, matrix4x4d& m) {
matrix4x4d m2 = matrix4x4d::Identity();
m = matrix4x4d::Identity();
const Frame* f = fFrom;
const Frame* root = Space::GetRootFrame();
while((f!=root) && (relTo !=f)) {
pos += f->m_pos;
while((f != root) && (fTo != f)) {
f->ApplyLeavingTransform(m);
f = f->m_parent;
}
/* Now pos is relative to root, or to desired frame. */
while(relTo != f) {
pos -= relTo->m_pos;
relTo = relTo->m_parent;
while(fTo != f) {
fTo->ApplyEnteringTransform(m2);
fTo = fTo->m_parent;
}
return pos;
m = m2 * m;
}
void Frame::RotateInTimestep(double step) {
double ang = m_angVel.Length() * step;
if(ang == 0) return;
vector3d rotAxis = vector3d::Normalize(m_angVel);
matrix4x4d rotMatrix = matrix4x4d::RotateMatrix(ang, rotAxis.x, rotAxis.y, rotAxis.z);
m_orient = m_orient * rotMatrix;
}

View File

@ -12,23 +12,28 @@ public:
Frame(Frame* parent, const char* label, unsigned int flags);
~Frame(void);
const char* GetLabel(void) { return m_label.c_str(); }
void SetLabel(const char* label) { m_label = label; }
void SetPosition(const vector3d &pos) { m_pos = pos; }
vector3d GetPosition(void) { return m_pos; }
void SetVelocity(const vector3d& vel) { m_vel = vel; }
vector3d GetVelocity(void) { return m_vel; }
void SetRadius(double radius) { m_radius = radius; }
const char* GetLabel(void) const { return m_label.c_str(); }
void SetLabel(const char* label) { m_label = label; }
void SetPosition(const vector3d &pos) { m_pos = pos; }
vector3d GetPosition(void) const { return m_pos; }
void SetVelocity(const vector3d& vel) { m_vel = vel; }
vector3d GetVelocity(void) const { return m_vel; }
void SetAngVelocity(const vector3d& angvel) { m_angVel = angvel; }
vector3d GetAngVelocity(void) const { return m_angVel; }
const matrix4x4d& GetOrientation(void) const { return m_orient; }
void SetOrientation(const matrix4x4d& m) { m_orient = m; }
void SetRadius(double radius) { m_radius = radius; }
void RemoveChild(Frame* f);
void AddGeom(dGeomID g) { dSpaceAdd(m_dSpaceID, g); }
void RemoveGeom(dGeomID g) { dSpaceRemove(m_dSpaceID, g); }
dSpaceID GetSpaceID(void) { return m_dSpaceID; }
void AddGeom(dGeomID g) { dSpaceAdd(m_dSpaceID, g); }
void RemoveGeom(dGeomID g) { dSpaceRemove(m_dSpaceID, g); }
dSpaceID GetSpaceID(void) const { return m_dSpaceID; }
void RotateInTimestep(double step);
static vector3d GetFramePosRelativeToOther(const Frame* frame, const Frame* relTo);
vector3d GetPosRelativeToOtherFrame(const Frame* relTo) const {
return GetFramePosRelativeToOther(this, relTo);
}
void ApplyLeavingTransform(matrix4x4d& m) const;
void ApplyEnteringTransform(matrix4x4d& m) const;
static void GetFrameTransform(const Frame* fFrom, const Frame* fTo, matrix4x4d& m);
bool IsLocalPosInFrame(const vector3d& pos) {
return (pos.Length() < m_radius);
@ -46,6 +51,8 @@ private:
vector3d m_pos;
/* We don't use this to move frame, rather, orbital rails determine velocity. */
vector3d m_vel;
vector3d m_angVel; /* This however *is* directly applied (for rotating frames). */
matrix4x4d m_orient;
std::string m_label;
double m_radius;
int m_flags;

View File

@ -34,6 +34,8 @@ public:
}
};
class Frame;
/* Implementation is done in main.cpp, just to confuse you. :D */
class L3D {
public:

View File

@ -194,8 +194,6 @@ void L3D::MainLoop(void) {
const float zpos = EARTH_RADIUS * 1;
Frame* pframe = *(Space::rootFrame->m_children.begin());
player->SetFrame(pframe);
player->SetPosition(vector3d(0, zpos*0.1, zpos));
for(int i = 0; i < 4; i++) {
Ship* body = new Ship(ShipType::SLEEK/*LADYBIRD*/);
@ -207,12 +205,21 @@ void L3D::MainLoop(void) {
Space::AddBody(body);
}
Frame* stationFrame = new Frame(pframe, "Station frame...");
stationFrame->SetRadius(5000);
stationFrame->sBody = 0;
stationFrame->SetPosition(vector3d(0,0,zpos));
stationFrame->SetAngVelocity(vector3d(0,0,0.5));
SpaceStation* station = new SpaceStation();
station->SetLabel("Poemi-chan's Folly");
station->SetFrame(pframe);
station->SetPosition(vector3d(5000, zpos*0.1, zpos-10000));
station->SetFrame(stationFrame);
station->SetPosition(vector3d(0,0,0));
Space::AddBody(station);
player->SetFrame(stationFrame);
player->SetPosition(vector3d(0,0,2000));
Gui::Init(scrWidth, scrHeight, 640, 480);
cpan = new ShipCpanel();
@ -227,7 +234,7 @@ void L3D::MainLoop(void) {
infoView = new InfoView();
SetView(world_view);
player->SetDockedWith(station);
//player->SetDockedWith(station);
Uint32 last_stats = SDL_GetTicks();
int frame_stat = 0;

View File

@ -174,6 +174,12 @@ public:
return m;
}
void ClearToRotOnly(void) {
cell[12] = 0;
cell[13] = 0;
cell[14] = 0;
}
T& operator[] (const int i) { return cell[i]; }
friend matrix4x4 operator+(const matrix4x4& a, const matrix4x4& b) {
matrix4x4 m;
@ -223,12 +229,28 @@ public:
return out;
}
void Translatef(T x, T y, T z) {
void Translate(vector3<T> t) {
Translate(t.x, t.y, t.z);
}
void Translate(T x, T y, T z) {
matrix4x4 m = Identity();
m[12] = x;
m[13] = y;
m[14] = z;
*this = (*this) * m;
*this = m * (*this);
}
static matrix4x4 Translation(vector3<T> v) {
return Translation(v.x, v.y, v.z);
}
static matrix4x4 Translation(T x, T y, T z) {
matrix4x4 m = Identity();
m[12] = x;
m[13] = y;
m[14] = z;
return m;
}
matrix4x4 InverseOf(void) const {

View File

@ -88,7 +88,7 @@ double ModelBody::GetRadius(void) const {
return std::max(aabbAll[1] - aabbAll[0], std::max(aabbAll[3] - aabbAll[2], aabbAll[5] - aabbAll[4]));
}
void ModelBody::SetRotation(const matrix4x4d& r) {
void ModelBody::SetRotMatrix(const matrix4x4d& r) {
dMatrix3 _m;
r.SaveToOdeMatrix(_m);
for(unsigned int i = 0; i < geoms.size(); i++) {
@ -168,12 +168,15 @@ void ModelBody::RenderSbreModel(const Frame* camFrame, int model, ObjParams* par
sbreSetViewport(L3D::GetScrWidth(), L3D::GetScrHeight(), L3D::GetScrWidth()
*0.5, 5.0f, 100000.0f, 0.0f, 1.0f);
vector3d pos = GetPositionRelTo(camFrame);
pos = L3D::world_view->viewingRotation*pos;
matrix4x4d frameTrans;
Frame::GetFrameTransform(GetFrame(), camFrame, frameTrans);
vector3d pos = GetPosition();
pos = L3D::world_view->viewingRotation * frameTrans * pos;
Vector p; p.x = pos.x; p.y = pos.y; p.z = -pos.z;
matrix4x4d rot;
rot.LoadFromOdeMatrix(dGeomGetRotation(geoms[0]));
rot = L3D::world_view->viewingRotation * rot;
rot = L3D::world_view->viewingRotation * frameTrans * rot;
Matrix m;
m.x1 = rot[0]; m.x2 = rot[4]; m.x3 = -rot[8];
m.y1 = rot[1]; m.y2 = rot[5]; m.y3 = -rot[9];

View File

@ -12,7 +12,7 @@ public:
ModelBody(void);
virtual ~ModelBody(void);
void SetPosition(vector3d p);
virtual void SetRotation(const matrix4x4d& r);
virtual void SetRotMatrix(const matrix4x4d& r);
/* Not valid to SetVelocity on these. If you want them to move, use a DynamicBody. */
vector3d GetPosition(void);
virtual double GetRadius(void) const;

View File

@ -50,6 +50,7 @@ void Space::MoveOrbitingObjectFrames(Frame* f) {
f->SetPosition(pos);
f->SetVelocity(vel);
}
f->RotateInTimestep(L3D::GetTimeStep());
for(std::list<Frame*>::iterator i = f->m_children.begin(); i != f->m_children.end(); ++i) {
MoveOrbitingObjectFrames(*i);
@ -117,13 +118,27 @@ void Space::UpdateFramesOfReference(void) {
if(!b->GetFrame()->IsLocalPosInFrame(b->GetPosition())) {
printf("%s leaves frame %s\n", b->GetLabel().c_str(), b->GetFrame()->GetLabel());
b->SetVelocity(b->GetVelocity() + b->GetFrame()->GetVelocity());
vector3d oldFrameVel = b->GetFrame()->GetVelocity();
Frame* new_frame = b->GetFrame()->m_parent;
if(new_frame) { /* Don't fall out of root frame. */
vector3d new_pos = b->GetPositionRelTo(new_frame);
matrix4x4d m = matrix4x4d::Identity();
b->GetFrame()->ApplyLeavingTransform(m);
vector3d new_pos = m * b->GetPosition();
matrix4x4d rot;
b->GetRotMatrix(rot);
b->SetRotMatrix(m * rot);
b->SetFrame(new_frame);
b->SetPosition(new_pos);
/* Get rid of transforms. */
m.ClearToRotOnly();
b->SetVelocity(m*b->GetVelocity() + oldFrameVel);
} else {
b->SetVelocity(b->GetVelocity() + oldFrameVel);
}
}
@ -131,12 +146,21 @@ void Space::UpdateFramesOfReference(void) {
for(std::list<Frame*>::iterator j = b->GetFrame()->m_children.begin();
j != b->GetFrame()->m_children.end(); ++j) {
Frame* child = *j;
vector3d pos = b->GetFrame()->GetPosRelativeToOtherFrame(child) + b->GetPosition();
matrix4x4d m;
Frame::GetFrameTransform(b->GetFrame(), child, m);
vector3d pos = m * b->GetPosition();
if(child->IsLocalPosInFrame(pos)) {
printf("%s enters frame %s\n", b->GetLabel().c_str(), child->GetLabel());
b->SetPosition(pos);
b->SetFrame(child);
b->SetVelocity(b->GetVelocity() - child->GetVelocity());
matrix4x4d rot;
b->GetRotMatrix(rot);
b->SetRotMatrix(m * rot);
/* Get rid of transforms. */
m.ClearToRotOnly();
b->SetVelocity(m*b->GetVelocity()-child->GetVelocity());
break;
}
}

View File

@ -57,8 +57,6 @@ void SpaceStation::GetDockingSurface(CollMeshSet* mset, int midx) {
SpaceStation::SpaceStation(void) : ModelBody() {
SetModel(STATION_SBRE_MODEL);
matrix4x4d m = matrix4x4d::RotateYMatrix(M_PI-M_PI/6);
SetRotation(m);
CollMeshSet* mset = GetModelCollMeshSet(STATION_SBRE_MODEL);
for(unsigned int i = 0; i < geomColl.size(); i++) {

View File

@ -109,7 +109,9 @@ void WorldView::Draw3D(void) {
glCallList(m_bgstarsDlist);
/* Position light at sol. */
vector3d lpos = vector3d::Normalize(Frame::GetFramePosRelativeToOther(Space::GetRootFrame(), &cam_frame));
matrix4x4d m;
Frame::GetFrameTransform(Space::GetRootFrame(), &cam_frame, m);
vector3d lpos = vector3d::Normalize(m*vector3d(0,0,0));
float lightPos[4];
lightPos[0] = lpos.x;
lightPos[1] = lpos.y;