void XMLHelper::fillElementFromQuaternion(TiXmlElement& elem, const Ogre::Quaternion& quaternion) { //split the quaternion into an axis and a degree (our format allows us to store the angle element as a radian too, but I prefer degrees) Ogre::Degree degrees; Ogre::Vector3 axis; quaternion.ToAngleAxis(degrees, axis); fillElementFromVector3(elem, axis); elem.SetDoubleAttribute("degrees", degrees.valueDegrees()); }
void fix_gta_coord(Ogre::Quaternion& quat) { swap(quat.y, quat.z); Ogre::Radian angle; Ogre::Vector3 axis; quat.ToAngleAxis(angle, axis); //swap(axis.y, axis.z); axis = Ogre::Quaternion(Ogre::Degree(-90), Ogre::Vector3::UNIT_X) * axis; quat.FromAngleAxis(angle, axis); }
Ogre::Degree Entity::GetRotation() const { assert( m_model_root_node ); Ogre::Quaternion q = m_model_root_node->getOrientation(); Ogre::Degree temp; Ogre::Vector3 vec = Ogre::Vector3::UNIT_Z; q.ToAngleAxis( temp, vec ); return temp; }
gkRadian gkSteering::getAngle(const gkVector3& from, const gkVector3& to) { Ogre::Vector3 from1 = getProjectionOnPlane(from, m_steerAxis); Ogre::Vector3 to1 = getProjectionOnPlane(to, m_steerAxis); Ogre::Quaternion q = from1.getRotationTo(to1); Ogre::Radian angle; Ogre::Vector3 rAxis; q.ToAngleAxis(angle, rAxis); rAxis = angle.valueRadians() * (rAxis * m_steerAxis); angle = rAxis.x + rAxis.y + rAxis.z; return angle; }
void QuaternionAdapter::updateGui(const Ogre::Quaternion& quaternion) { mSelfUpdate = true; if (&quaternion) { Ogre::Vector3 axis; Ogre::Degree angle; quaternion.ToAngleAxis( angle, axis); mVectorAdapter.updateGui(axis); if (mDegreeWindow) { mDegreeWindow->setText(Ogre::StringConverter::toString(angle.valueDegrees())); } } else { mVectorAdapter.updateGui(Ogre::Vector3::ZERO); if (mDegreeWindow) { mDegreeWindow->setText(""); } } mSelfUpdate = false; }
void DefaultDrone::show(){ Parent::show(); float f = timeAlive(); Coordinator::Transform base; if (mTransformCoordinator){ base = mTransformCoordinator->getValue(timeAlive()); }else{ base.mPos = Ogre::Vector3::ZERO; base.mRot = Ogre::Quaternion::IDENTITY; base.mScl = Ogre::Vector3::UNIT_SCALE; } getNode()->setPosition(base.mPos); getNode()->setOrientation(base.mRot); Ogre::TransformKeyFrame key(NULL, 0); key = dynamic_cast<DefaultDroneDBE*>(mDbe)->getKeyFrame(f); Ogre::Vector3 v = key.getTranslate(); v=v*base.mScl; getNode()->translate(v); Ogre::Radian angle; Ogre::Vector3 axis; Ogre::Quaternion r = key.getRotation(); if ( base.mScl.x == -1){ r.ToAngleAxis(angle, axis); axis.x *= -1; angle = (Ogre::Radian)0-angle; r.FromAngleAxis(angle, axis); } mSceneNode->rotate(r); /*Ogre::Node* n = getNode(); n->setPosition(mDelta+mTransformCoordinator->getValue(timeAlive()).mPos);*/ }
void PropertiesWindow::addPropertyQuaternion(const Property& prop, CEGUI::MultiColumnList* table, const CeGuiString& key) { // Check column count // if count = 3 | MainTable // if count = 2 | Array table int colCount = table->getColumnCount(); int rowCount = table->getRowCount(); Ogre::Quaternion quat = prop.toQuaternion(); Ogre::Degree angle; Ogre::Vector3 axis; quat.ToAngleAxis( angle, axis ); char buf_angle [50]; sprintf(buf_angle, "%1.2f", angle.valueDegrees()); char buf_v1 [50]; sprintf(buf_v1, "%1.2f", axis.x); char buf_v2 [50]; sprintf(buf_v2, "%1.2f", axis.y); char buf_v3 [50]; sprintf(buf_v3, "%1.2f", axis.z); // Table has the three columns Key, Type, Value if ( colCount == 3 ) { // Add row for the first IntTriple value table->addRow(rowCount); table->setItem(new ListboxTextItem(key + " "), 0, rowCount); table->setItem(new ListboxTextItem("Quaternion "), 1, rowCount); table->setItem(new ListboxTextItem("Axis: ( " + CEGUI::String(buf_v1) + ", " + CEGUI::String(buf_v2) + ", " + CEGUI::String(buf_v3) + " )"), 2, rowCount); // Add second for the second IntTriple value table->addRow(rowCount + 1); table->setItem(new ListboxTextItem("Degree: " + CEGUI::String(buf_angle)), 2, rowCount + 1); } // Table has the two columns Type, Value else if ( colCount == 2 ) { table->addRow(rowCount); table->setItem(new ListboxTextItem("Quaternion "), 0, rowCount); table->setItem(new ListboxTextItem("Axis: ( " + CEGUI::String(buf_v1) + ", " + CEGUI::String(buf_v2) + ", " + CEGUI::String(buf_v3) + " )"), 2, rowCount); // Add second for the second IntTriple value table->addRow(rowCount + 1); table->setItem(new ListboxTextItem("Degree " + CEGUI::String(buf_angle)), 2, rowCount + 1); } }
void game_tick( unsigned int now, GameState & gs, SharedRenderState & rs ) { // get the latest mouse buttons state and orientation zstr_send( gs.zmq_input_req, "mouse_state" ); char * mouse_state = zstr_recv( gs.zmq_input_req ); Uint8 buttons; Ogre::Quaternion orientation; parse_mouse_state( mouse_state, orientation, buttons ); free( mouse_state ); // at 16 ms tick and the last 10 orientations buffered, that's 150ms worth of orientation history gs.orientation_history[ gs.orientation_index ].t = now; gs.orientation_history[ gs.orientation_index ].o = orientation; gs.orientation_index = ( gs.orientation_index + 1 ) % ORIENTATION_LOG; // oldest orientation unsigned int q1_index = gs.orientation_index; // NOTE: the problem with using the successive orientations to infer an angular speed, // is that if the orientation is changing fast enough, this code will 'flip' the speed around // e.g. this doesn't work, need to use the XY mouse data to track angular speed // NOTE: uncomment the following line to use the full history, notice the 'flip' happens at much lower speed q1_index = ( q1_index + ORIENTATION_LOG - 2 ) % ORIENTATION_LOG; Ogre::Quaternion q1 = gs.orientation_history[ q1_index ].o; Uint32 q1_t = gs.orientation_history[ q1_index ].t; Ogre::Quaternion omega = 2.0f * ( orientation - q1 ) * q1.UnitInverse() * ( 1000.0f / (float)( now - q1_t ) ); omega.ToAngleAxis( gs.smoothed_angular_velocity, gs.smoothed_angular ); // printf( "%f %f %f - %f\n", gs.smoothed_angular.x, gs.smoothed_angular.y, gs.smoothed_angular.z, gs.smoothed_angular_velocity.valueDegrees() ); rs.smoothed_angular = gs.smoothed_angular; if ( ( buttons & SDL_BUTTON( 1 ) ) != 0 ) { if ( !gs.mouse_pressed ) { gs.mouse_pressed = true; // changing the control scheme: the player is now driving the orientation of the head directly with the mouse // tell the input logic to reset the orientation to match the current orientation of the head zstr_sendf( gs.zmq_input_req, "mouse_reset %f %f %f %f", rs.orientation.w, rs.orientation.x, rs.orientation.y, rs.orientation.z ); zstr_recv( gs.zmq_input_req ); // wait for ack from input // IF RENDER TICK HAPPENS HERE: render will not know that it should grab the orientation directly from the mouse, // but the orientation coming from game should still be ok? zstr_sendf( gs.zmq_render_socket, "# %s", "1" ); // IF RENDER TICK HAPPENS HERE (before a new gamestate): // the now reset input orientation will combine with the old game state, that's bad } } else { if ( gs.mouse_pressed ) { gs.mouse_pressed = false; // changing the control scheme: the head will free spin and slow down for a bit, then it will resume bouncing around // the player looses mouse control, the game grabs latest orientation and angular velocity // the input thread was authoritative on orientation until now, so accept that as our starting orientation rs.orientation = orientation; gs.rotation_speed = gs.smoothed_angular_velocity; gs.rotation = gs.smoothed_angular; zstr_sendf( gs.zmq_render_socket, "# %s", "0" ); // IF RENDER TICK HAPPENS HERE (before a new gamestate): render will pull the head orientation from the game state rather than input, but game state won't have the fixed orientation yet } } if ( rs.position.x > gs.bounce || rs.position.x < -gs.bounce ) { gs.direction.x *= -1.0f; } if ( rs.position.y > gs.bounce || rs.position.y < -gs.bounce ) { gs.direction.y *= -1.0f; } Ogre::Vector2 delta = gs.speed * ( (float)GAME_DELAY / 1000.0f ) * gs.direction; if ( !gs.mouse_pressed ) { if ( gs.rotation_speed.valueDegrees() == 0.0f ) { rs.position.x += delta.x; rs.position.y += delta.y; } // printf( "game tick position: %f %f\n", rs.position.x, rs.position.y ); // update the orientation of the head on a free roll // gs.rotation is unit length // gs.rotation_speed is in degrees/seconds // NOTE: sinf/cosf really needed there? gs.rotation_speed *= 0.97f; if ( gs.rotation_speed.valueDegrees() < 20.f ) { gs.rotation_speed = 0.0f; } float factor = sinf( 0.5f * Ogre::Degree( gs.rotation_speed * GAME_TICK_FLOAT ).valueRadians() ); Ogre::Quaternion rotation_tick( cosf( 0.5f * Ogre::Degree( gs.rotation_speed * GAME_TICK_FLOAT ).valueRadians() ), factor * gs.rotation.x, factor * gs.rotation.y, factor * gs.rotation.z ); rs.orientation = rotation_tick * rs.orientation; } else { // keep updating the orientation in the render state, even while the render thread is ignoring it: // when the game thread resumes control of the head orientation, it will interpolate from one of these states, // so we keep updating the orientation to avoid a short glitch at the discontinuity rs.orientation = orientation; } }
void DefaultDrone::updateAlive(double timeDelta, double parentTime){ float f = timeAlive(); if (!mDbe->isStatic()){ Coordinator::Transform base; if (mTransformCoordinator){ base = mTransformCoordinator->getValue(timeAlive()); }else{ base = dynamic_cast<Coordinator::TransformCoordinator*>(Coordinator::CoordinatorFactory::getSingleton()->get("static_transform:0,0,0"))->getValue(0); } getNode()->setPosition(base.mPos); getNode()->setOrientation(base.mRot); Ogre::TransformKeyFrame key(NULL, 0); key = dynamic_cast<DefaultDroneDBE*>(mDbe)->getKeyFrame(f); Ogre::Vector3 v = key.getTranslate(); v=v*base.mScl; getNode()->translate(v); Ogre::Radian angle; Ogre::Vector3 axis; Ogre::Quaternion r = key.getRotation(); if ( base.mScl.x == -1){ r.ToAngleAxis(angle, axis); axis.x *= -1; angle = (Ogre::Radian)0-angle; r.FromAngleAxis(angle, axis); } mSceneNode->rotate(r); } { list<GoAnim::GoAnim*>::iterator it, begin, end; begin = mGoAnim.begin(); end = mGoAnim.end(); for (it=begin;it!=end;it++){ (*it)->update(timeDelta, parentTime); } }{ list<FIRING_TIME>::iterator it, begin, end; begin = (dynamic_cast<DefaultDroneDBE*>(mDbe)->getFiringTime())->begin(); end = (dynamic_cast<DefaultDroneDBE*>(mDbe)->getFiringTime())->end(); for (it=begin;it!=end;it++){ if (mLevelSegment->isTimeInFrame(getTimeOn()+(*it).time)){ //Util::Log("IsTimeInFrame:"+ts(getTimeOn()+(*it).time)); if ((*it).firingOption == FIRING_START){ fire((*it).mount, (*it).inertia); }else{ ceaseFire((*it).mount); } } } }{ /*list<DRONE_TIMED_ANIM>::iterator it, begin, end; begin = (dynamic_cast<DefaultDroneDBE*>(mDbe)->getTimedAnim())->begin(); end = (dynamic_cast<DefaultDroneDBE*>(mDbe)->getTimedAnim())->end(); for (it=begin;it!=end;it++){ if (mLevelSegment->isTimeInFrame(getTimeOn()+(*it).time)){ Util::Log("IsTimeInFrame:"+ts(getTimeOn()+(*it).time)); Ogre::AnimationState* as; as = mEntity->getAnimationState( (*it).label ); as->setEnabled(true); as->setLoop((*it).loop); mAnim.push_back(as); //fire((*it).type); } }*/ }{ list<Ogre::AnimationState*>::iterator it, begin, end; begin = mAnim.begin(); end = mAnim.end(); for (it=begin;it!=end;it++){ (*it)->addTime(timeDelta);//Level::getSingleton()->getTimeDelta()); } } }
void OGRERendererRacer::update() { mpVehicle = mpApp->mRacer; const cml::vector3d& pos = mpVehicle->mPos; mVehicleNode->setPosition(pos[0], pos[1], pos[2]); Ogre::Quaternion q; const quat& orientation = mpVehicle->getOrientation(); q.w = orientation.as_vector()[0]; q.x = orientation.as_vector()[1]; q.y = orientation.as_vector()[2]; q.z = orientation.as_vector()[3]; if (q != mOrientation) { Ogre::Quaternion transition = q * mOrientation.Inverse(); Ogre::Radian a; Ogre::Vector3 v; transition.ToAngleAxis(a, v); if (a.valueDegrees() > 0.1) { Ogre::Quaternion t2; // TODO 3: Make rotation speed configurable t2.FromAngleAxis(a * 0.05, v); mOrientation = t2 * mOrientation; } else { mOrientation = q; } } //################# BEGIN Construct Sideward thrust roll quaternion ################ // cml::vector3f velDirSidewardComponent = cml::dot(mpVehicle->mDirLeft, mpVehicle->mVelocity) * mpVehicle->mDirLeft; if (mpVehicle->mAddThrustLeft || mpVehicle->mAddThrustRight) { mRollAngle = -mpVehicle->mThrustSideward * 500; } else { mRollAngle *= 0.98; } float dot = cml::dot(mpVehicle->mDirLeft, mpVehicle->mVelocity); mRollAngle = -dot * 50; Ogre::Quaternion qSidewardThrustRoll(Ogre::Degree(mRollAngle), Ogre::Vector3(0, 0, -1)); cml::vector3f g = mpVehicle->getGravity(); cml::vector3f velDirGravityComponent = cml::dot(g, mpVehicle->mVelocity) * g; dot = cml::dot(velDirGravityComponent, g); if (velDirGravityComponent.length() > 0.000001) { mPitchAngle = -cml::sign(dot) * velDirGravityComponent.length() * 500000; } else { if (mpVehicle->mAddThrustForward && mPitchAngle > -7) { mPitchAngle -= 0.1; } else { mPitchAngle *= 0.95; } } Ogre::Quaternion qForwardThrustPitch(Ogre::Degree(mPitchAngle), Ogre::Vector3(1, 0, 0)); //################# END Construct Sideward thrust roll quaternion ################ bool mSidewardThrustRollCamera = false; if (mSidewardThrustRollCamera) { // Roll both vehicle and camera: mVehicleNode->setOrientation(q * qSidewardThrustRoll * qForwardThrustPitch); } else { // Roll only the vehicle, not the camera: mVehicleNode->setOrientation(mOrientation); mVehicleMeshNode->setOrientation(qSidewardThrustRoll * qForwardThrustPitch); } //############# BEGIN Update engine particle emitters #################### // TODO 1: Reimplement bool emit = (mpVehicle->mGameState == 0) && mpVehicle->mThrustForward > 0; mEngineFlameParticleSystem->setEmitting(emit); mEngineSmokeParticleSystem->setEmitting(emit); Ogre::ParticleEmitter* emitter = mEngineFlameParticleSystem->getEmitter(0); emitter->setParticleVelocity(mpVehicle->mThrustForward * 6000); emitter->setEmissionRate(mpVehicle->mThrustForward * 10000); emitter = mEngineSmokeParticleSystem->getEmitter(0); emitter->setEmissionRate(mpVehicle->mThrustForward * 7000); //############# END Update engine particle emitters #################### }