Esempio n. 1
0
void SkyManager::update(float duration)
{
    if (!mEnabled) return;
    const MWWorld::Fallback* fallback=MWBase::Environment::get().getWorld()->getFallback();

    if (!mParticle.isNull())
    {
        for (unsigned int i=0; i<mParticle->mControllers.size(); ++i)
            mParticle->mControllers[i].update();
    }

    updateRain(duration);

    // UV Scroll the clouds
    mCloudAnimationTimer += duration * mCloudSpeed;
    sh::Factory::getInstance().setSharedParameter ("cloudAnimationTimer",
        sh::makeProperty<sh::FloatValue>(new sh::FloatValue(mCloudAnimationTimer)));

    /// \todo improve this
    mMasser->setPhase( static_cast<Moon::Phase>( (int) ((mDay % 32)/4.f)) );
    mSecunda->setPhase ( static_cast<Moon::Phase>( (int) ((mDay % 32)/4.f)) );

    mSecunda->setColour ( mMoonRed ? fallback->getFallbackColour("Moons_Script_Color") : ColourValue(1,1,1,1));
    mMasser->setColour (ColourValue(1,1,1,1));

    if (mSunEnabled)
    {
        // take 1/10 sec for fading the glare effect from invisible to full
        if (mGlareFade > mGlare)
        {
            mGlareFade -= duration*10;
            if (mGlareFade < mGlare) mGlareFade = mGlare;
        }
        else if (mGlareFade < mGlare)
        {
            mGlareFade += duration*10;
            if (mGlareFade > mGlare) mGlareFade = mGlare;
        }

        // increase the strength of the sun glare effect depending
        // on how directly the player is looking at the sun
        Vector3 sun = mSunGlare->getPosition();
        Vector3 cam = mCamera->getRealDirection();
        const Degree angle = sun.angleBetween( cam );
        float val = 1- (angle.valueDegrees() / 180.f);
        val = (val*val*val*val)*6;
        mSunGlare->setSize(val * mGlareFade);
    }

    mSunGlare->setVisible(mSunEnabled);
    mSun->setVisible(mSunEnabled);
    mMasser->setVisible(mMasserEnabled);
    mSecunda->setVisible(mSecundaEnabled);

    // rotate the stars by 360 degrees every 4 days
    mAtmosphereNight->roll(Degree(MWBase::Environment::get().getWorld()->getTimeScaleFactor()*duration*360 / (3600*96.f)));
}
Esempio n. 2
0
	Degree wrapAngle(Degree angle)
	{
		if (angle.valueDegrees() < -360.0f)
			angle += Degree(360.0f);

		if (angle.valueDegrees() > 360.0f)
			angle -= Degree(360.0f);

		return angle;
	}
Esempio n. 3
0
void SkyManager::update(float duration)
{
    if (!mEnabled) return;

    mCamera->getParentSceneNode ()->needUpdate ();
    mRootNode->setPosition(mCamera->getDerivedPosition());

    // UV Scroll the clouds
    mCloudAnimationTimer += duration * mCloudSpeed * (MWBase::Environment::get().getWorld()->getTimeScaleFactor()/30.f);
    sh::Factory::getInstance().setSharedParameter ("cloudAnimationTimer",
        sh::makeProperty<sh::FloatValue>(new sh::FloatValue(mCloudAnimationTimer)));

    /// \todo improve this
    mMasser->setPhase( static_cast<Moon::Phase>( (int) ((mDay % 32)/4.f)) );
    mSecunda->setPhase ( static_cast<Moon::Phase>( (int) ((mDay % 32)/4.f)) );

    mSecunda->setColour ( mMoonRed ? ColourValue(1.0, 0.0784, 0.0784) : ColourValue(1,1,1,1));
    mMasser->setColour (ColourValue(1,1,1,1));

    if (mSunEnabled)
    {
        // take 1/10 sec for fading the glare effect from invisible to full
        if (mGlareFade > mGlare)
        {
            mGlareFade -= duration*10;
            if (mGlareFade < mGlare) mGlareFade = mGlare;
        }
        else if (mGlareFade < mGlare)
        {
            mGlareFade += duration*10;
            if (mGlareFade > mGlare) mGlareFade = mGlare;
        }

        // increase the strength of the sun glare effect depending
        // on how directly the player is looking at the sun
        Vector3 sun = mSunGlare->getPosition();
        sun = Vector3(sun.x, sun.z, -sun.y);
        Vector3 cam = mCamera->getRealDirection();
        const Degree angle = sun.angleBetween( cam );
        float val = 1- (angle.valueDegrees() / 180.f);
        val = (val*val*val*val)*2;

        mSunGlare->setSize(val * mGlareFade);
    }

    mSunGlare->setVisible(mSunEnabled);
    mSun->setVisible(mSunEnabled);
    mMasser->setVisible(mMasserEnabled);
    mSecunda->setVisible(mSecundaEnabled);

    // rotate the stars by 360 degrees every 4 days
    mAtmosphereNight->roll(Degree(MWBase::Environment::get().getWorld()->getTimeScaleFactor()*duration*360 / (3600*96.f)));
}
Esempio n. 4
0
void SkyManager::update(float duration)
{
    if (!mEnabled) return;

    // UV Scroll the clouds
    mCloudMaterial->getTechnique(0)->getPass(0)->getFragmentProgramParameters()->setNamedConstantFromTime("time", MWBase::Environment::get().getWorld()->getTimeScaleFactor()/30.f);

    /// \todo improve this
    mMasser->setPhase( static_cast<Moon::Phase>( (int) ((mDay % 32)/4.f)) );
    mSecunda->setPhase ( static_cast<Moon::Phase>( (int) ((mDay % 32)/4.f)) );


    if (mSunEnabled)
    {
        // take 1/5 sec for fading the glare effect from invisible to full
        if (mGlareFade > mGlare)
        {
            mGlareFade -= duration*5;
            if (mGlareFade < mGlare) mGlareFade = mGlare;
        }
        else if (mGlareFade < mGlare)
        {
            mGlareFade += duration*5;
            if (mGlareFade > mGlare) mGlareFade = mGlare;
        }

        // increase the strength of the sun glare effect depending
        // on how directly the player is looking at the sun
        Vector3 sun = mSunGlare->getPosition();
        sun = Vector3(sun.x, sun.z, -sun.y);
        Vector3 cam = mCamera->getRealDirection();
        const Degree angle = sun.angleBetween( cam );
        float val = 1- (angle.valueDegrees() / 180.f);
        val = (val*val*val*val)*2;

        mSunGlare->setSize(val * mGlareFade);
    }

    mSunGlare->setVisible(mSunEnabled);
    mSun->setVisible(mSunEnabled);
    mMasser->setVisible(mMasserEnabled);
    mSecunda->setVisible(mSecundaEnabled);

    // rotate the stars by 360 degrees every 4 days
    mAtmosphereNight->roll(Degree(MWBase::Environment::get().getWorld()->getTimeScaleFactor()*duration*360 / (3600*96.f)));
}
Esempio n. 5
0
AIPerception::AIPerception(ObjectTag tag, float viewRange, Degree fieldOfView, float memorySpan, Object* owner)
{
	time = 0;
	this->tag = tag;
	this->fieldOfView = Math::Cos(fieldOfView.valueRadians(), false);
	this->memorySpan = memorySpan;
	this->owner = owner;
	this->viewRangeSq = viewRange * viewRange;
}
Esempio n. 6
0
//------------------------------------------------------------------------
void print_time(const AstroCoordinate& acoord)
{
	char buf[256];
	char c;
	int y, m, d, hh, mm;
	double utc, sec;

	acoord.getTime().get(y, m, d, utc);
	sec2ims(utc, c, hh, mm, sec);
	printf("UTC: %04d-%02d-%02dT%02d:%02d:%02d\n", y, m, d, hh, mm, (int)sec);

	struct tm t;
	utc2localtime(y, m, d, hh, mm, (int)sec, t);
	strftime(buf, sizeof(buf), "%Y-%m-%d %X %Z", &t);
	printf("LOC: %s\n", buf);

	Degree lst; lst.setHs(acoord.lst()); lst.sprintHms(buf, NULL);
	printf("LST: %s\n", buf);
}
Esempio n. 7
0
void XmlDataPersistance::addDegree(QDomElement &element, Degree *parent)
{
    Degree *degree = new Degree;
    degree->setTitle(element.firstChildElement("titre").text());
    degree->setType(element.attribute("type","formation"));
    addUvs(degree,element);
    addQuotas(degree,element);

    for(QDomElement qElem = element.firstChildElement("quota");!qElem.isNull();qElem = qElem.nextSiblingElement("quota"))
    {
        degree->setQuota(qElem.attribute("categorie"),qElem.text().toInt());
    }

    for(QDomElement childElement = element.firstChildElement("item"); !childElement.isNull(); childElement = childElement.nextSiblingElement("item"))
    {
        addDegree(childElement,degree);
    }

    degree->setParent(parent);
    degrees_.push_back(degree);
}
Esempio n. 8
0
void FlexAirfoil::updateForces()
{
	if(!airfoil) return;
	if (broken) return;
//	if (innan) {LOG("STEP "+TOSTRING(innan)+" "+TOSTRING(nblu));innan++;}
	//evaluate wind direction
	Vector3 wind=-(nodes[nfld].Velocity+nodes[nfrd].Velocity)/2.0;
	//add wash
	int i;
	for (i=0; i<free_wash; i++)
		wind-=(0.5*washpropratio[i]*aeroengines[washpropnum[i]]->getpropwash())*aeroengines[washpropnum[i]]->getAxis();
	float wspeed=wind.length();
	//chord vector, front to back
	Vector3 chordv=((nodes[nbld].RelPosition-nodes[nfld].RelPosition)+(nodes[nbrd].RelPosition-nodes[nfrd].RelPosition))/2.0;
	float chord=chordv.length();
	//span vector, left to right
	Vector3 spanv=((nodes[nfrd].RelPosition-nodes[nfld].RelPosition)+(nodes[nbrd].RelPosition-nodes[nbld].RelPosition))/2.0;
	float span=spanv.length();
	//lift vector
//if (_isnan(spanv.x) || _isnan(spanv.y) || _isnan(spanv.z)) LOG("spanv is NaN "+TOSTRING(nblu));
//if (_isnan(wind.x) || _isnan(wind.y) || _isnan(wind.z)) LOG("wind is NaN "+TOSTRING(nblu));
	Vector3 liftv=spanv.crossProduct(-wind);
//if (_isnan(liftv.x) || _isnan(liftv.y) || _isnan(liftv.z)) LOG("liftv0 is NaN "+TOSTRING(nblu));
//if (_isnan(liftv.x) || _isnan(liftv.y) || _isnan(liftv.z)) LOG("liftv1 is NaN "+TOSTRING(nblu));

	//wing normal
	float s=span*chord;
	Vector3 normv=chordv.crossProduct(spanv);
	normv.normalise();
	//calculate angle of attack
	Vector3 pwind;
	pwind=Plane(Vector3::ZERO, normv, chordv).projectVector(-wind);
	Vector3 dumb;
	Degree daoa;
	chordv.getRotationTo(-pwind).ToAngleAxis(daoa, dumb);
	aoa=daoa.valueDegrees();
	float raoa=daoa.valueRadians();
	if (dumb.dotProduct(spanv)>0) {aoa=-aoa; raoa=-raoa;};

//if (_isnan(aoa)) LOG("aoa is NaN "+TOSTRING(nblu));
	//get airfoil data
	float cz, cx, cm;
	if (isstabilator)
		airfoil->getparams(aoa-deflection, chordratio, 0, &cz, &cx, &cm);
	else
		airfoil->getparams(aoa, chordratio, deflection, &cz, &cx, &cm);
	//compute surface
//if (_isnan(cz)) LOG("cz is NaN "+TOSTRING(nblu));
	//float fs=span*(fabs(thickness*cos(raoa))+fabs(chord*sin(raoa)));
	//float ts=span*(fabs(chord*cos(raoa))+fabs(thickness*sin(raoa)));

	//tropospheric model valid up to 11.000m (33.000ft)
	float altitude=nodes[nfld].AbsPosition.y;
	//float sea_level_temperature=273.15+15.0; //in Kelvin (not used)
	float sea_level_pressure=101325; //in Pa
	//float airtemperature=sea_level_temperature-altitude*0.0065; //in Kelvin (not used)
	float airpressure=sea_level_pressure*approx_pow(1.0-0.0065*altitude/288.15, 5.24947); //in Pa
	float airdensity=airpressure*0.0000120896;//1.225 at sea level

	Vector3 wforce=Vector3::ZERO;
	//drag
	wforce=(cx*0.5*airdensity*wspeed*s)*wind;

//if (_isnan(wforce.x) || _isnan(wforce.y) || _isnan(wforce.z)) LOG("wforce1 is NaN "+TOSTRING(nblu));
	//induced drag
	if (useInducedDrag) 
	{
		Vector3 idf=(cx*cx*0.25*airdensity*wspeed*idArea*idArea/(3.14159*idSpan*idSpan))*wind;
//if (_isnan(idf.length())) LOG("idf is NaN "+TOSTRING(nblu));

		if (idLeft)
		{
			nodes[nblu].Forces+=idf;
			nodes[nbld].Forces+=idf;
		}
		else
		{
			nodes[nbru].Forces+=idf;
			nodes[nbrd].Forces+=idf;
		}
	}

//if (_isnan(wforce.x) || _isnan(wforce.y) || _isnan(wforce.z)) LOG("wforce1a is NaN "+TOSTRING(nblu));
//if (_isnan(cz)) LOG("cz is NaN "+TOSTRING(nblu));
//if (_isnan(wspeed)) LOG("wspeed is NaN "+TOSTRING(nblu));
//if (_isnan(airdensity)) LOG("airdensity is NaN "+TOSTRING(nblu));
//if (_isnan(s)) LOG("s is NaN "+TOSTRING(nblu));
//if (_isnan(liftv.x) || _isnan(liftv.y) || _isnan(liftv.z)) LOG("liftv is NaN "+TOSTRING(nblu));
	//lift
	wforce+=(cz*0.5*airdensity*wspeed*chord)*liftv;


/*if (_isnan(wforce.x) || _isnan(wforce.y) || _isnan(wforce.z)) 
{
	if (innan==0) innan=1;
	LOG("wforce2 is NaN "+TOSTRING(nblu));
}
*/
	//moment
	float moment=-cm*0.5*airdensity*wspeed*wspeed*s;//*chord;
	//apply forces

	Vector3 f1=wforce*(liftcoef * 0.75/4.0f)+normv*(liftcoef *moment/(4.0f*0.25f));
	Vector3 f2=wforce*(liftcoef *0.25/4.0f)-normv*(liftcoef *moment/(4.0f*0.75f));

	//focal at 0.25 chord
	nodes[nfld].Forces+=f1;
	nodes[nflu].Forces+=f1;
	nodes[nfrd].Forces+=f1;
	nodes[nfru].Forces+=f1;
	nodes[nbld].Forces+=f2;
	nodes[nblu].Forces+=f2;
	nodes[nbrd].Forces+=f2;
	nodes[nbru].Forces+=f2;



//	sprintf(debug, "wind %i kts, aoa %i, cz %f, vf %f ", (int)(wspeed*1.9438), (int)aoa, cz, normv.y);

}
void LandVehicleSimulation::UpdateVehicle(Beam* curr_truck, float seconds_since_last_frame)
{
	using namespace Ogre;

	if (!curr_truck->replaymode)
	{
		if (RoR::Application::GetInputEngine()->getEventBoolValueBounce(EV_TRUCK_LEFT_MIRROR_LEFT))
			curr_truck->leftMirrorAngle-=0.001;

		if (RoR::Application::GetInputEngine()->getEventBoolValueBounce(EV_TRUCK_LEFT_MIRROR_RIGHT))
			curr_truck->leftMirrorAngle+=0.001;

		if (RoR::Application::GetInputEngine()->getEventBoolValueBounce(EV_TRUCK_RIGHT_MIRROR_LEFT))
			curr_truck->rightMirrorAngle-=0.001;

		if (RoR::Application::GetInputEngine()->getEventBoolValueBounce(EV_TRUCK_RIGHT_MIRROR_RIGHT))
			curr_truck->rightMirrorAngle+=0.001;

	} // end of (!curr_truck->replaymode) block

#ifdef USE_ANGELSCRIPT
	if (!curr_truck->replaymode && !curr_truck->vehicle_ai->IsActive())
#else
    if (!curr_truck->replaymode)
#endif // USE_ANGELSCRIPT
	{
		// steering
		float tmp_left_digital  = RoR::Application::GetInputEngine()->getEventValue(EV_TRUCK_STEER_LEFT,  false, InputEngine::ET_DIGITAL);
		float tmp_right_digital = RoR::Application::GetInputEngine()->getEventValue(EV_TRUCK_STEER_RIGHT, false, InputEngine::ET_DIGITAL);
		float tmp_left_analog   = RoR::Application::GetInputEngine()->getEventValue(EV_TRUCK_STEER_LEFT,  false, InputEngine::ET_ANALOG);
		float tmp_right_analog  = RoR::Application::GetInputEngine()->getEventValue(EV_TRUCK_STEER_RIGHT, false, InputEngine::ET_ANALOG);

		float sum = -std::max(tmp_left_digital,tmp_left_analog)+ std::max(tmp_right_digital,tmp_right_analog);

		if (sum < -1) sum = -1;
		if (sum > 1) sum = 1;

		curr_truck->hydrodircommand = sum;

		if ((tmp_left_digital < tmp_left_analog) || (tmp_right_digital < tmp_right_analog))
		{
			curr_truck->hydroSpeedCoupling = false;
		} 
		else
		{
			curr_truck->hydroSpeedCoupling = true;
		}

		if (curr_truck->engine)
		{
			static bool arcadeControls = BSETTING("ArcadeControls", false);

			float accl  = RoR::Application::GetInputEngine()->getEventValue(EV_TRUCK_ACCELERATE);
			float brake = RoR::Application::GetInputEngine()->getEventValue(EV_TRUCK_BRAKE);

			if (RoR::Application::GetInputEngine()->getEventValue(EV_TRUCK_ACCELERATE_MODIFIER_25) ||
				RoR::Application::GetInputEngine()->getEventValue(EV_TRUCK_ACCELERATE_MODIFIER_50))
			{
				float acclModifier = 0.0f;
				if (RoR::Application::GetInputEngine()->getEventValue(EV_TRUCK_ACCELERATE_MODIFIER_25))
				{
					acclModifier += 0.25f;
				}
				if (RoR::Application::GetInputEngine()->getEventValue(EV_TRUCK_ACCELERATE_MODIFIER_50))
				{
					acclModifier += 0.50f;
				}
				accl *= acclModifier;
			}

			if (RoR::Application::GetInputEngine()->getEventValue(EV_TRUCK_BRAKE_MODIFIER_25) ||
				RoR::Application::GetInputEngine()->getEventValue(EV_TRUCK_BRAKE_MODIFIER_50))
			{
				float brakeModifier = 0.0f;
				if (RoR::Application::GetInputEngine()->getEventValue(EV_TRUCK_BRAKE_MODIFIER_25))
				{
					brakeModifier += 0.25f;
				}
				if (RoR::Application::GetInputEngine()->getEventValue(EV_TRUCK_BRAKE_MODIFIER_50))
				{
					brakeModifier += 0.50f;
				}
				brake *= brakeModifier;
			}

			// arcade controls are only working with auto-clutch!
			if (!arcadeControls || curr_truck->engine->getAutoMode() > BeamEngine::SEMIAUTO)
			{
				// classic mode, realistic
				curr_truck->engine->autoSetAcc(accl);
				curr_truck->brake = brake * curr_truck->brakeforce;
			} 
			else
			{
				// start engine
				if (curr_truck->engine->hasContact() && !curr_truck->engine->isRunning() && (accl > 0 || brake > 0))
				{
					curr_truck->engine->start();
				}

				// arcade controls: hey - people wanted it x| ... <- and it's convenient
				if (curr_truck->engine->getGear() >= 0)
				{
					// neutral or drive forward, everything is as its used to be: brake is brake and accel. is accel.
					curr_truck->engine->autoSetAcc(accl);
					curr_truck->brake = brake * curr_truck->brakeforce;
				} 
				else
				{
					// reverse gear, reverse controls: brake is accel. and accel. is brake.
					curr_truck->engine->autoSetAcc(brake);
					curr_truck->brake = accl * curr_truck->brakeforce;
				}

				// only when the truck really is not moving anymore
				if (fabs(curr_truck->WheelSpeed) <= 1.0f)
				{
					Vector3 hdir = curr_truck->getDirection();
					float velocity = hdir.dotProduct(curr_truck->nodes[0].Velocity);

					// switching point, does the user want to drive forward from backward or the other way round? change gears?
					if (velocity < 1.0f && brake > 0.5f && accl < 0.5f && curr_truck->engine->getGear() > 0)
					{
						// we are on the brake, jump to reverse gear
						if (curr_truck->engine->getAutoMode() == BeamEngine::AUTOMATIC)
						{
							curr_truck->engine->autoShiftSet(BeamEngine::REAR);
						} 
						else
						{
							curr_truck->engine->setGear(-1);
						}
					} else if (velocity > -1.0f && brake < 0.5f && accl > 0.5f && curr_truck->engine->getGear() < 0)
					{
						// we are on the gas pedal, jump to first gear when we were in rear gear
						if (curr_truck->engine->getAutoMode() == BeamEngine::AUTOMATIC)
						{									
							curr_truck->engine->autoShiftSet(BeamEngine::DRIVE);
						} 
						else
						{
							curr_truck->engine->setGear(1);
						}
					}
				}
			}

			// IMI
			// gear management -- it might, should be transferred to a standalone function of Beam or RoRFrameListener
			if (curr_truck->engine->getAutoMode() == BeamEngine::AUTOMATIC)
			{
				if (RoR::Application::GetInputEngine()->getEventBoolValueBounce(EV_TRUCK_AUTOSHIFT_UP))
				{
					curr_truck->engine->autoShiftUp();
				}
				if (RoR::Application::GetInputEngine()->getEventBoolValueBounce(EV_TRUCK_AUTOSHIFT_DOWN))
				{
					curr_truck->engine->autoShiftDown();
				}
			}

			if (RoR::Application::GetInputEngine()->getEventBoolValueBounce(EV_TRUCK_TOGGLE_CONTACT))
			{
				curr_truck->engine->toggleContact();
			}

			if (RoR::Application::GetInputEngine()->getEventBoolValue(EV_TRUCK_STARTER) && curr_truck->engine->hasContact() && !curr_truck->engine->isRunning())
			{
				// starter
				curr_truck->engine->setstarter(1);
#ifdef USE_OPENAL
				SoundScriptManager::getSingleton().trigStart(curr_truck, SS_TRIG_STARTER);
#endif // OPENAL
			} 
			else
			{
				curr_truck->engine->setstarter(0);
#ifdef USE_OPENAL
				SoundScriptManager::getSingleton().trigStop(curr_truck, SS_TRIG_STARTER);
#endif // OPENAL
			}

			if (RoR::Application::GetInputEngine()->getEventBoolValueBounce(EV_TRUCK_SWITCH_SHIFT_MODES))
			{
				// toggle Auto shift
				curr_truck->engine->toggleAutoMode();

				// force gui update
				curr_truck->triggerGUIFeaturesChanged();
#ifdef USE_MYGUI
				switch(curr_truck->engine->getAutoMode())
				{
					case BeamEngine::AUTOMATIC:
						RoR::Application::GetConsole()->putMessage(Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_NOTICE, _L("Automatic shift"), "cog.png", 3000);
						RoR::Application::GetGuiManager()->PushNotification("Gearbox Mode:", "Automatic shift");
						break;
					case BeamEngine::SEMIAUTO:
						RoR::Application::GetConsole()->putMessage(Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_NOTICE, _L("Manual shift - Auto clutch"), "cog.png", 3000);
						RoR::Application::GetGuiManager()->PushNotification("Gearbox Mode:", "Manual shift - Auto clutch");
						break;
					case BeamEngine::MANUAL:
						RoR::Application::GetConsole()->putMessage(Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_NOTICE, _L("Fully Manual: sequential shift"), "cog.png", 3000);
						RoR::Application::GetGuiManager()->PushNotification("Gearbox Mode:", "Fully Manual: sequential shift");
						break;
					case BeamEngine::MANUAL_STICK:
						RoR::Application::GetConsole()->putMessage(Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_NOTICE, _L("Fully manual: stick shift"), "cog.png", 3000);
						RoR::Application::GetGuiManager()->PushNotification("Gearbox Mode:", "Fully manual: stick shift");
						break;
					case BeamEngine::MANUAL_RANGES:
						RoR::Application::GetConsole()->putMessage(Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_NOTICE, _L("Fully Manual: stick shift with ranges"), "cog.png", 3000);
						RoR::Application::GetGuiManager()->PushNotification("Gearbox Mode:", "Fully Manual: stick shift with ranges");
						break;
				}
#endif //USE_MYGUI
			}

			// joy clutch
			float cval = RoR::Application::GetInputEngine()->getEventValue(EV_TRUCK_MANUAL_CLUTCH);
			curr_truck->engine->setManualClutch(cval);

			int shiftmode = curr_truck->engine->getAutoMode();

			if (shiftmode <= BeamEngine::MANUAL) // auto, semi auto and sequential shifting
			{
				if (RoR::Application::GetInputEngine()->getEventBoolValueBounce(EV_TRUCK_SHIFT_UP))
				{
						curr_truck->engine->shift(1);
				} 
				else if (RoR::Application::GetInputEngine()->getEventBoolValueBounce(EV_TRUCK_SHIFT_DOWN))
				{
					if (shiftmode  > BeamEngine::SEMIAUTO ||
						shiftmode == BeamEngine::SEMIAUTO  && !arcadeControls ||
						shiftmode == BeamEngine::SEMIAUTO  && curr_truck->engine->getGear() > 0 ||
						shiftmode == BeamEngine::AUTOMATIC)
					{
						curr_truck->engine->shift(-1);
					}
				} 
				else if (shiftmode != BeamEngine::AUTOMATIC && RoR::Application::GetInputEngine()->getEventBoolValueBounce(EV_TRUCK_SHIFT_NEUTRAL))
				{
					curr_truck->engine->shiftTo(0);
				}
			} 
			else //if (shiftmode > BeamEngine::MANUAL) // h-shift or h-shift with ranges shifting
			{
				bool gear_changed = false;
				bool found        = false;
				int curgear       = curr_truck->engine->getGear();
				int curgearrange    = curr_truck->engine->getGearRange();
				int gearoffset      = std::max(0, curgear - curgearrange * 6);

				// one can select range only if in neutral
				if (shiftmode==BeamEngine::MANUAL_RANGES && curgear == 0)
				{
					//  maybe this should not be here, but should experiment
					if (RoR::Application::GetInputEngine()->getEventBoolValueBounce(EV_TRUCK_SHIFT_LOWRANGE) && curgearrange != 0)
					{
						curr_truck->engine->setGearRange(0);
						gear_changed = true;
#ifdef USE_MYGUI
						RoR::Application::GetConsole()->putMessage(Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_NOTICE, _L("Low range selected"), "cog.png", 3000);
#endif //USE_MYGUI
					} 
					else if (RoR::Application::GetInputEngine()->getEventBoolValueBounce(EV_TRUCK_SHIFT_MIDRANGE)  && curgearrange != 1 && curr_truck->engine->getNumGearsRanges()>1)
					{
						curr_truck->engine->setGearRange(1);
						gear_changed = true;
#ifdef USE_MYGUI
						RoR::Application::GetConsole()->putMessage(Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_NOTICE, _L("Mid range selected"), "cog.png", 3000);
#endif //USE_MYGUI
					} 
					else if (RoR::Application::GetInputEngine()->getEventBoolValueBounce(EV_TRUCK_SHIFT_HIGHRANGE) && curgearrange != 2 && curr_truck->engine->getNumGearsRanges()>2)
					{
						curr_truck->engine->setGearRange(2);
						gear_changed = true;
#ifdef USE_MYGUI
						RoR::Application::GetConsole()->putMessage(Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_NOTICE, _L("High range selected"), "cog.png", 3000);
#endif // USE_MYGUI
					}
				}
//zaxxon
				if (curgear == -1)
				{
					gear_changed = !RoR::Application::GetInputEngine()->getEventBoolValue(EV_TRUCK_SHIFT_GEAR_REVERSE);
				} 
				else if (curgear > 0 && curgear < 19)
				{
					if (shiftmode==BeamEngine::MANUAL)
					{
						gear_changed = !RoR::Application::GetInputEngine()->getEventBoolValue(EV_TRUCK_SHIFT_GEAR01 + curgear -1);
					} else
					{
						gear_changed = !RoR::Application::GetInputEngine()->getEventBoolValue(EV_TRUCK_SHIFT_GEAR01 + gearoffset-1); // range mode
					}
				}

				if (gear_changed || curgear == 0)
				{
					if (RoR::Application::GetInputEngine()->getEventBoolValue(EV_TRUCK_SHIFT_GEAR_REVERSE))
					{
						curr_truck->engine->shiftTo(-1);
						found = true;
					} 
					else if (RoR::Application::GetInputEngine()->getEventBoolValue(EV_TRUCK_SHIFT_NEUTRAL))
					{
						curr_truck->engine->shiftTo(0);
						found = true;
					} 
					else
					{
						if (shiftmode == BeamEngine::MANUAL_STICK)
						{
							for (int i=1; i < 19 && !found; i++)
							{
								if (RoR::Application::GetInputEngine()->getEventBoolValue(EV_TRUCK_SHIFT_GEAR01 + i - 1))
								{
									curr_truck->engine->shiftTo(i);
									found = true;
								}
							}
						} 
						else // BeamEngine::MANUALMANUAL_RANGES
						{
							for (int i=1; i < 7 && !found; i++)
							{
								if (RoR::Application::GetInputEngine()->getEventBoolValue(EV_TRUCK_SHIFT_GEAR01 + i - 1))
								{
									curr_truck->engine->shiftTo(i + curgearrange * 6);
									found = true;
								}
							}
						}
					}
					if (!found)
					{
						curr_truck->engine->shiftTo(0);
					}
				} // end of if (gear_changed)
			} // end of shitmode > BeamEngine::MANUAL

			if (curr_truck->engine->hasContact() &&
				curr_truck->engine->getAutoMode()  == BeamEngine::AUTOMATIC &&
				curr_truck->engine->getAutoShift() != BeamEngine::NEUTRAL &&
				std::abs(curr_truck->WheelSpeed) < 0.1f)
			{
				Vector3 dirDiff = curr_truck->getDirection();
				Degree pitchAngle = Radian(asin(dirDiff.dotProduct(Vector3::UNIT_Y)));

				if (std::abs(pitchAngle.valueDegrees()) > 1.0f)
				{
					if (curr_truck->engine->getAutoShift() > BeamEngine::NEUTRAL && curr_truck->WheelSpeed < +0.1f && pitchAngle.valueDegrees() > +1.0f ||
					    curr_truck->engine->getAutoShift() < BeamEngine::NEUTRAL && curr_truck->WheelSpeed > -0.1f && pitchAngle.valueDegrees() < -1.0f)
					{
						// anti roll back in BeamEngine::AUTOMATIC (DRIVE, TWO, ONE) mode
						// anti roll forth in BeamEngine::AUTOMATIC (REAR) mode
						float downhill_force = std::abs(sin(pitchAngle.valueRadians()) * curr_truck->getTotalMass());
						float engine_force = std::abs(curr_truck->engine->getTorque());
						float ratio = std::max(0.0f, 1.0f - (engine_force / downhill_force) / 2.0f);
						curr_truck->brake = curr_truck->brakeforce * sqrt(ratio);
					}
				} else if (brake == 0.0f && accl == 0.0f && curr_truck->parkingbrake == 0)
				{
					float ratio = std::max(0.0f, 0.1f - std::abs(curr_truck->WheelSpeed)) * 5.0f;
					curr_truck->brake = curr_truck->brakeforce * ratio;
				}
			}
		} // end of ->engine
#ifdef USE_OPENAL
		if (curr_truck->brake > curr_truck->brakeforce / 6.0f)
		{
			SoundScriptManager::getSingleton().trigStart(curr_truck, SS_TRIG_BRAKE);
		} 
		else
		{
			SoundScriptManager::getSingleton().trigStop(curr_truck, SS_TRIG_BRAKE);
		}
#endif // USE_OPENAL
	} // end of ->replaymode

	if (RoR::Application::GetInputEngine()->getEventBoolValueBounce(EV_TRUCK_TOGGLE_AXLE_LOCK))
	{
		// toggle auto shift
		if (!curr_truck->getAxleLockCount())
		{
#ifdef USE_MYGUI
			RoR::Application::GetConsole()->putMessage(Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_NOTICE, _L("No differential installed on current vehicle!"), "warning.png", 3000);
			RoR::Application::GetGuiManager()->PushNotification("Differential:", "No differential installed on current vehicle!");
#endif // USE_MYGUI
		} 
		else
		{
			curr_truck->toggleAxleLock();
#ifdef USE_MYGUI
			RoR::Application::GetConsole()->putMessage(Console::CONSOLE_MSGTYPE_INFO, Console::CONSOLE_SYSTEM_NOTICE, _L("Differentials switched to: ") + curr_truck->getAxleLockName(), "cog.png", 3000);
			RoR::Application::GetGuiManager()->PushNotification("Differential:", "Differentials switched to: " + curr_truck->getAxleLockName());
#endif // USE_MYGUI
		}
	}

#ifdef USE_OPENAL
	if (curr_truck->ispolice)
	{
		if (RoR::Application::GetInputEngine()->getEventBoolValueBounce(EV_TRUCK_HORN))
		{
			SoundScriptManager::getSingleton().trigToggle(curr_truck, SS_TRIG_HORN);
		}
	} 
	else
	{
		if (RoR::Application::GetInputEngine()->getEventBoolValue(EV_TRUCK_HORN) && !curr_truck->replaymode)
		{
			SoundScriptManager::getSingleton().trigStart(curr_truck, SS_TRIG_HORN);
		} else
		{
			SoundScriptManager::getSingleton().trigStop(curr_truck, SS_TRIG_HORN);
		}
	}
#endif // OPENAL

	if (RoR::Application::GetInputEngine()->getEventBoolValueBounce(EV_TRUCK_PARKING_BRAKE))
	{
		curr_truck->parkingbrakeToggle();
	}

	if (RoR::Application::GetInputEngine()->getEventBoolValueBounce(EV_TRUCK_ANTILOCK_BRAKE))
	{
		if (curr_truck->alb_present && !curr_truck->alb_notoggle)
		{
			curr_truck->antilockbrakeToggle();
		}
	}

	if (RoR::Application::GetInputEngine()->getEventBoolValueBounce(EV_TRUCK_TRACTION_CONTROL))
	{
		if (!curr_truck->tc_notoggle) curr_truck->tractioncontrolToggle();
	}

	if (RoR::Application::GetInputEngine()->getEventBoolValueBounce(EV_TRUCK_CRUISE_CONTROL))
	{
		curr_truck->cruisecontrolToggle();
	}
	if (curr_truck->cc_mode)
	{
		LandVehicleSimulation::UpdateCruiseControl(curr_truck, seconds_since_last_frame);
	}
	LandVehicleSimulation::CheckSpeedLimit(curr_truck, seconds_since_last_frame);
}
Esempio n. 10
0
inline Radian::Radian(Degree degrees)
    : mRadValue(degrees.valueRadians()) {}
Esempio n. 11
0
// Tests
TEST_F(Matrix3Test, Matrix3Test) {
    // Test Identity
    {
        Matrix3 identity;
        identity.set_identity();
        
        ASSERT_TRUE(identity.is_identity());
    }
    
    // Test quaternion identity -> matrix3 identity. Identity quaternion, no rotation
    {
        Matrix3 matrix = Matrix3::CreateRotate(Quaternion::IDENTITY);
        
        ASSERT_TRUE(matrix.is_identity());
    }
    
    // 180° turn around X axis
    {
        Matrix3 matrix = Matrix3::CreateRotate(Quaternion(0, 1, 0, 0));
        
        Vector3 axis;
        Degree angle;
        matrix.ToAxisAngle(axis, angle);
        
        ASSERT_TRUE(angle.ValueDegrees() == 180.0f);
        ASSERT_TRUE(axis.x >= 1.0f);
    }
    
    // 180° turn around Y axis
    {
        Matrix3 matrix = Matrix3::CreateRotate(Quaternion(0, 0, 1, 0));
        
        Vector3 axis;
        Degree angle;
        matrix.ToAxisAngle(axis, angle);
        
        ASSERT_TRUE(angle.ValueDegrees() == 180.0f);
        ASSERT_TRUE(axis.y >= 1.0f);
    }
    
    // 180° turn around Z axis
    {
        Matrix3 matrix = Matrix3::CreateRotate(Quaternion(0, 0, 0, 1));
        
        Vector3 axis;
        Degree angle;
        matrix.ToAxisAngle(axis, angle);
        
        ASSERT_TRUE(angle.ValueDegrees() == 180.0f);
        ASSERT_TRUE(axis.z >= 1.0f);
    }
    
    // 90° rotation around X axis
    {
        Matrix3 matrix = Matrix3::CreateRotate(Quaternion(std::sqrt(0.5f), std::sqrt(0.5f), 0, 0));
        
        Vector3 axis;
        Degree angle;
        matrix.ToAxisAngle(axis, angle);
        
        ASSERT_TRUE(angle.ValueDegrees() == 90.0f);
        ASSERT_TRUE(axis.x >= 1.0f);
    }
    
    // 90° rotation around Y axis
    {
        Matrix3 matrix = Matrix3::CreateRotate(Quaternion(std::sqrt(0.5f), 0, std::sqrt(0.5f), 0));
        
        Vector3 axis;
        Degree angle;
        matrix.ToAxisAngle(axis, angle);
        
        ASSERT_TRUE(angle.ValueDegrees() == 90.0f);
        ASSERT_TRUE(axis.y >= 1.0f);
    }
    
    // 90° rotation around Z axis
    {
        Matrix3 matrix = Matrix3::CreateRotate(Quaternion(std::sqrt(0.5f), 0, 0, std::sqrt(0.5f)));
        
        Vector3 axis;
        Degree angle;
        matrix.ToAxisAngle(axis, angle);
        
        ASSERT_TRUE(angle.ValueDegrees() == 90.0f);
        ASSERT_TRUE(axis.z >= 1.0f);
    }
    
    //sqrt(0.5)	-sqrt(0.5)	0	0	-90° rotation around X axis
    {
        Matrix3 matrix = Matrix3::CreateRotate(Quaternion(std::sqrt(0.5f), -std::sqrt(0.5f), 0, 0));
        
        Vector3 axis;
        Degree angle;
        matrix.ToAxisAngle(axis, angle);
        
        ASSERT_TRUE(angle.ValueDegrees() == 90.0f);
        ASSERT_TRUE(std::abs(axis.x) >= 1.0f);
    }
    
    // -90° rotation around Y axis
    {
        Matrix3 matrix = Matrix3::CreateRotate(Quaternion(std::sqrt(0.5f), 0, -std::sqrt(0.5f), 0));
        
        Vector3 axis;
        Degree angle;
        matrix.ToAxisAngle(axis, angle);
        
        ASSERT_TRUE(angle.ValueDegrees() == 90.0f);
        ASSERT_TRUE(std::abs(axis.y) >= 1.0f);
    }
    
    // -90° rotation around Z axis
    {
        Matrix3 matrix = Matrix3::CreateRotate(Quaternion(std::sqrt(0.5f), 0, 0, -std::sqrt(0.5f)));
        
        Vector3 axis;
        Degree angle;
        matrix.ToAxisAngle(axis, angle);
        
        ASSERT_TRUE(angle.ValueDegrees() == 90.0f);
        ASSERT_TRUE(std::abs(axis.z) >= 1.0f);
    }
}
tAction TeacherFollowTheLineLineRoom::computeNextAction()
{
    // Determine if a change of state is possible
    if (state == STATE_FORWARD_1)
    {
        if (target.x < 0)
        {
            target.x = m_pMap->properties.get("spot1_x")->toInt();
            target.y = m_pMap->properties.get("spot1_y")->toInt();
        }
        else
        {
            if ((m_robot_position.x >= target.x - 1) && (m_robot_position.x <= target.x + 1) &&
                (m_robot_position.y >= target.y - 1) && (m_robot_position.y <= target.y + 1))
            {
                target.x = m_pMap->properties.get("spot2_x")->toInt();
                target.y = m_pMap->properties.get("spot2_y")->toInt();

                state = STATE_FORWARD_2;
            }
        }
    }
    else if (state == STATE_FORWARD_2)
    {
        if ((m_robot_position.x >= target.x - 1) && (m_robot_position.x <= target.x + 1) &&
            (m_robot_position.y >= target.y - 1) && (m_robot_position.y <= target.y + 1))
        {
            target.x = -1;
            target.y = -1;

            state = STATE_LOOK_FOR_FLAG;
        }
    }
    else if (state == STATE_LOOK_FOR_FLAG)
    {
        if (!m_detected_targets.empty())
        {
            target = m_detected_targets[0];
            state = STATE_GO_TOWARD_FLAG;
        }
    }

    // Select the action to perform
    if (state == STATE_LOOK_FOR_FLAG)
    {
        if (m_pMap->properties.get("haxis")->toBool())
            return ACTION_TURN_RIGHT;
        else
            return ACTION_TURN_LEFT;
    }
    else if (target.x >= 0)
    {
        Degree angle = getAngleToTarget(target);

        if (angle.valueDegrees() >= 3.0f)
            return ACTION_TURN_RIGHT;
        else if (angle.valueDegrees() <= -3.0f)
            return ACTION_TURN_LEFT;
        else
            return ACTION_GO_FORWARD;
    }

    return ACTION_TURN_LEFT;
}
Esempio n. 13
0
	Radian Radian::operator-(const Degree& d) const {
		return Radian(mRad - d.valueRadians());
	}
Esempio n. 14
0
	Radian::Radian(const Degree& d) : mRad(d.valueRadians()) {}
Esempio n. 15
0
void Turboprop::updateForces(float dt, int doUpdate)
{
	if (doUpdate)
	{
		//tropospheric model valid up to 11.000m (33.000ft)
		float altitude=nodes[noderef].AbsPosition.y;
		//float sea_level_temperature=273.15+15.0; //in Kelvin
		float sea_level_pressure=101325; //in Pa
		//float airtemperature=sea_level_temperature-altitude*0.0065; //in Kelvin
		float airpressure=sea_level_pressure*pow(1.0-0.0065*altitude/288.15, 5.24947); //in Pa
		airdensity=airpressure*0.0000120896;//1.225 at sea level
#ifdef USE_OPENAL
		//sound update
		SoundScriptManager::getSingleton().modulate(trucknum, mod_id, rpm);
#endif //OPENAL
	}

	timer+=dt;
	//evaluate the rotation speed
	float velacc=0;
	for (int i=0; i<numblades; i++) velacc+=(nodes[nodep[i]].Velocity-nodes[noderef].Velocity).length();
	rpm=(velacc/numblades) * RAD_PER_SEC_TO_RPM / radius;
	//check for broken prop
	Vector3 avg=Vector3::ZERO;
	for (int i=0; i<numblades; i++) avg+=nodes[nodep[i]].RelPosition;
	avg=avg/numblades;
	if ((avg-nodes[noderef].RelPosition).length()>0.4)
	{
		failed=true;
	}
	//evaluate engine power
	float enginepower=0; //in kilo-Watt
	float warmupfactor=1.0;
	if (warmup)
	{
		warmupfactor=(timer-warmupstart)/warmuptime;
		if (warmupfactor>=1.0) warmup=false;
	}
	float revpenalty=1.0;
	if (reverse) revpenalty=0.5;
	if (!failed && ignition) enginepower=(0.0575+throtle*revpenalty*0.9425)*fullpower*warmupfactor;
	//the magic formula
	float enginecouple=0.0; //in N.m
	if (rpm>10.0) enginecouple=9549.3*enginepower/rpm;
	else enginecouple=9549.3*enginepower/10.0;
	indicated_torque=enginecouple;
	
	if (torquenode!=-1)
	{
		Vector3 along=nodes[noderef].RelPosition-nodes[nodeback].RelPosition;
		Plane ppl=Plane(along, 0);
		Vector3 orth=ppl.projectVector(nodes[noderef].RelPosition)-ppl.projectVector(nodes[torquenode].RelPosition);
		Vector3 cdir=orth.crossProduct(along);
		cdir.normalise();
		nodes[torquenode].Forces+=(enginecouple/torquedist)*cdir;
	}
	
	float tipforce=(enginecouple/radius)/numblades;
	//okay, now we know the contribution from the engine

	//pitch
	if (fixed_pitch>0) pitch=fixed_pitch; else
	{
		if (!reverse)
		{
			if (throtle<0.01)
			{
				//beta range
				if (pitch>0 && rpm<regspeed*1.4) pitch-=pitchspeed*dt;
				if (rpm>regspeed*1.4) pitch+=pitchspeed*dt;
			}
			else
			{
				float dpitch=rpm-regspeed;
				if (dpitch>pitchspeed) dpitch=pitchspeed;
				if (dpitch<-pitchspeed) dpitch=-pitchspeed;
				if (!(dpitch<0 && pitch<0) && !(dpitch>0 && pitch>45)) pitch+=dpitch*dt;
			}
		} else
		{
			if (rpm<regspeed*1.1)
			{
				if (pitch<-4.0) pitch+=pitchspeed*dt;
				else pitch-=pitchspeed*dt;
			}
			if (rpm>regspeed*1.11)
			{
				pitch-=pitchspeed*dt;
			}
		}
	}
	if (!failed)
	{
		axis=nodes[noderef].RelPosition-nodes[nodeback].RelPosition;
		axis.normalise();
	}
	//estimate amount of energy
	float estrotenergy=0.5*numblades*nodes[nodep[0]].mass*radius*radius*(rpm/RAD_PER_SEC_TO_RPM)*(rpm/RAD_PER_SEC_TO_RPM);
	//for each blade
	float totthrust=0;
	float tottorque=0;
	for (int i=0; i<numblades; i++)
	{
		if (!failed && ignition)
		{
			Vector3 totaltipforce=Vector3::ZERO;
			//span vector, left to right
			Vector3 spanv=(nodes[nodep[i]].RelPosition-nodes[noderef].RelPosition);
			spanv.normalise();
			//chord vector, front to back
			Vector3 refchordv=-axis.crossProduct(spanv);
			//grab this for propulsive forces
			Vector3 tipf=-refchordv;
			totaltipforce+=(tipforce-rpm/10.0)*tipf; //add a bit of mechanical friction
			//for each blade segment (there are 6 elements)
			for (int j=0; j<5; j++) //outer to inner, the 6th blade element is ignored
			{
				//proportion
				float proport=((float)j+0.5)/6.0;
				//evaluate wind direction
				Vector3 wind=-(nodes[nodep[i]].Velocity*(1.0-proport)+nodes[noderef].Velocity*proport);
				float wspeed=wind.length();

				Vector3 liftv=spanv.crossProduct(-wind);
				liftv.normalise();
				//rotate according to pitch
				Vector3 chordv=Quaternion(Degree(pitch+twistmap[j]-7.0), spanv)*refchordv;
				//wing normal
				Vector3 normv=chordv.crossProduct(spanv);
				//calculate angle of attack
				Vector3 pwind=Plane(Vector3::ZERO, normv, chordv).projectVector(wind);
				Vector3 dumb;
				Degree daoa;
				chordv.getRotationTo(pwind).ToAngleAxis(daoa, dumb);
				float aoa=daoa.valueDegrees();
				float raoa=daoa.valueRadians();
				if (dumb.dotProduct(spanv)>0) {aoa=-aoa; raoa=-raoa;};
				//get airfoil data
				float cz, cx, cm;
				airfoil->getparams(aoa, 1.0, 0.0, &cz, &cx, &cm);
				//surface computation
				float s=radius*bladewidth/6.0;

				//drag
				//wforce=(8.0*cx+cx*cx/(3.14159*radius/0.4))*0.5*airdensity*wspeed*s*wind;
				Vector3 eforce=(4.0*cx+cx*cx/(3.14159*radius/bladewidth))*0.5*airdensity*wspeed*s*wind;
				//lift
				float lift=cz*0.5*airdensity*wspeed*wspeed*s;
				eforce+=lift*liftv;
				totthrust+=eforce.dotProduct(axis);

				//apply forces
				nodes[noderef].Forces+=eforce*proport;
				totaltipforce+=eforce*(1.0-proport);

//				if (i==0) sprintf(debug, "rend %.4i%%, wind %.3i kts, aoa %.3i, power %.5ihp, thrust %.6ilbf, torque %.6ilbft, pitch %.3i, propwash %.3i kts", (int)(100.0*wforce.dotProduct(axis)*numblades*nodes[noderef].Velocity.length()/(rpm*0.10471976*2.0*3.14159*enginecouple)), (int)(wspeed*1.9438), (int)aoa, (int)(enginepower*1.34), (int)(wforce.dotProduct(axis)*numblades*0.2248), (int)(enginecouple/1.35582), (int)pitch, (int)(propwash*1.9438));
				//			if (i==0) sprintf(debug, "lfx=%f lfy=%f lfz=%f vx=%f vy=%f vz=%f cx=%f cz=%f lift=%f", liftv.x, liftv.y, liftv.z, wind.x, wind.y, wind.z, cx, cz, lift);
			}
			tottorque+=tipf.dotProduct(totaltipforce)*radius;
			//correct amount of energy
			float correctfactor=0;
			if (rpm>100) correctfactor=(rotenergy-estrotenergy)/(numblades*radius*dt*rpm/RAD_PER_SEC_TO_RPM);
			if (correctfactor>1000.0) correctfactor=1000.0;
			if (correctfactor<-1000.0) correctfactor=-1000.0;
			nodes[nodep[i]].Forces+=totaltipforce+correctfactor*tipf;
		}
		else
		{
			//failed case
			//add drag
			Vector3 wind=-nodes[nodep[i]].Velocity;
			// determine nodes speed and divide by engines speed (with some magic numbers for tuning) to keep it rotating longer when shutoff in flight and stop after a while when plane is stopped (on the ground)
			float wspeed= (wind.length()/15.0f) / (nodes[noderef].Velocity.length()/2.0f);
			nodes[nodep[i]].Forces+=airdensity*wspeed*wind;
		}
	}
	//compute the next energy level
	rotenergy+=(double)tottorque*dt*rpm/RAD_PER_SEC_TO_RPM;
//	sprintf(debug, "pitch %i thrust %i totenergy=%i apparentenergy=%i", (int)pitch, (int)totthrust, (int)rotenergy, (int)estrotenergy);
	//prop wash
	float speed=nodes[noderef].Velocity.length();
	float thrsign=1.0;
	if (totthrust<0) {thrsign=-0.1; totthrust=-totthrust;};
	if (!failed) propwash=thrsign*sqrt(totthrust/(0.5*airdensity*proparea)+speed*speed)-speed; else propwash=0;
	if (propwash<0) propwash=0;
}
Esempio n. 16
0
	String toString(Degree val, unsigned short precision, 
		unsigned short width, char fill, std::ios::fmtflags flags)
	{
		return toString(val.valueDegrees(), precision, width, fill, flags);
	}
Esempio n. 17
0
void TreeLoader2D::addTree(Entity *entity, const Vector3 &position, Degree yaw, Real scale, void* userData)
{
  //First convert the coordinate to PagedGeometry's local system
#ifdef PAGEDGEOMETRY_ALTERNATE_COORDSYSTEM
  Vector3 pos = geom->_convertToLocal(position);
#else
  Vector3 pos = position;
#endif

  //Check that the tree is within bounds (DEBUG)
#ifdef _DEBUG
  const Real smallVal = 0.01f;
  if (pos.x < actualBounds.left-smallVal || pos.x > actualBounds.right+smallVal || pos.z < actualBounds.top-smallVal || pos.z > actualBounds.bottom+smallVal)
  OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Tree position is out of bounds", "TreeLoader::addTree()");
  if (scale < minimumScale || scale > maximumScale)
  OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Tree scale out of range", "TreeLoader::addTree()");
#endif

  //If the tree is slightly out of bounds (due to imprecise coordinate conversion), fix it
  if (pos.x < actualBounds.left)
    pos.x = actualBounds.left;
  else if (pos.x > actualBounds.right)
    pos.x = actualBounds.right;

  if (pos.z < actualBounds.top)
    pos.z = actualBounds.top;
  else if (pos.z > actualBounds.bottom)
    pos.z = actualBounds.bottom;

  Real x = pos.x;
  Real z = pos.z;

  //Find the appropriate page grid for the entity
  PageGridListIterator i;
  i = pageGridList.find(entity);

  std::vector<TreeDef> *pageGrid;
  if (i != pageGridList.end()) {
    //If it exists, get the page grid
    pageGrid = i->second;
  } else {
    //If it does not exist, create a new page grid
    pageGrid = new std::vector<TreeDef>[pageGridX * pageGridZ];

    //Register the new page grid in the pageGridList for later retrieval
    pageGridList.insert(PageGridListValue(entity, pageGrid));
  }

  //Calculate the gridbounds-relative position of the tree
  Real xrel = x - gridBounds.left;
  Real zrel = z - gridBounds.top;

  //Get the appropriate grid element based on the new tree's position
  int pageX = Math::Floor(xrel / pageSize);
  int pageZ = Math::Floor(zrel / pageSize);
  std::vector<TreeDef> &treeList = _getGridPage(pageGrid, pageX, pageZ);

  //Create the new tree
  TreeDef tree;
  tree.xPos = 65535 * (xrel - (pageX * pageSize)) / pageSize;
  tree.zPos = 65535 * (zrel - (pageZ * pageSize)) / pageSize;
  tree.rotation = 255 * (yaw.valueDegrees() / 360.0f);
  tree.scale = 255 * ((scale - minimumScale) / maximumScale);

#ifdef PAGEDGEOMETRY_USER_DATA
  tree.userData = userData;
#endif

  //Add it to the tree list
  treeList.push_back(tree);

  //Rebuild geometry if necessary
  geom->reloadGeometryPage(Vector3(x, 0, z));
}
void TestAngular()
{

  Radian const rad( 1. );
  Assert( fequal( rad.GetValue(), 1. ) );
  Assert( fequal( rad.GetConvertedValue(), 1. ) );
  Assert( fequal( rad.GetFactor(), 1. ) );

  AngularSecond const second( 1. );
  Assert( fequal( second.GetValue(), 1. ) );
  Assert( fequal( second.GetConvertedValue(), second.GetFactor() ) );

  Degree const degree( 1. );
  Assert( fequal( degree.GetValue(), 1. ) );
  Assert( fequal( degree.GetConvertedValue(), degree.GetFactor() ) );


  Radian const pi( 3.1415926535897932384626433832795 );
  Degree const unit_180_degree = pi;
  AngularMinute const unit_10800_minute = pi;

  Assert( fequal( pi.sin(), 0. ) );
  Assert( fequal( pi.cos(), -1. ) );
  Assert( fequal( pi.tan(), 0. ) );

  Assert( fequal( unit_180_degree.GetValue(), 180. ) );
  Assert( fequal( unit_180_degree.sin(), 0. ) );
  Assert( fequal( unit_180_degree.cos(), -1. ) );
  Assert( fequal( unit_180_degree.tan(), 0. ) );

  Assert( fequal( unit_10800_minute.GetValue(), 10800. ) );
  Assert( fequal( unit_10800_minute.sin(), 0. ) );
  Assert( fequal( unit_10800_minute.cos(), -1. ) );
  Assert( fequal( unit_10800_minute.tan(), 0. ) );

  Assert( Degree( 360. ) == Grade( 400. ) );
  Assert( Degree( 1.) == AngularMinute( 60. ) );
  Assert( Degree( 1.) == AngularSecond( 3600. ) );
  
  Degree toNormalize( 0. );
  toNormalize.Normalize();
  Assert( fequal( toNormalize.GetValue(), 0. ) );

  toNormalize = 360.;
  toNormalize.Normalize();
  Assert( fequal( toNormalize.GetValue(), 0. ) );

  toNormalize = -540.;
  toNormalize.Normalize();
  Assert( fequal( toNormalize.GetValue(), 180. ) );
  Assert( fequal( toNormalize.sin(), 0. ) );
  Assert( fequal( toNormalize.cos(), -1. ) );
  Assert( fequal( toNormalize.tan(), 0. ) );


  OutputLine( Radian::Suffix() );
  OutputLine( Degree::Suffix() );
  OutputLine( Grade::Suffix() );
  OutputLine( AngularMinute::Suffix() );
  OutputLine( AngularSecond::Suffix() );

}
	//---------------------------------------------------------------------
	void LiSPSMShadowCameraSetup::setCameraLightDirectionThreshold(Degree angle)
	{
		mCosCamLightDirThreshold = Math::Cos(angle.valueRadians());
	}
Esempio n. 20
0
Radian::Radian(const Degree& deg)
{
    mRad = deg.getValue() * 180 / PI;
}
Esempio n. 21
0
Radian Radian::operator - (const Degree& deg)
{
    return Radian(mRad - deg.getValue() * 180 / PI);
}
Esempio n. 22
0
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
Radian::Radian(const Degree& _degree)
    :   m_radian(_degree.toRadians())
{
}
Esempio n. 23
0
    void SGModel::updateBone(int64_t time, ObjectPtr skeleton)
    {
        BonePtr bone = smart_pointer_cast<Bone>(skeleton);

        ActionDataPtr actionData = smart_pointer_cast<ActionData>(mCurActionData);
        
        KeyFrameDataPtr kf1, kf2;

        // 平移变换数据
        Vector3 translation;
        auto itrT = actionData->mBonesTranslation.find(bone->getName());
        if (itrT != actionData->mBonesTranslation.end())
        {
            ActionData::KeyFrames &keyframesT = itrT->second;

            if (searchKeyframe(keyframesT, time, actionData->mDuration, mCurKeyFrameT, kf1, kf2, mIsLoop))
            {
                KeyFrameDataTPtr keyframe1 = smart_pointer_cast<KeyFrameDataT>(kf1);
                KeyFrameDataTPtr keyframe2 = smart_pointer_cast<KeyFrameDataT>(kf2);
                double t = double(time - keyframe1->mTimestamp) / double(keyframe2->mTimestamp - keyframe1->mTimestamp);
                Vector3 &base = keyframe1->mTranslation;
                translation = (base + (keyframe2->mTranslation - base) * t);
                T3D_LOG_INFO("Keyframe #1 T(%f, %f, %f)", keyframe1->mTranslation[0], keyframe1->mTranslation[1], keyframe1->mTranslation[2]);
                T3D_LOG_INFO("Keyframe #2 T(%f, %f, %f)", keyframe2->mTranslation[0], keyframe2->mTranslation[1], keyframe2->mTranslation[2]);
                T3D_LOG_INFO("Bone : %s [%f], T(%f, %f, %f)", bone->getName().c_str(), t, translation[0], translation[1], translation[2]);

                bone->setTranslation(translation);
            }
        }
        
        // 旋转变换数据
        Quaternion orientation;
        auto itrR = actionData->mBonesRotation.find(bone->getName());
        if (itrR != actionData->mBonesRotation.end())
        {
            ActionData::KeyFrames &keyframesR = itrR->second;

            if (searchKeyframe(keyframesR, time, actionData->mDuration, mCurKeyFrameR, kf1, kf2, mIsLoop))
            {
                KeyFrameDataRPtr keyframe1 = smart_pointer_cast<KeyFrameDataR>(kf1);
                KeyFrameDataRPtr keyframe2 = smart_pointer_cast<KeyFrameDataR>(kf2);
                double t = double(time - keyframe1->mTimestamp) / double(keyframe2->mTimestamp - keyframe1->mTimestamp);
                orientation.lerp(keyframe1->mOrientation, keyframe2->mOrientation, t/* / 1000*/);
                T3D_LOG_INFO("Keyframe #1 R(%f, %f, %f, %f)", keyframe1->mOrientation[0], keyframe1->mOrientation[1], keyframe1->mOrientation[2], keyframe1->mOrientation[3]);
                T3D_LOG_INFO("Keyframe #2 R(%f, %f, %f, %f)", keyframe2->mOrientation[0], keyframe2->mOrientation[1], keyframe2->mOrientation[2], keyframe2->mOrientation[3]);
                Degree deg;
                Vector3 axis;
                orientation.toAngleAxis(deg, axis);
                T3D_LOG_INFO("Bone : %s [%d], R(%f, %f, %f, %f), deg=%f, Axis(%f, %f, %f)", bone->getName().c_str(), time, orientation[0], orientation[1], orientation[2], orientation[3], deg.valueDegrees(), axis[0], axis[1], axis[2]);

                bone->setOrientation(orientation);
            }
        }

        // 缩放变换数据
        Vector3 scaling;
        auto itrS = actionData->mBonesScaling.find(bone->getName());
        if (itrS != actionData->mBonesScaling.end())
        {
            ActionData::KeyFrames &keyframesS = itrS->second;

            if (searchKeyframe(keyframesS, time, actionData->mDuration, mCurKeyFrameS, kf1, kf2, mIsLoop))
            {
                KeyFrameDataSPtr keyframe1 = smart_pointer_cast<KeyFrameDataS>(kf1);
                KeyFrameDataSPtr keyframe2 = smart_pointer_cast<KeyFrameDataS>(kf2);
                double t = double(time - keyframe1->mTimestamp) / double(keyframe2->mTimestamp - keyframe1->mTimestamp);
                Vector3 &base = keyframe1->mScaling;
                scaling = (base * (keyframe2->mScaling - base) * t);
                T3D_LOG_INFO("Keyframe #1 S(%f, %f, %f)", keyframe1->mScaling[0], keyframe1->mScaling[1], keyframe1->mScaling[2]);
                T3D_LOG_INFO("Keyframe #2 S(%f, %f, %f)", keyframe2->mScaling[0], keyframe2->mScaling[1], keyframe2->mScaling[2]);
                T3D_LOG_INFO("Bone : %s [%f], S(%f, %f, %f)", bone->getName().c_str(), t, scaling[0], scaling[1], scaling[2]);

                bone->setScaling(scaling);
            }
        }

        bone->updateBone();

        auto itr = bone->getChildren().begin();
        while (itr != bone->getChildren().end())
        {
            updateBone(time, *itr);
            ++itr;
        }
    }
Esempio n. 24
0
//------------------------------------------------------------------------
void calc_main(AstroCoordinate& acoord, Planets& pl)
{
	acoord.beginConvert();
	pl.calc(acoord);
	Vec3 sun  = pl.vecQ(Planets::SUN);
	Vec3 moon = pl.vecQ(Planets::MOON);
	double cosSun = sun.inner(moon);	// sun/moonは方向余弦なので、その内積は位相角のcosである.
	if (cosSun > 1) cosSun = 1;			// acos()でのDOMAINエラー回避.
	if (cosSun < -1) cosSun = -1;		// acos()でのDOMAINエラー回避.
	Degree phase; phase.setArcCos(cosSun);	// acos は 0..180度の範囲で値を返す.
	if (sun.x * moon.y - sun.y * moon.x < 0) { // XY平面の外積値が負の値なら、位相角度を 180~360度の範囲に補正する.
		phase.setNeg(); phase.mod360();
	}
	acoord.conv_q2tq(sun);
	acoord.conv_q2tq(moon);
	acoord.conv_q2h(sun);
	acoord.conv_q2h(moon);
	if (gAddRefraction) { // 大気差補正.
		acoord.addRefraction(sun);
		acoord.addRefraction(moon);
	}

	//--- 結果表示.
	print_time(acoord);
	print_alt(sun, moon, phase.degree());

	//--- 全惑星の赤経赤緯表示.
	if (gPlanetRaDc) {
		print_planet(acoord, pl, "SUN",     Planets::SUN);
		print_planet(acoord, pl, "MOON",    Planets::MOON);
		print_planet(acoord, pl, "MERCURY", Planets::MERCURY);
		print_planet(acoord, pl, "VENUS",   Planets::VENUS);
		print_planet(acoord, pl, "MARS",    Planets::MARS);
		print_planet(acoord, pl, "JUPITER", Planets::JUPITER);
		print_planet(acoord, pl, "SATURN",  Planets::SATURN);
		print_planet(acoord, pl, "URANUS",  Planets::URANUS);
		print_planet(acoord, pl, "NEPTUNE", Planets::NEPTUNE);
		print_planet(acoord, pl, "PLUTO",   Planets::PLUTO);
	}

	//--- 出没計算.
	if (gTableDays != 0) {
		AstroTime t = acoord.getTime();
		const double jd_end = t.jd() + gTableDays;
		const double sun_rz  = sin(dms2rad(0,0,960));	// 太陽視半径による出没補正. 視半径は 960" で決め打ち.
		const double min30_z = sin(hms2rad(0,30,0));	// 時角30分の高度のz座標値.
		const double min3_z  = sin(hms2rad(0,3,0));	// 時角1分の高度のz座標値.
		const double sec15_z = sin(hms2rad(0,0,15));	// 時角15秒の高度のz座標値.
		int step = -1;	// 初回は指定時刻の1秒前の高度を計算する.
		for (t.addSec(step); t.jd() < jd_end; t.addSec(step)) {
			// 前回時刻の高度を保存する. ただし、初回はこの値を使ってはいけない.
			const Vec3 sun0 = sun;
			const Vec3 moon0 = moon;
			// 今回時刻の高度を計算する.
			acoord.setTime(t);
			acoord.beginConvert();
			pl.calc(acoord);
			sun  = pl.vecQ(Planets::SUN);
			moon = pl.vecQ(Planets::MOON);
			acoord.conv_q2tq(sun);
			acoord.conv_q2tq(moon);
			acoord.conv_q2h(sun);
			acoord.conv_q2h(moon);
			// 大気差補正は常時実施する.
			acoord.addRefraction(sun);
			acoord.addRefraction(moon);
			// 太陽視半径分を高度補正する.
			sun.z += sun_rz;
			if (step > 0) {
				// 前回時刻の高度と比較し、境界値を跨いだ時刻を出没時刻として表示する.
				if (sun0.z < 0 && sun.z >= 0) print_table("SUN-RISE", t);
				if (sun0.z >= 0 && sun.z < 0) print_table("SUN-SET",  t);
				if (moon0.z < 0 && moon.z >= 0) print_table("MOON-RISE", t);
				if (moon0.z >= 0 && moon.z < 0) print_table("MOON-SET",  t);
				// 前回時刻の東西と比較し、子午線を跨いだ時刻を南中時刻として表示する.
				if (sun0.y >= 0 && sun.y < 0) print_table("SUN-CULM",  t);
				if (moon0.y >= 0 && moon.y < 0) print_table("MOON-CULM",  t);
			}
			double z = min_value(fabs(sun.z), fabs(moon.z));
			double y = min_value(fabs(sun.y), fabs(moon.y));
			z = min_value(z, y);	// 地平線通過、子午線通過付近の最小座標値を求める.
			if (z >= min30_z)
				step = 20*60; // 高度が±時角30分以上なら20分単位で時刻を進める.
			else if (z >= min3_z)
				step = 2*60; // 高度が±時角3分以上なら2分単位で時刻を進める.
			else if (z >= sec15_z)
				step = 10; // 高度が±時角15秒以上なら10秒単位で時刻を進める.
			else
				step = 1; // 1秒単位で時刻を進める.
		}
	}
}
Esempio n. 25
0
double cos(const Degree& degree)
{
    return std::cos(degree.toRadian());
}
Esempio n. 26
0
double tan(const Degree& degree)
{
    return std::tan(degree.toRadian());
}
    bool StepRecognitionMovement::run(Ogre::Real elapsedTime,  Ogre::Vector3 direction, Ogre::Vector3 rotation)
    {
        Vector3 vel = mMovingCreature->getCreature()->getActor()->getPhysicalThing()->getVelocity();
        Real velY = vel.y;
        vel.y = 0;
        // raycast in the direction we should move to
        Vector3 globalDir = mMovingCreature->getCreature()->getOrientation() * direction; // the direction in global space
        if( globalDir == Vector3::ZERO )
            return true;



        // the materials that are triggered here
        PhysicsMaterialRaycast::MaterialVector materialVector;
        materialVector.push_back(PhysicsManager::getSingleton().getMaterialID("character")); // should we perhaps only use level here?
        materialVector.push_back(PhysicsManager::getSingleton().getMaterialID("camera"));



        // first of all check if we are not standing in front of a wall or sth like this
        PhysicalThing *thing = mMovingCreature->getCreature()->getActor()->getPhysicalThing();
        Real height = thing->_getBody()->getCollision()->getAABB().getSize().y;
        Vector3 start = mMovingCreature->getCreature()->getPosition() + Vector3(0,height/2,0);
        Vector3 end = start + globalDir * 0.5;
        RaycastInfo info;
        info = mRaycast.execute(
                PhysicsManager::getSingleton()._getNewtonWorld(),
                &materialVector,
                start,
                end,
                true);
        if(info.mBody)
        {
            mMoveToNextTarget = false;
            return false;
        }



        if( !mMoveToNextTarget ) // check if we need to move up for a step
        {
            Real raylen = vel.length() / 3;  // use longer ray, if higher velocity
            if ( raylen < 0.5 )
                raylen = 0.4;

            //std::ostringstream oss;
            //oss << "StepRecognition Raylen: " << raylen;
            //LOG_MESSAGE(Logger::RULES, oss.str());


            // raycasts
            Vector3 start = mMovingCreature->getCreature()->getPosition() + Vector3::UNIT_Y * 0.1f;
            globalDir.y = 0;
            globalDir.normalise();
            Vector3 end = start + globalDir*raylen;

            bool foundbody = false;
            Real foundDistance = 0;

            RaycastInfo info;
            do
            {
                info = 
                    mRaycast.execute(
                            PhysicsManager::getSingleton()._getNewtonWorld(),
                            &materialVector,
                            start, end, true);

                // do we need to check bodies left and right of this ray? (step width?)


                // already found nearer body
                if( foundbody )
                {
                    if( info.mBody && (info.mDistance*raylen >= foundDistance*raylen + 0.19) || // step deep enough
                            !info.mBody )
                    {
                        // found a step
                        mMoveToNextTarget = true;
                        mNextTarget = start + globalDir*raylen*foundDistance + 0.1 * globalDir;
                        std::ostringstream oss;
                        Vector3 stepInLocalCoords = mNextTarget - mMovingCreature->getCreature()->getPosition();
                        Quaternion ori = mMovingCreature->getCreature()->getOrientation();
                        stepInLocalCoords = ori.Inverse() * stepInLocalCoords;
                        oss << "Step-Recognition: Next Step: " << stepInLocalCoords;
                        LOG_MESSAGE(Logger::RULES, oss.str());
                        break;
                    }
                }

                if( info.mBody )
                {
                    foundbody = true;
                    foundDistance = info.mDistance;
                }


                start += Vector3::UNIT_Y * 0.05f;
                end += Vector3::UNIT_Y * 0.05f;
            }
            while( info.mBody && (start - mMovingCreature->getCreature()->getPosition()).y <= 0.5 );
        }


        // check if the target is still needed
        // perform check also to verify found step
        if( mMoveToNextTarget )
        {
            Vector3 diffToTarget = mNextTarget - mMovingCreature->getCreature()->getPosition();
            Real diffToTargetY = diffToTarget.y;
            diffToTarget.y = 0;

            // different direction
            Vector3 globalDir = mMovingCreature->getCreature()->getOrientation() * direction; // the direction in global space
            globalDir.y = 0;


            if( globalDir == Vector3::ZERO )
            {
                mMoveToNextTarget = false;
                LOG_MESSAGE(Logger::RULES, "Testing Step-Recognition: Step direction null");
                return false;
            }

            // target reached
            if( diffToTarget.squaredLength() < 0.01)
            {
                mMoveToNextTarget = false;
                LOG_MESSAGE(Logger::RULES, "Testing Step-Recognition: Step reached");
                return false;
            }

            // different direction
            Quaternion oriDiff = diffToTarget.getRotationTo(globalDir, Vector3::UNIT_Y);
            Degree angleDiff;
            Vector3 axis = Vector3::UNIT_Y;
            oriDiff.ToAngleAxis(angleDiff, axis);
            Real f = angleDiff.valueDegrees();
            //std::ostringstream oss;
            //oss << "Step-Recognition: angle: " << f << "    axis: " << axis;
            //LOG_MESSAGE(Logger::RULES, oss.str());
            //if( !diffToTarget.directionEquals(globalDir, Degree(15)) )
            if( f > 2.0f )
            {
                mMoveToNextTarget = false;
                //LOG_MESSAGE(Logger::RULES, "Testing Step-Recognition: Step direction wrong");
                return false;
            }


            // already above target, but slow velocity
            if( diffToTargetY < 0 && fabs(velY) < 0.01 )
            {
                mMoveToNextTarget = false;
                //LOG_MESSAGE(Logger::RULES, "Testing Step-Recognition: slow and abov target-height!");
                return false;
            }
        }

        return mMoveToNextTarget;
    }