mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-23 08:39:18 +02:00
no pneumatic relay sound on brake acting speed change, enabled playback of multiple bookend sounds, extra pantograph control for ai during longer stops, shadow angle calculation tweak, moon appearance tweak, minor bug fixes
This commit is contained in:
116
Driver.cpp
116
Driver.cpp
@@ -1212,8 +1212,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ // zawalidrogi nie ma (albo pojazd jest samochodem), sprawdzić sygnał
|
{ // zawalidrogi nie ma (albo pojazd jest samochodem), sprawdzić sygnał
|
||||||
if (sSpeedTable[i].iFlags & spShuntSemaphor) // jeśli Tm - w zasadzie to sprawdzić
|
if (sSpeedTable[i].iFlags & spShuntSemaphor) // jeśli Tm - w zasadzie to sprawdzić komendę!
|
||||||
// komendę!
|
|
||||||
{ // jeśli podana prędkość manewrowa
|
{ // jeśli podana prędkość manewrowa
|
||||||
if ((OrderCurrentGet() & Obey_train) ? v == 0.0 : false)
|
if ((OrderCurrentGet() & Obey_train) ? v == 0.0 : false)
|
||||||
{ // jeśli tryb pociągowy a tarcze ma ShuntVelocity 0 0
|
{ // jeśli tryb pociągowy a tarcze ma ShuntVelocity 0 0
|
||||||
@@ -3340,8 +3339,7 @@ bool TController::PutCommand( std::string NewCommand, double NewValue1, double N
|
|||||||
iDirectionOrder = -iDirection; // jak się podczepi, to jazda w przeciwną stronę
|
iDirectionOrder = -iDirection; // jak się podczepi, to jazda w przeciwną stronę
|
||||||
OrderNext(Change_direction);
|
OrderNext(Change_direction);
|
||||||
}
|
}
|
||||||
WaitingTime =
|
WaitingTime = 0.0; // nie ma co dalej czekać, można zatrąbić i jechać, chyba że już jedzie
|
||||||
0.0; // nie ma co dalej czekać, można zatrąbić i jechać, chyba że już jedzie
|
|
||||||
}
|
}
|
||||||
else // if (NewValue2==0.0) //zerowy sprzęg
|
else // if (NewValue2==0.0) //zerowy sprzęg
|
||||||
if (NewValue1 >= 0.0) // jeśli ilość wagonów inna niż wszystkie
|
if (NewValue1 >= 0.0) // jeśli ilość wagonów inna niż wszystkie
|
||||||
@@ -3358,8 +3356,7 @@ bool TController::PutCommand( std::string NewCommand, double NewValue1, double N
|
|||||||
else if (mvOccupied->Couplers[mvOccupied->DirAbsolute > 0 ? 1 : 0].CouplingFlag >
|
else if (mvOccupied->Couplers[mvOccupied->DirAbsolute > 0 ? 1 : 0].CouplingFlag >
|
||||||
0) // z tyłu coś
|
0) // z tyłu coś
|
||||||
OrderNext(Disconnect); // jak ciągnie, to tylko odczep (NewValue1) wagonów
|
OrderNext(Disconnect); // jak ciągnie, to tylko odczep (NewValue1) wagonów
|
||||||
WaitingTime =
|
WaitingTime = 0.0; // nie ma co dalej czekać, można zatrąbić i jechać, chyba że już jedzie
|
||||||
0.0; // nie ma co dalej czekać, można zatrąbić i jechać, chyba że już jedzie
|
|
||||||
}
|
}
|
||||||
if (NewValue1 == -1.0)
|
if (NewValue1 == -1.0)
|
||||||
{
|
{
|
||||||
@@ -3495,6 +3492,13 @@ TController::UpdateSituation(double dt) {
|
|||||||
fActionTime += dt; // czas używany przy regulacji prędkości i zamykaniu drzwi
|
fActionTime += dt; // czas używany przy regulacji prędkości i zamykaniu drzwi
|
||||||
LastReactionTime += dt;
|
LastReactionTime += dt;
|
||||||
LastUpdatedTime += dt;
|
LastUpdatedTime += dt;
|
||||||
|
if( ( mvOccupied->Vel < 0.05 )
|
||||||
|
&& ( ( OrderCurrentGet() & ( Obey_train | Shunt ) ) != 0 ) ) {
|
||||||
|
IdleTime += dt;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
IdleTime = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
// log vehicle data
|
// log vehicle data
|
||||||
if( ( WriteLogFlag )
|
if( ( WriteLogFlag )
|
||||||
@@ -3628,15 +3632,13 @@ TController::UpdateSituation(double dt) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mvOccupied->Vel > 0.0) {
|
if( mvOccupied->Vel > 1.0 ) {
|
||||||
// jeżeli jedzie
|
// jeżeli jedzie
|
||||||
if( iDrivigFlags & moveDoorOpened ) {
|
if( iDrivigFlags & moveDoorOpened ) {
|
||||||
// jeśli drzwi otwarte
|
// jeśli drzwi otwarte
|
||||||
if( mvOccupied->Vel > 1.0 ) {
|
|
||||||
// nie zamykać drzwi przy drganiach, bo zatrzymanie na W4 akceptuje niewielkie prędkości
|
// nie zamykać drzwi przy drganiach, bo zatrzymanie na W4 akceptuje niewielkie prędkości
|
||||||
Doors( false );
|
Doors( false );
|
||||||
}
|
}
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
// NOTE: this section moved all cars to the edge of their respective roads
|
// NOTE: this section moved all cars to the edge of their respective roads
|
||||||
// it may have some use eventually for collision avoidance,
|
// it may have some use eventually for collision avoidance,
|
||||||
@@ -3650,43 +3652,63 @@ TController::UpdateSituation(double dt) {
|
|||||||
mvOccupied->ChangeOffsetH(0.01 * mvOccupied->Vel *
|
mvOccupied->ChangeOffsetH(0.01 * mvOccupied->Vel *
|
||||||
dt); // Ra: co to miało być, to nie wiem
|
dt); // Ra: co to miało być, to nie wiem
|
||||||
*/
|
*/
|
||||||
if (mvControlling->EnginePowerSource.SourceType == CurrentCollector)
|
}
|
||||||
{
|
|
||||||
if ((fOverhead2 >= 0.0) || iOverheadZero)
|
if (mvControlling->EnginePowerSource.SourceType == CurrentCollector) {
|
||||||
{ // jeśli jazda bezprądowa albo z opuszczonym pantografem
|
|
||||||
|
if( mvOccupied->Vel > 0.05 ) {
|
||||||
|
// is moving
|
||||||
|
if( ( fOverhead2 >= 0.0 ) || iOverheadZero ) {
|
||||||
|
// jeśli jazda bezprądowa albo z opuszczonym pantografem
|
||||||
while( DecSpeed( true ) ) { ; } // zerowanie napędu
|
while( DecSpeed( true ) ) { ; } // zerowanie napędu
|
||||||
}
|
}
|
||||||
if ((fOverhead2 > 0.0) || iOverheadDown)
|
if( ( fOverhead2 > 0.0 ) || iOverheadDown ) {
|
||||||
{ // jazda z opuszczonymi pantografami
|
// jazda z opuszczonymi pantografami
|
||||||
mvControlling->PantFront( false );
|
mvControlling->PantFront( false );
|
||||||
mvControlling->PantRear( false );
|
mvControlling->PantRear( false );
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{ // jeśli nie trzeba opuszczać pantografów
|
// jeśli nie trzeba opuszczać pantografów
|
||||||
if (iDirection >= 0) // jak jedzie w kierunku sprzęgu 0
|
// jazda na tylnym
|
||||||
mvControlling->PantRear(true); // jazda na tylnym
|
if( iDirection >= 0 ) {
|
||||||
else
|
// jak jedzie w kierunku sprzęgu 0
|
||||||
|
mvControlling->PantRear( true );
|
||||||
|
}
|
||||||
|
else {
|
||||||
mvControlling->PantFront( true );
|
mvControlling->PantFront( true );
|
||||||
}
|
}
|
||||||
if (mvOccupied->Vel > 10) // opuszczenie przedniego po rozpędzeniu się
|
}
|
||||||
{
|
if( mvOccupied->Vel > 10 ) {
|
||||||
if (mvControlling->EnginePowerSource.CollectorParameters.CollectorsNo >
|
// opuszczenie przedniego po rozpędzeniu się o ile jest więcej niż jeden
|
||||||
1) // o ile jest więcej niż jeden
|
if( mvControlling->EnginePowerSource.CollectorParameters.CollectorsNo > 1 ) {
|
||||||
if( iDirection >= 0 ) // jak jedzie w kierunku sprzęgu 0
|
if( iDirection >= 0 ) // jak jedzie w kierunku sprzęgu 0
|
||||||
{ // poczekać na podniesienie tylnego
|
{ // poczekać na podniesienie tylnego
|
||||||
if (mvControlling->PantRearVolt !=
|
if( mvControlling->PantRearVolt != 0.0 ) {
|
||||||
0.0) // czy jest napięcie zasilające na tylnym?
|
// czy jest napięcie zasilające na tylnym?
|
||||||
mvControlling->PantFront( false ); // opuszcza od sprzęgu 0
|
mvControlling->PantFront( false ); // opuszcza od sprzęgu 0
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
{ // poczekać na podniesienie przedniego
|
else { // poczekać na podniesienie przedniego
|
||||||
if (mvControlling->PantFrontVolt !=
|
if( mvControlling->PantFrontVolt != 0.0 ) {
|
||||||
0.0) // czy jest napięcie zasilające na przednim?
|
// czy jest napięcie zasilające na przednim?
|
||||||
mvControlling->PantRear( false ); // opuszcza od sprzęgu 1
|
mvControlling->PantRear( false ); // opuszcza od sprzęgu 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if( ( IdleTime > 45.0 )
|
||||||
|
// NOTE: abs(stoptime) covers either at least 15 sec remaining for a scheduled stop, or 15+ secs spent at a basic stop
|
||||||
|
&& ( std::abs( fStopTime ) > 15.0 ) ) {
|
||||||
|
// spending a longer at a stop, raise also front pantograph
|
||||||
|
if( iDirection >= 0 ) // jak jedzie w kierunku sprzęgu 0
|
||||||
|
mvControlling->PantFront( true );
|
||||||
|
else
|
||||||
|
mvControlling->PantRear( true );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// horn control
|
// horn control
|
||||||
if( fWarningDuration > 0.0 ) {
|
if( fWarningDuration > 0.0 ) {
|
||||||
@@ -4200,29 +4222,19 @@ TController::UpdateSituation(double dt) {
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
SetDriverPsyche(); // Ra: było w PrepareEngine(), potrzebne tu?
|
SetDriverPsyche(); // Ra: było w PrepareEngine(), potrzebne tu?
|
||||||
// no albo przypisujemy -WaitingExpireTime, albo porównujemy z WaitingExpireTime
|
|
||||||
// if
|
if (OrderList[OrderPos] & (Shunt | Obey_train | Connect)) {
|
||||||
// ((VelSignal==0.0)&&(WaitingTime>WaitingExpireTime)&&(mvOccupied->RunningTrack.Velmax!=0.0))
|
// odjechać sam może tylko jeśli jest w trybie jazdy
|
||||||
if (OrderList[OrderPos] &
|
// automatyczne ruszanie po odstaniu albo spod SBL
|
||||||
(Shunt | Obey_train | Connect)) // odjechać sam może tylko jeśli jest w trybie jazdy
|
if( ( VelSignal == 0.0 )
|
||||||
{ // automatyczne ruszanie po odstaniu albo spod SBL
|
&& ( WaitingTime > 0.0 )
|
||||||
if ((VelSignal == 0.0) && (WaitingTime > 0.0) &&
|
&& ( mvOccupied->RunningTrack.Velmax != 0.0 ) ) {
|
||||||
(mvOccupied->RunningTrack.Velmax != 0.0))
|
// jeśli stoi, a upłynął czas oczekiwania i tor ma niezerową prędkość
|
||||||
{ // jeśli stoi, a upłynął czas oczekiwania i tor ma niezerową prędkość
|
if( ( OrderList[ OrderPos ] & ( Obey_train | Shunt ) )
|
||||||
/*
|
&& ( iDrivigFlags & moveStopHere ) ) {
|
||||||
if (WriteLogFlag)
|
// zakaz ruszania z miejsca bez otrzymania wolnej drogi
|
||||||
{
|
WaitingTime = -WaitingExpireTime;
|
||||||
append(AIlogFile);
|
|
||||||
writeln(AILogFile,ElapsedTime:5:2,": ",Name," V=0 waiting time expired!
|
|
||||||
(",WaitingTime:4:1,")");
|
|
||||||
close(AILogFile);
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
if ((OrderList[OrderPos] & (Obey_train | Shunt)) ?
|
|
||||||
(iDrivigFlags & moveStopHere) :
|
|
||||||
false)
|
|
||||||
WaitingTime = -WaitingExpireTime; // zakaz ruszania z miejsca bez otrzymania
|
|
||||||
// wolnej drogi
|
|
||||||
else if (mvOccupied->CategoryFlag & 1)
|
else if (mvOccupied->CategoryFlag & 1)
|
||||||
{ // jeśli pociąg
|
{ // jeśli pociąg
|
||||||
if (AIControllFlag)
|
if (AIControllFlag)
|
||||||
|
|||||||
1
Driver.h
1
Driver.h
@@ -291,6 +291,7 @@ private:
|
|||||||
double fStopTime = 0.0; // czas postoju przed dalszą jazdą (np. na przystanku)
|
double fStopTime = 0.0; // czas postoju przed dalszą jazdą (np. na przystanku)
|
||||||
double WaitingTime = 0.0; // zliczany czas oczekiwania do samoistnego ruszenia
|
double WaitingTime = 0.0; // zliczany czas oczekiwania do samoistnego ruszenia
|
||||||
double WaitingExpireTime = 31.0; // tyle ma czekać, zanim się ruszy // maksymlany czas oczekiwania do samoistnego ruszenia
|
double WaitingExpireTime = 31.0; // tyle ma czekać, zanim się ruszy // maksymlany czas oczekiwania do samoistnego ruszenia
|
||||||
|
double IdleTime {}; // keeps track of time spent at a stop
|
||||||
|
|
||||||
private: //---//---//---//---// koniec zmiennych, poniżej metody //---//---//---//---//
|
private: //---//---//---//---// koniec zmiennych, poniżej metody //---//---//---//---//
|
||||||
void SetDriverPsyche();
|
void SetDriverPsyche();
|
||||||
|
|||||||
@@ -1106,9 +1106,10 @@ void TDynamicObject::ABuCheckMyTrack()
|
|||||||
// do jednej tablicy. Wykonuje sie tylko raz - po to 'ABuChecked'
|
// do jednej tablicy. Wykonuje sie tylko raz - po to 'ABuChecked'
|
||||||
TTrack *OldTrack = MyTrack;
|
TTrack *OldTrack = MyTrack;
|
||||||
TTrack *NewTrack = Axle0.GetTrack();
|
TTrack *NewTrack = Axle0.GetTrack();
|
||||||
if ((NewTrack != OldTrack) && OldTrack)
|
if( NewTrack != OldTrack ) {
|
||||||
{
|
if( OldTrack ) {
|
||||||
OldTrack->RemoveDynamicObject( this );
|
OldTrack->RemoveDynamicObject( this );
|
||||||
|
}
|
||||||
NewTrack->AddDynamicObject(this);
|
NewTrack->AddDynamicObject(this);
|
||||||
}
|
}
|
||||||
iAxleFirst = 0; // pojazd powiązany z przednią osią - Axle0
|
iAxleFirst = 0; // pojazd powiązany z przednią osią - Axle0
|
||||||
|
|||||||
@@ -2974,10 +2974,7 @@ bool TMoverParameters::BrakeDelaySwitch(int BDS)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
rBDS = false;
|
rBDS = false;
|
||||||
if( true == rBDS ) {
|
|
||||||
// if setting was changed emit the sound of pneumatic relay
|
|
||||||
SetFlag( SoundFlag, sound::pneumatic );
|
|
||||||
}
|
|
||||||
return rBDS;
|
return rBDS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -8128,7 +8125,10 @@ bool TMoverParameters::CheckLocomotiveParameters(bool ReadyFlag, int Dir)
|
|||||||
{
|
{
|
||||||
WriteLog( "Ready to depart" );
|
WriteLog( "Ready to depart" );
|
||||||
CompressedVolume = VeselVolume * MinCompressor * ( 9.8 ) / 10.0;
|
CompressedVolume = VeselVolume * MinCompressor * ( 9.8 ) / 10.0;
|
||||||
ScndPipePress = CompressedVolume / VeselVolume;
|
ScndPipePress = (
|
||||||
|
VeselVolume > 0.0 ?
|
||||||
|
CompressedVolume / VeselVolume :
|
||||||
|
0.0 );
|
||||||
PipePress = CntrlPipePress;
|
PipePress = CntrlPipePress;
|
||||||
BrakePress = 0.0;
|
BrakePress = 0.0;
|
||||||
LocalBrakePos = 0;
|
LocalBrakePos = 0;
|
||||||
@@ -8633,8 +8633,6 @@ bool TMoverParameters::RunCommand( std::string Command, double CValue1, double C
|
|||||||
if( true == Hamulec->SetBDF( brakesetting ) ) {
|
if( true == Hamulec->SetBDF( brakesetting ) ) {
|
||||||
BrakeDelayFlag = brakesetting;
|
BrakeDelayFlag = brakesetting;
|
||||||
OK = true;
|
OK = true;
|
||||||
// if setting was changed emit the sound of pneumatic relay
|
|
||||||
SetFlag( SoundFlag, sound::pneumatic );
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
OK = false;
|
OK = false;
|
||||||
|
|||||||
@@ -1223,7 +1223,7 @@ bool TModel3d::LoadFromFile(std::string const &FileName, bool dynamic)
|
|||||||
{
|
{
|
||||||
if (FileExists(name + ".t3d"))
|
if (FileExists(name + ".t3d"))
|
||||||
{
|
{
|
||||||
LoadFromTextFile(FileName, dynamic); // wczytanie tekstowego
|
LoadFromTextFile(name + ".t3d", dynamic); // wczytanie tekstowego
|
||||||
if( !dynamic ) {
|
if( !dynamic ) {
|
||||||
// pojazdy dopiero po ustawieniu animacji
|
// pojazdy dopiero po ustawieniu animacji
|
||||||
Init(); // generowanie siatek i zapis E3D
|
Init(); // generowanie siatek i zapis E3D
|
||||||
|
|||||||
@@ -3805,7 +3805,7 @@ bool TTrain::Update( double const Deltatime )
|
|||||||
if( m_linebreakerstate == 2 ) {
|
if( m_linebreakerstate == 2 ) {
|
||||||
// for diesels and/or vehicles with toggle switch setup we complete the engine start here
|
// for diesels and/or vehicles with toggle switch setup we complete the engine start here
|
||||||
// TBD, TODO: arrange a better way to start the diesel engines
|
// TBD, TODO: arrange a better way to start the diesel engines
|
||||||
if( ( ggMainOffButton.SubModel == nullptr )
|
if( ( ggMainOnButton.SubModel == nullptr )
|
||||||
|| ( ( mvControlled->EngineType == DieselEngine )
|
|| ( ( mvControlled->EngineType == DieselEngine )
|
||||||
|| ( mvControlled->EngineType == DieselElectric ) ) ) {
|
|| ( mvControlled->EngineType == DieselElectric ) ) ) {
|
||||||
if( mvControlled->MainSwitch( true ) ) {
|
if( mvControlled->MainSwitch( true ) ) {
|
||||||
@@ -4277,13 +4277,13 @@ bool TTrain::Update( double const Deltatime )
|
|||||||
}
|
}
|
||||||
|
|
||||||
btLampkaWylSzybki.Turn(
|
btLampkaWylSzybki.Turn(
|
||||||
( ( (m_linebreakerstate > 0)
|
( ( (m_linebreakerstate == 2)
|
||||||
|| (true == mvControlled->Mains) ) ?
|
|| (true == mvControlled->Mains) ) ?
|
||||||
true :
|
true :
|
||||||
false ) );
|
false ) );
|
||||||
// NOTE: 'off' variant uses the same test, but opposite resulting states
|
// NOTE: 'off' variant uses the same test, but opposite resulting states
|
||||||
btLampkaWylSzybkiOff.Turn(
|
btLampkaWylSzybkiOff.Turn(
|
||||||
( ( ( m_linebreakerstate > 0 )
|
( ( ( m_linebreakerstate == 2 )
|
||||||
|| ( true == mvControlled->Mains ) ) ?
|
|| ( true == mvControlled->Mains ) ) ?
|
||||||
false :
|
false :
|
||||||
true ) );
|
true ) );
|
||||||
|
|||||||
18
TrkFoll.cpp
18
TrkFoll.cpp
@@ -189,18 +189,19 @@ bool TTrackFollower::Move(double fDistance, bool bPrimary)
|
|||||||
*/
|
*/
|
||||||
if (s < 0)
|
if (s < 0)
|
||||||
{ // jeśli przekroczenie toru od strony Point1
|
{ // jeśli przekroczenie toru od strony Point1
|
||||||
bCanSkip = bPrimary ? pCurrentTrack->CheckDynamicObject(Owner) : false;
|
bCanSkip = ( bPrimary && pCurrentTrack->CheckDynamicObject( Owner ) );
|
||||||
if (bCanSkip) // tylko główna oś przenosi pojazd do innego toru
|
if( bCanSkip ) {
|
||||||
Owner->MyTrack->RemoveDynamicObject(
|
// tylko główna oś przenosi pojazd do innego toru
|
||||||
Owner); // zdejmujemy pojazd z dotychczasowego toru
|
// zdejmujemy pojazd z dotychczasowego toru
|
||||||
|
Owner->MyTrack->RemoveDynamicObject( Owner );
|
||||||
|
}
|
||||||
dir = fDirection;
|
dir = fDirection;
|
||||||
if (pCurrentTrack->eType == tt_Cross)
|
if (pCurrentTrack->eType == tt_Cross)
|
||||||
{
|
{
|
||||||
if (!SetCurrentTrack(pCurrentTrack->Connected(iSegment, fDirection), 0))
|
if (!SetCurrentTrack(pCurrentTrack->Connected(iSegment, fDirection), 0))
|
||||||
return false; // wyjście z błędem
|
return false; // wyjście z błędem
|
||||||
}
|
}
|
||||||
else if (!SetCurrentTrack(pCurrentTrack->Connected(-1, fDirection),
|
else if (!SetCurrentTrack(pCurrentTrack->Connected(-1, fDirection), 0)) // ustawia fDirection
|
||||||
0)) // ustawia fDirection
|
|
||||||
return false; // wyjście z błędem
|
return false; // wyjście z błędem
|
||||||
if (dir == fDirection) //(pCurrentTrack->iPrevDirection)
|
if (dir == fDirection) //(pCurrentTrack->iPrevDirection)
|
||||||
{ // gdy kierunek bez zmiany (Point1->Point2)
|
{ // gdy kierunek bez zmiany (Point1->Point2)
|
||||||
@@ -215,8 +216,7 @@ bool TTrackFollower::Move(double fDistance, bool bPrimary)
|
|||||||
if (bCanSkip)
|
if (bCanSkip)
|
||||||
{ // jak główna oś, to dodanie pojazdu do nowego toru
|
{ // jak główna oś, to dodanie pojazdu do nowego toru
|
||||||
pCurrentTrack->AddDynamicObject(Owner);
|
pCurrentTrack->AddDynamicObject(Owner);
|
||||||
iEventFlag =
|
iEventFlag = 3; // McZapkie-020602: umozliwienie uruchamiania event1,2 po zmianie toru
|
||||||
3; // McZapkie-020602: umozliwienie uruchamiania event1,2 po zmianie toru
|
|
||||||
iEventallFlag = 3; // McZapkie-280503: jw, dla eventall1,2
|
iEventallFlag = 3; // McZapkie-280503: jw, dla eventall1,2
|
||||||
if (!Owner->MyTrack)
|
if (!Owner->MyTrack)
|
||||||
return false;
|
return false;
|
||||||
@@ -225,7 +225,7 @@ bool TTrackFollower::Move(double fDistance, bool bPrimary)
|
|||||||
}
|
}
|
||||||
else if (s > pCurrentSegment->GetLength())
|
else if (s > pCurrentSegment->GetLength())
|
||||||
{ // jeśli przekroczenie toru od strony Point2
|
{ // jeśli przekroczenie toru od strony Point2
|
||||||
bCanSkip = bPrimary ? pCurrentTrack->CheckDynamicObject(Owner) : false;
|
bCanSkip = ( bPrimary && pCurrentTrack->CheckDynamicObject( Owner ) );
|
||||||
if (bCanSkip) // tylko główna oś przenosi pojazd do innego toru
|
if (bCanSkip) // tylko główna oś przenosi pojazd do innego toru
|
||||||
Owner->MyTrack->RemoveDynamicObject(
|
Owner->MyTrack->RemoveDynamicObject(
|
||||||
Owner); // zdejmujemy pojazd z dotychczasowego toru
|
Owner); // zdejmujemy pojazd z dotychczasowego toru
|
||||||
|
|||||||
@@ -2170,7 +2170,7 @@ world_environment::update() {
|
|||||||
if( moonlightlevel > sunlightlevel ) {
|
if( moonlightlevel > sunlightlevel ) {
|
||||||
// rare situations when the moon is brighter than the sun, typically at night
|
// rare situations when the moon is brighter than the sun, typically at night
|
||||||
Global.SunAngle = m_moon.getAngle();
|
Global.SunAngle = m_moon.getAngle();
|
||||||
Global.DayLight.position = m_moon.getPosition();
|
Global.DayLight.position = m_moon.getDirection();
|
||||||
Global.DayLight.direction = -1.0f * m_moon.getDirection();
|
Global.DayLight.direction = -1.0f * m_moon.getDirection();
|
||||||
keylightintensity = moonlightlevel;
|
keylightintensity = moonlightlevel;
|
||||||
// if the moon is up, it overrides the twilight
|
// if the moon is up, it overrides the twilight
|
||||||
|
|||||||
24
moon.cpp
24
moon.cpp
@@ -36,11 +36,11 @@ void
|
|||||||
cMoon::update() {
|
cMoon::update() {
|
||||||
|
|
||||||
move();
|
move();
|
||||||
glm::vec3 position( 0.f, 0.f, -2000.f * Global.fDistanceFactor );
|
glm::vec3 position( 0.f, 0.f, -1.f );
|
||||||
position = glm::rotateX( position, glm::radians( static_cast<float>( m_body.elevref ) ) );
|
position = glm::rotateX( position, glm::radians( static_cast<float>( m_body.elevref ) ) );
|
||||||
position = glm::rotateY( position, glm::radians( static_cast<float>( -m_body.hrang ) ) );
|
position = glm::rotateY( position, glm::radians( static_cast<float>( -m_body.hrang ) ) );
|
||||||
|
|
||||||
m_position = position;
|
m_position = glm::normalize( position );
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -48,12 +48,13 @@ cMoon::render() {
|
|||||||
|
|
||||||
::glColor4f( 225.f / 255.f, 225.f / 255.f, 255.f / 255.f, 1.f );
|
::glColor4f( 225.f / 255.f, 225.f / 255.f, 255.f / 255.f, 1.f );
|
||||||
// debug line to locate the moon easier
|
// debug line to locate the moon easier
|
||||||
|
auto const position { m_position * 2000.f };
|
||||||
::glBegin( GL_LINES );
|
::glBegin( GL_LINES );
|
||||||
::glVertex3fv( glm::value_ptr( m_position ) );
|
::glVertex3fv( glm::value_ptr( position ) );
|
||||||
::glVertex3f( m_position.x, 0.f, m_position.z );
|
::glVertex3f( position.x, 0.f, position.z );
|
||||||
::glEnd();
|
::glEnd();
|
||||||
::glPushMatrix();
|
::glPushMatrix();
|
||||||
::glTranslatef( m_position.x, m_position.y, m_position.z );
|
::glTranslatef( position.x, position.y, position.z );
|
||||||
::gluSphere( moonsphere, /* (float)( Global.iWindowHeight / Global.FieldOfView ) * 0.5 * */ ( m_body.distance / 60.2666 ) * 9.037461, 12, 12 );
|
::gluSphere( moonsphere, /* (float)( Global.iWindowHeight / Global.FieldOfView ) * 0.5 * */ ( m_body.distance / 60.2666 ) * 9.037461, 12, 12 );
|
||||||
::glPopMatrix();
|
::glPopMatrix();
|
||||||
}
|
}
|
||||||
@@ -61,7 +62,7 @@ cMoon::render() {
|
|||||||
glm::vec3
|
glm::vec3
|
||||||
cMoon::getDirection() {
|
cMoon::getDirection() {
|
||||||
|
|
||||||
return glm::normalize( m_position );
|
return m_position;
|
||||||
}
|
}
|
||||||
|
|
||||||
float
|
float
|
||||||
@@ -117,14 +118,15 @@ void cMoon::move() {
|
|||||||
if( m_observer.minute >= 0 ) { localtime.wMinute = m_observer.minute; }
|
if( m_observer.minute >= 0 ) { localtime.wMinute = m_observer.minute; }
|
||||||
if( m_observer.second >= 0 ) { localtime.wSecond = m_observer.second; }
|
if( m_observer.second >= 0 ) { localtime.wSecond = m_observer.second; }
|
||||||
|
|
||||||
double ut = localtime.wHour
|
double ut =
|
||||||
+ localtime.wMinute / 60.0; // too low resolution, noticeable skips
|
localtime.wHour
|
||||||
// NOTE: finer resolution disabled to reduce shadow crawl in current implementation
|
+ localtime.wMinute / 60.0 // too low resolution, noticeable skips
|
||||||
|
+ localtime.wSecond / 3600.0; // good enough in normal circumstances
|
||||||
/*
|
/*
|
||||||
+ localtime.wSecond / 3600.0 // good enough in normal circumstances
|
|
||||||
+ localtime.wMilliseconds / 3600000.0; // for really smooth movement
|
+ localtime.wMilliseconds / 3600000.0; // for really smooth movement
|
||||||
*/
|
*/
|
||||||
double daynumber = 367 * localtime.wYear
|
double daynumber
|
||||||
|
= 367 * localtime.wYear
|
||||||
- 7 * ( localtime.wYear + ( localtime.wMonth + 9 ) / 12 ) / 4
|
- 7 * ( localtime.wYear + ( localtime.wMonth + 9 ) / 12 ) / 4
|
||||||
+ 275 * localtime.wMonth / 9
|
+ 275 * localtime.wMonth / 9
|
||||||
+ localtime.wDay
|
+ localtime.wDay
|
||||||
|
|||||||
2
moon.h
2
moon.h
@@ -16,8 +16,6 @@ public:
|
|||||||
void init();
|
void init();
|
||||||
void update();
|
void update();
|
||||||
void render();
|
void render();
|
||||||
// returns location of the sun in the 3d scene
|
|
||||||
glm::vec3 getPosition() { return m_position; }
|
|
||||||
// returns vector pointing at the sun
|
// returns vector pointing at the sun
|
||||||
glm::vec3 getDirection();
|
glm::vec3 getDirection();
|
||||||
// returns current elevation above horizon
|
// returns current elevation above horizon
|
||||||
|
|||||||
33
renderer.cpp
33
renderer.cpp
@@ -397,7 +397,12 @@ opengl_renderer::Render() {
|
|||||||
Timer::subsystem.gfx_total.start(); // note: gfx_total is actually frame total, clean this up
|
Timer::subsystem.gfx_total.start(); // note: gfx_total is actually frame total, clean this up
|
||||||
Timer::subsystem.gfx_color.start();
|
Timer::subsystem.gfx_color.start();
|
||||||
// fetch simulation data
|
// fetch simulation data
|
||||||
|
if( World.InitPerformed() ) {
|
||||||
m_sunlight = Global.DayLight;
|
m_sunlight = Global.DayLight;
|
||||||
|
// quantize sun angle to reduce shadow crawl
|
||||||
|
auto const quantizationstep { 0.004f };
|
||||||
|
m_sunlight.direction = glm::normalize( quantizationstep * glm::roundEven( m_sunlight.direction * ( 1.f / quantizationstep ) ) );
|
||||||
|
}
|
||||||
// generate new frame
|
// generate new frame
|
||||||
m_renderpass.draw_mode = rendermode::none; // force setup anew
|
m_renderpass.draw_mode = rendermode::none; // force setup anew
|
||||||
m_debugtimestext.clear();
|
m_debugtimestext.clear();
|
||||||
@@ -420,24 +425,7 @@ opengl_renderer::Render() {
|
|||||||
+ "; dyn: " + to_string( m_debugstats.dynamics ) + " mod: " + to_string( m_debugstats.models ) + " sub: " + to_string( m_debugstats.submodels )
|
+ "; dyn: " + to_string( m_debugstats.dynamics ) + " mod: " + to_string( m_debugstats.models ) + " sub: " + to_string( m_debugstats.submodels )
|
||||||
+ "; trk: " + to_string( m_debugstats.paths ) + " shp: " + to_string( m_debugstats.shapes )
|
+ "; trk: " + to_string( m_debugstats.paths ) + " shp: " + to_string( m_debugstats.shapes )
|
||||||
+ " trc: " + to_string( m_debugstats.traction ) + " lin: " + to_string( m_debugstats.lines );
|
+ " trc: " + to_string( m_debugstats.traction ) + " lin: " + to_string( m_debugstats.lines );
|
||||||
/*
|
|
||||||
float lightcutoff{},
|
|
||||||
lightexponent{},
|
|
||||||
lightconstant{},
|
|
||||||
lightlinear{};
|
|
||||||
::glGetLightfv( GL_LIGHT1, GL_SPOT_CUTOFF, &lightcutoff );
|
|
||||||
::glGetLightfv( GL_LIGHT1, GL_SPOT_EXPONENT, &lightexponent );
|
|
||||||
::glGetLightfv( GL_LIGHT1, GL_CONSTANT_ATTENUATION, &lightconstant );
|
|
||||||
::glGetLightfv( GL_LIGHT1, GL_LINEAR_ATTENUATION, &lightlinear );
|
|
||||||
m_debugstatstext =
|
|
||||||
"light1 cutoff: " + to_string( lightcutoff, 2 )
|
|
||||||
+ " exponent: " + to_string( lightexponent, 2 )
|
|
||||||
+ " constant attn: " + to_string( lightconstant, 2 )
|
|
||||||
+ " linear attn: " + to_string( lightlinear, 3 );
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
m_debugstatstext = "sun hour angle: " + to_string( -World.Environment.m_sun.getHourAngle(), 6 );
|
|
||||||
*/
|
|
||||||
++m_framestamp;
|
++m_framestamp;
|
||||||
|
|
||||||
return true; // for now always succeed
|
return true; // for now always succeed
|
||||||
@@ -1481,7 +1469,14 @@ opengl_renderer::Render( world_environment *Environment ) {
|
|||||||
{
|
{
|
||||||
Bind_Texture( m_moontexture );
|
Bind_Texture( m_moontexture );
|
||||||
glm::vec3 mooncolor( 255.0f / 255.0f, 242.0f / 255.0f, 231.0f / 255.0f );
|
glm::vec3 mooncolor( 255.0f / 255.0f, 242.0f / 255.0f, 231.0f / 255.0f );
|
||||||
::glColor4f( mooncolor.x, mooncolor.y, mooncolor.z, static_cast<GLfloat>( 1.0 - Global.fLuminance * 0.5 ) );
|
// fade the moon if it's near the sun in the sky, especially during the day
|
||||||
|
::glColor4f(
|
||||||
|
mooncolor.r, mooncolor.g, mooncolor.b,
|
||||||
|
std::max<float>(
|
||||||
|
0.f,
|
||||||
|
1.0
|
||||||
|
- 0.5 * Global.fLuminance
|
||||||
|
- 0.65 * std::max( 0.f, glm::dot( Environment->m_sun.getDirection(), Environment->m_moon.getDirection() ) ) ) );
|
||||||
|
|
||||||
auto const moonposition = modelview * glm::vec4( Environment->m_moon.getDirection(), 1.0f );
|
auto const moonposition = modelview * glm::vec4( Environment->m_moon.getDirection(), 1.0f );
|
||||||
::glPushMatrix();
|
::glPushMatrix();
|
||||||
|
|||||||
@@ -820,6 +820,11 @@ state_manager::deserialize_dynamic( cParser &Input, scene::scratch_data &Scratch
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
if( vehicle->MyTrack != nullptr ) {
|
||||||
|
// rare failure case where vehicle with length of 0 is added to the track,
|
||||||
|
// treated as error code and consequently deleted, but still remains on the track
|
||||||
|
vehicle->MyTrack->RemoveDynamicObject( vehicle );
|
||||||
|
}
|
||||||
delete vehicle;
|
delete vehicle;
|
||||||
skip_until( Input, "enddynamic" );
|
skip_until( Input, "enddynamic" );
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|||||||
@@ -305,7 +305,7 @@ void CSkyDome::RebuildColors() {
|
|||||||
auto const sunbasedphase = clamp( (1.0f / 15.0f) * ( degreesabovehorizon - 10.0f ), 0.0f, 1.0f );
|
auto const sunbasedphase = clamp( (1.0f / 15.0f) * ( degreesabovehorizon - 10.0f ), 0.0f, 1.0f );
|
||||||
// correction is applied in linear manner from the bottom, becomes fully in effect for vertices with y = 0.50
|
// correction is applied in linear manner from the bottom, becomes fully in effect for vertices with y = 0.50
|
||||||
auto const heightbasedphase = clamp( vertex.y * 2.0f, 0.0f, 1.0f );
|
auto const heightbasedphase = clamp( vertex.y * 2.0f, 0.0f, 1.0f );
|
||||||
// this height-based factor is reduced the farther the sky is up in the sky
|
// this height-based factor is reduced the farther the sun is up in the sky
|
||||||
float const shiftfactor = clamp( interpolate(heightbasedphase, sunbasedphase, sunbasedphase), 0.0f, 1.0f );
|
float const shiftfactor = clamp( interpolate(heightbasedphase, sunbasedphase, sunbasedphase), 0.0f, 1.0f );
|
||||||
// h = 210 makes for 'typical' sky tone
|
// h = 210 makes for 'typical' sky tone
|
||||||
shiftedcolor = glm::vec3( 210.0f, colorconverter.y, colorconverter.z );
|
shiftedcolor = glm::vec3( 210.0f, colorconverter.y, colorconverter.z );
|
||||||
|
|||||||
40
sound.cpp
40
sound.cpp
@@ -324,7 +324,13 @@ sound_source::play( int const Flags ) {
|
|||||||
if( m_pitchvariation == 0.f ) {
|
if( m_pitchvariation == 0.f ) {
|
||||||
m_pitchvariation = 0.01f * static_cast<float>( Random( 97.5, 102.5 ) );
|
m_pitchvariation = 0.01f * static_cast<float>( Random( 97.5, 102.5 ) );
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
if( ( ( m_flags & sound_flags::exclusive ) != 0 )
|
||||||
|
&& ( sound( sound_id::end ).playing > 0 ) ) {
|
||||||
|
// request termination of the optional ending bookend for single instance sounds
|
||||||
|
m_stopend = true;
|
||||||
|
}
|
||||||
|
*/
|
||||||
if( sound( sound_id::main ).buffer != null_handle ) {
|
if( sound( sound_id::main ).buffer != null_handle ) {
|
||||||
// basic variant: single main sound, with optional bookends
|
// basic variant: single main sound, with optional bookends
|
||||||
play_basic();
|
play_basic();
|
||||||
@@ -352,8 +358,8 @@ sound_source::play_basic() {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// for single part non-looping samples we allow spawning multiple instances, if not prevented by set flags
|
// for single part non-looping samples we allow spawning multiple instances, if not prevented by set flags
|
||||||
if( ( sound( sound_id::begin ).buffer == null_handle )
|
if( ( ( m_flags & ( sound_flags::exclusive | sound_flags::looping ) ) == 0 )
|
||||||
&& ( ( m_flags & ( sound_flags::exclusive | sound_flags::looping ) ) == 0 ) ) {
|
&& ( sound( sound_id::begin ).buffer == null_handle ) ) {
|
||||||
insert( sound_id::main );
|
insert( sound_id::main );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -448,7 +454,7 @@ sound_source::stop( bool const Skipend ) {
|
|||||||
if( ( false == Skipend )
|
if( ( false == Skipend )
|
||||||
&& ( sound( sound_id::end ).buffer != null_handle )
|
&& ( sound( sound_id::end ).buffer != null_handle )
|
||||||
&& ( sound( sound_id::end ).buffer != sound( sound_id::main ).buffer ) // end == main can happen in malformed legacy cases
|
&& ( sound( sound_id::end ).buffer != sound( sound_id::main ).buffer ) // end == main can happen in malformed legacy cases
|
||||||
&& ( sound( sound_id::end ).playing == 0 ) ) {
|
/* && ( sound( sound_id::end ).playing == 0 ) */ ) {
|
||||||
// spawn potentially defined sound end sample, if the emitter is currently active
|
// spawn potentially defined sound end sample, if the emitter is currently active
|
||||||
insert( sound_id::end );
|
insert( sound_id::end );
|
||||||
}
|
}
|
||||||
@@ -485,7 +491,18 @@ sound_source::update_basic( audio::openal_source &Source ) {
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
if( ( true == m_stopend )
|
||||||
|
&& ( Source.sounds[ Source.sound_index ] == sound_id::end ) ) {
|
||||||
|
// kill the sound if it's the bookend sample and stopping it was requested
|
||||||
|
Source.stop();
|
||||||
|
update_counter( sound_id::end, -1 );
|
||||||
|
if( sound( sound_id::end ).playing == 0 ) {
|
||||||
|
m_stopend = false;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*/
|
||||||
if( sound( sound_id::begin ).buffer != null_handle ) {
|
if( sound( sound_id::begin ).buffer != null_handle ) {
|
||||||
// potentially a multipart sound
|
// potentially a multipart sound
|
||||||
// detect the moment when the sound moves from startup sample to the main
|
// detect the moment when the sound moves from startup sample to the main
|
||||||
@@ -562,7 +579,18 @@ sound_source::update_combined( audio::openal_source &Source ) {
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
if( ( true == m_stopend )
|
||||||
|
&& ( Source.sounds[ Source.sound_index ] == sound_id::end ) ) {
|
||||||
|
// kill the sound if it's the bookend sample and stopping it was requested
|
||||||
|
Source.stop();
|
||||||
|
update_counter( sound_id::end, -1 );
|
||||||
|
if( sound( sound_id::end ).playing == 0 ) {
|
||||||
|
m_stopend = false;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*/
|
||||||
if( sound( sound_id::begin ).buffer != null_handle ) {
|
if( sound( sound_id::begin ).buffer != null_handle ) {
|
||||||
// potentially a multipart sound
|
// potentially a multipart sound
|
||||||
// detect the moment when the sound moves from startup sample to the main
|
// detect the moment when the sound moves from startup sample to the main
|
||||||
|
|||||||
3
sound.h
3
sound.h
@@ -203,6 +203,9 @@ private:
|
|||||||
sound_properties m_properties; // current properties of the emitted sounds
|
sound_properties m_properties; // current properties of the emitted sounds
|
||||||
float m_pitchvariation {}; // emitter-specific shift in base pitch
|
float m_pitchvariation {}; // emitter-specific shift in base pitch
|
||||||
bool m_stop { false }; // indicates active sample instances should be terminated
|
bool m_stop { false }; // indicates active sample instances should be terminated
|
||||||
|
/*
|
||||||
|
bool m_stopend { false }; // indicates active instances of optional ending sound should be terminated
|
||||||
|
*/
|
||||||
bool m_playbeginning { true }; // indicates started sounds should be preceeded by opening bookend if there's one
|
bool m_playbeginning { true }; // indicates started sounds should be preceeded by opening bookend if there's one
|
||||||
std::array<sound_data, 3> m_sounds { {} }; // basic sounds emitted by the source, main and optional bookends
|
std::array<sound_data, 3> m_sounds { {} }; // basic sounds emitted by the source, main and optional bookends
|
||||||
std::vector<soundchunk_pair> m_soundchunks; // table of samples activated when associated variable is within certain range
|
std::vector<soundchunk_pair> m_soundchunks; // table of samples activated when associated variable is within certain range
|
||||||
|
|||||||
20
sun.cpp
20
sun.cpp
@@ -54,7 +54,7 @@ cSun::update() {
|
|||||||
position = glm::rotateX( position, glm::radians( static_cast<float>( m_body.elevref ) ) );
|
position = glm::rotateX( position, glm::radians( static_cast<float>( m_body.elevref ) ) );
|
||||||
position = glm::rotateY( position, glm::radians( static_cast<float>( -m_body.hrang ) ) );
|
position = glm::rotateY( position, glm::radians( static_cast<float>( -m_body.hrang ) ) );
|
||||||
|
|
||||||
m_position = position;
|
m_position = glm::normalize( position );
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -62,12 +62,13 @@ cSun::render() {
|
|||||||
|
|
||||||
::glColor4f( 255.f / 255.f, 242.f / 255.f, 231.f / 255.f, 1.f );
|
::glColor4f( 255.f / 255.f, 242.f / 255.f, 231.f / 255.f, 1.f );
|
||||||
// debug line to locate the sun easier
|
// debug line to locate the sun easier
|
||||||
|
auto const position { m_position * 2000.f };
|
||||||
::glBegin( GL_LINES );
|
::glBegin( GL_LINES );
|
||||||
::glVertex3fv( glm::value_ptr( m_position ) );
|
::glVertex3fv( glm::value_ptr( position ) );
|
||||||
::glVertex3f( m_position.x, 0.f, m_position.z );
|
::glVertex3f( position.x, 0.f, position.z );
|
||||||
::glEnd();
|
::glEnd();
|
||||||
::glPushMatrix();
|
::glPushMatrix();
|
||||||
::glTranslatef( m_position.x, m_position.y, m_position.z );
|
::glTranslatef( position.x, position.y, position.z );
|
||||||
// radius is a result of scaling true distance down to 2km -- it's scaled by equal ratio
|
// radius is a result of scaling true distance down to 2km -- it's scaled by equal ratio
|
||||||
::gluSphere( sunsphere, m_body.distance * 9.359157, 12, 12 );
|
::gluSphere( sunsphere, m_body.distance * 9.359157, 12, 12 );
|
||||||
::glPopMatrix();
|
::glPopMatrix();
|
||||||
@@ -140,14 +141,15 @@ void cSun::move() {
|
|||||||
if( m_observer.minute >= 0 ) { localtime.wMinute = m_observer.minute; }
|
if( m_observer.minute >= 0 ) { localtime.wMinute = m_observer.minute; }
|
||||||
if( m_observer.second >= 0 ) { localtime.wSecond = m_observer.second; }
|
if( m_observer.second >= 0 ) { localtime.wSecond = m_observer.second; }
|
||||||
|
|
||||||
double ut = localtime.wHour
|
double ut =
|
||||||
+ localtime.wMinute / 60.0; // too low resolution, noticeable skips
|
localtime.wHour
|
||||||
// NOTE: finer resolution disabled to reduce shadow crawl in current implementation
|
+ localtime.wMinute / 60.0 // too low resolution, noticeable skips
|
||||||
|
+ localtime.wSecond / 3600.0; // good enough in normal circumstances
|
||||||
/*
|
/*
|
||||||
+ localtime.wSecond / 3600.0 // good enough in normal circumstances
|
|
||||||
+ localtime.wMilliseconds / 3600000.0; // for really smooth movement
|
+ localtime.wMilliseconds / 3600000.0; // for really smooth movement
|
||||||
*/
|
*/
|
||||||
double daynumber = 367 * localtime.wYear
|
double daynumber =
|
||||||
|
367 * localtime.wYear
|
||||||
- 7 * ( localtime.wYear + ( localtime.wMonth + 9 ) / 12 ) / 4
|
- 7 * ( localtime.wYear + ( localtime.wMonth + 9 ) / 12 ) / 4
|
||||||
+ 275 * localtime.wMonth / 9
|
+ 275 * localtime.wMonth / 9
|
||||||
+ localtime.wDay
|
+ localtime.wDay
|
||||||
|
|||||||
Reference in New Issue
Block a user