16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-23 23:49:17 +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:
tmj-fstate
2018-02-13 23:58:31 +01:00
parent e65e01a7a2
commit 62327d5d08
17 changed files with 185 additions and 140 deletions

View File

@@ -1212,8 +1212,7 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
}
else
{ // zawalidrogi nie ma (albo pojazd jest samochodem), sprawdzić sygnał
if (sSpeedTable[i].iFlags & spShuntSemaphor) // jeśli Tm - w zasadzie to sprawdzić
// komendę!
if (sSpeedTable[i].iFlags & spShuntSemaphor) // jeśli Tm - w zasadzie to sprawdzić komendę!
{ // jeśli podana prędkość manewrowa
if ((OrderCurrentGet() & Obey_train) ? v == 0.0 : false)
{ // 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ę
OrderNext(Change_direction);
}
WaitingTime =
0.0; // nie ma co dalej czekać, można zatrąbić i jechać, chyba że już jedzie
WaitingTime = 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
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 >
0) // z tyłu coś
OrderNext(Disconnect); // jak ciągnie, to tylko odczep (NewValue1) wagonów
WaitingTime =
0.0; // nie ma co dalej czekać, można zatrąbić i jechać, chyba że już jedzie
WaitingTime = 0.0; // nie ma co dalej czekać, można zatrąbić i jechać, chyba że już jedzie
}
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
LastReactionTime += dt;
LastUpdatedTime += dt;
if( ( mvOccupied->Vel < 0.05 )
&& ( ( OrderCurrentGet() & ( Obey_train | Shunt ) ) != 0 ) ) {
IdleTime += dt;
}
else {
IdleTime = 0.0;
}
// log vehicle data
if( ( WriteLogFlag )
@@ -3628,14 +3632,12 @@ TController::UpdateSituation(double dt) {
}
}
if (mvOccupied->Vel > 0.0) {
if( mvOccupied->Vel > 1.0 ) {
// jeżeli jedzie
if( iDrivigFlags & moveDoorOpened ) {
// jeśli drzwi otwarte
if( mvOccupied->Vel > 1.0 ) {
// nie zamykać drzwi przy drganiach, bo zatrzymanie na W4 akceptuje niewielkie prędkości
Doors( false );
}
// nie zamykać drzwi przy drganiach, bo zatrzymanie na W4 akceptuje niewielkie prędkości
Doors( false );
}
/*
// NOTE: this section moved all cars to the edge of their respective roads
@@ -3650,40 +3652,60 @@ TController::UpdateSituation(double dt) {
mvOccupied->ChangeOffsetH(0.01 * mvOccupied->Vel *
dt); // Ra: co to miało być, to nie wiem
*/
if (mvControlling->EnginePowerSource.SourceType == CurrentCollector)
{
if ((fOverhead2 >= 0.0) || iOverheadZero)
{ // jeśli jazda bezprądowa albo z opuszczonym pantografem
}
if (mvControlling->EnginePowerSource.SourceType == CurrentCollector) {
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
}
if ((fOverhead2 > 0.0) || iOverheadDown)
{ // jazda z opuszczonymi pantografami
mvControlling->PantFront(false);
mvControlling->PantRear(false);
if( ( fOverhead2 > 0.0 ) || iOverheadDown ) {
// jazda z opuszczonymi pantografami
mvControlling->PantFront( false );
mvControlling->PantRear( false );
}
else
{ // jeśli nie trzeba opuszczać pantografów
if (iDirection >= 0) // jak jedzie w kierunku sprzęgu 0
mvControlling->PantRear(true); // jazda na tylnym
else
mvControlling->PantFront(true);
else {
// jeśli nie trzeba opuszczać pantografów
// jazda na tylnym
if( iDirection >= 0 ) {
// jak jedzie w kierunku sprzęgu 0
mvControlling->PantRear( true );
}
else {
mvControlling->PantFront( true );
}
}
if (mvOccupied->Vel > 10) // opuszczenie przedniego po rozpędzeniu się
{
if (mvControlling->EnginePowerSource.CollectorParameters.CollectorsNo >
1) // o ile jest więcej niż jeden
if (iDirection >= 0) // jak jedzie w kierunku sprzęgu 0
if( mvOccupied->Vel > 10 ) {
// opuszczenie przedniego po rozpędzeniu się o ile jest więcej niż jeden
if( mvControlling->EnginePowerSource.CollectorParameters.CollectorsNo > 1 ) {
if( iDirection >= 0 ) // jak jedzie w kierunku sprzęgu 0
{ // poczekać na podniesienie tylnego
if (mvControlling->PantRearVolt !=
0.0) // czy jest napięcie zasilające na tylnym?
mvControlling->PantFront(false); // opuszcza od sprzęgu 0
if( mvControlling->PantRearVolt != 0.0 ) {
// czy jest napięcie zasilające na tylnym?
mvControlling->PantFront( false ); // opuszcza od sprzęgu 0
}
}
else
{ // poczekać na podniesienie przedniego
if (mvControlling->PantFrontVolt !=
0.0) // czy jest napięcie zasilające na przednim?
mvControlling->PantRear(false); // opuszcza od sprzęgu 1
else { // poczekać na podniesienie przedniego
if( mvControlling->PantFrontVolt != 0.0 ) {
// czy jest napięcie zasilające na przednim?
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 );
}
}
}
@@ -4200,29 +4222,19 @@ TController::UpdateSituation(double dt) {
}
else
SetDriverPsyche(); // Ra: było w PrepareEngine(), potrzebne tu?
// no albo przypisujemy -WaitingExpireTime, albo porównujemy z WaitingExpireTime
// if
// ((VelSignal==0.0)&&(WaitingTime>WaitingExpireTime)&&(mvOccupied->RunningTrack.Velmax!=0.0))
if (OrderList[OrderPos] &
(Shunt | Obey_train | Connect)) // odjechać sam może tylko jeśli jest w trybie jazdy
{ // automatyczne ruszanie po odstaniu albo spod SBL
if ((VelSignal == 0.0) && (WaitingTime > 0.0) &&
(mvOccupied->RunningTrack.Velmax != 0.0))
{ // jeśli stoi, a upłynął czas oczekiwania i tor ma niezerową prędkość
/*
if (WriteLogFlag)
{
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
if (OrderList[OrderPos] & (Shunt | Obey_train | Connect)) {
// odjechać sam może tylko jeśli jest w trybie jazdy
// automatyczne ruszanie po odstaniu albo spod SBL
if( ( VelSignal == 0.0 )
&& ( WaitingTime > 0.0 )
&& ( mvOccupied->RunningTrack.Velmax != 0.0 ) ) {
// jeśli stoi, a upłynął czas oczekiwania i tor ma niezerową prędkość
if( ( OrderList[ OrderPos ] & ( Obey_train | Shunt ) )
&& ( iDrivigFlags & moveStopHere ) ) {
// zakaz ruszania z miejsca bez otrzymania wolnej drogi
WaitingTime = -WaitingExpireTime;
}
else if (mvOccupied->CategoryFlag & 1)
{ // jeśli pociąg
if (AIControllFlag)

View File

@@ -291,6 +291,7 @@ private:
double fStopTime = 0.0; // czas postoju przed dalszą jazdą (np. na przystanku)
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 IdleTime {}; // keeps track of time spent at a stop
private: //---//---//---//---// koniec zmiennych, poniżej metody //---//---//---//---//
void SetDriverPsyche();

View File

@@ -1106,9 +1106,10 @@ void TDynamicObject::ABuCheckMyTrack()
// do jednej tablicy. Wykonuje sie tylko raz - po to 'ABuChecked'
TTrack *OldTrack = MyTrack;
TTrack *NewTrack = Axle0.GetTrack();
if ((NewTrack != OldTrack) && OldTrack)
{
OldTrack->RemoveDynamicObject(this);
if( NewTrack != OldTrack ) {
if( OldTrack ) {
OldTrack->RemoveDynamicObject( this );
}
NewTrack->AddDynamicObject(this);
}
iAxleFirst = 0; // pojazd powiązany z przednią osią - Axle0

View File

@@ -2974,10 +2974,7 @@ bool TMoverParameters::BrakeDelaySwitch(int BDS)
}
else
rBDS = false;
if( true == rBDS ) {
// if setting was changed emit the sound of pneumatic relay
SetFlag( SoundFlag, sound::pneumatic );
}
return rBDS;
}
@@ -8128,7 +8125,10 @@ bool TMoverParameters::CheckLocomotiveParameters(bool ReadyFlag, int Dir)
{
WriteLog( "Ready to depart" );
CompressedVolume = VeselVolume * MinCompressor * ( 9.8 ) / 10.0;
ScndPipePress = CompressedVolume / VeselVolume;
ScndPipePress = (
VeselVolume > 0.0 ?
CompressedVolume / VeselVolume :
0.0 );
PipePress = CntrlPipePress;
BrakePress = 0.0;
LocalBrakePos = 0;
@@ -8633,8 +8633,6 @@ bool TMoverParameters::RunCommand( std::string Command, double CValue1, double C
if( true == Hamulec->SetBDF( brakesetting ) ) {
BrakeDelayFlag = brakesetting;
OK = true;
// if setting was changed emit the sound of pneumatic relay
SetFlag( SoundFlag, sound::pneumatic );
}
else {
OK = false;

View File

@@ -1223,7 +1223,7 @@ bool TModel3d::LoadFromFile(std::string const &FileName, bool dynamic)
{
if (FileExists(name + ".t3d"))
{
LoadFromTextFile(FileName, dynamic); // wczytanie tekstowego
LoadFromTextFile(name + ".t3d", dynamic); // wczytanie tekstowego
if( !dynamic ) {
// pojazdy dopiero po ustawieniu animacji
Init(); // generowanie siatek i zapis E3D

View File

@@ -3805,7 +3805,7 @@ bool TTrain::Update( double const Deltatime )
if( m_linebreakerstate == 2 ) {
// 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
if( ( ggMainOffButton.SubModel == nullptr )
if( ( ggMainOnButton.SubModel == nullptr )
|| ( ( mvControlled->EngineType == DieselEngine )
|| ( mvControlled->EngineType == DieselElectric ) ) ) {
if( mvControlled->MainSwitch( true ) ) {
@@ -4277,13 +4277,13 @@ bool TTrain::Update( double const Deltatime )
}
btLampkaWylSzybki.Turn(
( ( (m_linebreakerstate > 0)
( ( (m_linebreakerstate == 2)
|| (true == mvControlled->Mains) ) ?
true :
false ) );
// NOTE: 'off' variant uses the same test, but opposite resulting states
btLampkaWylSzybkiOff.Turn(
( ( ( m_linebreakerstate > 0 )
( ( ( m_linebreakerstate == 2 )
|| ( true == mvControlled->Mains ) ) ?
false :
true ) );

View File

@@ -189,18 +189,19 @@ bool TTrackFollower::Move(double fDistance, bool bPrimary)
*/
if (s < 0)
{ // jeśli przekroczenie toru od strony Point1
bCanSkip = bPrimary ? pCurrentTrack->CheckDynamicObject(Owner) : false;
if (bCanSkip) // tylko główna oś przenosi pojazd do innego toru
Owner->MyTrack->RemoveDynamicObject(
Owner); // zdejmujemy pojazd z dotychczasowego toru
bCanSkip = ( bPrimary && pCurrentTrack->CheckDynamicObject( Owner ) );
if( bCanSkip ) {
// tylko główna oś przenosi pojazd do innego toru
// zdejmujemy pojazd z dotychczasowego toru
Owner->MyTrack->RemoveDynamicObject( Owner );
}
dir = fDirection;
if (pCurrentTrack->eType == tt_Cross)
{
if (!SetCurrentTrack(pCurrentTrack->Connected(iSegment, fDirection), 0))
return false; // wyjście z błędem
}
else if (!SetCurrentTrack(pCurrentTrack->Connected(-1, fDirection),
0)) // ustawia fDirection
else if (!SetCurrentTrack(pCurrentTrack->Connected(-1, fDirection), 0)) // ustawia fDirection
return false; // wyjście z błędem
if (dir == fDirection) //(pCurrentTrack->iPrevDirection)
{ // gdy kierunek bez zmiany (Point1->Point2)
@@ -215,8 +216,7 @@ bool TTrackFollower::Move(double fDistance, bool bPrimary)
if (bCanSkip)
{ // jak główna oś, to dodanie pojazdu do nowego toru
pCurrentTrack->AddDynamicObject(Owner);
iEventFlag =
3; // McZapkie-020602: umozliwienie uruchamiania event1,2 po zmianie toru
iEventFlag = 3; // McZapkie-020602: umozliwienie uruchamiania event1,2 po zmianie toru
iEventallFlag = 3; // McZapkie-280503: jw, dla eventall1,2
if (!Owner->MyTrack)
return false;
@@ -225,7 +225,7 @@ bool TTrackFollower::Move(double fDistance, bool bPrimary)
}
else if (s > pCurrentSegment->GetLength())
{ // 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
Owner->MyTrack->RemoveDynamicObject(
Owner); // zdejmujemy pojazd z dotychczasowego toru

View File

@@ -2170,7 +2170,7 @@ world_environment::update() {
if( moonlightlevel > sunlightlevel ) {
// rare situations when the moon is brighter than the sun, typically at night
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();
keylightintensity = moonlightlevel;
// if the moon is up, it overrides the twilight

View File

@@ -36,11 +36,11 @@ void
cMoon::update() {
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::rotateY( position, glm::radians( static_cast<float>( -m_body.hrang ) ) );
m_position = position;
m_position = glm::normalize( position );
}
void
@@ -48,12 +48,13 @@ cMoon::render() {
::glColor4f( 225.f / 255.f, 225.f / 255.f, 255.f / 255.f, 1.f );
// debug line to locate the moon easier
auto const position { m_position * 2000.f };
::glBegin( GL_LINES );
::glVertex3fv( glm::value_ptr( m_position ) );
::glVertex3f( m_position.x, 0.f, m_position.z );
::glVertex3fv( glm::value_ptr( position ) );
::glVertex3f( position.x, 0.f, position.z );
::glEnd();
::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 );
::glPopMatrix();
}
@@ -61,7 +62,7 @@ cMoon::render() {
glm::vec3
cMoon::getDirection() {
return glm::normalize( m_position );
return m_position;
}
float
@@ -117,14 +118,15 @@ void cMoon::move() {
if( m_observer.minute >= 0 ) { localtime.wMinute = m_observer.minute; }
if( m_observer.second >= 0 ) { localtime.wSecond = m_observer.second; }
double ut = localtime.wHour
+ localtime.wMinute / 60.0; // too low resolution, noticeable skips
// NOTE: finer resolution disabled to reduce shadow crawl in current implementation
/*
+ localtime.wSecond / 3600.0 // good enough in normal circumstances
double ut =
localtime.wHour
+ localtime.wMinute / 60.0 // too low resolution, noticeable skips
+ localtime.wSecond / 3600.0; // good enough in normal circumstances
/*
+ 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
+ 275 * localtime.wMonth / 9
+ localtime.wDay

2
moon.h
View File

@@ -16,8 +16,6 @@ public:
void init();
void update();
void render();
// returns location of the sun in the 3d scene
glm::vec3 getPosition() { return m_position; }
// returns vector pointing at the sun
glm::vec3 getDirection();
// returns current elevation above horizon

View File

@@ -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_color.start();
// fetch simulation data
m_sunlight = Global.DayLight;
if( World.InitPerformed() ) {
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
m_renderpass.draw_mode = rendermode::none; // force setup anew
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 )
+ "; trk: " + to_string( m_debugstats.paths ) + " shp: " + to_string( m_debugstats.shapes )
+ " 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;
return true; // for now always succeed
@@ -1481,7 +1469,14 @@ opengl_renderer::Render( world_environment *Environment ) {
{
Bind_Texture( m_moontexture );
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 );
::glPushMatrix();

View File

@@ -820,6 +820,11 @@ state_manager::deserialize_dynamic( cParser &Input, scene::scratch_data &Scratch
}
}
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;
skip_until( Input, "enddynamic" );
return nullptr;

View File

@@ -305,7 +305,7 @@ void CSkyDome::RebuildColors() {
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
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 );
// h = 210 makes for 'typical' sky tone
shiftedcolor = glm::vec3( 210.0f, colorconverter.y, colorconverter.z );

View File

@@ -324,7 +324,13 @@ sound_source::play( int const Flags ) {
if( m_pitchvariation == 0.f ) {
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 ) {
// basic variant: single main sound, with optional bookends
play_basic();
@@ -352,8 +358,8 @@ sound_source::play_basic() {
}
else {
// 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 )
&& ( ( m_flags & ( sound_flags::exclusive | sound_flags::looping ) ) == 0 ) ) {
if( ( ( m_flags & ( sound_flags::exclusive | sound_flags::looping ) ) == 0 )
&& ( sound( sound_id::begin ).buffer == null_handle ) ) {
insert( sound_id::main );
}
}
@@ -448,7 +454,7 @@ sound_source::stop( bool const Skipend ) {
if( ( false == Skipend )
&& ( 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 ).playing == 0 ) ) {
/* && ( sound( sound_id::end ).playing == 0 ) */ ) {
// spawn potentially defined sound end sample, if the emitter is currently active
insert( sound_id::end );
}
@@ -485,7 +491,18 @@ sound_source::update_basic( audio::openal_source &Source ) {
}
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 ) {
// potentially a multipart sound
// 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;
}
/*
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 ) {
// potentially a multipart sound
// detect the moment when the sound moves from startup sample to the main

View File

@@ -203,6 +203,9 @@ private:
sound_properties m_properties; // current properties of the emitted sounds
float m_pitchvariation {}; // emitter-specific shift in base pitch
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
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

26
sun.cpp
View File

@@ -54,7 +54,7 @@ cSun::update() {
position = glm::rotateX( position, glm::radians( static_cast<float>( m_body.elevref ) ) );
position = glm::rotateY( position, glm::radians( static_cast<float>( -m_body.hrang ) ) );
m_position = position;
m_position = glm::normalize( position );
}
void
@@ -62,12 +62,13 @@ cSun::render() {
::glColor4f( 255.f / 255.f, 242.f / 255.f, 231.f / 255.f, 1.f );
// debug line to locate the sun easier
::glBegin( GL_LINES );
::glVertex3fv( glm::value_ptr( m_position ) );
::glVertex3f( m_position.x, 0.f, m_position.z );
auto const position { m_position * 2000.f };
::glBegin( GL_LINES );
::glVertex3fv( glm::value_ptr( position ) );
::glVertex3f( position.x, 0.f, position.z );
::glEnd();
::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
::gluSphere( sunsphere, m_body.distance * 9.359157, 12, 12 );
::glPopMatrix();
@@ -140,14 +141,15 @@ void cSun::move() {
if( m_observer.minute >= 0 ) { localtime.wMinute = m_observer.minute; }
if( m_observer.second >= 0 ) { localtime.wSecond = m_observer.second; }
double ut = localtime.wHour
+ localtime.wMinute / 60.0; // too low resolution, noticeable skips
// NOTE: finer resolution disabled to reduce shadow crawl in current implementation
/*
+ localtime.wSecond / 3600.0 // good enough in normal circumstances
double ut =
localtime.wHour
+ localtime.wMinute / 60.0 // too low resolution, noticeable skips
+ localtime.wSecond / 3600.0; // good enough in normal circumstances
/*
+ 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
+ 275 * localtime.wMonth / 9
+ localtime.wDay

View File

@@ -1,5 +1,5 @@
#pragma once
#define VERSION_MAJOR 18
#define VERSION_MINOR 210
#define VERSION_MINOR 213
#define VERSION_REVISION 0