[Fix] Set body velocities correctly as they enter and leave moving frames.

This commit is contained in:
Rtch90 2017-12-24 17:57:14 +00:00
parent 3beac715c7
commit 0e59178d77
8 changed files with 34 additions and 14 deletions

View File

@ -15,6 +15,8 @@ public:
virtual Object::Type GetType(void) { return Object::BODY; }
virtual void SetPosition(vector3d p) = 0;
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 void Render(const Frame* camFrame) = 0;
virtual void SetFrame(Frame* f) { m_frame = f; }

View File

@ -53,6 +53,11 @@ DynamicBody::~DynamicBody(void) {
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) {
dBodySetLinearVel(m_body, v.x, v.y, v.z);
}

View File

@ -11,7 +11,8 @@ public:
DynamicBody(void);
virtual ~DynamicBody(void);
virtual void SetRotation(const matrix4x4d& r);
void SetVelocity(vector3d v);
virtual void SetVelocity(vector3d v);
virtual vector3d GetVelocity(void);
void SetAngVelocity(vector3d v);
void SetMesh(ObjMesh* m);
virtual bool OnCollision(Body* b, Uint32 flags) { return true; }

View File

@ -23,6 +23,7 @@ void Frame::Init(Frame* parent, const char* label, unsigned int flags) {
m_flags = flags;
m_radius = 0;
m_pos = vector3d(0.0f);
m_vel = vector3d(0.0);
m_dSpaceID = dHashSpaceCreate(0);
if(m_parent) {
m_parent->m_children.push_back(this);

View File

@ -15,6 +15,9 @@ public:
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; }
void RemoveChild(Frame* f);
void AddGeom(dGeomID g) { dSpaceAdd(m_dSpaceID, g); }
@ -41,6 +44,8 @@ public:
private:
void Init(Frame* parent, const char* label, unsigned int flags);
vector3d m_pos;
/* We don't use this to move frame, rather, orbital rails determine velocity. */
vector3d m_vel;
std::string m_label;
double m_radius;
int m_flags;

View File

@ -318,7 +318,8 @@ void L3D::HyperspaceTo(StarSystem* dest) {
Space::Clear();
Space::BuildSystem();
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);
}

View File

@ -41,14 +41,18 @@ void Space::Clear(void) {
L3D::player->SetFrame(rootFrame);
}
void Space::MoveFramesOfReference(Frame* f) {
void Space::MoveOrbitingObjectFrames(Frame* f) {
if(f->sBody) {
/* Not too efficient. */
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->SetVelocity(vel);
}
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());
Frame* myframe;
if(sbody->parent) {
myframe = new Frame(f, sbody->name.c_str());
vector3d pos = sbody->orbit.CartesianPosAtTime(0);
myframe->SetPosition(pos);
myframe->SetRadius(10*sbody->GetRadius());
myframe->sBody = sbody;
b->SetFrame(myframe);
@ -94,6 +95,7 @@ just_make_child:
void Space::BuildSystem(void) {
GenBody(L3D::current_system->rootBody, rootFrame);
MoveOrbitingObjectFrames(rootFrame);
}
void Space::AddBody(Body* b) {
@ -115,6 +117,8 @@ 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());
Frame* new_frame = b->GetFrame()->m_parent;
if(new_frame) { /* Don't fall out of root frame. */
vector3d new_pos = b->GetPositionRelTo(new_frame);
@ -126,12 +130,13 @@ void Space::UpdateFramesOfReference(void) {
/* Entering into frames. */
for(std::list<Frame*>::iterator j = b->GetFrame()->m_children.begin();
j != b->GetFrame()->m_children.end(); ++j) {
Frame* kid = *j;
vector3d pos = b->GetFrame()->GetPosRelativeToOtherFrame(kid) + b->GetPosition();
if(kid->IsLocalPosInFrame(pos)) {
printf("%s enters frame %s\n", b->GetLabel().c_str(), kid->GetLabel());
Frame* child = *j;
vector3d pos = b->GetFrame()->GetPosRelativeToOtherFrame(child) + b->GetPosition();
if(child->IsLocalPosInFrame(pos)) {
printf("%s enters frame %s\n", b->GetLabel().c_str(), child->GetLabel());
b->SetPosition(pos);
b->SetFrame(kid);
b->SetFrame(child);
b->SetVelocity(b->GetVelocity() - child->GetVelocity());
break;
}
}
@ -240,7 +245,7 @@ void Space::TimeStep(float step) {
/* TODO: Does not need to be done this often. */
UpdateFramesOfReference();
MoveFramesOfReference(rootFrame);
MoveOrbitingObjectFrames(rootFrame);
for(bodiesIter_t i = bodies.begin(); i != bodies.end(); ++i) {
(*i)->TimeStepUpdate(step);

View File

@ -24,7 +24,7 @@ public:
typedef std::list<Body*>::iterator bodiesIter_t;
static Frame* rootFrame;
private:
static void MoveFramesOfReference(Frame* f);
static void MoveOrbitingObjectFrames(Frame* f);
static void UpdateFramesOfReference(void);
static void CollideFrame(Frame* f);
static void PruneCorpses(void);