static double calc_ivel(double dist, double vel, double acc) { bool inv = false; if (dist < 0) { dist = -dist; vel = -vel; inv = true; } double ivel = 0.9 * sqrt(vel*vel + 2.0 * acc * dist); // fudge hardly necessary double endvel = ivel - (acc * Pi::GetTimeStep()); if (float_is_zero_general(vel) && endvel <= 0.0) ivel = dist / Pi::GetTimeStep(); // last frame discrete correction else ivel = (ivel + endvel) * 0.5; // discrete overshoot correction // else ivel = endvel + 0.5*acc/PHYSICS_HZ; // unknown next timestep discrete overshoot correction return (inv) ? -ivel : ivel; }
void DynamicBody::UpdateInterpolatedTransform(double alpha) { // interpolating matrices like this is a sure sign of madness vector3d outPos = alpha*vector3d(m_orient[12], m_orient[13], m_orient[14]) + (1.0-alpha)*vector3d(m_oldOrient[12], m_oldOrient[13], m_oldOrient[14]); m_interpolatedTransform = m_oldOrient; { double len = m_oldAngDisplacement.Length() * double(alpha); if (! float_is_zero_general(len)) { vector3d rotAxis = m_oldAngDisplacement.Normalized(); matrix4x4d rotMatrix = matrix4x4d::RotateMatrix(len, rotAxis.x, rotAxis.y, rotAxis.z); m_interpolatedTransform = rotMatrix * m_interpolatedTransform; } } m_interpolatedTransform[12] = outPos.x; m_interpolatedTransform[13] = outPos.y; m_interpolatedTransform[14] = outPos.z; }
void SystemView::PutBody(SBody *b, vector3d offset) { if (b->type == SBody::TYPE_STARPORT_SURFACE) return; if (b->type != SBody::TYPE_GRAVPOINT) { glGetFloatv (GL_MODELVIEW_MATRIX, &s_invRot[0]); s_invRot[12] = s_invRot[13] = s_invRot[14] = 0; s_invRot = s_invRot.InverseOf(); glColor3f(1,1,1); glBegin(GL_TRIANGLE_FAN); double radius = b->GetRadius() * m_zoom; const vector3f offsetf(offset); for (float ang=0; ang<2.0f*M_PI; ang+=M_PI*0.05f) { vector3f p = offsetf + s_invRot * vector3f(radius*sin(ang), -radius*cos(ang), 0); glVertex3fv(&p.x); } glEnd(); PutLabel(b, offset); } if (b->children.size()) for(std::vector<SBody*>::iterator kid = b->children.begin(); kid != b->children.end(); ++kid) { if (float_is_zero_general((*kid)->orbit.semiMajorAxis)) continue; if ((*kid)->orbit.semiMajorAxis * m_zoom < ROUGH_SIZE_OF_TURD) { PutOrbit(*kid, offset); } // not using current time yet vector3d pos = (*kid)->orbit.OrbitalPosAtTime(m_time); pos *= double(m_zoom); //glTranslatef(pos.x, pos.y, pos.z); PutBody(*kid, offset + pos); } }
void Player::PollControls(const float timeStep) { static bool stickySpeedKey = false; if (Pi::game->GetTimeAccel() == Game::TIMEACCEL_PAUSED || Pi::player->IsDead() || GetFlightState() != FLYING) return; // if flying { ClearThrusterState(); SetGunState(0,0); SetGunState(1,0); vector3d wantAngVel(0.0); double angThrustSoftness = 50.0; // have to use this function. SDL mouse position event is bugged in windows int mouseMotion[2]; SDL_GetRelativeMouseState (mouseMotion+0, mouseMotion+1); // call to flush if (Pi::MouseButtonState(SDL_BUTTON_RIGHT)) { matrix4x4d rot; GetRotMatrix(rot); if (!m_mouseActive) { m_mouseDir = vector3d(-rot[8],-rot[9],-rot[10]); // in world space m_mouseX = m_mouseY = 0; m_mouseActive = true; } vector3d objDir = m_mouseDir * rot; const double radiansPerPixel = 0.002; m_mouseX += mouseMotion[0] * radiansPerPixel; double modx = clipmouse(objDir.x, m_mouseX); m_mouseX -= modx; const bool invertY = (Pi::IsMouseYInvert() ? !m_invertMouse : m_invertMouse); m_mouseY += mouseMotion[1] * radiansPerPixel * (invertY ? -1 : 1); double mody = clipmouse(objDir.y, m_mouseY); m_mouseY -= mody; if(!float_is_zero_general(modx) || !float_is_zero_general(mody)) { matrix4x4d mrot = matrix4x4d::RotateYMatrix(modx); mrot.RotateX(mody); m_mouseDir = (rot * (mrot * objDir)).Normalized(); } } else m_mouseActive = false; // disable all keyboard controls while the console is active if (!Pi::IsConsoleActive()) { if (m_flightControlState == CONTROL_FIXSPEED) { double oldSpeed = m_setSpeed; if (stickySpeedKey) { if (!(KeyBindings::increaseSpeed.IsActive() || KeyBindings::decreaseSpeed.IsActive())) { stickySpeedKey = false; } } if (!stickySpeedKey) { if (KeyBindings::increaseSpeed.IsActive()) m_setSpeed += std::max(fabs(m_setSpeed)*0.05, 1.0); if (KeyBindings::decreaseSpeed.IsActive()) m_setSpeed -= std::max(fabs(m_setSpeed)*0.05, 1.0); if ( ((oldSpeed < 0.0) && (m_setSpeed >= 0.0)) || ((oldSpeed > 0.0) && (m_setSpeed <= 0.0)) ) { // flipped from going forward to backwards. make the speed 'stick' at zero // until the player lets go of the key and presses it again stickySpeedKey = true; m_setSpeed = 0; } } } if (KeyBindings::thrustForward.IsActive()) SetThrusterState(2, -1.0); if (KeyBindings::thrustBackwards.IsActive()) SetThrusterState(2, 1.0); if (KeyBindings::thrustUp.IsActive()) SetThrusterState(1, 1.0); if (KeyBindings::thrustDown.IsActive()) SetThrusterState(1, -1.0); if (KeyBindings::thrustLeft.IsActive()) SetThrusterState(0, -1.0); if (KeyBindings::thrustRight.IsActive()) SetThrusterState(0, 1.0); if (KeyBindings::fireLaser.IsActive() || (Pi::MouseButtonState(SDL_BUTTON_LEFT) && Pi::MouseButtonState(SDL_BUTTON_RIGHT))) { SetGunState(Pi::worldView->GetActiveWeapon(), 1); } if (KeyBindings::yawLeft.IsActive()) wantAngVel.y += 1.0; if (KeyBindings::yawRight.IsActive()) wantAngVel.y += -1.0; if (KeyBindings::pitchDown.IsActive()) wantAngVel.x += -1.0; if (KeyBindings::pitchUp.IsActive()) wantAngVel.x += 1.0; if (KeyBindings::rollLeft.IsActive()) wantAngVel.z += 1.0; if (KeyBindings::rollRight.IsActive()) wantAngVel.z -= 1.0; if (KeyBindings::fastRotate.IsActive()) angThrustSoftness = 10.0; } vector3d changeVec; changeVec.x = KeyBindings::pitchAxis.GetValue(); changeVec.y = KeyBindings::yawAxis.GetValue(); changeVec.z = KeyBindings::rollAxis.GetValue(); // Deadzone if(changeVec.LengthSqr() < m_joystickDeadzone) changeVec = vector3d(0.0); changeVec *= 2.0; wantAngVel += changeVec; double invTimeAccelRate = 1.0 / Pi::game->GetTimeAccelRate(); for (int axis=0; axis<3; axis++) wantAngVel[axis] = Clamp(wantAngVel[axis], -invTimeAccelRate, invTimeAccelRate); if (m_mouseActive) AIFaceDirection(m_mouseDir); else AIModelCoordsMatchAngVel(wantAngVel, angThrustSoftness); } }