[Fix] Set body velocities correctly as they enter and leave moving frames.
This commit is contained in:
parent
3beac715c7
commit
0e59178d77
@ -15,6 +15,8 @@ public:
|
|||||||
virtual Object::Type GetType(void) { return Object::BODY; }
|
virtual Object::Type GetType(void) { return Object::BODY; }
|
||||||
virtual void SetPosition(vector3d p) = 0;
|
virtual void SetPosition(vector3d p) = 0;
|
||||||
virtual vector3d GetPosition(void) = 0; /* Within frame. */
|
virtual vector3d GetPosition(void) = 0; /* Within frame. */
|
||||||
|
virtual void SetVelocity(vector3d v) { assert(0); }
|
||||||
|
virtual vector3d GetVelocity(void) { assert(0); return vector3d(0.0); }
|
||||||
virtual double GetRadius(void) const = 0 ;
|
virtual double GetRadius(void) const = 0 ;
|
||||||
virtual void Render(const Frame* camFrame) = 0;
|
virtual void Render(const Frame* camFrame) = 0;
|
||||||
virtual void SetFrame(Frame* f) { m_frame = f; }
|
virtual void SetFrame(Frame* f) { m_frame = f; }
|
||||||
|
@ -53,6 +53,11 @@ DynamicBody::~DynamicBody(void) {
|
|||||||
dBodyDestroy(m_body);
|
dBodyDestroy(m_body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vector3d DynamicBody::GetVelocity(void) {
|
||||||
|
const dReal* v = dBodyGetLinearVel(m_body);
|
||||||
|
return vector3d(v[0], v[1], v[2]);
|
||||||
|
}
|
||||||
|
|
||||||
void DynamicBody::SetVelocity(vector3d v) {
|
void DynamicBody::SetVelocity(vector3d v) {
|
||||||
dBodySetLinearVel(m_body, v.x, v.y, v.z);
|
dBodySetLinearVel(m_body, v.x, v.y, v.z);
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,8 @@ public:
|
|||||||
DynamicBody(void);
|
DynamicBody(void);
|
||||||
virtual ~DynamicBody(void);
|
virtual ~DynamicBody(void);
|
||||||
virtual void SetRotation(const matrix4x4d& r);
|
virtual void SetRotation(const matrix4x4d& r);
|
||||||
void SetVelocity(vector3d v);
|
virtual void SetVelocity(vector3d v);
|
||||||
|
virtual vector3d GetVelocity(void);
|
||||||
void SetAngVelocity(vector3d v);
|
void SetAngVelocity(vector3d v);
|
||||||
void SetMesh(ObjMesh* m);
|
void SetMesh(ObjMesh* m);
|
||||||
virtual bool OnCollision(Body* b, Uint32 flags) { return true; }
|
virtual bool OnCollision(Body* b, Uint32 flags) { return true; }
|
||||||
|
@ -23,6 +23,7 @@ void Frame::Init(Frame* parent, const char* label, unsigned int flags) {
|
|||||||
m_flags = flags;
|
m_flags = flags;
|
||||||
m_radius = 0;
|
m_radius = 0;
|
||||||
m_pos = vector3d(0.0f);
|
m_pos = vector3d(0.0f);
|
||||||
|
m_vel = vector3d(0.0);
|
||||||
m_dSpaceID = dHashSpaceCreate(0);
|
m_dSpaceID = dHashSpaceCreate(0);
|
||||||
if(m_parent) {
|
if(m_parent) {
|
||||||
m_parent->m_children.push_back(this);
|
m_parent->m_children.push_back(this);
|
||||||
|
@ -15,6 +15,9 @@ public:
|
|||||||
const char* GetLabel(void) { return m_label.c_str(); }
|
const char* GetLabel(void) { return m_label.c_str(); }
|
||||||
void SetLabel(const char* label) { m_label = label; }
|
void SetLabel(const char* label) { m_label = label; }
|
||||||
void SetPosition(const vector3d &pos) { m_pos = pos; }
|
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; }
|
void SetRadius(double radius) { m_radius = radius; }
|
||||||
void RemoveChild(Frame* f);
|
void RemoveChild(Frame* f);
|
||||||
void AddGeom(dGeomID g) { dSpaceAdd(m_dSpaceID, g); }
|
void AddGeom(dGeomID g) { dSpaceAdd(m_dSpaceID, g); }
|
||||||
@ -41,6 +44,8 @@ public:
|
|||||||
private:
|
private:
|
||||||
void Init(Frame* parent, const char* label, unsigned int flags);
|
void Init(Frame* parent, const char* label, unsigned int flags);
|
||||||
vector3d m_pos;
|
vector3d m_pos;
|
||||||
|
/* We don't use this to move frame, rather, orbital rails determine velocity. */
|
||||||
|
vector3d m_vel;
|
||||||
std::string m_label;
|
std::string m_label;
|
||||||
double m_radius;
|
double m_radius;
|
||||||
int m_flags;
|
int m_flags;
|
||||||
|
@ -318,7 +318,8 @@ void L3D::HyperspaceTo(StarSystem* dest) {
|
|||||||
Space::Clear();
|
Space::Clear();
|
||||||
Space::BuildSystem();
|
Space::BuildSystem();
|
||||||
float ang = rng.Double(M_PI);
|
float ang = rng.Double(M_PI);
|
||||||
L3D::player->SetPosition(vector3d(sin(ang)*8*AU, cos(ang)*8*AU, 0));
|
L3D::player->SetPosition(vector3d(sin(ang)*AU, cos(ang)*AU,0));
|
||||||
|
L3D::player->SetVelocity(vector3d(0.0));
|
||||||
dest->GetPos(&L3D::playerLoc);
|
dest->GetPos(&L3D::playerLoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,14 +41,18 @@ void Space::Clear(void) {
|
|||||||
L3D::player->SetFrame(rootFrame);
|
L3D::player->SetFrame(rootFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Space::MoveFramesOfReference(Frame* f) {
|
void Space::MoveOrbitingObjectFrames(Frame* f) {
|
||||||
if(f->sBody) {
|
if(f->sBody) {
|
||||||
|
/* Not too efficient. */
|
||||||
vector3d pos = f->sBody->orbit.CartesianPosAtTime(L3D::GetGameTime());
|
vector3d pos = f->sBody->orbit.CartesianPosAtTime(L3D::GetGameTime());
|
||||||
|
vector3d pos2 = f->sBody->orbit.CartesianPosAtTime(L3D::GetGameTime()+1.0);
|
||||||
|
vector3d vel = pos2 - pos;
|
||||||
f->SetPosition(pos);
|
f->SetPosition(pos);
|
||||||
|
f->SetVelocity(vel);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(std::list<Frame*>::iterator i = f->m_children.begin(); i != f->m_children.end(); ++i) {
|
for(std::list<Frame*>::iterator i = f->m_children.begin(); i != f->m_children.end(); ++i) {
|
||||||
MoveFramesOfReference(*i);
|
MoveOrbitingObjectFrames(*i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,11 +71,8 @@ void Space::GenBody(StarSystem::SBody* sbody, Frame* f) {
|
|||||||
b->SetLabel(sbody->name.c_str());
|
b->SetLabel(sbody->name.c_str());
|
||||||
|
|
||||||
Frame* myframe;
|
Frame* myframe;
|
||||||
|
|
||||||
if(sbody->parent) {
|
if(sbody->parent) {
|
||||||
myframe = new Frame(f, sbody->name.c_str());
|
myframe = new Frame(f, sbody->name.c_str());
|
||||||
vector3d pos = sbody->orbit.CartesianPosAtTime(0);
|
|
||||||
myframe->SetPosition(pos);
|
|
||||||
myframe->SetRadius(10*sbody->GetRadius());
|
myframe->SetRadius(10*sbody->GetRadius());
|
||||||
myframe->sBody = sbody;
|
myframe->sBody = sbody;
|
||||||
b->SetFrame(myframe);
|
b->SetFrame(myframe);
|
||||||
@ -94,6 +95,7 @@ just_make_child:
|
|||||||
|
|
||||||
void Space::BuildSystem(void) {
|
void Space::BuildSystem(void) {
|
||||||
GenBody(L3D::current_system->rootBody, rootFrame);
|
GenBody(L3D::current_system->rootBody, rootFrame);
|
||||||
|
MoveOrbitingObjectFrames(rootFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Space::AddBody(Body* b) {
|
void Space::AddBody(Body* b) {
|
||||||
@ -115,6 +117,8 @@ void Space::UpdateFramesOfReference(void) {
|
|||||||
if(!b->GetFrame()->IsLocalPosInFrame(b->GetPosition())) {
|
if(!b->GetFrame()->IsLocalPosInFrame(b->GetPosition())) {
|
||||||
printf("%s leaves frame %s\n", b->GetLabel().c_str(), b->GetFrame()->GetLabel());
|
printf("%s leaves frame %s\n", b->GetLabel().c_str(), b->GetFrame()->GetLabel());
|
||||||
|
|
||||||
|
b->SetVelocity(b->GetVelocity() + b->GetFrame()->GetVelocity());
|
||||||
|
|
||||||
Frame* new_frame = b->GetFrame()->m_parent;
|
Frame* new_frame = b->GetFrame()->m_parent;
|
||||||
if(new_frame) { /* Don't fall out of root frame. */
|
if(new_frame) { /* Don't fall out of root frame. */
|
||||||
vector3d new_pos = b->GetPositionRelTo(new_frame);
|
vector3d new_pos = b->GetPositionRelTo(new_frame);
|
||||||
@ -126,12 +130,13 @@ void Space::UpdateFramesOfReference(void) {
|
|||||||
/* Entering into frames. */
|
/* Entering into frames. */
|
||||||
for(std::list<Frame*>::iterator j = b->GetFrame()->m_children.begin();
|
for(std::list<Frame*>::iterator j = b->GetFrame()->m_children.begin();
|
||||||
j != b->GetFrame()->m_children.end(); ++j) {
|
j != b->GetFrame()->m_children.end(); ++j) {
|
||||||
Frame* kid = *j;
|
Frame* child = *j;
|
||||||
vector3d pos = b->GetFrame()->GetPosRelativeToOtherFrame(kid) + b->GetPosition();
|
vector3d pos = b->GetFrame()->GetPosRelativeToOtherFrame(child) + b->GetPosition();
|
||||||
if(kid->IsLocalPosInFrame(pos)) {
|
if(child->IsLocalPosInFrame(pos)) {
|
||||||
printf("%s enters frame %s\n", b->GetLabel().c_str(), kid->GetLabel());
|
printf("%s enters frame %s\n", b->GetLabel().c_str(), child->GetLabel());
|
||||||
b->SetPosition(pos);
|
b->SetPosition(pos);
|
||||||
b->SetFrame(kid);
|
b->SetFrame(child);
|
||||||
|
b->SetVelocity(b->GetVelocity() - child->GetVelocity());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -240,7 +245,7 @@ void Space::TimeStep(float step) {
|
|||||||
|
|
||||||
/* TODO: Does not need to be done this often. */
|
/* TODO: Does not need to be done this often. */
|
||||||
UpdateFramesOfReference();
|
UpdateFramesOfReference();
|
||||||
MoveFramesOfReference(rootFrame);
|
MoveOrbitingObjectFrames(rootFrame);
|
||||||
|
|
||||||
for(bodiesIter_t i = bodies.begin(); i != bodies.end(); ++i) {
|
for(bodiesIter_t i = bodies.begin(); i != bodies.end(); ++i) {
|
||||||
(*i)->TimeStepUpdate(step);
|
(*i)->TimeStepUpdate(step);
|
||||||
|
@ -24,7 +24,7 @@ public:
|
|||||||
typedef std::list<Body*>::iterator bodiesIter_t;
|
typedef std::list<Body*>::iterator bodiesIter_t;
|
||||||
static Frame* rootFrame;
|
static Frame* rootFrame;
|
||||||
private:
|
private:
|
||||||
static void MoveFramesOfReference(Frame* f);
|
static void MoveOrbitingObjectFrames(Frame* f);
|
||||||
static void UpdateFramesOfReference(void);
|
static void UpdateFramesOfReference(void);
|
||||||
static void CollideFrame(Frame* f);
|
static void CollideFrame(Frame* f);
|
||||||
static void PruneCorpses(void);
|
static void PruneCorpses(void);
|
||||||
|
Loading…
Reference in New Issue
Block a user