[Add] Centrifuagal and Coriolis effect in rotating frames.

This commit is contained in:
Rtch90 2018-08-22 21:47:39 +01:00
parent 3e14d9cd5a
commit 392705570c
9 changed files with 63 additions and 13 deletions

View File

@ -99,16 +99,32 @@ vector3d DynamicBody::GetPosition(void) const {
void DynamicBody::TimeStepUpdate(const float timeStep) { void DynamicBody::TimeStepUpdate(const float timeStep) {
if(m_enabled) { if(m_enabled) {
/* This is for rotating frames. It is reested. */
vector3d angRot = GetFrame()->GetAngVelocity();
{
double omega = angRot.Length();
if(omega) {
/* Centifugal force. */
vector3d perpend = vector3d::Cross(angRot, GetPosition());
perpend = vector3d::Normalize(Vector3d::Corss(perpend, angRot));
double R = vector3d::Dot(perpend, GetPosition());
double centrifugal = m_mass * omega * R;
m_force += centrifuagal * perpend;
/* Coriolis force. */
m_force += -2*m_mass*vector3d::Cross(angRot, GetVelocity());
}
}
m_oldOrient = m_orient; m_oldOrient = m_orient;
m_vel += timeStep * m_force * (1.0/m_mass); m_vel += timeStep * m_force * (1.0/m_mass);
m_angVel += timeStep * m_torque * (1.0 / m_angInertia); m_angVel += timeStep * m_torque * (1.0 / m_angInertia);
vector3d consideredAngVel = m_angVel - angRot;
vector3d pos = GetPosition(); vector3d pos = GetPosition();
/* Applying angular velocity :/ */ /* Applying angular velocity :/ */
{ {
double len = m_angVel.Length(); double len = consideredAngVel.Length();
if(len != 0) { if(len != 0) {
vector3d rotAxis = m_angVel * (1.0 / len); vector3d rotAxis = consideredAngVel * (1.0 / len);
matrix4x4d rotMatrix = matrix4x4d::RotateMatrix(len * timeStep, matrix4x4d rotMatrix = matrix4x4d::RotateMatrix(len * timeStep,
rotAxis.x, rotAxis.y, rotAxis.z); rotAxis.x, rotAxis.y, rotAxis.z);
m_orient = rotMatrix * m_orient; m_orient = rotMatrix * m_orient;

View File

@ -130,3 +130,20 @@ void Frame::RotateInTimestep(double step) {
m_orient = rotMatrix * m_orient; m_orient = rotMatrix * m_orient;
} }
/*
* For an object in a rotating frame, relative to non-rotating frames it
* must attain this velocity within rotating frame to be stationary.
*/
vector3d Frame::GetStasisVelocityAtPosition(const vector3d& pos) const {
const double omega = m_angVel.Length();
if(omega) {
vector3d perpend = vector3d::Cross(m_angVel, pos);
perpend = vector3d::Normalize(vector3d::Cross(perpend, m_angVel));
double R = vector3d::Dot(perpend, pos);
perpend *= R;
return -vector3d::Cross(m_angVel, perpend);
} else {
return vector3d(0,0,0);
}
}

View File

@ -28,6 +28,7 @@ public:
vector3d GetVelocity(void) const { return m_vel; } vector3d GetVelocity(void) const { return m_vel; }
void SetAngVelocity(const vector3d& angvel) { m_angVel = angvel; } void SetAngVelocity(const vector3d& angvel) { m_angVel = angvel; }
vector3d GetAngVelocity(void) const { return m_angVel; } vector3d GetAngVelocity(void) const { return m_angVel; }
vector3d GetStasisVelocityAtPosition(const vector3d& pos) const;
const matrix4x4d& GetOrientation(void) const { return m_orient; } const matrix4x4d& GetOrientation(void) const { return m_orient; }
void SetOrientation(const matrix4x4d& m) { m_orient = m; } void SetOrientation(const matrix4x4d& m) { m_orient = m; }
void SetRadius(double radius) { m_radius = radius; } void SetRadius(double radius) { m_radius = radius; }

View File

@ -581,7 +581,7 @@ void TextureFontFace::LayoutString(const char* _str, float maxWidth) {
glPushMatrix(); glPushMatrix();
for(int i = 0; i < num; i++) { for(int i = 0; i < num; i++) {
word_t word = words.front(); word_t word = words.front();
if(word.word) RenderString(word.word); if(word.word) RenderMarkup(word.word);
glTranslatef(word.advx + _spaceWidth 0, 0); glTranslatef(word.advx + _spaceWidth 0, 0);
words.pop_front(); words.pop_front();
} }

View File

@ -195,11 +195,14 @@ void L3D::HandleEvents(void) {
matrix4x4d m; L3D::player->GetRotMatrix(m); matrix4x4d m; L3D::player->GetRotMatrix(m);
vector3d dir = m*vector3d(0,0,-1); vector3d dir = m*vector3d(0,0,-1);
if(KeyState(SDLK_LSHIFT)) { if(KeyState(SDLK_LSHIFT)) {
Frame* rotFrame = new Frame(L3D::player->GetFrame(), "Station rot frame");
rotFrame->SetRadius(3000.0); //(1.1*sbody->GetRadius());
rotFrame->SetPosition(L3D::player->GetPosition()+5000.0*dir);
rotFrame->SetAngVelocity(vector3d(0, 2*M_PI/10,0));
SpaceStation* station = new SpaceStation(SpaceStation::JJHOOP); SpaceStation* station = new SpaceStation(SpaceStation::JJHOOP);
station->SetLabel("Poemi-chan's Folly"); station->SetLabel("Poemi-chan's Folly");
station->SetFrame(L3D::player->GetFrame()); station->SetFrame(rotFrame);
station->SetRotMatrix(matrix4x4d::RotateZMatrix(M_PI)); station->SetRotMatrix(matrix4x4d::RotateZMatrix(M_PI));
station->SetPosition(L3D::player->GetPosition()+5000.0*dir);
Space::AddBody(station); Space::AddBody(station);
} else { } else {
Ship* ship = new Ship(ShipType::LADYBIRD); Ship* ship = new Ship(ShipType::LADYBIRD);

View File

@ -226,7 +226,9 @@ void Player::DrawHUD(const Frame* cam_frame) {
/* Direction indicator. */ /* Direction indicator. */
const float sz = HUD_CROSSHAIR_SIZE; const float sz = HUD_CROSSHAIR_SIZE;
const vector3d vel = GetVelocity(); vector3d vel = GetVelocity();
vel -= GetFrame()->GetStasisVelocityAtPosition(GetPosition());
vector3d loc_v = cam_frame->GetOrientation().InverseOf() * vel; vector3d loc_v = cam_frame->GetOrientation().InverseOf() * vel;
if(loc_v.z < 0) { if(loc_v.z < 0) {
GLdouble pos[3]; GLdouble pos[3];

View File

@ -77,6 +77,7 @@ void Ship::AIModelCoordsMatchSpeedRelTo(const vector3d v, const Ship* other) {
AIAccelToModelRelativeVelocity(relToVel); AIAccelToModelRelativeVelocity(relToVel);
} }
#include "frame.h"
/* /*
* Try to reach this model-relative velocity. * Try to reach this model-relative velocity.
* (0,0,-100) would mean going 100m/s forward. * (0,0,-100) would mean going 100m/s forward.
@ -84,7 +85,16 @@ void Ship::AIModelCoordsMatchSpeedRelTo(const vector3d v, const Ship* other) {
void Ship::AIAccelToModelRelativeVelocity(const vector3d v) { void Ship::AIAccelToModelRelativeVelocity(const vector3d v) {
const ShipType& stype = GetShipType(); const ShipType& stype = GetShipType();
vector3d relVel = GetVelocity(); // - enemy->GetVelocity(); /*
* Ok. For rotating frames linked to space stations we want to set speed
* relative to non-rotating frame (so we apply Frame::GetStasisVelocityAtPosition.
* For rotating frames linked to planets we want to set velocity relative to
* surface, so we do not apply Frame::GetStasisVelocityAtPosition.
*/
vector3d relVel = GetVelocity();
if(!GetFrame()->m_astroBody) {
relVel -= GetFrame()->GetStasisVelocityAtPosition(GetPosition());
}
matrix4x4d m; GetRotMatrix(m); matrix4x4d m; GetRotMatrix(m);
relVel = m.InverseOf() * relVel; relVel = m.InverseOf() * relVel;

View File

@ -87,7 +87,7 @@ ShipCpanel::ShipCpanel(void) : Gui::Fixed(Gui::Screen::GetWidth(), 64) {
Add(m_clock, 2, 1); Add(m_clock, 2, 1);
tempMsg = new Gui::Label(""); tempMsg = new Gui::Label("");
Add(tempMsg, 170, 44); Add(tempMsg, 170, 4);
} }
void ShipCpanel::SetTemporaryMessage(Body* const sender, std::string msg) { void ShipCpanel::SetTemporaryMessage(Body* const sender, std::string msg) {

View File

@ -235,12 +235,11 @@ void Space::UpdateFramesOfReference(void) {
b->GetRotMatrix(rot); b->GetRotMatrix(rot);
b->SetRotMatrix(m * rot); b->SetRotMatrix(m * rot);
b->SetVelocity(oldFrameVel + m_ApplyRotationOnly(b->GetVelocity() -
b->GetFrame()->GetStasisVelocityAtPosition(b->GetPosition())));
b->SetFrame(new_frame); b->SetFrame(new_frame);
b->SetPosition(new_pos); b->SetPosition(new_pos);
/* Get rid of transforms. */
m.ClearToRotOnly();
b->SetVelocity(m*b->GetVelocity() + oldFrameVel);
} else { } else {
b->SetVelocity(b->GetVelocity() + oldFrameVel); b->SetVelocity(b->GetVelocity() + oldFrameVel);
} }
@ -264,7 +263,9 @@ void Space::UpdateFramesOfReference(void) {
/* Get rid of transforms. */ /* Get rid of transforms. */
m.ClearToRotOnly(); m.ClearToRotOnly();
b->SetVelocity(m*b->GetVelocity()-child->GetVelocity()); b->SetVelocity(m*b->GetVelocity()
- kid->GetVelocity()
+ kid->GetStasisVelocityAtPosition(pos));
break; break;
} }
} }