[Add] Centrifuagal and Coriolis effect in rotating frames.
This commit is contained in:
parent
3e14d9cd5a
commit
392705570c
@ -99,16 +99,32 @@ vector3d DynamicBody::GetPosition(void) const {
|
||||
|
||||
void DynamicBody::TimeStepUpdate(const float timeStep) {
|
||||
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_vel += timeStep * m_force * (1.0/m_mass);
|
||||
m_angVel += timeStep * m_torque * (1.0 / m_angInertia);
|
||||
vector3d consideredAngVel = m_angVel - angRot;
|
||||
|
||||
vector3d pos = GetPosition();
|
||||
/* Applying angular velocity :/ */
|
||||
{
|
||||
double len = m_angVel.Length();
|
||||
double len = consideredAngVel.Length();
|
||||
if(len != 0) {
|
||||
vector3d rotAxis = m_angVel * (1.0 / len);
|
||||
vector3d rotAxis = consideredAngVel * (1.0 / len);
|
||||
matrix4x4d rotMatrix = matrix4x4d::RotateMatrix(len * timeStep,
|
||||
rotAxis.x, rotAxis.y, rotAxis.z);
|
||||
m_orient = rotMatrix * m_orient;
|
||||
|
@ -130,3 +130,20 @@ void Frame::RotateInTimestep(double step) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,7 @@ public:
|
||||
vector3d GetVelocity(void) const { return m_vel; }
|
||||
void SetAngVelocity(const vector3d& angvel) { m_angVel = angvel; }
|
||||
vector3d GetAngVelocity(void) const { return m_angVel; }
|
||||
vector3d GetStasisVelocityAtPosition(const vector3d& pos) const;
|
||||
const matrix4x4d& GetOrientation(void) const { return m_orient; }
|
||||
void SetOrientation(const matrix4x4d& m) { m_orient = m; }
|
||||
void SetRadius(double radius) { m_radius = radius; }
|
||||
|
@ -581,7 +581,7 @@ void TextureFontFace::LayoutString(const char* _str, float maxWidth) {
|
||||
glPushMatrix();
|
||||
for(int i = 0; i < num; i++) {
|
||||
word_t word = words.front();
|
||||
if(word.word) RenderString(word.word);
|
||||
if(word.word) RenderMarkup(word.word);
|
||||
glTranslatef(word.advx + _spaceWidth 0, 0);
|
||||
words.pop_front();
|
||||
}
|
||||
|
@ -195,11 +195,14 @@ void L3D::HandleEvents(void) {
|
||||
matrix4x4d m; L3D::player->GetRotMatrix(m);
|
||||
vector3d dir = m*vector3d(0,0,-1);
|
||||
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);
|
||||
station->SetLabel("Poemi-chan's Folly");
|
||||
station->SetFrame(L3D::player->GetFrame());
|
||||
station->SetFrame(rotFrame);
|
||||
station->SetRotMatrix(matrix4x4d::RotateZMatrix(M_PI));
|
||||
station->SetPosition(L3D::player->GetPosition()+5000.0*dir);
|
||||
Space::AddBody(station);
|
||||
} else {
|
||||
Ship* ship = new Ship(ShipType::LADYBIRD);
|
||||
|
@ -226,7 +226,9 @@ void Player::DrawHUD(const Frame* cam_frame) {
|
||||
|
||||
/* Direction indicator. */
|
||||
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;
|
||||
if(loc_v.z < 0) {
|
||||
GLdouble pos[3];
|
||||
|
@ -77,6 +77,7 @@ void Ship::AIModelCoordsMatchSpeedRelTo(const vector3d v, const Ship* other) {
|
||||
AIAccelToModelRelativeVelocity(relToVel);
|
||||
}
|
||||
|
||||
#include "frame.h"
|
||||
/*
|
||||
* Try to reach this model-relative velocity.
|
||||
* (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) {
|
||||
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);
|
||||
relVel = m.InverseOf() * relVel;
|
||||
|
||||
|
@ -87,7 +87,7 @@ ShipCpanel::ShipCpanel(void) : Gui::Fixed(Gui::Screen::GetWidth(), 64) {
|
||||
Add(m_clock, 2, 1);
|
||||
|
||||
tempMsg = new Gui::Label("");
|
||||
Add(tempMsg, 170, 44);
|
||||
Add(tempMsg, 170, 4);
|
||||
}
|
||||
|
||||
void ShipCpanel::SetTemporaryMessage(Body* const sender, std::string msg) {
|
||||
|
@ -235,12 +235,11 @@ void Space::UpdateFramesOfReference(void) {
|
||||
b->GetRotMatrix(rot);
|
||||
b->SetRotMatrix(m * rot);
|
||||
|
||||
b->SetVelocity(oldFrameVel + m_ApplyRotationOnly(b->GetVelocity() -
|
||||
b->GetFrame()->GetStasisVelocityAtPosition(b->GetPosition())));
|
||||
|
||||
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);
|
||||
}
|
||||
@ -264,7 +263,9 @@ void Space::UpdateFramesOfReference(void) {
|
||||
|
||||
/* Get rid of transforms. */
|
||||
m.ClearToRotOnly();
|
||||
b->SetVelocity(m*b->GetVelocity()-child->GetVelocity());
|
||||
b->SetVelocity(m*b->GetVelocity()
|
||||
- kid->GetVelocity()
|
||||
+ kid->GetStasisVelocityAtPosition(pos));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user