mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-21 20:39:18 +02:00
build 180215. sound velocity calculation, ai brake charging logic tweak, 3d shapes boundary calculation fixes
This commit is contained in:
23
Driver.cpp
23
Driver.cpp
@@ -3488,6 +3488,10 @@ TController::UpdateSituation(double dt) {
|
|||||||
ElapsedTime += dt;
|
ElapsedTime += dt;
|
||||||
WaitingTime += dt;
|
WaitingTime += dt;
|
||||||
fBrakeTime -= dt; // wpisana wartość jest zmniejszana do 0, gdy ujemna należy zmienić nastawę hamulca
|
fBrakeTime -= dt; // wpisana wartość jest zmniejszana do 0, gdy ujemna należy zmienić nastawę hamulca
|
||||||
|
if( mvOccupied->fBrakeCtrlPos != mvOccupied->Handle->GetPos( bh_FS ) ) {
|
||||||
|
// brake charging timeout starts after charging ends
|
||||||
|
BrakeChargingCooldown += dt;
|
||||||
|
}
|
||||||
fStopTime += dt; // zliczanie czasu postoju, nie ruszy dopóki ujemne
|
fStopTime += dt; // zliczanie czasu postoju, nie ruszy dopóki ujemne
|
||||||
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;
|
||||||
@@ -4581,9 +4585,10 @@ TController::UpdateSituation(double dt) {
|
|||||||
TDynamicObject *d = pVehicles[0]; // pojazd na czele składu
|
TDynamicObject *d = pVehicles[0]; // pojazd na czele składu
|
||||||
while (d)
|
while (d)
|
||||||
{
|
{
|
||||||
AbsAccS += d->MoverParameters->TotalMass * d->MoverParameters->AccS * d->DirectionGet() * iDirection;
|
AbsAccS += d->MoverParameters->TotalMass * d->MoverParameters->AccS * ( d->DirectionGet() == iDirection ? 1 : -1 );
|
||||||
d = d->Next(); // kolejny pojazd, podłączony od tyłu (licząc od czoła)
|
d = d->Next(); // kolejny pojazd, podłączony od tyłu (licząc od czoła)
|
||||||
}
|
}
|
||||||
|
AbsAccS *= iDirection;
|
||||||
AbsAccS /= fMass;
|
AbsAccS /= fMass;
|
||||||
}
|
}
|
||||||
AbsAccS_pub = AbsAccS;
|
AbsAccS_pub = AbsAccS;
|
||||||
@@ -4890,16 +4895,22 @@ TController::UpdateSituation(double dt) {
|
|||||||
&& ( AccDesired > -0.03 ) ) {
|
&& ( AccDesired > -0.03 ) ) {
|
||||||
mvOccupied->BrakeReleaser( 1 );
|
mvOccupied->BrakeReleaser( 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ( mvOccupied->BrakeCtrlPos == 0 )
|
if( ( mvOccupied->BrakeCtrlPos == 0 )
|
||||||
&& ( AbsAccS < 0.0 )
|
&& ( AbsAccS < 0.03 )
|
||||||
&& ( AccDesired > -0.03 ) ) {
|
&& ( AccDesired > -0.03 )
|
||||||
|
&& ( VelDesired - mvOccupied->Vel > 2.0 ) ) {
|
||||||
|
|
||||||
if( ( mvOccupied->EqvtPipePress < 4.95 )
|
if( ( mvOccupied->EqvtPipePress < 4.95 )
|
||||||
&& ( fReady > 0.35 ) ) { // a reszta składu jest na to gotowa
|
&& ( fReady > 0.35 )
|
||||||
|
&& ( BrakeChargingCooldown >= 0.0 ) ) {
|
||||||
|
|
||||||
if( iDrivigFlags & moveOerlikons ) {
|
if( ( iDrivigFlags & moveOerlikons )
|
||||||
|
|| ( mvOccupied->BrakeDelayFlag & bdelay_G ) ) {
|
||||||
// napełnianie w Oerlikonie
|
// napełnianie w Oerlikonie
|
||||||
mvOccupied->BrakeLevelSet( -1 );
|
mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_FS ) );
|
||||||
|
// don't charge the brakes too often, or we risk overcharging
|
||||||
|
BrakeChargingCooldown = -120.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( Need_BrakeRelease ) {
|
else if( Need_BrakeRelease ) {
|
||||||
|
|||||||
1
Driver.h
1
Driver.h
@@ -212,6 +212,7 @@ public:
|
|||||||
double fLastStopExpDist = -1.0; // odległość wygasania ostateniego przystanku
|
double fLastStopExpDist = -1.0; // odległość wygasania ostateniego przystanku
|
||||||
double ReactionTime = 0.0; // czas reakcji Ra: czego i na co? świadomości AI
|
double ReactionTime = 0.0; // czas reakcji Ra: czego i na co? świadomości AI
|
||||||
double fBrakeTime = 0.0; // wpisana wartość jest zmniejszana do 0, gdy ujemna należy zmienić nastawę hamulca
|
double fBrakeTime = 0.0; // wpisana wartość jest zmniejszana do 0, gdy ujemna należy zmienić nastawę hamulca
|
||||||
|
double BrakeChargingCooldown {}; // prevents the ai from trying to charge the train brake too frequently
|
||||||
double fReady = 0.0; // poziom odhamowania wagonów
|
double fReady = 0.0; // poziom odhamowania wagonów
|
||||||
bool Ready = false; // ABu: stan gotowosci do odjazdu - sprawdzenie odhamowania wagonow
|
bool Ready = false; // ABu: stan gotowosci do odjazdu - sprawdzenie odhamowania wagonow
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -997,13 +997,13 @@ TSubModel::create_geometry( std::size_t &Dataoffset, gfx::geometrybank_handle co
|
|||||||
|
|
||||||
if( m_geometry != NULL ) {
|
if( m_geometry != NULL ) {
|
||||||
// calculate bounding radius while we're at it
|
// calculate bounding radius while we're at it
|
||||||
// NOTE: doesn't take into account transformation hierarchy TODO: implement it
|
float squaredradius {};
|
||||||
float squaredradius { 0.f };
|
|
||||||
// if this happens to be root node it may already have non-squared radius of the largest child
|
// if this happens to be root node it may already have non-squared radius of the largest child
|
||||||
// since we're comparing squared radii, we need to square it back for correct results
|
// since we're comparing squared radii, we need to square it back for correct results
|
||||||
m_boundingradius *= m_boundingradius;
|
m_boundingradius *= m_boundingradius;
|
||||||
|
auto const submodeloffset { offset( std::numeric_limits<float>::max() ) };
|
||||||
for( auto const &vertex : GfxRenderer.Vertices( m_geometry ) ) {
|
for( auto const &vertex : GfxRenderer.Vertices( m_geometry ) ) {
|
||||||
squaredradius = static_cast<float>( glm::length2( vertex.position ) );
|
squaredradius = glm::length2( submodeloffset + vertex.position );
|
||||||
if( squaredradius > m_boundingradius ) {
|
if( squaredradius > m_boundingradius ) {
|
||||||
m_boundingradius = squaredradius;
|
m_boundingradius = squaredradius;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,9 +55,12 @@ openal_source::stop() {
|
|||||||
|
|
||||||
// updates state of the source
|
// updates state of the source
|
||||||
void
|
void
|
||||||
openal_source::update( double const Deltatime ) {
|
openal_source::update( double const Deltatime, glm::vec3 const &Listenervelocity ) {
|
||||||
|
|
||||||
update_deltatime = Deltatime; // cached for time-based processing of data from the controller
|
update_deltatime = Deltatime; // cached for time-based processing of data from the controller
|
||||||
|
if( sound_range < 0.0 ) {
|
||||||
|
sound_velocity = Listenervelocity; // cached for doppler shift calculation
|
||||||
|
}
|
||||||
|
|
||||||
if( id != audio::null_resource ) {
|
if( id != audio::null_resource ) {
|
||||||
|
|
||||||
@@ -89,11 +92,15 @@ openal_source::sync_with( sound_properties const &State ) {
|
|||||||
sync = sync_state::bad_resource;
|
sync = sync_state::bad_resource;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
// velocity
|
// velocity
|
||||||
// not used yet
|
if( ( update_deltatime > 0.0 )
|
||||||
glm::vec3 const velocity { ( State.location - properties.location ) / update_deltatime };
|
&& ( sound_range >= 0 )
|
||||||
*/
|
&& ( properties.location != glm::dvec3() ) ) {
|
||||||
|
// after sound position was initialized we can start velocity calculations
|
||||||
|
sound_velocity = ( State.location - properties.location ) / update_deltatime;
|
||||||
|
}
|
||||||
|
// NOTE: velocity at this point can be either listener velocity for global sounds, actual sound velocity, or 0 if sound position is yet unknown
|
||||||
|
::alSourcefv( id, AL_VELOCITY, glm::value_ptr( sound_velocity ) );
|
||||||
// location
|
// location
|
||||||
properties.location = State.location;
|
properties.location = State.location;
|
||||||
sound_distance = properties.location - glm::dvec3 { Global.pCameraPosition };
|
sound_distance = properties.location - glm::dvec3 { Global.pCameraPosition };
|
||||||
@@ -289,6 +296,7 @@ void
|
|||||||
openal_renderer::update( double const Deltatime ) {
|
openal_renderer::update( double const Deltatime ) {
|
||||||
|
|
||||||
// update listener
|
// update listener
|
||||||
|
// orientation
|
||||||
glm::dmat4 cameramatrix;
|
glm::dmat4 cameramatrix;
|
||||||
Global.pCamera->SetMatrix( cameramatrix );
|
Global.pCamera->SetMatrix( cameramatrix );
|
||||||
auto rotationmatrix { glm::mat3{ cameramatrix } };
|
auto rotationmatrix { glm::mat3{ cameramatrix } };
|
||||||
@@ -296,18 +304,23 @@ openal_renderer::update( double const Deltatime ) {
|
|||||||
glm::vec3{ 0, 0,-1 } * rotationmatrix ,
|
glm::vec3{ 0, 0,-1 } * rotationmatrix ,
|
||||||
glm::vec3{ 0, 1, 0 } * rotationmatrix };
|
glm::vec3{ 0, 1, 0 } * rotationmatrix };
|
||||||
::alListenerfv( AL_ORIENTATION, reinterpret_cast<ALfloat const *>( orientation ) );
|
::alListenerfv( AL_ORIENTATION, reinterpret_cast<ALfloat const *>( orientation ) );
|
||||||
/*
|
// velocity
|
||||||
glm::dvec3 const listenerposition { Global.pCameraPosition };
|
if( Deltatime > 0 ) {
|
||||||
// not used yet
|
glm::dvec3 const listenerposition { Global.pCameraPosition };
|
||||||
glm::vec3 const velocity { ( listenerposition - m_listenerposition ) / Deltatime };
|
glm::dvec3 const listenermovement { listenerposition - m_listenerposition };
|
||||||
m_listenerposition = listenerposition;
|
m_listenerposition = listenerposition;
|
||||||
*/
|
m_listenervelocity = (
|
||||||
|
glm::length( listenermovement ) < 1000.0 ? // large jumps are typically camera changes
|
||||||
|
listenermovement / Deltatime :
|
||||||
|
glm::vec3() );
|
||||||
|
::alListenerfv( AL_VELOCITY, reinterpret_cast<ALfloat const *>( glm::value_ptr( m_listenervelocity ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
// update active emitters
|
// update active emitters
|
||||||
auto source { std::begin( m_sources ) };
|
auto source { std::begin( m_sources ) };
|
||||||
while( source != std::end( m_sources ) ) {
|
while( source != std::end( m_sources ) ) {
|
||||||
// update each source
|
// update each source
|
||||||
source->update( Deltatime );
|
source->update( Deltatime, m_listenervelocity );
|
||||||
// if after the update the source isn't playing, put it away on the spare stack, it's done
|
// if after the update the source isn't playing, put it away on the spare stack, it's done
|
||||||
if( false == source->is_playing ) {
|
if( false == source->is_playing ) {
|
||||||
source->clear();
|
source->clear();
|
||||||
@@ -367,7 +380,8 @@ openal_renderer::fetch_source() {
|
|||||||
&& ( leastimportantweight < 1.f ) ) {
|
&& ( leastimportantweight < 1.f ) ) {
|
||||||
// only accept the candidate if it's outside of its nominal hearing range
|
// only accept the candidate if it's outside of its nominal hearing range
|
||||||
leastimportantsource->stop();
|
leastimportantsource->stop();
|
||||||
leastimportantsource->update( 0 ); // HACK: a roundabout way to notify the controller its emitter has stopped
|
// HACK: dt of 0 is a roundabout way to notify the controller its emitter has stopped
|
||||||
|
leastimportantsource->update( 0, m_listenervelocity );
|
||||||
leastimportantsource->clear();
|
leastimportantsource->clear();
|
||||||
// we should be now free to grab the id and get rid of the remains
|
// we should be now free to grab the id and get rid of the remains
|
||||||
newsource.id = leastimportantsource->id;
|
newsource.id = leastimportantsource->id;
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ struct openal_source {
|
|||||||
play();
|
play();
|
||||||
// updates state of the source
|
// updates state of the source
|
||||||
void
|
void
|
||||||
update( double const Deltatime );
|
update( double const Deltatime, glm::vec3 const &Listenervelocity );
|
||||||
// configures state of the source to match the provided set of properties
|
// configures state of the source to match the provided set of properties
|
||||||
void
|
void
|
||||||
sync_with( sound_properties const &State );
|
sync_with( sound_properties const &State );
|
||||||
@@ -90,6 +90,7 @@ private:
|
|||||||
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; // cached distance between sound and the listener
|
||||||
|
glm::vec3 sound_velocity; // 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
|
||||||
};
|
};
|
||||||
@@ -142,6 +143,7 @@ private:
|
|||||||
ALCcontext * m_context { nullptr };
|
ALCcontext * m_context { nullptr };
|
||||||
bool m_ready { false }; // renderer is initialized and functional
|
bool m_ready { false }; // renderer is initialized and functional
|
||||||
glm::dvec3 m_listenerposition;
|
glm::dvec3 m_listenerposition;
|
||||||
|
glm::vec3 m_listenervelocity;
|
||||||
|
|
||||||
buffer_manager m_buffers;
|
buffer_manager m_buffers;
|
||||||
// TBD: list of sources as vector, sorted by distance, for openal implementations with limited number of active sources?
|
// TBD: list of sources as vector, sorted by distance, for openal implementations with limited number of active sources?
|
||||||
|
|||||||
16
scene.cpp
16
scene.cpp
@@ -649,6 +649,12 @@ void
|
|||||||
basic_section::insert( shape_node Shape ) {
|
basic_section::insert( shape_node Shape ) {
|
||||||
|
|
||||||
auto const &shapedata = Shape.data();
|
auto const &shapedata = Shape.data();
|
||||||
|
|
||||||
|
// re-calculate section radius, in case shape geometry extends outside the section's boundaries
|
||||||
|
m_area.radius = std::max<float>(
|
||||||
|
m_area.radius,
|
||||||
|
static_cast<float>( glm::length( m_area.center - shapedata.area.center ) + shapedata.area.radius ) );
|
||||||
|
|
||||||
if( ( true == shapedata.translucent )
|
if( ( true == shapedata.translucent )
|
||||||
|| ( shapedata.rangesquared_max <= 90000.0 )
|
|| ( shapedata.rangesquared_max <= 90000.0 )
|
||||||
|| ( shapedata.rangesquared_min > 0.0 ) ) {
|
|| ( shapedata.rangesquared_min > 0.0 ) ) {
|
||||||
@@ -657,11 +663,6 @@ basic_section::insert( shape_node Shape ) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// large, opaque shapes are placed on section level
|
// large, opaque shapes are placed on section level
|
||||||
// re-calculate section radius, in case shape geometry extends outside the section's boundaries
|
|
||||||
m_area.radius = std::max<float>(
|
|
||||||
m_area.radius,
|
|
||||||
static_cast<float>( glm::length( m_area.center - Shape.data().area.center ) + Shape.data().area.radius ) );
|
|
||||||
|
|
||||||
for( auto &shape : m_shapes ) {
|
for( auto &shape : m_shapes ) {
|
||||||
// check first if the shape can't be merged with one of the shapes already present in the section
|
// check first if the shape can't be merged with one of the shapes already present in the section
|
||||||
if( true == shape.merge( Shape ) ) {
|
if( true == shape.merge( Shape ) ) {
|
||||||
@@ -1038,13 +1039,12 @@ basic_region::insert_shape( shape_node Shape, scratch_data &Scratchpad, bool con
|
|||||||
while( true == RaTriangleDivider( shapes[ index ], shapes ) ) {
|
while( true == RaTriangleDivider( shapes[ index ], shapes ) ) {
|
||||||
; // all work is done during expression check
|
; // all work is done during expression check
|
||||||
}
|
}
|
||||||
// with the trimming done we can calculate shape's bounding radius
|
|
||||||
shape.compute_radius();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// move the data into appropriate section(s)
|
// move the data into appropriate section(s)
|
||||||
for( auto &shape : shapes ) {
|
for( auto &shape : shapes ) {
|
||||||
|
// with the potential splitting done we can calculate each chunk's bounding radius
|
||||||
|
shape.compute_radius();
|
||||||
if( point_inside( shape.m_data.area.center ) ) {
|
if( point_inside( shape.m_data.area.center ) ) {
|
||||||
// NOTE: nodes placed outside of region boundaries are discarded
|
// NOTE: nodes placed outside of region boundaries are discarded
|
||||||
section( shape.m_data.area.center ).insert( shape );
|
section( shape.m_data.area.center ).insert( shape );
|
||||||
|
|||||||
@@ -835,8 +835,8 @@ sound_source::location() const {
|
|||||||
void
|
void
|
||||||
sound_source::update_counter( sound_handle const Sound, int const Value ) {
|
sound_source::update_counter( sound_handle const Sound, int const Value ) {
|
||||||
|
|
||||||
sound( Sound ).playing += Value;
|
sound( Sound ).playing = std::max( 0, sound( Sound ).playing + Value );
|
||||||
assert( sound( Sound ).playing >= 0 );
|
// assert( sound( Sound ).playing >= 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
Reference in New Issue
Block a user