mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-22 20:59:19 +02:00
build 181128. coupler sounds enhancement, minor ai logic tweaks, minor bug fixes
This commit is contained in:
@@ -44,6 +44,7 @@ struct light_array;
|
|||||||
namespace scene {
|
namespace scene {
|
||||||
struct node_data;
|
struct node_data;
|
||||||
class basic_node;
|
class basic_node;
|
||||||
|
using group_handle = std::size_t;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Mtable
|
namespace Mtable
|
||||||
|
|||||||
10
Driver.cpp
10
Driver.cpp
@@ -2072,6 +2072,14 @@ bool TController::CheckVehicles(TOrders user)
|
|||||||
p = pVehicles[0];
|
p = pVehicles[0];
|
||||||
while (p)
|
while (p)
|
||||||
{
|
{
|
||||||
|
// HACK: wagony muszą mieć baterię załączoną do otwarcia drzwi...
|
||||||
|
if( ( p != pVehicle )
|
||||||
|
&& ( ( p->MoverParameters->Couplers[ side::front ].CouplingFlag & ( coupling::control | coupling::permanent ) ) == 0 )
|
||||||
|
&& ( ( p->MoverParameters->Couplers[ side::rear ].CouplingFlag & ( coupling::control | coupling::permanent ) ) == 0 ) ) {
|
||||||
|
// NOTE: don't set battery in the occupied vehicle, let the user/ai do it explicitly
|
||||||
|
p->MoverParameters->BatterySwitch( true );
|
||||||
|
}
|
||||||
|
|
||||||
if (p->asDestination == "none")
|
if (p->asDestination == "none")
|
||||||
p->DestinationSet(TrainParams->Relation2, TrainParams->TrainName); // relacja docelowa, jeśli nie było
|
p->DestinationSet(TrainParams->Relation2, TrainParams->TrainName); // relacja docelowa, jeśli nie było
|
||||||
if (AIControllFlag) // jeśli prowadzi komputer
|
if (AIControllFlag) // jeśli prowadzi komputer
|
||||||
@@ -3212,8 +3220,6 @@ void TController::Doors( bool const Open, int const Side ) {
|
|||||||
// tu będzie jeszcze długość peronu zaokrąglona do 10m (20m bezpieczniej, bo nie modyfikuje bitu 1)
|
// tu będzie jeszcze długość peronu zaokrąglona do 10m (20m bezpieczniej, bo nie modyfikuje bitu 1)
|
||||||
auto *vehicle = pVehicles[0]; // pojazd na czole składu
|
auto *vehicle = pVehicles[0]; // pojazd na czole składu
|
||||||
while( vehicle != nullptr ) {
|
while( vehicle != nullptr ) {
|
||||||
// wagony muszą mieć baterię załączoną do otwarcia drzwi...
|
|
||||||
vehicle->MoverParameters->BatterySwitch( true );
|
|
||||||
// otwieranie drzwi w pojazdach - flaga zezwolenia była by lepsza
|
// otwieranie drzwi w pojazdach - flaga zezwolenia była by lepsza
|
||||||
if( vehicle->MoverParameters->DoorOpenCtrl != control_t::passenger ) {
|
if( vehicle->MoverParameters->DoorOpenCtrl != control_t::passenger ) {
|
||||||
// if the door are controlled by the driver, we let the user operate them...
|
// if the door are controlled by the driver, we let the user operate them...
|
||||||
|
|||||||
46
DynObj.cpp
46
DynObj.cpp
@@ -1374,8 +1374,6 @@ TDynamicObject::couple( int const Side ) {
|
|||||||
Side, 2,
|
Side, 2,
|
||||||
MoverParameters->Couplers[ Side ].Connected,
|
MoverParameters->Couplers[ Side ].Connected,
|
||||||
coupling::coupler ) ) {
|
coupling::coupler ) ) {
|
||||||
// tmp->MoverParameters->Couplers[CouplNr].Render=true; //podłączony sprzęg będzie widoczny
|
|
||||||
m_couplersounds[ Side ].dsbCouplerAttach.play();
|
|
||||||
// one coupling type per key press
|
// one coupling type per key press
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1393,9 +1391,6 @@ TDynamicObject::couple( int const Side ) {
|
|||||||
Side, 2,
|
Side, 2,
|
||||||
MoverParameters->Couplers[ Side ].Connected,
|
MoverParameters->Couplers[ Side ].Connected,
|
||||||
( MoverParameters->Couplers[ Side ].CouplingFlag | coupling::brakehose ) ) ) {
|
( MoverParameters->Couplers[ Side ].CouplingFlag | coupling::brakehose ) ) ) {
|
||||||
// TODO: dedicated sound for connecting cable-type connections
|
|
||||||
m_couplersounds[ Side ].dsbCouplerDetach.play();
|
|
||||||
|
|
||||||
SetPneumatic( Side != 0, true );
|
SetPneumatic( Side != 0, true );
|
||||||
if( Side == side::front ) {
|
if( Side == side::front ) {
|
||||||
PrevConnected->SetPneumatic( Side != 0, true );
|
PrevConnected->SetPneumatic( Side != 0, true );
|
||||||
@@ -1417,9 +1412,6 @@ TDynamicObject::couple( int const Side ) {
|
|||||||
Side, 2,
|
Side, 2,
|
||||||
MoverParameters->Couplers[ Side ].Connected,
|
MoverParameters->Couplers[ Side ].Connected,
|
||||||
( MoverParameters->Couplers[ Side ].CouplingFlag | coupling::mainhose ) ) ) {
|
( MoverParameters->Couplers[ Side ].CouplingFlag | coupling::mainhose ) ) ) {
|
||||||
// TODO: dedicated sound for connecting cable-type connections
|
|
||||||
m_couplersounds[ Side ].dsbCouplerDetach.play();
|
|
||||||
|
|
||||||
SetPneumatic( Side != 0, false );
|
SetPneumatic( Side != 0, false );
|
||||||
if( Side == side::front ) {
|
if( Side == side::front ) {
|
||||||
PrevConnected->SetPneumatic( Side != 0, false );
|
PrevConnected->SetPneumatic( Side != 0, false );
|
||||||
@@ -1441,8 +1433,6 @@ TDynamicObject::couple( int const Side ) {
|
|||||||
Side, 2,
|
Side, 2,
|
||||||
MoverParameters->Couplers[ Side ].Connected,
|
MoverParameters->Couplers[ Side ].Connected,
|
||||||
( MoverParameters->Couplers[ Side ].CouplingFlag | coupling::control ) ) ) {
|
( MoverParameters->Couplers[ Side ].CouplingFlag | coupling::control ) ) ) {
|
||||||
// TODO: dedicated sound for connecting cable-type connections
|
|
||||||
m_couplersounds[ Side ].dsbCouplerAttach.play();
|
|
||||||
// one coupling type per key press
|
// one coupling type per key press
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1457,8 +1447,6 @@ TDynamicObject::couple( int const Side ) {
|
|||||||
Side, 2,
|
Side, 2,
|
||||||
MoverParameters->Couplers[ Side ].Connected,
|
MoverParameters->Couplers[ Side ].Connected,
|
||||||
( MoverParameters->Couplers[ Side ].CouplingFlag | coupling::gangway ) ) ) {
|
( MoverParameters->Couplers[ Side ].CouplingFlag | coupling::gangway ) ) ) {
|
||||||
// TODO: dedicated gangway sound
|
|
||||||
m_couplersounds[ Side ].dsbCouplerAttach.play();
|
|
||||||
// one coupling type per key press
|
// one coupling type per key press
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1473,9 +1461,6 @@ TDynamicObject::couple( int const Side ) {
|
|||||||
Side, 2,
|
Side, 2,
|
||||||
MoverParameters->Couplers[ Side ].Connected,
|
MoverParameters->Couplers[ Side ].Connected,
|
||||||
( MoverParameters->Couplers[ Side ].CouplingFlag | coupling::heating ) ) ) {
|
( MoverParameters->Couplers[ Side ].CouplingFlag | coupling::heating ) ) ) {
|
||||||
|
|
||||||
// TODO: dedicated 'click' sound for connecting cable-type connections
|
|
||||||
m_couplersounds[ Side ].dsbCouplerDetach.play();
|
|
||||||
// one coupling type per key press
|
// one coupling type per key press
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1494,11 +1479,6 @@ TDynamicObject::uncouple( int const Side ) {
|
|||||||
}
|
}
|
||||||
// jeżeli sprzęg niezablokowany, jest co odczepić i się da
|
// jeżeli sprzęg niezablokowany, jest co odczepić i się da
|
||||||
auto const couplingflag { Dettach( Side ) };
|
auto const couplingflag { Dettach( Side ) };
|
||||||
if( couplingflag == coupling::faux ) {
|
|
||||||
// dźwięk odczepiania
|
|
||||||
m_couplersounds[ Side ].dsbCouplerAttach.play();
|
|
||||||
m_couplersounds[ Side ].dsbCouplerDetach.play();
|
|
||||||
}
|
|
||||||
return couplingflag;
|
return couplingflag;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2565,9 +2545,9 @@ void TDynamicObject::AttachPrev(TDynamicObject *Object, int iType)
|
|||||||
loc.Z=Object->vPosition.y;
|
loc.Z=Object->vPosition.y;
|
||||||
Object->MoverParameters->Loc=loc; //ustawienie dodawanego pojazdu
|
Object->MoverParameters->Loc=loc; //ustawienie dodawanego pojazdu
|
||||||
*/
|
*/
|
||||||
MoverParameters->Attach(iDirection, Object->iDirection ^ 1, Object->MoverParameters, iType, true);
|
MoverParameters->Attach(iDirection, Object->iDirection ^ 1, Object->MoverParameters, iType, true, false);
|
||||||
MoverParameters->Couplers[iDirection].Render = false;
|
MoverParameters->Couplers[iDirection].Render = false;
|
||||||
Object->MoverParameters->Attach(Object->iDirection ^ 1, iDirection, MoverParameters, iType, true);
|
Object->MoverParameters->Attach(Object->iDirection ^ 1, iDirection, MoverParameters, iType, true, false);
|
||||||
Object->MoverParameters->Couplers[Object->iDirection ^ 1].Render = true; // rysowanie sprzęgu w dołączanym
|
Object->MoverParameters->Couplers[Object->iDirection ^ 1].Render = true; // rysowanie sprzęgu w dołączanym
|
||||||
if (iDirection)
|
if (iDirection)
|
||||||
{ //łączenie standardowe
|
{ //łączenie standardowe
|
||||||
@@ -4503,6 +4483,11 @@ void TDynamicObject::RenderSounds() {
|
|||||||
|
|
||||||
auto &coupler { MoverParameters->Couplers[ couplerindex ] };
|
auto &coupler { MoverParameters->Couplers[ couplerindex ] };
|
||||||
|
|
||||||
|
if( coupler.sounds == sound::none ) {
|
||||||
|
++couplerindex;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if( true == TestFlag( coupler.sounds, sound::bufferclash ) ) {
|
if( true == TestFlag( coupler.sounds, sound::bufferclash ) ) {
|
||||||
// zderzaki uderzaja o siebie
|
// zderzaki uderzaja o siebie
|
||||||
if( true == TestFlag( coupler.sounds, sound::loud ) ) {
|
if( true == TestFlag( coupler.sounds, sound::loud ) ) {
|
||||||
@@ -4527,6 +4512,7 @@ void TDynamicObject::RenderSounds() {
|
|||||||
.play( sound_flags::exclusive );
|
.play( sound_flags::exclusive );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( true == TestFlag( coupler.sounds, sound::couplerstretch ) ) {
|
if( true == TestFlag( coupler.sounds, sound::couplerstretch ) ) {
|
||||||
// sprzegi sie rozciagaja
|
// sprzegi sie rozciagaja
|
||||||
if( true == TestFlag( coupler.sounds, sound::loud ) ) {
|
if( true == TestFlag( coupler.sounds, sound::loud ) ) {
|
||||||
@@ -4552,8 +4538,22 @@ void TDynamicObject::RenderSounds() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
coupler.sounds = 0;
|
// TODO: dedicated sound for each connection type
|
||||||
|
// until then, play legacy placeholders:
|
||||||
|
if( ( coupler.sounds & ( sound::attachcoupler | sound::attachcontrol | sound::attachgangway ) ) != 0 ) {
|
||||||
|
m_couplersounds[ couplerindex ].dsbCouplerAttach.play();
|
||||||
|
}
|
||||||
|
if( ( coupler.sounds & ( sound::attachbrakehose | sound::attachmainhose | sound::attachheating ) ) != 0 ) {
|
||||||
|
m_couplersounds[ couplerindex ].dsbCouplerDetach.play();
|
||||||
|
}
|
||||||
|
if( true == TestFlag( coupler.sounds, sound::detachall ) ) {
|
||||||
|
// TODO: dedicated disconnect sounds
|
||||||
|
m_couplersounds[ couplerindex ].dsbCouplerAttach.play();
|
||||||
|
m_couplersounds[ couplerindex ].dsbCouplerDetach.play();
|
||||||
|
}
|
||||||
|
|
||||||
++couplerindex;
|
++couplerindex;
|
||||||
|
coupler.sounds = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
MoverParameters->SoundFlag = 0;
|
MoverParameters->SoundFlag = 0;
|
||||||
|
|||||||
@@ -1019,7 +1019,7 @@ multi_event::init() {
|
|||||||
|
|
||||||
auto const conditiontchecksmemcell { m_conditions.flags & ( flags::text | flags::value_1 | flags::value_2 ) };
|
auto const conditiontchecksmemcell { m_conditions.flags & ( flags::text | flags::value_1 | flags::value_2 ) };
|
||||||
// not all multi-events have memory cell checks, for the ones which don't we can keep quiet about it
|
// not all multi-events have memory cell checks, for the ones which don't we can keep quiet about it
|
||||||
init_targets( simulation::Memory, "memory cell", ( false == conditiontchecksmemcell ) );
|
init_targets( simulation::Memory, "memory cell", conditiontchecksmemcell );
|
||||||
if( m_ignored ) {
|
if( m_ignored ) {
|
||||||
// legacy compatibility behaviour, instead of disabling the event we disable the memory cell comparison test
|
// legacy compatibility behaviour, instead of disabling the event we disable the memory cell comparison test
|
||||||
m_conditions.flags &= ~( flags::text | flags::value_1 | flags::value_2 );
|
m_conditions.flags &= ~( flags::text | flags::value_1 | flags::value_2 );
|
||||||
|
|||||||
@@ -209,13 +209,20 @@ static int const s_CAtest = 128;
|
|||||||
/*dzwieki*/
|
/*dzwieki*/
|
||||||
enum sound {
|
enum sound {
|
||||||
none,
|
none,
|
||||||
loud = 0x1,
|
loud = 1 << 0,
|
||||||
couplerstretch = 0x2,
|
couplerstretch = 1 << 1,
|
||||||
bufferclash = 0x4,
|
bufferclash = 1 << 2,
|
||||||
relay = 0x10,
|
relay = 1 << 3,
|
||||||
parallel = 0x20,
|
parallel = 1 << 4,
|
||||||
shuntfield = 0x40,
|
shuntfield = 1 << 5,
|
||||||
pneumatic = 0x80
|
pneumatic = 1 << 6,
|
||||||
|
detachall = 1 << 7,
|
||||||
|
attachcoupler = 1 << 8,
|
||||||
|
attachbrakehose = 1 << 9,
|
||||||
|
attachmainhose = 1 << 10,
|
||||||
|
attachcontrol = 1 << 11,
|
||||||
|
attachgangway = 1 << 12,
|
||||||
|
attachheating = 1 << 13
|
||||||
};
|
};
|
||||||
|
|
||||||
//szczególne typy pojazdów (inna obsługa) dla zmiennej TrainType
|
//szczególne typy pojazdów (inna obsługa) dla zmiennej TrainType
|
||||||
@@ -1245,7 +1252,7 @@ public:
|
|||||||
double Distance(const TLocation &Loc1, const TLocation &Loc2, const TDimension &Dim1, const TDimension &Dim2);
|
double Distance(const TLocation &Loc1, const TLocation &Loc2, const TDimension &Dim1, const TDimension &Dim2);
|
||||||
/* double Distance(const vector3 &Loc1, const vector3 &Loc2, const vector3 &Dim1, const vector3 &Dim2);
|
/* double Distance(const vector3 &Loc1, const vector3 &Loc2, const vector3 &Dim1, const vector3 &Dim2);
|
||||||
*/ //bool AttachA(int ConnectNo, int ConnectToNr, TMoverParameters *ConnectTo, int CouplingType, bool Forced = false);
|
*/ //bool AttachA(int ConnectNo, int ConnectToNr, TMoverParameters *ConnectTo, int CouplingType, bool Forced = false);
|
||||||
bool Attach(int ConnectNo, int ConnectToNr, TMoverParameters *ConnectTo, int CouplingType, bool Forced = false);
|
bool Attach(int ConnectNo, int ConnectToNr, TMoverParameters *ConnectTo, int CouplingType, bool Forced = false, bool Audible = true);
|
||||||
int DettachStatus(int ConnectNo);
|
int DettachStatus(int ConnectNo);
|
||||||
bool Dettach(int ConnectNo);
|
bool Dettach(int ConnectNo);
|
||||||
void SetCoupleDist();
|
void SetCoupleDist();
|
||||||
|
|||||||
@@ -406,7 +406,7 @@ double TMoverParameters::CouplerDist(int Coupler)
|
|||||||
return Couplers[ Coupler ].CoupleDist;
|
return Couplers[ Coupler ].CoupleDist;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool TMoverParameters::Attach(int ConnectNo, int ConnectToNr, TMoverParameters *ConnectTo, int CouplingType, bool Forced)
|
bool TMoverParameters::Attach(int ConnectNo, int ConnectToNr, TMoverParameters *ConnectTo, int CouplingType, bool Forced, bool Audible)
|
||||||
{ //łączenie do swojego sprzęgu (ConnectNo) pojazdu (ConnectTo) stroną (ConnectToNr)
|
{ //łączenie do swojego sprzęgu (ConnectNo) pojazdu (ConnectTo) stroną (ConnectToNr)
|
||||||
// Ra: zwykle wykonywane dwukrotnie, dla każdego pojazdu oddzielnie
|
// Ra: zwykle wykonywane dwukrotnie, dla każdego pojazdu oddzielnie
|
||||||
// Ra: trzeba by odróżnić wymóg dociśnięcia od uszkodzenia sprzęgu przy podczepianiu AI do
|
// Ra: trzeba by odróżnić wymóg dociśnięcia od uszkodzenia sprzęgu przy podczepianiu AI do
|
||||||
@@ -433,12 +433,32 @@ bool TMoverParameters::Attach(int ConnectNo, int ConnectToNr, TMoverParameters *
|
|||||||
coupler.Render = true; // tego rysować
|
coupler.Render = true; // tego rysować
|
||||||
othercoupler.Render = false; // a tego nie
|
othercoupler.Render = false; // a tego nie
|
||||||
};
|
};
|
||||||
|
auto const couplingchange { CouplingType ^ coupler.CouplingFlag };
|
||||||
coupler.CouplingFlag = CouplingType; // ustawienie typu sprzęgu
|
coupler.CouplingFlag = CouplingType; // ustawienie typu sprzęgu
|
||||||
// if (CouplingType!=ctrain_virtual) //Ra: wirtualnego nie łączymy zwrotnie!
|
// if (CouplingType!=ctrain_virtual) //Ra: wirtualnego nie łączymy zwrotnie!
|
||||||
//{//jeśli łączenie sprzęgiem niewirtualnym, ustawiamy połączenie zwrotne
|
//{//jeśli łączenie sprzęgiem niewirtualnym, ustawiamy połączenie zwrotne
|
||||||
othercoupler.CouplingFlag = CouplingType;
|
othercoupler.CouplingFlag = CouplingType;
|
||||||
othercoupler.Connected = this;
|
othercoupler.Connected = this;
|
||||||
othercoupler.CoupleDist = coupler.CoupleDist;
|
othercoupler.CoupleDist = coupler.CoupleDist;
|
||||||
|
|
||||||
|
if( ( true == Audible ) && ( couplingchange != 0 ) ) {
|
||||||
|
// set sound event flag
|
||||||
|
int soundflag{ sound::none };
|
||||||
|
std::vector<std::pair<coupling, sound>> const soundmappings = {
|
||||||
|
{ coupling::coupler, sound::attachcoupler },
|
||||||
|
{ coupling::brakehose, sound::attachbrakehose },
|
||||||
|
{ coupling::mainhose, sound::attachmainhose },
|
||||||
|
{ coupling::control, sound::attachcontrol},
|
||||||
|
{ coupling::gangway, sound::attachgangway},
|
||||||
|
{ coupling::heating, sound::attachheating} };
|
||||||
|
for( auto const &soundmapping : soundmappings ) {
|
||||||
|
if( ( couplingchange & soundmapping.first ) != 0 ) {
|
||||||
|
soundflag |= soundmapping.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SetFlag( coupler.sounds, soundflag );
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
//}
|
//}
|
||||||
// podłączenie nie udało się - jest wirtualne
|
// podłączenie nie udało się - jest wirtualne
|
||||||
@@ -489,6 +509,10 @@ bool TMoverParameters::Dettach(int ConnectNo)
|
|||||||
Couplers[ConnectNo].Connected->Couplers[Couplers[ConnectNo].ConnectedNr].CouplingFlag =
|
Couplers[ConnectNo].Connected->Couplers[Couplers[ConnectNo].ConnectedNr].CouplingFlag =
|
||||||
0; // pozostaje sprzęg wirtualny
|
0; // pozostaje sprzęg wirtualny
|
||||||
Couplers[ConnectNo].CouplingFlag = 0; // pozostaje sprzęg wirtualny
|
Couplers[ConnectNo].CouplingFlag = 0; // pozostaje sprzęg wirtualny
|
||||||
|
|
||||||
|
// set sound event flag
|
||||||
|
SetFlag( Couplers[ ConnectNo ].sounds, sound::detachall );
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (i > 0)
|
else if (i > 0)
|
||||||
@@ -4395,7 +4419,8 @@ double TMoverParameters::CouplerForce(int CouplerN, double dt)
|
|||||||
// sprzeganie wagonow z samoczynnymi sprzegami}
|
// sprzeganie wagonow z samoczynnymi sprzegami}
|
||||||
// CouplingFlag:=ctrain_coupler+ctrain_pneumatic+ctrain_controll+ctrain_passenger+ctrain_scndpneumatic;
|
// CouplingFlag:=ctrain_coupler+ctrain_pneumatic+ctrain_controll+ctrain_passenger+ctrain_scndpneumatic;
|
||||||
// EN57
|
// EN57
|
||||||
Couplers[ CouplerN ].CouplingFlag = coupling::coupler | coupling::brakehose | coupling::mainhose | coupling::control;
|
Couplers[ CouplerN ].CouplingFlag = coupling::coupler /*| coupling::brakehose | coupling::mainhose | coupling::control*/;
|
||||||
|
SetFlag( Couplers[ CouplerN ].sounds, sound::attachcoupler );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4847,9 +4872,13 @@ double TMoverParameters::TractionForce( double dt ) {
|
|||||||
|
|
||||||
EnginePower = Voltage * Im / 1000.0;
|
EnginePower = Voltage * Im / 1000.0;
|
||||||
/*
|
/*
|
||||||
// NOTE: this part is experimentally disabled, as it generated early traction force drop for undetermined purpose
|
// power curve drop
|
||||||
if ((tmpV > 2) && (EnginePower < tmp))
|
// NOTE: disabled for the time being due to side-effects
|
||||||
Ft = Ft * EnginePower / tmp;
|
if( ( tmpV > 1 ) && ( EnginePower < tmp ) ) {
|
||||||
|
Ft = interpolate(
|
||||||
|
Ft, EnginePower / tmp,
|
||||||
|
clamp( tmpV - 1.0, 0.0, 1.0 ) );
|
||||||
|
}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -81,7 +81,13 @@ openal_source::update( double const Deltatime, glm::vec3 const &Listenervelocity
|
|||||||
if( sound_range < 0.0 ) {
|
if( sound_range < 0.0 ) {
|
||||||
sound_velocity = Listenervelocity; // cached for doppler shift calculation
|
sound_velocity = Listenervelocity; // cached for doppler shift calculation
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
// HACK: if the application gets stuck for long time loading assets the audio can gone awry.
|
||||||
|
// terminate all sources when it happens to stay on the safe side
|
||||||
|
if( Deltatime > 1.0 ) {
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
*/
|
||||||
if( id != audio::null_resource ) {
|
if( id != audio::null_resource ) {
|
||||||
|
|
||||||
sound_change = false;
|
sound_change = false;
|
||||||
@@ -314,7 +320,6 @@ openal_renderer::erase( sound_source const *Controller ) {
|
|||||||
// updates state of all active emitters
|
// updates state of all active emitters
|
||||||
void
|
void
|
||||||
openal_renderer::update( double const Deltatime ) {
|
openal_renderer::update( double const Deltatime ) {
|
||||||
|
|
||||||
// update listener
|
// update listener
|
||||||
// gain
|
// gain
|
||||||
::alListenerf( AL_GAIN, clamp( Global.AudioVolume, 0.f, 2.f ) * ( Global.iPause == 0 ? 1.f : 0.15f ) );
|
::alListenerf( AL_GAIN, clamp( Global.AudioVolume, 0.f, 2.f ) * ( Global.iPause == 0 ? 1.f : 0.15f ) );
|
||||||
@@ -411,6 +416,14 @@ openal_renderer::fetch_source() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( newsource.id == audio::null_resource ) {
|
||||||
|
// for sources with functional emitter reset emitter parameters from potential last use
|
||||||
|
::alSourcef( newsource.id, AL_PITCH, 1.f );
|
||||||
|
::alSourcef( newsource.id, AL_GAIN, 1.f );
|
||||||
|
::alSourcefv( newsource.id, AL_POSITION, glm::value_ptr( glm::vec3{ 0.f } ) );
|
||||||
|
::alSourcefv( newsource.id, AL_VELOCITY, glm::value_ptr( glm::vec3{ 0.f } ) );
|
||||||
|
}
|
||||||
|
|
||||||
return newsource;
|
return newsource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -89,11 +89,11 @@ struct openal_source {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// members
|
// members
|
||||||
double update_deltatime; // time delta of most current update
|
double update_deltatime { 0.0 }; // time delta of most current update
|
||||||
float pitch_variation { 1.f }; // emitter-specific variation of the base pitch
|
float pitch_variation { 1.f }; // emitter-specific variation of the base pitch
|
||||||
float sound_range { 50.f }; // cached audible range of the emitted samples
|
float sound_range { 50.f }; // cached audible range of the emitted samples
|
||||||
glm::vec3 sound_distance; // cached distance between sound and the listener
|
glm::vec3 sound_distance { 0.f }; // cached distance between sound and the listener
|
||||||
glm::vec3 sound_velocity; // sound movement vector
|
glm::vec3 sound_velocity { 0.f }; // sound movement vector
|
||||||
bool is_in_range { false }; // helper, indicates the source was recently within audible range
|
bool is_in_range { false }; // helper, indicates the source was recently within audible range
|
||||||
bool is_multipart { false }; // multi-part sounds are kept alive at longer ranges
|
bool is_multipart { false }; // multi-part sounds are kept alive at longer ranges
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -75,12 +75,12 @@ private:
|
|||||||
bool
|
bool
|
||||||
mode_snap() const;
|
mode_snap() const;
|
||||||
// members
|
// members
|
||||||
|
state_backup m_statebackup; // helper, cached variables to be restored on mode exit
|
||||||
editormode_input m_input;
|
editormode_input m_input;
|
||||||
TCamera Camera;
|
TCamera Camera;
|
||||||
double fTime50Hz { 0.0 }; // bufor czasu dla komunikacji z PoKeys
|
double fTime50Hz { 0.0 }; // bufor czasu dla komunikacji z PoKeys
|
||||||
scene::basic_editor m_editor;
|
scene::basic_editor m_editor;
|
||||||
scene::basic_node *m_node; // currently selected scene node
|
scene::basic_node *m_node; // currently selected scene node
|
||||||
bool m_takesnapshot { true }; // helper, hints whether snapshot of selected node(s) should be taken before modification
|
bool m_takesnapshot { true }; // helper, hints whether snapshot of selected node(s) should be taken before modification
|
||||||
state_backup m_statebackup; // helper, cached variables to be restored on mode exit
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ itemproperties_panel::update( scene::basic_node const *Node ) {
|
|||||||
if( false == is_open ) { return; }
|
if( false == is_open ) { return; }
|
||||||
|
|
||||||
text_lines.clear();
|
text_lines.clear();
|
||||||
|
m_grouplines.clear();
|
||||||
|
|
||||||
std::string textline;
|
std::string textline;
|
||||||
|
|
||||||
// scenario inspector
|
// scenario inspector
|
||||||
@@ -41,7 +43,7 @@ itemproperties_panel::update( scene::basic_node const *Node ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
textline =
|
textline =
|
||||||
"node name: " + node->name()
|
"name: " + ( node->name().empty() ? "(none)" : node->name() )
|
||||||
+ "\nlocation: [" + to_string( node->location().x, 2 ) + ", " + to_string( node->location().y, 2 ) + ", " + to_string( node->location().z, 2 ) + "]"
|
+ "\nlocation: [" + to_string( node->location().x, 2 ) + ", " + to_string( node->location().y, 2 ) + ", " + to_string( node->location().z, 2 ) + "]"
|
||||||
+ " (distance: " + to_string( glm::length( glm::dvec3{ node->location().x, 0.0, node->location().z } -glm::dvec3{ camera.Pos.x, 0.0, camera.Pos.z } ), 1 ) + " m)";
|
+ " (distance: " + to_string( glm::length( glm::dvec3{ node->location().x, 0.0, node->location().z } -glm::dvec3{ camera.Pos.x, 0.0, camera.Pos.z } ), 1 ) + " m)";
|
||||||
text_lines.emplace_back( textline, Global.UITextColor );
|
text_lines.emplace_back( textline, Global.UITextColor );
|
||||||
@@ -65,7 +67,7 @@ itemproperties_panel::update( scene::basic_node const *Node ) {
|
|||||||
textline += ']';
|
textline += ']';
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
textline += "none";
|
textline += "(none)";
|
||||||
}
|
}
|
||||||
text_lines.emplace_back( textline, Global.UITextColor );
|
text_lines.emplace_back( textline, Global.UITextColor );
|
||||||
|
|
||||||
@@ -73,7 +75,7 @@ itemproperties_panel::update( scene::basic_node const *Node ) {
|
|||||||
auto modelfile { (
|
auto modelfile { (
|
||||||
( subnode->pModel != nullptr ) ?
|
( subnode->pModel != nullptr ) ?
|
||||||
subnode->pModel->NameGet() :
|
subnode->pModel->NameGet() :
|
||||||
"none" ) };
|
"(none)" ) };
|
||||||
if( modelfile.find( szModelPath ) == 0 ) {
|
if( modelfile.find( szModelPath ) == 0 ) {
|
||||||
// don't include 'models/' in the path
|
// don't include 'models/' in the path
|
||||||
modelfile.erase( 0, std::string{ szModelPath }.size() );
|
modelfile.erase( 0, std::string{ szModelPath }.size() );
|
||||||
@@ -82,7 +84,7 @@ itemproperties_panel::update( scene::basic_node const *Node ) {
|
|||||||
auto texturefile { (
|
auto texturefile { (
|
||||||
( subnode->Material()->replacable_skins[ 1 ] != null_handle ) ?
|
( subnode->Material()->replacable_skins[ 1 ] != null_handle ) ?
|
||||||
GfxRenderer.Material( subnode->Material()->replacable_skins[ 1 ] ).name :
|
GfxRenderer.Material( subnode->Material()->replacable_skins[ 1 ] ).name :
|
||||||
"none" ) };
|
"(none)" ) };
|
||||||
if( texturefile.find( szTexturePath ) == 0 ) {
|
if( texturefile.find( szTexturePath ) == 0 ) {
|
||||||
// don't include 'textures/' in the path
|
// don't include 'textures/' in the path
|
||||||
texturefile.erase( 0, std::string{ szTexturePath }.size() );
|
texturefile.erase( 0, std::string{ szTexturePath }.size() );
|
||||||
@@ -95,7 +97,7 @@ itemproperties_panel::update( scene::basic_node const *Node ) {
|
|||||||
auto const *subnode = static_cast<TTrack const *>( node );
|
auto const *subnode = static_cast<TTrack const *>( node );
|
||||||
// basic attributes
|
// basic attributes
|
||||||
textline =
|
textline =
|
||||||
"isolated: " + ( ( subnode->pIsolated != nullptr ) ? subnode->pIsolated->asName : "none" )
|
"isolated: " + ( ( subnode->pIsolated != nullptr ) ? subnode->pIsolated->asName : "(none)" )
|
||||||
+ "\nvelocity: " + to_string( subnode->SwitchExtension ? subnode->SwitchExtension->fVelocity : subnode->fVelocity )
|
+ "\nvelocity: " + to_string( subnode->SwitchExtension ? subnode->SwitchExtension->fVelocity : subnode->fVelocity )
|
||||||
+ "\nwidth: " + to_string( subnode->fTrackWidth ) + " m"
|
+ "\nwidth: " + to_string( subnode->fTrackWidth ) + " m"
|
||||||
+ "\nfriction: " + to_string( subnode->fFriction, 2 )
|
+ "\nfriction: " + to_string( subnode->fFriction, 2 )
|
||||||
@@ -105,14 +107,14 @@ itemproperties_panel::update( scene::basic_node const *Node ) {
|
|||||||
auto texturefile { (
|
auto texturefile { (
|
||||||
( subnode->m_material1 != null_handle ) ?
|
( subnode->m_material1 != null_handle ) ?
|
||||||
GfxRenderer.Material( subnode->m_material1 ).name :
|
GfxRenderer.Material( subnode->m_material1 ).name :
|
||||||
"none" ) };
|
"(none)" ) };
|
||||||
if( texturefile.find( szTexturePath ) == 0 ) {
|
if( texturefile.find( szTexturePath ) == 0 ) {
|
||||||
texturefile.erase( 0, std::string{ szTexturePath }.size() );
|
texturefile.erase( 0, std::string{ szTexturePath }.size() );
|
||||||
}
|
}
|
||||||
auto texturefile2{ (
|
auto texturefile2{ (
|
||||||
( subnode->m_material2 != null_handle ) ?
|
( subnode->m_material2 != null_handle ) ?
|
||||||
GfxRenderer.Material( subnode->m_material2 ).name :
|
GfxRenderer.Material( subnode->m_material2 ).name :
|
||||||
"none" ) };
|
"(none)" ) };
|
||||||
if( texturefile2.find( szTexturePath ) == 0 ) {
|
if( texturefile2.find( szTexturePath ) == 0 ) {
|
||||||
texturefile2.erase( 0, std::string{ szTexturePath }.size() );
|
texturefile2.erase( 0, std::string{ szTexturePath }.size() );
|
||||||
}
|
}
|
||||||
@@ -167,11 +169,72 @@ itemproperties_panel::update( scene::basic_node const *Node ) {
|
|||||||
+ " [" + to_string( subnode->Value1(), 2 ) + "]"
|
+ " [" + to_string( subnode->Value1(), 2 ) + "]"
|
||||||
+ " [" + to_string( subnode->Value2(), 2 ) + "]";
|
+ " [" + to_string( subnode->Value2(), 2 ) + "]";
|
||||||
text_lines.emplace_back( textline, Global.UITextColor );
|
text_lines.emplace_back( textline, Global.UITextColor );
|
||||||
textline = "track: " + ( subnode->asTrackName.empty() ? "none" : subnode->asTrackName );
|
textline = "track: " + ( subnode->asTrackName.empty() ? "(none)" : subnode->asTrackName );
|
||||||
text_lines.emplace_back( textline, Global.UITextColor );
|
text_lines.emplace_back( textline, Global.UITextColor );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
update_group();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
itemproperties_panel::update_group() {
|
||||||
|
|
||||||
|
auto const grouphandle { m_node->group() };
|
||||||
|
|
||||||
|
if( grouphandle == null_handle ) {
|
||||||
|
m_grouphandle = null_handle;
|
||||||
|
m_groupprefix.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto const &nodegroup { scene::Groups.group( grouphandle ) };
|
||||||
|
|
||||||
|
if( m_grouphandle != grouphandle ) {
|
||||||
|
// calculate group name from shared prefix of item names
|
||||||
|
std::vector<std::reference_wrapper<std::string const>> names;
|
||||||
|
// build list of custom item and event names
|
||||||
|
for( auto const *node : nodegroup.nodes ) {
|
||||||
|
auto const &name { node->name() };
|
||||||
|
if( name.empty() || name == "none" ) { continue; }
|
||||||
|
names.emplace_back( name );
|
||||||
|
}
|
||||||
|
for( auto const *event : nodegroup.events ) {
|
||||||
|
auto const &name { event->m_name };
|
||||||
|
if( name.empty() || name == "none" ) { continue; }
|
||||||
|
names.emplace_back( name );
|
||||||
|
}
|
||||||
|
// find the common prefix
|
||||||
|
if( names.size() > 1 ) {
|
||||||
|
m_groupprefix = names.front();
|
||||||
|
for( auto const &name : names ) {
|
||||||
|
// NOTE: first calculation runs over two instances of the same name, but, eh
|
||||||
|
auto const prefixlength{ len_common_prefix( m_groupprefix, name ) };
|
||||||
|
if( prefixlength > 0 ) {
|
||||||
|
m_groupprefix = m_groupprefix.substr( 0, prefixlength );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_groupprefix.clear();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// less than two names to compare means no prefix
|
||||||
|
m_groupprefix.clear();
|
||||||
|
}
|
||||||
|
m_grouphandle = grouphandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_grouplines.emplace_back(
|
||||||
|
"nodes: " + to_string( static_cast<int>( nodegroup.nodes.size() ) )
|
||||||
|
+ "\nevents: " + to_string( static_cast<int>( nodegroup.events.size() ) ),
|
||||||
|
Global.UITextColor );
|
||||||
|
m_grouplines.emplace_back(
|
||||||
|
"names prefix: " + ( m_groupprefix.empty() ? "(none)" : m_groupprefix ),
|
||||||
|
Global.UITextColor );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
itemproperties_panel::render() {
|
itemproperties_panel::render() {
|
||||||
|
|
||||||
@@ -209,16 +272,13 @@ bool
|
|||||||
itemproperties_panel::render_group() {
|
itemproperties_panel::render_group() {
|
||||||
|
|
||||||
if( m_node == nullptr ) { return false; }
|
if( m_node == nullptr ) { return false; }
|
||||||
if( m_node->group() == null_handle ) { return false; }
|
if( m_grouplines.empty() ) { return false; }
|
||||||
|
|
||||||
if( false == ImGui::CollapsingHeader( "Parent Group" ) ) { return false; }
|
if( false == ImGui::CollapsingHeader( "Parent Group" ) ) { return false; }
|
||||||
|
|
||||||
auto const &nodegroup { scene::Groups.group( m_node->group() ) };
|
for( auto const &line : m_grouplines ) {
|
||||||
auto const &linecolor { Global.UITextColor };
|
ImGui::TextColored( ImVec4( line.color.r, line.color.g, line.color.b, line.color.a ), line.data.c_str() );
|
||||||
|
}
|
||||||
ImGui::TextColored( ImVec4( linecolor.r, linecolor.g, linecolor.b, linecolor.a ),
|
|
||||||
( "Nodes: " + to_string( static_cast<int>( nodegroup.nodes.size() ) )
|
|
||||||
+ "\nEvents: " + to_string( static_cast<int>( nodegroup.events.size() ) ) ).c_str() );
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,8 +24,12 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// methods
|
// methods
|
||||||
|
void update_group();
|
||||||
bool render_group();
|
bool render_group();
|
||||||
|
|
||||||
// members
|
// members
|
||||||
scene::basic_node const *m_node { nullptr }; // scene node bound to the panel
|
scene::basic_node const *m_node { nullptr }; // scene node bound to the panel
|
||||||
|
scene::group_handle m_grouphandle { null_handle }; // scene group bound to the panel
|
||||||
|
std::string m_groupprefix;
|
||||||
|
std::vector<text_line> m_grouplines;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ struct bounding_area {
|
|||||||
deserialize( std::istream &Input );
|
deserialize( std::istream &Input );
|
||||||
};
|
};
|
||||||
|
|
||||||
using group_handle = std::size_t;
|
//using group_handle = std::size_t;
|
||||||
|
|
||||||
struct node_data {
|
struct node_data {
|
||||||
|
|
||||||
|
|||||||
@@ -323,6 +323,7 @@ state_serializer::deserialize_node( cParser &Input, scene::scratch_data &Scratch
|
|||||||
>> nodedata.range_min
|
>> nodedata.range_min
|
||||||
>> nodedata.name
|
>> nodedata.name
|
||||||
>> nodedata.type;
|
>> nodedata.type;
|
||||||
|
if( nodedata.name == "none" ) { nodedata.name.clear(); }
|
||||||
// type-based deserialization. not elegant but it'll do
|
// type-based deserialization. not elegant but it'll do
|
||||||
if( nodedata.type == "dynamic" ) {
|
if( nodedata.type == "dynamic" ) {
|
||||||
|
|
||||||
|
|||||||
@@ -466,7 +466,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 < 2 ) ) { // allows potential single extra instance to account for longer overlapping sounds
|
||||||
// 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 );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -411,6 +411,18 @@ substr_path( std::string const &Filename ) {
|
|||||||
"" );
|
"" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// returns length of common prefix between two provided strings
|
||||||
|
std::ptrdiff_t
|
||||||
|
len_common_prefix( std::string const &Left, std::string const &Right ) {
|
||||||
|
|
||||||
|
auto const *left { Left.data() };
|
||||||
|
auto const *right { Right.data() };
|
||||||
|
// compare up to the length of the shorter string
|
||||||
|
return ( Right.size() <= Left.size() ?
|
||||||
|
std::distance( right, std::mismatch( right, right + Right.size(), left ).first ) :
|
||||||
|
std::distance( left, std::mismatch( left, left + Left.size(), right ).first ) );
|
||||||
|
}
|
||||||
|
|
||||||
// helper, restores content of a 3d vector from provided input stream
|
// helper, restores content of a 3d vector from provided input stream
|
||||||
// TODO: review and clean up the helper routines, there's likely some redundant ones
|
// TODO: review and clean up the helper routines, there's likely some redundant ones
|
||||||
glm::dvec3 LoadPoint( cParser &Input ) {
|
glm::dvec3 LoadPoint( cParser &Input ) {
|
||||||
|
|||||||
@@ -200,6 +200,9 @@ replace_slashes( std::string &Filename );
|
|||||||
// returns potential path part from provided file name
|
// returns potential path part from provided file name
|
||||||
std::string substr_path( std::string const &Filename );
|
std::string substr_path( std::string const &Filename );
|
||||||
|
|
||||||
|
// returns common prefix of two provided strings
|
||||||
|
std::ptrdiff_t len_common_prefix( std::string const &Left, std::string const &Right );
|
||||||
|
|
||||||
template <typename Type_>
|
template <typename Type_>
|
||||||
void SafeDelete( Type_ &Pointer ) {
|
void SafeDelete( Type_ &Pointer ) {
|
||||||
delete Pointer;
|
delete Pointer;
|
||||||
|
|||||||
Reference in New Issue
Block a user