[Add] Initial work on rotating frames. Woop, our sun moves now.
This commit is contained in:
parent
ec3a81ed35
commit
5f51ee9cb1
@ -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 {
|
||||
|
@ -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. */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
23
src/frame.h
23
src/frame.h
@ -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(); }
|
||||
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) { return m_pos; }
|
||||
vector3d GetPosition(void) const { return m_pos; }
|
||||
void SetVelocity(const vector3d& vel) { m_vel = vel; }
|
||||
vector3d GetVelocity(void) { return m_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; }
|
||||
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;
|
||||
|
@ -34,6 +34,8 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class Frame;
|
||||
|
||||
/* Implementation is done in main.cpp, just to confuse you. :D */
|
||||
class L3D {
|
||||
public:
|
||||
|
17
src/main.cpp
17
src/main.cpp
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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];
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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++) {
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user