diff --git a/source/main/gfx/GfxData.h b/source/main/gfx/GfxData.h index 0f3219d48c..eb100d8e78 100644 --- a/source/main/gfx/GfxData.h +++ b/source/main/gfx/GfxData.h @@ -117,6 +117,12 @@ static const int CAMERA_MODE_ALWAYS_HIDDEN = -3; static const int CAMERA_MODE_ALWAYS_VISIBLE = -2; static const int CAMERA_MODE_3RDPERSON_ONLY = -1; +// Light attenuation defaults - matches defaults in `Ogre::Light::Light()` constructor. +static const float ATTENUATION_DEFAULT_RANGE_METERS = 250.f; //!< The absolute upper range of the light in meters. +static const float ATTENUATION_DEFAULT_CONSTANT_FACTOR = 1.f; //!< The constant factor in the attenuation formula: 1.0 means never attenuate, 0.0 is complete attenuation. +static const float ATTENUATION_DEFAULT_LINEAR_FACTOR = 0.f; //!< The linear factor in the attenuation formula: 1 means attenuate evenly over the distance. +static const float ATTENUATION_DEFAULT_QUADRATIC_FACTOR = 0.f; //!< The quadratic factor in the attenuation formula: adds a curvature to the attenuation formula. + enum ShifterPropAnim { SHIFTER_INVALID = 0, diff --git a/source/main/physics/ActorSpawner.cpp b/source/main/physics/ActorSpawner.cpp index 9d665580bb..5f0db34156 100644 --- a/source/main/physics/ActorSpawner.cpp +++ b/source/main/physics/ActorSpawner.cpp @@ -1997,6 +1997,13 @@ void ActorSpawner::ProcessFlare3(RigDef::Flare3 & def) flare_t& f = m_actor->ar_flares.back(); f.uses_inertia = true; this->_ProcessSimpleInertia(*def.inertia_defaults, f.inertia); + + // Also apply attenuation settings + f.light->setAttenuation( + def.attenuation_defaults->range, + def.attenuation_defaults->constant, + def.attenuation_defaults->linear, + def.attenuation_defaults->quadratic); } void ActorSpawner::ProcessFlare2(RigDef::Flare2 & def) diff --git a/source/main/resources/rig_def_fileformat/RigDef_File.h b/source/main/resources/rig_def_fileformat/RigDef_File.h index 09b98df968..07c300259b 100644 --- a/source/main/resources/rig_def_fileformat/RigDef_File.h +++ b/source/main/resources/rig_def_fileformat/RigDef_File.h @@ -148,6 +148,7 @@ enum class Keyword SCRIPTS, SECTION, SECTIONCONFIG, + SET_ATTENUATION_DEFAULTS, SET_BEAM_DEFAULTS, SET_BEAM_DEFAULTS_SCALE, SET_COLLISION_RANGE, @@ -406,6 +407,16 @@ struct AeroAnimator // used by Animator unsigned int engine_idx = 0u; }; +/// Sets the attenuation parameters of the light source i.e. how it diminishes with distance. +/// See `Ogre::Light::setAttenuation()` - https://ogrecave.github.io/ogre/api/latest/class_ogre_1_1_light.html#a43f763d809bc7da9a85fec15f57380f4 +struct AttenuationDefaults // used by Flare3 +{ + float range = RoR::ATTENUATION_DEFAULT_RANGE_METERS; //!< The absolute upper range of the light in meters. + float constant = RoR::ATTENUATION_DEFAULT_CONSTANT_FACTOR; //!< The constant factor in the attenuation formula: 1.0 means never attenuate, 0.0 is complete attenuation. + float linear = RoR::ATTENUATION_DEFAULT_LINEAR_FACTOR; //!< The linear factor in the attenuation formula: 1 means attenuate evenly over the distance. + float quadratic = RoR::ATTENUATION_DEFAULT_QUADRATIC_FACTOR; //!< The quadratic factor in the attenuation formula: adds a curvature to the attenuation formula. +}; + struct BaseWheel { float width = 0.f; @@ -882,6 +893,7 @@ struct Flare2 // Used for both 'flares' and 'flares2' sections struct Flare3: public Flare2 { std::shared_ptr inertia_defaults; + std::shared_ptr attenuation_defaults; }; struct Flexbody diff --git a/source/main/resources/rig_def_fileformat/RigDef_Parser.cpp b/source/main/resources/rig_def_fileformat/RigDef_Parser.cpp index aa5111ad4d..c64a52b51e 100644 --- a/source/main/resources/rig_def_fileformat/RigDef_Parser.cpp +++ b/source/main/resources/rig_def_fileformat/RigDef_Parser.cpp @@ -30,6 +30,7 @@ #include "SimConstants.h" #include "CacheSystem.h" #include "Console.h" +#include "GfxData.h" #include "RigDef_File.h" #include "RigDef_Regexes.h" #include "Utils.h" @@ -166,6 +167,9 @@ void Parser::ProcessCurrentLine() case Keyword::SECTION: this->ParseDirectiveSection(); return; + case Keyword::SET_ATTENUATION_DEFAULTS: + this->ParseDirectiveSetAttenuationDefaults(); + return; case Keyword::SET_BEAM_DEFAULTS: this->ParseDirectiveSetBeamDefaults(); return; @@ -544,6 +548,24 @@ void Parser::ParseDirectiveSetManagedMaterialsOptions() m_current_managed_material_options.double_sided = (this->GetArgChar(1) != '0'); } +void Parser::ParseDirectiveSetAttenuationDefaults() +{ + // Get values from the text file + float range = this->GetArgFloat(1); + float constant = (m_num_args > 2) ? this->GetArgFloat(2) : -1; + float linear = (m_num_args > 3) ? this->GetArgFloat(3) : -1; + float quadratic = (m_num_args > 4) ? this->GetArgFloat(4) : -1; + + // Create a 'preset' object as a clone of previous preset object. + m_user_attenuation_defaults = std::shared_ptr(new AttenuationDefaults(*m_user_attenuation_defaults)); + + // Update the preset values. If -1 then reset to builtin constant. + m_user_attenuation_defaults->range = (range < 0) ? ATTENUATION_DEFAULT_RANGE_METERS : range; + m_user_attenuation_defaults->constant = (constant < 0) ? ATTENUATION_DEFAULT_CONSTANT_FACTOR : constant; + m_user_attenuation_defaults->linear = (linear < 0) ? ATTENUATION_DEFAULT_LINEAR_FACTOR : linear; + m_user_attenuation_defaults->quadratic = (quadratic < 0) ? ATTENUATION_DEFAULT_QUADRATIC_FACTOR : quadratic; +} + void Parser::ParseDirectiveSetBeamDefaultsScale() { if (! this->CheckNumArguments(5)) { return; } @@ -964,11 +986,11 @@ void Parser::ParseFlaresUnified() void Parser::ParseFlares3() { - const bool is_flares2 = (m_current_block == Keyword::FLARES2); - if (! this->CheckNumArguments(is_flares2 ? 6 : 5)) { return; } + if (! this->CheckNumArguments(6)) { return; } Flare3 flare3; flare3.inertia_defaults = m_user_default_inertia; + flare3.attenuation_defaults = m_user_attenuation_defaults; flare3.reference_node = this->GetArgNodeRef(0); flare3.node_axis_x = this->GetArgNodeRef(1); @@ -2705,6 +2727,8 @@ void Parser::Prepare() m_user_beam_defaults->breaking_threshold = BEAM_BREAK; m_user_beam_defaults->visual_beam_diameter = DEFAULT_BEAM_DIAMETER; + m_user_attenuation_defaults = std::shared_ptr(new AttenuationDefaults); + m_root_module = m_definition->root_module; m_current_module = m_definition->root_module; diff --git a/source/main/resources/rig_def_fileformat/RigDef_Parser.h b/source/main/resources/rig_def_fileformat/RigDef_Parser.h index ce00061ef4..c0de97c3d7 100644 --- a/source/main/resources/rig_def_fileformat/RigDef_Parser.h +++ b/source/main/resources/rig_def_fileformat/RigDef_Parser.h @@ -97,6 +97,7 @@ class Parser void ParseDirectivePropCameraMode(); void ParseDirectiveSection(); void ParseDirectiveSectionConfig(); + void ParseDirectiveSetAttenuationDefaults(); void ParseDirectiveSetBeamDefaults(); void ParseDirectiveSetBeamDefaultsScale(); void ParseDirectiveSetDefaultMinimass(); @@ -257,6 +258,7 @@ class Parser // Data from user directives // Each affected section-struct has a shared_ptr to it's respective defaults std::shared_ptr m_user_default_inertia; + std::shared_ptr m_user_attenuation_defaults; std::shared_ptr m_user_beam_defaults; std::shared_ptr m_user_node_defaults; std::shared_ptr m_set_default_minimass; diff --git a/source/main/resources/rig_def_fileformat/RigDef_Regexes.h b/source/main/resources/rig_def_fileformat/RigDef_Regexes.h index fdb037b86d..098d3cb94b 100644 --- a/source/main/resources/rig_def_fileformat/RigDef_Regexes.h +++ b/source/main/resources/rig_def_fileformat/RigDef_Regexes.h @@ -2,7 +2,7 @@ This source file is part of Rigs of Rods Copyright 2005-2012 Pierre-Michel Ricordel Copyright 2007-2012 Thomas Fischer - Copyright 2013-2020 Petr Ohlidal + Copyright 2013-2023 Petr Ohlidal For more information, see http://www.rigsofrods.org/ @@ -200,6 +200,7 @@ namespace Regexes E_KEYWORD_BLOCK("scripts") \ E_KEYWORD_INLINE("section") \ E_KEYWORD_INLINE("sectionconfig") \ + E_KEYWORD_INLINE("set_attenuation_defaults") \ E_KEYWORD_INLINE("set_beam_defaults") \ E_KEYWORD_INLINE("set_beam_defaults_scale") \ E_KEYWORD_INLINE("set_collision_range") \