Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed GFX running on wall time instead of sim. time #3170

Merged
merged 5 commits into from
Dec 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ def requirements(self):
self.requires("rapidjson/cci.20211112", force=True)
self.requires("socketw/3.11.0@anotherfoxguy/stable")

self.requires("jasper/4.2.4", override=True)
self.requires("libpng/1.6.39", override=True)
self.requires("libwebp/1.3.2", override=True)
self.requires("zlib/1.2.13", override=True)
Expand Down
9 changes: 6 additions & 3 deletions source/main/ForwardDeclarations.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,12 @@ namespace RoR
typedef int FlareID_t; //!< Index into `Actor::ar_flares`, use `RoR::FLAREID_INVALID` as empty value
static const FlareID_t FLAREID_INVALID = -1;

typedef int ExhaustID_t; //!< Index into `Actor::exhausts`, use `RoR::EXHAUSTID_INVALID` as empty value
typedef int ExhaustID_t; //!< Index into `GfxActor::m_exhausts`, use `RoR::EXHAUSTID_INVALID` as empty value
static const ExhaustID_t EXHAUSTID_INVALID = -1;

typedef int CParticleID_t; //!< Index into `GfxActor::m_cparticles`, use `RoR::CPARTICLEID_INVALID` as empty value
static const CParticleID_t CPARTICLEID_INVALID = -1;

typedef int CommandkeyID_t; //!< Index into `Actor::ar_commandkeys` (BEWARE: indexed 1-MAX_COMMANDKEYS, 0 is invalid value, negative subscript of any size is acceptable, see `class CmdKeyArray` ).
static const CommandkeyID_t COMMANDKEYID_INVALID = 0;

Expand Down Expand Up @@ -187,8 +190,8 @@ namespace RoR
struct rotator_t;
struct flare_t;
struct rope_t;
struct exhaust_t;
struct cparticle_t;
struct Exhaust;
struct CParticle;
struct collision_box_t;
struct tie_t;
struct hook_t;
Expand Down
4 changes: 2 additions & 2 deletions source/main/audio/SoundScriptManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -305,14 +305,14 @@ void SoundScriptManager::modulate(int actor_id, int mod, float value, int linkTy
}
}

void SoundScriptManager::update(float dt_sec)
void SoundScriptManager::update(float dt)
{
if (App::sim_state->getEnum<SimState>() == SimState::RUNNING ||
App::sim_state->getEnum<SimState>() == SimState::EDITOR_MODE)
{
Ogre::SceneNode* cam_node = App::GetCameraManager()->GetCameraNode();
static Vector3 lastCameraPosition;
Vector3 cameraSpeed = (cam_node->getPosition() - lastCameraPosition) / dt_sec;
Vector3 cameraSpeed = (cam_node->getPosition() - lastCameraPosition) / dt;
lastCameraPosition = cam_node->getPosition();
Ogre::Vector3 upVector = App::GetCameraManager()->GetCameraNode()->getOrientation() * Ogre::Vector3::UNIT_Y;
// Direction points down -Z by default (adapted from Ogre::Camera)
Expand Down
2 changes: 1 addition & 1 deletion source/main/audio/SoundScriptManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ class SoundScriptManager : public Ogre::ScriptLoader

bool isDisabled() { return disabled; }

void update(float dt_sec);
void update(float dt);

SoundManager* getSoundManager() { return sound_manager; }

Expand Down
2 changes: 2 additions & 0 deletions source/main/gfx/DustPool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

#include "Application.h"
#include "GameContext.h"
#include "GfxScene.h"
#include "Terrain.h"
#include "Water.h"

Expand Down Expand Up @@ -195,6 +196,7 @@ void DustPool::update()
{
for (int i = 0; i < allocated; i++)
{
App::GetGfxScene()->AdjustParticleSystemTimeFactor(pss[i]);
ParticleEmitter* emit = pss[i]->getEmitter(0);
Vector3 ndir = velocities[i];
Real vel = ndir.length();
Expand Down
2 changes: 1 addition & 1 deletion source/main/gfx/DustPool.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ class DustPool
Ogre::SceneNode* sns[MAX_DUSTS];
Ogre::SceneNode* parent_snode;
Ogre::Vector3 positions[MAX_DUSTS];
Ogre::Vector3 velocities[MAX_DUSTS];
Ogre::Vector3 velocities[MAX_DUSTS]; //!< Velocity in wall time, ignoring the time scale.
float rates[MAX_DUSTS];
int allocated;
int size;
Expand Down
102 changes: 89 additions & 13 deletions source/main/gfx/GfxActor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,54 @@ RoR::GfxActor::~GfxActor()
HandleGenericException(WhereFrom(this, "destroying renderdash"), HANDLEGENERICEXCEPTION_LOGFILE);
}
}

// delete exhausts
for (std::vector<Exhaust>::iterator it = m_exhausts.begin(); it != m_exhausts.end(); it++)
{
try
{
if (it->smokeNode)
{
it->smokeNode->removeAndDestroyAllChildren();
App::GetGfxScene()->GetSceneManager()->destroySceneNode(it->smokeNode);
}
if (it->smoker)
{
it->smoker->removeAllAffectors();
it->smoker->removeAllEmitters();
App::GetGfxScene()->GetSceneManager()->destroyParticleSystem(it->smoker);
}
}
catch (...)
{
HandleGenericException(fmt::format("GfxActor::~GfxActor(); instanceID:{}, streamID:{}, filename:{}; deleting exhaust {}/{}.",
m_actor->ar_instance_id, m_actor->ar_net_stream_id, m_actor->ar_filename, std::distance(m_exhausts.begin(), it), m_exhausts.size()), HANDLEGENERICEXCEPTION_LOGFILE);
}
}

// delete custom particles
for (int i = 0; i < (int)m_cparticles.size(); i++)
{
try
{
if (m_cparticles[i].snode)
{
m_cparticles[i].snode->removeAndDestroyAllChildren();
App::GetGfxScene()->GetSceneManager()->destroySceneNode(m_cparticles[i].snode);
}
if (m_cparticles[i].psys)
{
m_cparticles[i].psys->removeAllAffectors();
m_cparticles[i].psys->removeAllEmitters();
App::GetGfxScene()->GetSceneManager()->destroyParticleSystem(m_cparticles[i].psys);
}
}
catch (...)
{
HandleGenericException(fmt::format("Actor::dispose(); instanceID:{}, streamID:{}, filename:{}; deleting custom particle {}/{}.",
m_actor->ar_instance_id, m_actor->ar_net_stream_id, m_actor->ar_filename, i, m_cparticles.size()), HANDLEGENERICEXCEPTION_LOGFILE);
}
}
}

ActorPtr RoR::GfxActor::GetActor()
Expand Down Expand Up @@ -419,7 +467,7 @@ void RoR::GfxActor::SetVideoCamState(VideoCamState state)
m_vidcam_state = state;
}

void RoR::GfxActor::UpdateVideoCameras(float dt_sec)
void RoR::GfxActor::UpdateVideoCameras(float dt)
{
if (m_vidcam_state != VideoCamState::VCSTATE_ENABLED_ONLINE)
return;
Expand Down Expand Up @@ -539,7 +587,7 @@ void RoR::GfxActor::UpdateVideoCameras(float dt_sec)
}
}

void RoR::GfxActor::UpdateParticles(float dt_sec)
void RoR::GfxActor::UpdateParticles(float dt)
{
float water_height = 0.f; // Unused if terrain has no water
if (App::GetGameContext()->GetTerrain()->getWater() != nullptr)
Expand All @@ -563,7 +611,7 @@ void RoR::GfxActor::UpdateParticles(float dt_sec)
// Dripping water?
if (nfx.nx_wet_time_sec != -1)
{
nfx.nx_wet_time_sec += dt_sec;
nfx.nx_wet_time_sec += dt;
if (nfx.nx_wet_time_sec > 5.f) // Dries off in 5 sec
{
nfx.nx_wet_time_sec = -1.f;
Expand Down Expand Up @@ -1844,6 +1892,7 @@ void RoR::GfxActor::UpdateSimDataBuffer()
m_simbuf.simbuf_clutch = m_actor->ar_engine->GetClutch();
m_simbuf.simbuf_num_gears = m_actor->ar_engine->getNumGears();
m_simbuf.simbuf_engine_max_rpm = m_actor->ar_engine->getMaxRPM();
m_simbuf.simbuf_engine_smoke = m_actor->ar_engine->GetSmoke();
}
if (m_actor->m_num_wheel_diffs > 0)
{
Expand All @@ -1858,6 +1907,7 @@ void RoR::GfxActor::UpdateSimDataBuffer()
m_simbuf.simbuf_lightmask = m_actor->m_lightmask;
m_simbuf.simbuf_smoke_enabled = m_actor->getSmokeEnabled();
m_simbuf.simbuf_parking_brake = m_actor->ar_parking_brake;
m_simbuf.simbuf_cparticles_active = m_actor->ar_cparticles_active;

// Aerial
m_simbuf.simbuf_hydro_aileron_state = m_actor->ar_hydro_aileron_state;
Expand Down Expand Up @@ -1986,19 +2036,45 @@ void RoR::GfxActor::UpdateAirbrakes()
}
}

// TODO: Also move the data structure + setup code to GfxActor ~ only_a_ptr, 05/2018
void RoR::GfxActor::UpdateCParticles()
{
//update custom particle systems
for (int i = 0; i < m_actor->ar_num_custom_particles; i++)
for (CParticle& cparticle: m_cparticles)
{
Ogre::Vector3 pos = m_simbuf.simbuf_nodes[m_actor->ar_custom_particles[i].emitterNode].AbsPosition;
Ogre::Vector3 dir = pos - m_simbuf.simbuf_nodes[m_actor->ar_custom_particles[i].directionNode].AbsPosition;
dir = fast_normalise(dir);
m_actor->ar_custom_particles[i].snode->setPosition(pos);
for (int j = 0; j < m_actor->ar_custom_particles[i].psys->getNumEmitters(); j++)
App::GetGfxScene()->AdjustParticleSystemTimeFactor(cparticle.psys);
const Ogre::Vector3 pos = m_simbuf.simbuf_nodes[cparticle.emitterNode].AbsPosition;
const Ogre::Vector3 dir = fast_normalise(pos - m_simbuf.simbuf_nodes[cparticle.directionNode].AbsPosition);
cparticle.snode->setPosition(pos);

for (unsigned short j = 0; j < cparticle.psys->getNumEmitters(); j++)
{
cparticle.psys->getEmitter(j)->setEnabled(m_simbuf.simbuf_cparticles_active);
cparticle.psys->getEmitter(j)->setDirection(dir);
}
}
}

void RoR::GfxActor::UpdateExhausts()
{
if (!m_simbuf.simbuf_has_engine)
return;

for (Exhaust& exhaust: m_exhausts)
{
if (!exhaust.smoker) // This remains `nullptr` if removed via `addonpart_unwanted_exhaust` or Tuning UI.
continue;

App::GetGfxScene()->AdjustParticleSystemTimeFactor(exhaust.smoker);
const Ogre::Vector3 pos = m_simbuf.simbuf_nodes[exhaust.emitterNode].AbsPosition;
const Ogre::Vector3 dir = pos - m_simbuf.simbuf_nodes[exhaust.directionNode].AbsPosition;
exhaust.smokeNode->setPosition(pos);

const bool active = m_simbuf.simbuf_smoke_enabled && m_simbuf.simbuf_engine_smoke != -1.f;
exhaust.smoker->getEmitter(0)->setEnabled(active);
if (active) // `setTimeToLive()` assert()s that argument is not negative.
{
m_actor->ar_custom_particles[i].psys->getEmitter(j)->setDirection(dir);
exhaust.smoker->getEmitter(0)->setColour(Ogre::ColourValue(0.0, 0.0, 0.0, 0.02 + m_simbuf.simbuf_engine_smoke * 0.06));
exhaust.smoker->getEmitter(0)->setTimeToLive((0.02 + m_simbuf.simbuf_engine_smoke * 0.06) / 0.04);
exhaust.smoker->getEmitter(0)->setParticleVelocity(1.0 + m_simbuf.simbuf_engine_smoke * 2.0, 2.0 + m_simbuf.simbuf_engine_smoke * 3.0);
}
}
}
Expand Down Expand Up @@ -3182,7 +3258,7 @@ bool ShouldEnableLightSource(FlareType type, bool is_player)
}
}

void RoR::GfxActor::UpdateFlares(float dt_sec, bool is_player)
void RoR::GfxActor::UpdateFlares(float dt, bool is_player)
{
// Flare states are determined in simulation, this function only applies them to OGRE objects
// ------------------------------------------------------------------------------------------
Expand Down
20 changes: 14 additions & 6 deletions source/main/gfx/GfxActor.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,13 @@ class GfxActor
void RegisterCabMesh(Ogre::Entity* ent, Ogre::SceneNode* snode, FlexObj* flexobj);
void SortFlexbodies();

// Retrieving elements

std::vector<FlexBody*>& GetFlexbodies() { return m_flexbodies; };
std::vector<Prop>& getProps() { return m_props; }
std::vector<CParticle>& getCParticles() { return m_cparticles; }
std::vector<Exhaust>& getExhausts() { return m_exhausts; }

// Visual changes

void SetMaterialFlareOn(int flare_index, bool state_on);
Expand Down Expand Up @@ -95,8 +102,8 @@ class GfxActor

// Visual updates

void UpdateVideoCameras(float dt_sec);
void UpdateParticles(float dt_sec);
void UpdateVideoCameras(float dt);
void UpdateParticles(float dt);
void UpdateRods();
void UpdateWheelVisuals();
void UpdateFlexbodies();
Expand All @@ -108,9 +115,10 @@ class GfxActor
void UpdatePropAnimations(float dt);
void UpdateAirbrakes();
void UpdateCParticles();
void UpdateExhausts();
void UpdateAeroEngines();
void UpdateNetLabels(float dt);
void UpdateFlares(float dt_sec, bool is_player);
void UpdateFlares(float dt, bool is_player);
void UpdateRenderdashRTT ();

// SimBuffers
Expand All @@ -132,17 +140,15 @@ class GfxActor
void CalculateDriverPos(Ogre::Vector3& out_pos, Ogre::Quaternion& out_rot);
int GetActorId() const;
int GetActorState() const;
std::vector<FlexBody*>& GetFlexbodies() { return m_flexbodies; };
Ogre::MaterialPtr& GetCabTransMaterial() { return m_cab_mat_visual_trans; }
VideoCamState GetVideoCamState() const { return m_vidcam_state; }
DebugViewType GetDebugView() const { return m_debug_view; }
Ogre::String GetResourceGroup() { return m_custom_resource_group; }
ActorPtr GetActor(); // Watch out for multithreading with this!
Ogre::MaterialPtr& GetCabTransMaterial() { return m_cab_mat_visual_trans; }
Ogre::TexturePtr GetHelpTex() { return m_help_tex; }
Ogre::MaterialPtr GetHelpMat() { return m_help_mat; }
bool HasDriverSeatProp() const { return m_driverseat_prop_index != -1; }
void CalcPropAnimation(PropAnim& anim, float& cstate, int& div, float dt);
std::vector<Prop>& getProps() { return m_props; }
size_t getNumVideoCameras() const { return m_videocameras.size(); }
SurveyMapEntity& getSurveyMapEntity() { return m_surveymap_entity; }
WheelSide getWheelSide(WheelID_t wheel_id) { return (wheel_id >= 0 && (size_t)wheel_id < m_wheels.size()) ? m_wheels[wheel_id].wx_side : WheelSide::INVALID; }
Expand Down Expand Up @@ -193,6 +199,8 @@ class GfxActor
DustPool* m_particles_ripple = nullptr;
DustPool* m_particles_sparks = nullptr;
DustPool* m_particles_clump = nullptr;
std::vector<CParticle> m_cparticles;
std::vector<Exhaust> m_exhausts;

// Cab mesh ('submesh' in truck fileformat)
FlexObj* m_cab_mesh = nullptr;
Expand Down
17 changes: 17 additions & 0 deletions source/main/gfx/GfxData.h
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,23 @@ struct FlareMaterial // materialflares
Ogre::ColourValue emissive_color;
};

struct Exhaust
{
NodeNum_t emitterNode = NODENUM_INVALID;
NodeNum_t directionNode = NODENUM_INVALID;
Ogre::SceneNode *smokeNode = nullptr;
Ogre::ParticleSystem* smoker = nullptr; //!< This remains `nullptr` if removed via `addonpart_unwanted_exhaust` or Tuning UI.
std::string particleSystemName; //!< Name in .particle file ~ for display in Tuning UI.
};

struct CParticle
{
NodeNum_t emitterNode = NODENUM_INVALID;
NodeNum_t directionNode = NODENUM_INVALID;
Ogre::SceneNode *snode = nullptr;
Ogre::ParticleSystem* psys = nullptr;
};

/// @} // addtogroup Gfx

} // namespace RoR
Loading
Loading