17
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-10-17 02:49:19 +02:00

Fix/sonar maintainability rebased (#209)

* refactor(sonar): use override instead of redundant virtual (cpp:S3471)

* refactor(sonar): remove empty statements, one declaration per statement (cpp:S1116, cpp:S1659)

* refactor(sonar): drop redundant lambda return types (cpp:S3574)

* refactor(sonar): prefer using over typedef (cpp:S5416)

* refactor(sonar): use =default for trivial special members (cpp:S3490)

* refactor(sonar): use nullptr literal (cpp:S4962)

* refactor(sonar): remove redundant access specifiers (cpp:S3539)

* refactor(sonar): remove redundant casts (cpp:S1905)

* refactor(sonar): use std::scoped_lock instead of std::lock_guard (cpp:S5997)

* refactor(sonar): construct elements in place with emplace_back (cpp:S6003)

* refactor(sonar): make narrowing conversions explicit (cpp:S5276)

* refactor(sonar): mark unused parameters (cpp:S1172)

Unused names are commented out; parameters used only on some platforms
are marked [[maybe_unused]].

* refactor(sonar): declare non-mutating member functions const (cpp:S5817)

Virtual functions are left untouched so overrides keep matching.

* refactor(sonar): merge collapsible nested if statements (cpp:S1066)

Comments that preceded the inner if are kept above the merged statement.

* refactor(sonar): scope single-use variables in if init-statements (cpp:S6004)

* fix(sonar): give polymorphic base classes virtual destructors (cpp:S1235)

* refactor(sonar): use try_emplace for map insertion (cpp:S6030)

* refactor(sonar): use auto where the type is spelled out on the right (cpp:S5827)

* refactor(sonar): remove redundant parentheses (cpp:S1110)

* refactor(sonar): document intentionally empty functions (cpp:S1186)

* refactor(sonar): remove dead stores (cpp:S1854)

Side effects (e.g. LISTLINE++) are kept.

* refactor(sonar): remove unused variables, captures and private fields (cpp:S1481, cpp:S1068)

* refactor(sonar): use structured bindings for pair access (cpp:S6005)

* refactor(sonar): use range-based loops and ranges algorithms (cpp:S5566)

* refactor(sonar): split chained assignments (cpp:S1121)

* refactor(sonar): add default cases to switch statements (cpp:S3562)

* refactor(sonar): use std::size for array lengths (cpp:S7127)

* refactor(sonar): use std::ranges algorithms and std::erase(_if) (cpp:S6197)

* refactor(sonar): access static members through the class (cpp:S2209)

* refactor(sonar): add braces around nested if-else (cpp:S5261)

* refactor(sonar): avoid side effects inside typeid operands (cpp:S5279)

* refactor(sonar): drop top-level const from by-value return types (cpp:S5951)

* refactor(sonar): declare variables separately from their type definitions (cpp:S3646)

* refactor(sonar): declare loop counters in the for statement (cpp:S5955)

* refactor(sonar): rely on class template argument deduction (cpp:S6012)

* refactor(sonar): inherit base constructors instead of forwarding them (cpp:S5952)

* refactor(sonar): rename locals that shadow outer declarations (cpp:S1117)

Only local variables and definition parameters are renamed; shadowing
struct fields and enumerators in headers are left for a separate change.

* refactor(sonar): reduce enum qualification with using enum (cpp:S6177)

Applied only where no unqualified name in the block could be captured by
the introduced enumerators.

* refactor(sonar): mark converting constructors explicit (cpp:S1709)

sound_source and the gl::object conversion operators stay implicit; they
are relied upon by copy-list-initialisation and GL calls.

* refactor(sonar): initialise members in initialiser lists or declarations (cpp:S3230)

* refactor(sonar): make read-only local references and pointers const (cpp:S5350)

* refactor(sonar): take read-only pointer and reference parameters as const (cpp:S995)

TTrain command handlers keep their signature, it is fixed by the handler table.

* refactor(sonar): pass expensive-to-copy parameters by const reference (cpp:S1238)

Signatures declared in files touched by PR 206 (Driver.h, EU07.cpp) and
virtual overrides are left unchanged.

* refactor(sonar): use transparent comparators for string-keyed maps (cpp:S6045)

std::unordered_map instances and map types exposed in headers used by
other modules are left as they are.

* fix(sonar): do not use UI text as a printf format string (cpp:S5281)

Text lines containing '%' would otherwise be interpreted as format
specifiers by ImGui::TextColored.

* refactor(sonar): use std::bind_front for callbacks (cpp:S5995)

* refactor(sonar): drop const_cast on string literals passed to the Python C API (cpp:S859)

* refactor(sonar): take read-only string parameters as std::string_view (cpp:S6009)

The Windows messaging helpers keep std::string, they need c_str().

* refactor(sonar): make read-only global tables const (cpp:S5421)

Mutable global state (flags, timers, singletons) is left as is.

* refactor(sonar): replace single-case switch statements with if (cpp:S1301)

* refactor(sonar): format UUIDs and log timestamps with std::format (cpp:S6494, cpp:S5945)

* refactor(sonar): use std::array for local fixed-size arrays (cpp:S5945)

Arrays that are class members or part of headers are left unchanged.

* fix(sonar): test the bearing damage bit, not bit 0 (cpp:S872)

'DamageFlag & dtrain_bearing > 0' parsed as 'DamageFlag & (dtrain_bearing > 0)',
i.e. DamageFlag & 1, so bearing friction reacted to the wrong damage flag.

* refactor(sonar): assorted small fixes

- empty() instead of size() comparisons (cpp:S1155)
- member initialisers in declaration order (cpp:S3229)
- no redundant c_str() when a std::string is accepted (cpp:S7121)
- contains() on associative containers (cpp:S6171)
- const reference instead of a copying range-for (cpp:S6032)
- starts_with() for prefix checks (cpp:S6178)
- no std::move on temporaries (cpp:S5274)
- has_value() on std::optional (cpp:S7172)
- bool literals for bool members (cpp:S5820)
- inline only on the definition (cpp:S3548)
- explicit base access specifier (cpp:S5965)
- explicit element access instead of dereferencing an array (cpp:S7116)
- rely on the C++20 rewritten operator!= (cpp:S6186)

* refactor(sonar): more small fixes

- std::format instead of iostream manipulators in to_string/to_hex_str (cpp:S6495);
  output verified identical, negative hex values keep the unsigned form
- remove an empty compound statement (cpp:S108)
- drop an always-false unsigned < 0 branch (cpp:S1768)
- explicit lambda capture (cpp:S3608)
- std::make_unique (cpp:S5950)

* chore: strip stray carriage returns left in TTrain constructor comments

* fix: keep quantize() in its own value type

The S5276 change cast the result of the generic quantize<Type_>() to
unsigned int, which truncated float/double callers (shadow angle slider,
editor rotation snapping, AI speed control steps) and broke negative values.

* fix(sonar): use integer loop counters in segment sampling (cpp:S2193)

* refactor(sonar): clean up issues reported on PR 209

- remove locals left unused after the dead-store cleanup (cpp:S1481, cpp:S1854)
- unnamed unused parameter (cpp:S1172)
- single-use declarations moved into if init-statements (cpp:S6004)
- auto for casted initialisers (cpp:S5827)
- const references and pointers where nothing is modified (cpp:S5350)
- rename structured bindings shadowed by inner declarations (cpp:S1117)
This commit is contained in:
jerrrrycho
2026-10-11 13:22:33 +02:00
committed by GitHub
parent c26041f2e7
commit 6263fe539b
162 changed files with 4220 additions and 4598 deletions

View File

@@ -14,39 +14,43 @@ namespace flip_s3tc
struct dxt1_block
{
uint16_t c0, c1;
uint8_t dcba,
hgfe,
lkji,
ponm;
uint16_t c0;
uint16_t c1;
uint8_t dcba;
uint8_t hgfe;
uint8_t lkji;
uint8_t ponm;
};
struct dxt23_block
{
uint16_t adacabaa,
ahagafae,
alakajai,
apaoanam;
uint16_t c0, c1;
uint8_t dcba,
hgfe,
lkji,
ponm;
uint16_t adacabaa;
uint16_t ahagafae;
uint16_t alakajai;
uint16_t apaoanam;
uint16_t c0;
uint16_t c1;
uint8_t dcba;
uint8_t hgfe;
uint8_t lkji;
uint8_t ponm;
};
struct dxt45_block
{
uint8_t a0, a1;
uint8_t a0;
uint8_t a1;
struct
{
uint8_t alpha[3];
} ahagafaeadacabaa,
apaoanamalakajai;
uint16_t c0, c1;
uint8_t dcba,
hgfe,
lkji,
ponm;
uint16_t c0;
uint16_t c1;
uint8_t dcba;
uint8_t hgfe;
uint8_t lkji;
uint8_t ponm;
};
#pragma pack(pop)
@@ -123,16 +127,16 @@ void flip_dxt45_block(struct dxt45_block *block)
*/
void flip_dxt1_image(void *data, int width, int height)
{
int x, y;
struct dxt1_block temp1, temp2;
struct dxt1_block *blocks = (struct dxt1_block *)data;
struct dxt1_block temp1;
struct dxt1_block temp2;
auto blocks = (struct dxt1_block *)data;
width = (width + 3) / 4;
height = (height + 3) / 4;
for (y = 0; y < height / 2; ++y)
for (int y = 0; y < height / 2; ++y)
{
for (x = 0; x < width; ++x)
for (int x = 0; x < width; ++x)
{
temp1 = blocks[y * width + x];
temp2 = blocks[(height - y - 1) * width + x];
@@ -152,16 +156,16 @@ void flip_dxt1_image(void *data, int width, int height)
*/
void flip_dxt23_image(void *data, int width, int height)
{
int x, y;
struct dxt23_block temp1, temp2;
struct dxt23_block *blocks = (struct dxt23_block *)data;
struct dxt23_block temp1;
struct dxt23_block temp2;
auto blocks = (struct dxt23_block *)data;
width = (width + 3) / 4;
height = (height + 3) / 4;
for (y = 0; y < height / 2; ++y)
for (int y = 0; y < height / 2; ++y)
{
for (x = 0; x < width; ++x)
for (int x = 0; x < width; ++x)
{
temp1 = blocks[y * width + x];
temp2 = blocks[(height - y - 1) * width + x];
@@ -181,16 +185,16 @@ void flip_dxt23_image(void *data, int width, int height)
*/
void flip_dxt45_image(void *data, int width, int height)
{
int x, y;
struct dxt45_block temp1, temp2;
struct dxt45_block *blocks = (struct dxt45_block *)data;
struct dxt45_block temp1;
struct dxt45_block temp2;
auto blocks = (struct dxt45_block *)data;
width = (width + 3) / 4;
height = (height + 3) / 4;
for (y = 0; y < height / 2; ++y)
for (int y = 0; y < height / 2; ++y)
{
for (x = 0; x < width; ++x)
for (int x = 0; x < width; ++x)
{
temp1 = blocks[y * width + x];
temp2 = blocks[(height - y - 1) * width + x];

View File

@@ -24,7 +24,7 @@ cFrustum::calculate( glm::mat4 const &Projection, glm::mat4 const &Modelview ) {
// multiply the matrices to retrieve clipping planes (column-major, same layout as the old float[16] form)
auto const clipmatrix { Projection * Modelview };
float clip[ 16 ];
std::array<float, 16> clip{};
for( int column = 0; column < 4; ++column ) {
for( int row = 0; row < 4; ++row ) {
clip[ column * 4 + row ] = clipmatrix[ column ][ row ];
@@ -73,16 +73,11 @@ bool
cFrustum::point_inside( float const X, float const Y, float const Z ) const {
// cycle through the sides of the frustum, checking if the point is behind them
for( int idx = 0; idx < 6; ++idx ) {
if( m_frustum[ idx ][ plane_A ] * X
+ m_frustum[ idx ][ plane_B ] * Y
+ m_frustum[ idx ][ plane_C ] * Z
+ m_frustum[ idx ][ plane_D ] <= 0 )
return false;
}
// the point is in front of each frustum plane, i.e. inside of the frustum
return true;
return std::ranges::all_of( m_frustum, [&]( auto const &frustumplane ) {
return frustumplane[ plane_A ] * X
+ frustumplane[ plane_B ] * Y
+ frustumplane[ plane_C ] * Z
+ frustumplane[ plane_D ] > 0; } );
}
float
@@ -90,12 +85,12 @@ cFrustum::sphere_inside( float const X, float const Y, float const Z, float cons
float distance;
// go through all the sides of the frustum. bail out as soon as possible
for( int idx = 0; idx < 6; ++idx ) {
for (auto &frustumplane : m_frustum) {
distance =
m_frustum[ idx ][ plane_A ] * X
+ m_frustum[ idx ][ plane_B ] * Y
+ m_frustum[ idx ][ plane_C ] * Z
+ m_frustum[ idx ][ plane_D ];
frustumplane[ plane_A ] * X
+ frustumplane[ plane_B ] * Y
+ frustumplane[ plane_C ] * Z
+ frustumplane[ plane_D ];
if( distance <= -Radius )
return 0.0f;
}
@@ -105,52 +100,50 @@ cFrustum::sphere_inside( float const X, float const Y, float const Z, float cons
bool
cFrustum::cube_inside( float const X, float const Y, float const Z, float const Size ) const {
for( int idx = 0; idx < 6; ++idx ) {
if( m_frustum[ idx ][ plane_A ] * ( X - Size )
+ m_frustum[ idx ][ plane_B ] * ( Y - Size )
+ m_frustum[ idx ][ plane_C ] * ( Z - Size )
+ m_frustum[ idx ][ plane_D ] > 0 )
continue;
if( m_frustum[ idx ][ plane_A ] * ( X + Size )
+ m_frustum[ idx ][ plane_B ] * ( Y - Size )
+ m_frustum[ idx ][ plane_C ] * ( Z - Size )
+ m_frustum[ idx ][ plane_D ] > 0 )
continue;
if( m_frustum[ idx ][ plane_A ] * ( X - Size )
+ m_frustum[ idx ][ plane_B ] * ( Y + Size )
+ m_frustum[ idx ][ plane_C ] * ( Z - Size )
+ m_frustum[ idx ][ plane_D ] > 0 )
continue;
if( m_frustum[ idx ][ plane_A ] * ( X + Size )
+ m_frustum[ idx ][ plane_B ] * ( Y + Size )
+ m_frustum[ idx ][ plane_C ] * ( Z - Size )
+ m_frustum[ idx ][ plane_D ] > 0 )
continue;
if( m_frustum[ idx ][ plane_A ] * ( X - Size )
+ m_frustum[ idx ][ plane_B ] * ( Y - Size )
+ m_frustum[ idx ][ plane_C ] * ( Z + Size )
+ m_frustum[ idx ][ plane_D ] > 0 )
continue;
if( m_frustum[ idx ][ plane_A ] * ( X + Size )
+ m_frustum[ idx ][ plane_B ] * ( Y - Size )
+ m_frustum[ idx ][ plane_C ] * ( Z + Size )
+ m_frustum[ idx ][ plane_D ] > 0 )
continue;
if( m_frustum[ idx ][ plane_A ] * ( X - Size )
+ m_frustum[ idx ][ plane_B ] * ( Y + Size )
+ m_frustum[ idx ][ plane_C ] * ( Z + Size )
+ m_frustum[ idx ][ plane_D ] > 0 )
continue;
if( m_frustum[ idx ][ plane_A ] * ( X + Size )
+ m_frustum[ idx ][ plane_B ] * ( Y + Size )
+ m_frustum[ idx ][ plane_C ] * ( Z + Size )
+ m_frustum[ idx ][ plane_D ] > 0 )
continue;
// the cube is inside unless all of its corners lie behind one of the frustum planes
return std::ranges::all_of( m_frustum, [&]( auto const &frustumplane ) {
if( frustumplane[ plane_A ] * ( X - Size )
+ frustumplane[ plane_B ] * ( Y - Size )
+ frustumplane[ plane_C ] * ( Z - Size )
+ frustumplane[ plane_D ] > 0 )
return true;
if( frustumplane[ plane_A ] * ( X + Size )
+ frustumplane[ plane_B ] * ( Y - Size )
+ frustumplane[ plane_C ] * ( Z - Size )
+ frustumplane[ plane_D ] > 0 )
return true;
if( frustumplane[ plane_A ] * ( X - Size )
+ frustumplane[ plane_B ] * ( Y + Size )
+ frustumplane[ plane_C ] * ( Z - Size )
+ frustumplane[ plane_D ] > 0 )
return true;
if( frustumplane[ plane_A ] * ( X + Size )
+ frustumplane[ plane_B ] * ( Y + Size )
+ frustumplane[ plane_C ] * ( Z - Size )
+ frustumplane[ plane_D ] > 0 )
return true;
if( frustumplane[ plane_A ] * ( X - Size )
+ frustumplane[ plane_B ] * ( Y - Size )
+ frustumplane[ plane_C ] * ( Z + Size )
+ frustumplane[ plane_D ] > 0 )
return true;
if( frustumplane[ plane_A ] * ( X + Size )
+ frustumplane[ plane_B ] * ( Y - Size )
+ frustumplane[ plane_C ] * ( Z + Size )
+ frustumplane[ plane_D ] > 0 )
return true;
if( frustumplane[ plane_A ] * ( X - Size )
+ frustumplane[ plane_B ] * ( Y + Size )
+ frustumplane[ plane_C ] * ( Z + Size )
+ frustumplane[ plane_D ] > 0 )
return true;
if( frustumplane[ plane_A ] * ( X + Size )
+ frustumplane[ plane_B ] * ( Y + Size )
+ frustumplane[ plane_C ] * ( Z + Size )
+ frustumplane[ plane_D ] > 0 )
return true;
return false;
}
return true;
return false; } );
}
void cFrustum::normalize_plane( cFrustum::side const Side ) {

View File

@@ -29,12 +29,7 @@ light_array::insert( TDynamicObject const *Owner ) {
void
light_array::remove( TDynamicObject const *Owner ) {
data.erase(
std::remove_if(
data.begin(),
data.end(),
[=]( light_record const &light ){ return light.owner == Owner; } ),
data.end() );
std::erase_if( data, [=]( light_record const &light ){ return light.owner == Owner; } );
}
// updates records in the collection
@@ -75,13 +70,13 @@ light_array::update() {
light.intensity = std::max(0.0f, std::log((float)light.count + 1.0f));
if (light.owner->DimHeadlights && !light.owner->HighBeamLights && isEnabled) // tylko przyciemnione
light.intensity *= light.owner->MoverParameters->dimMultiplier;
light.intensity *= static_cast<float>(light.owner->MoverParameters->dimMultiplier);
else if (!light.owner->DimHeadlights && !light.owner->HighBeamLights && isEnabled) // normalne
light.intensity *= light.owner->MoverParameters->normMultiplier;
light.intensity *= static_cast<float>(light.owner->MoverParameters->normMultiplier);
else if (light.owner->DimHeadlights && light.owner->HighBeamLights && isEnabled) // przyciemnione dlugie
light.intensity *= light.owner->MoverParameters->highDimMultiplier;
light.intensity *= static_cast<float>(light.owner->MoverParameters->highDimMultiplier);
else if (!light.owner->DimHeadlights && light.owner->HighBeamLights && isEnabled) // dlugie zwykle
light.intensity *= light.owner->MoverParameters->highMultiplier;
light.intensity *= static_cast<float>(light.owner->MoverParameters->highMultiplier);
else if (!isEnabled)
{
light.intensity = 0.0f;

View File

@@ -36,7 +36,7 @@ public:
update();
// types
typedef std::vector<light_record> lightrecord_array;
using lightrecord_array = std::vector<light_record>;
// members
lightrecord_array data;

View File

@@ -3,7 +3,7 @@
std::unique_ptr<gfx_renderer> null_renderer::create_func()
{
return std::unique_ptr<null_renderer>(new null_renderer());
return std::make_unique<null_renderer>();
}
bool null_renderer::renderer_register = gfx_renderer_factory::get_instance()->register_backend("null", null_renderer::create_func);

View File

@@ -17,22 +17,22 @@ public:
// constructors:
null_geometrybank() = default;
// destructor
~null_geometrybank() {};
~null_geometrybank() = default;
private:
// methods:
// create() subclass details
void
create_( gfx::geometry_handle const &Geometry ) override {}
create_( gfx::geometry_handle const &Geometry ) override { /* null implementation, nothing to do */ }
// replace() subclass details
void
replace_( gfx::geometry_handle const &Geometry ) override {}
replace_( gfx::geometry_handle const &Geometry ) override { /* null implementation, nothing to do */ }
// draw() subclass details
auto
draw_( gfx::geometry_handle const &Geometry, gfx::stream_units const &Units, unsigned int const Streams ) -> std::size_t override { return 0; }
// release() subclass details
void
release_() override {}
release_() override { /* null implementation, nothing to do */ }
};
// bare-bones render controller, in lack of anything better yet
@@ -43,7 +43,7 @@ public:
// constructors
null_renderer() = default;
// destructor
~null_renderer() { }
~null_renderer() = default;
// methods
bool
Init( GLFWwindow *Window ) override { return true; }
@@ -51,14 +51,14 @@ public:
bool
Render() override { return true; }
void
SwapBuffers() override {}
SwapBuffers() override { /* null implementation, nothing to do */ }
inline
float
Framerate() override { return 10.0f; }
bool AddViewport(const global_settings::extraviewport_config &conf) override { return false; }
bool Debug_Ui_State(std::optional<bool>) override { return false; }
void Shutdown() override {}
void Shutdown() override { /* null implementation, nothing to do */ }
// geometry methods
// NOTE: hands-on geometry management is exposed as a temporary measure; ultimately all visualization data should be generated/handled automatically by the renderer itself
@@ -100,10 +100,10 @@ public:
Fetch_Material( std::string const &Filename, bool const Loadnow = true ) override {
m_materials.push_back(std::make_shared<opengl_material>());
m_materials.back()->name = Filename;
return m_materials.size();
return static_cast<material_handle>(m_materials.size());
}
void
Bind_Material( material_handle const Material, TSubModel const *sm = nullptr, lighting_data const *lighting = nullptr ) override {}
Bind_Material( material_handle const Material, TSubModel const *sm = nullptr, lighting_data const *lighting = nullptr ) override { /* null implementation, nothing to do */ }
IMaterial const *
Material( material_handle const Material ) const override { return m_materials.at(Material - 1).get(); }
// shader methods
@@ -112,18 +112,18 @@ public:
texture_handle
Fetch_Texture( std::string const &Filename, bool const Loadnow = true, GLint format_hint = GL_SRGB_ALPHA ) override { throw std::runtime_error("not impl"); }
void
Bind_Texture( texture_handle const Texture ) override {}
Bind_Texture( texture_handle const Texture ) override { /* null implementation, nothing to do */ }
void
Bind_Texture( std::size_t const Unit, texture_handle const Texture ) override {}
Bind_Texture( std::size_t const Unit, texture_handle const Texture ) override { /* null implementation, nothing to do */ }
opengl_texture &
Texture( texture_handle const Texture ) override { throw std::runtime_error("not impl"); }
opengl_texture const &
Texture( texture_handle const Texture ) const override { throw std::runtime_error("not impl"); }
// utility methods
void
Pick_Control_Callback( std::function<void( TSubModel const *, const glm::vec2 )> Callback ) override {}
Pick_Control_Callback( std::function<void( TSubModel const *, const glm::vec2 )> Callback ) override { /* null implementation, nothing to do */ }
void
Pick_Node_Callback( std::function<void( scene::basic_node * )> Callback ) override {}
Pick_Node_Callback( std::function<void( scene::basic_node * )> Callback ) override { /* null implementation, nothing to do */ }
TSubModel const *
Pick_Control() const override { return nullptr; }
scene::basic_node const *
@@ -132,11 +132,11 @@ public:
Mouse_Position() const override { return glm::dvec3(); }
// maintenance methods
void
Update( double const Deltatime ) override {}
Update( double const Deltatime ) override { /* null implementation, nothing to do */ }
void
Update_Pick_Control() override {}
Update_Pick_Control() override { /* null implementation, nothing to do */ }
void
Update_Pick_Node() override {}
Update_Pick_Node() override { /* null implementation, nothing to do */ }
glm::dvec3
Update_Mouse_Position() override { return glm::dvec3(); }
// debug methods
@@ -144,13 +144,13 @@ public:
info_times() const override { return empty_str; }
std::string const &
info_stats() const override { return empty_str; }
void MakeScreenshot() override {}
void MakeScreenshot() override { /* null implementation, nothing to do */ }
static std::unique_ptr<gfx_renderer> create_func();
static bool renderer_register;
virtual imgui_renderer *GetImguiRenderer()
imgui_renderer *GetImguiRenderer() override
{
return nullptr;
}

View File

@@ -16,7 +16,7 @@ void opengl33_light::apply_intensity(float const Factor) {
factor = Factor;
}
void opengl33_light::apply_angle() {}
void opengl33_light::apply_angle() const { /* nothing to do */ }
//---------------------------------------------------------------------------

View File

@@ -18,7 +18,7 @@ struct opengl33_light : public basic_light {
float factor;
void apply_intensity(float const Factor = 1.0f);
void apply_angle();
void apply_angle() const;
opengl33_light &operator=(basic_light const &Right) {
basic_light::operator=(Right);

View File

@@ -49,19 +49,19 @@ opengl33_particles::update( opengl_camera const &Camera ) {
// build billboard data for particles from visible sources
auto const camerarotation { glm::mat3( Camera.modelview() ) };
particle_vertex vertex;
for( auto const &source : sources ) {
for( auto const &[sourcekey, sourcedata] : sources ) {
auto const particlecolor {
glm::clamp(
source.second.color()
sourcedata.color()
* ( glm::vec3 { Global.DayLight.ambient }
+ 0.35f * glm::vec3{ Global.DayLight.diffuse } ) * simulation::Environment.light_intensity(),
glm::vec3{ 0.f }, glm::vec3{ 1.f } ) };
auto const &particles { source.second.sequence() };
auto const &particles { sourcedata.sequence() };
// TODO: put sanity cap on the overall amount of particles that can be drawn
auto const sizestep { 256.0 * billboard_vertices.size() };
m_particlevertices.reserve(
sizestep * std::ceil( m_particlevertices.size() + ( particles.size() * billboard_vertices.size() ) / sizestep ) );
static_cast<std::size_t>( sizestep * std::ceil( static_cast<double>(m_particlevertices.size()) + ( static_cast<double>(particles.size() * billboard_vertices.size()) ) / sizestep ) ) );
for( auto const &particle : particles ) {
// TODO: particle color support
vertex.color[ 0 ] = particlecolor.r;
@@ -72,9 +72,9 @@ opengl33_particles::update( opengl_camera const &Camera ) {
auto const offset { glm::vec3{ particle.position - Camera.position() } };
auto const rotation { glm::angleAxis( particle.rotation, glm::vec3{ 0.f, 0.f, 1.f } ) };
for( auto const &billboardvertex : billboard_vertices ) {
vertex.position = offset + ( rotation * billboardvertex.first * particle.size ) * camerarotation;
vertex.texture = billboardvertex.second;
for( auto const &[billboardoffset, billboardtexture] : billboard_vertices ) {
vertex.position = offset + ( rotation * billboardoffset * particle.size ) * camerarotation;
vertex.texture = billboardtexture;
m_particlevertices.emplace_back( vertex );
}
@@ -113,14 +113,14 @@ opengl33_particles::render() {
m_vao->setup_attrib(*m_buffer, 1, 4, GL_FLOAT, sizeof(particle_vertex), 12);
m_vao->setup_attrib(*m_buffer, 2, 2, GL_FLOAT, sizeof(particle_vertex), 28);
m_buffer->unbind(gl::buffer::ARRAY_BUFFER);
m_vao->unbind();
gl::buffer::unbind(gl::buffer::ARRAY_BUFFER);
gl::vao::unbind();
}
if (!m_shader) {
gl::shader vert("smoke.vert");
gl::shader frag("smoke.frag");
gl::program *prog = new gl::program({vert, frag});
auto prog = new gl::program({vert, frag});
m_shader = std::unique_ptr<gl::program>(prog);
}
@@ -128,11 +128,11 @@ opengl33_particles::render() {
m_shader->bind();
m_vao->bind();
glDrawArrays(GL_TRIANGLES, 0, m_particlevertices.size());
glDrawArrays(GL_TRIANGLES, 0, static_cast<GLsizei>(m_particlevertices.size()));
m_shader->unbind();
m_vao->unbind();
m_buffer->unbind(gl::buffer::ARRAY_BUFFER);
gl::program::unbind();
gl::vao::unbind();
gl::buffer::unbind(gl::buffer::ARRAY_BUFFER);
return m_particlevertices.size() / 6;
}

View File

@@ -36,7 +36,7 @@ opengl33_precipitation::create( int const Tesselation ) {
std::uint16_t index = 0;
// auto const radius { 25.f }; // cylinder radius
std::vector<float> radii { 25.f, 10.f, 5.f, 1.f };
std::vector radii { 25.f, 10.f, 5.f, 1.f };
for( auto radius : radii ) {
for( int i = 0; i <= latitudes; ++i ) {
@@ -121,7 +121,7 @@ opengl33_precipitation::update() {
m_indexbuffer->upload(gl::buffer::ELEMENT_ARRAY_BUFFER, m_indices.data(), 0, m_indices.size() * sizeof( unsigned short ));
m_vao->setup_ebo(*m_indexbuffer);
m_vao->unbind();
gl::vao::unbind();
// NOTE: vertex and index source data is superfluous past this point, but, eh
}
@@ -155,5 +155,5 @@ opengl33_precipitation::render() {
::glDrawElements( GL_TRIANGLES, static_cast<GLsizei>( m_indices.size() ), GL_UNSIGNED_SHORT, reinterpret_cast<void const*>( 0 ) );
m_vao->unbind();
gl::vao::unbind();
}

View File

@@ -44,15 +44,13 @@ void opengl33_skydome::update() {
m_indexbuffer->upload(gl::buffer::ELEMENT_ARRAY_BUFFER, skydome.indices().data(), 0, skydome.indices().size() * sizeof( unsigned short ));
m_vao->setup_ebo(*m_indexbuffer);
m_vao->unbind();
gl::vao::unbind();
}
// ship the current dynamic data to the gpu
if( true == skydome.is_dirty() ) {
if( m_coloursbuffer ) {
// the colour buffer was already initialized, so on this run we update its content
m_coloursbuffer->upload( gl::buffer::ARRAY_BUFFER, skydome.colors().data(), 0, skydome.colors().size() * sizeof( glm::vec3 ) );
skydome.is_dirty() = false;
}
if (true == skydome.is_dirty() && m_coloursbuffer) {
// the colour buffer was already initialized, so on this run we update its content
m_coloursbuffer->upload( gl::buffer::ARRAY_BUFFER, skydome.colors().data(), 0, skydome.colors().size() * sizeof( glm::vec3 ) );
skydome.is_dirty() = false;
}
}

View File

@@ -19,7 +19,7 @@ public:
// constructors
opengl33_skydome() = default;
// destructor
~opengl33_skydome() {;}
~opengl33_skydome() = default;
// methods
// updates data stores on the opengl end. NOTE: unbinds buffers
void update();

View File

@@ -38,7 +38,7 @@ opengl_camera::visible( TDynamicObject const *Dynamic ) const {
// sphere test is faster than AABB, so we'll use it here
// we're giving vehicles some extra padding, to allow for things like shared bogeys extending past the main body
return ( m_frustum.sphere_inside( Dynamic->GetPosition(), Dynamic->radius() * 1.25 ) > 0.0f );
return ( m_frustum.sphere_inside( Dynamic->GetPosition(), static_cast<float>(Dynamic->radius() * 1.25) ) > 0.0f );
}
// debug helper, draws shape of frustum in world space

View File

@@ -24,7 +24,7 @@ public:
update_frustum() { update_frustum( m_projection, m_modelview ); }
inline
void
update_frustum(glm::mat4 frustumtest_proj) {
update_frustum(glm::mat4 const &frustumtest_proj) {
update_frustum(frustumtest_proj, m_modelview); }
void
update_frustum( glm::mat4 const &Projection, glm::mat4 const &Modelview );

View File

@@ -90,23 +90,23 @@ opengl_vbogeometrybank::draw_( gfx::geometry_handle const &Geometry, gfx::stream
}
::glDrawRangeElementsBaseVertex(
chunk.type,
0, chunkrecord.vertex_count,
chunkrecord.index_count, GL_UNSIGNED_INT, reinterpret_cast<void const *>( chunkrecord.index_offset * sizeof( gfx::basic_index ) ),
chunkrecord.vertex_offset );
0, static_cast<GLuint>(chunkrecord.vertex_count),
static_cast<GLsizei>(chunkrecord.index_count), GL_UNSIGNED_INT, reinterpret_cast<void const *>( chunkrecord.index_offset * sizeof( gfx::basic_index ) ),
static_cast<GLint>(chunkrecord.vertex_offset) );
}
else {
bind_streams( Units, Streams, chunkrecord.vertex_offset );
::glDrawRangeElements(
chunk.type,
0, chunkrecord.vertex_count,
chunkrecord.index_count, GL_UNSIGNED_INT, reinterpret_cast<void const *>( chunkrecord.index_offset * sizeof( gfx::basic_index ) ) );
0, static_cast<GLuint>(chunkrecord.vertex_count),
static_cast<GLsizei>(chunkrecord.index_count), GL_UNSIGNED_INT, reinterpret_cast<void const *>( chunkrecord.index_offset * sizeof( gfx::basic_index ) ) );
}
}
else {
if( m_activestreams != Streams ) {
bind_streams( Units, Streams );
}
::glDrawArrays( chunk.type, chunkrecord.vertex_offset, chunkrecord.vertex_count );
::glDrawArrays( chunk.type, static_cast<GLint>(chunkrecord.vertex_offset), static_cast<GLsizei>(chunkrecord.vertex_count) );
}
// ...post-render cleanup
/*
@@ -139,9 +139,8 @@ opengl_vbogeometrybank::setup_buffer() {
// may be better to initiate upload earlier (during update phase) and trust this effort won't go to waste
if( true == m_chunks.empty() ) { return; }
std::size_t
vertexcount{ 0 },
indexcount{ 0 };
std::size_t vertexcount{ 0 };
std::size_t indexcount{ 0 };
auto chunkiterator = m_chunks.cbegin();
for( auto &chunkrecord : m_chunkrecords ) {
// fill records for all chunks, based on the chunk data
@@ -195,7 +194,7 @@ opengl_vbogeometrybank::setup_buffer() {
}
void
opengl_vbogeometrybank::bind_buffer() {
opengl_vbogeometrybank::bind_buffer() const {
::glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_indexbuffer );
::glBindBuffer( GL_ARRAY_BUFFER, m_vertexbuffer );

View File

@@ -58,7 +58,7 @@ private:
void
setup_buffer();
void
bind_buffer();
bind_buffer() const;
void
delete_buffer();
static
@@ -87,7 +87,7 @@ public:
opengl_dlgeometrybank() = default;
// destructor:
~opengl_dlgeometrybank() {
for( auto &chunkrecord : m_chunkrecords ) {
for( auto const &chunkrecord : m_chunkrecords ) {
::glDeleteLists( chunkrecord.list, 1 ); } }
private:

View File

@@ -90,7 +90,7 @@ private:
};
enum stack_mode { gl_modelview = 0, gl_projection = 1, gl_texture = 2 };
typedef std::vector<opengl_stack> openglstack_array;
using openglstack_array = std::vector<opengl_stack>;
public:
// constructors:

View File

@@ -47,19 +47,19 @@ opengl_particles::update( opengl_camera const &Camera ) {
// build billboard data for particles from visible sources
auto const camerarotation { glm::mat3( Camera.modelview() ) };
particle_vertex vertex;
for( auto const &source : sources ) {
for( auto const &[sourcekey, sourcedata] : sources ) {
auto const particlecolor {
glm::clamp(
source.second.color()
sourcedata.color()
* ( glm::vec3 { Global.DayLight.ambient } + 0.35f * glm::vec3{ Global.DayLight.diffuse } )
* 255.f,
glm::vec3{ 0.f }, glm::vec3{ 255.f } ) };
auto const &particles { source.second.sequence() };
auto const &particles { sourcedata.sequence() };
// TODO: put sanity cap on the overall amount of particles that can be drawn
auto const sizestep { 256.0 * billboard_vertices.size() };
m_particlevertices.reserve(
sizestep * std::ceil( m_particlevertices.size() + ( particles.size() * billboard_vertices.size() ) / sizestep ) );
static_cast<std::size_t>( sizestep * std::ceil( static_cast<double>(m_particlevertices.size()) + ( static_cast<double>(particles.size() * billboard_vertices.size()) ) / sizestep ) ) );
for( auto const &particle : particles ) {
// TODO: particle color support
vertex.color[ 0 ] = static_cast<std::uint_fast8_t>( particlecolor.r );
@@ -70,9 +70,9 @@ opengl_particles::update( opengl_camera const &Camera ) {
auto const offset { glm::vec3{ particle.position - Camera.position() } };
auto const rotation { glm::angleAxis( particle.rotation, glm::vec3{ 0.f, 0.f, 1.f } ) };
for( auto const &billboardvertex : billboard_vertices ) {
vertex.position = offset + ( rotation * billboardvertex.first * particle.size ) * camerarotation;
vertex.texture = billboardvertex.second;
for( auto const &[billboardoffset, billboardtexture] : billboard_vertices ) {
vertex.position = offset + ( rotation * billboardoffset * particle.size ) * camerarotation;
vertex.texture = billboardtexture;
m_particlevertices.emplace_back( vertex );
}
@@ -147,7 +147,7 @@ opengl_particles::render( GLint const Textureunit ) {
::glTexCoordPointer( 2, GL_FLOAT, sizeof( particle_vertex ), reinterpret_cast<void const *>( sizeof( float ) * 3 + sizeof( std::uint8_t ) * 4 ) );
::glEnableClientState( GL_TEXTURE_COORD_ARRAY );
// ...draw...
::glDrawArrays( GL_QUADS, 0, m_particlevertices.size() );
::glDrawArrays( GL_QUADS, 0, static_cast<GLsizei>(m_particlevertices.size()) );
// ...and cleanup
::glPopClientAttrib();
::glBindBuffer( GL_ARRAY_BUFFER, 0 );

View File

@@ -39,7 +39,7 @@ opengl_precipitation::create( int const Tesselation ) {
std::uint16_t index = 0;
// auto const radius { 25.f }; // cylinder radius
std::vector<float> radii { 25.f, 10.f, 5.f, 1.f };
std::vector radii { 25.f, 10.f, 5.f, 1.f };
for( auto radius : radii ) {
for( int i = 0; i <= latitudes; ++i ) {

View File

@@ -54,20 +54,18 @@ void opengl_skydome::update() {
}
// ship the current dynamic data to the gpu
// TODO: ship the data if it changed since the last update
if( true == skydome.is_dirty() ) {
if( ( m_coloursbuffer > 0 ) && ( m_coloursbuffer != (GLuint)-1 ) ) {
::glBindBuffer( GL_ARRAY_BUFFER, m_coloursbuffer );
auto &colors{ skydome.colors() };
/*
float twilightfactor = std::clamp( -simulation::Environment.sun().getAngle(), 0.0f, 18.0f ) / 18.0f;
auto gamma = std::lerp( glm::vec3( 0.45f ), glm::vec3( 1.0f ), twilightfactor );
for( auto & color : colors ) {
color = glm::pow( color, gamma );
}
*/
::glBufferSubData( GL_ARRAY_BUFFER, 0, colors.size() * sizeof( glm::vec3 ), colors.data() );
skydome.is_dirty() = false;
if (true == skydome.is_dirty() && ( m_coloursbuffer > 0 ) && ( m_coloursbuffer != (GLuint)-1 )) {
::glBindBuffer( GL_ARRAY_BUFFER, m_coloursbuffer );
auto &colors{ skydome.colors() };
/*
float twilightfactor = std::clamp( -simulation::Environment.sun().getAngle(), 0.0f, 18.0f ) / 18.0f;
auto gamma = std::lerp( glm::vec3( 0.45f ), glm::vec3( 1.0f ), twilightfactor );
for( auto & color : colors ) {
color = glm::pow( color, gamma );
}
*/
::glBufferSubData( GL_ARRAY_BUFFER, 0, colors.size() * sizeof( glm::vec3 ), colors.data() );
skydome.is_dirty() = false;
}
// cleanup
::glPopClientAttrib();

View File

@@ -56,7 +56,7 @@ smoke_source::particle_emitter::deserialize( cParser &Input ) {
}
void
smoke_source::particle_emitter::initialize( smoke_particle &Particle ) {
smoke_source::particle_emitter::initialize( smoke_particle &Particle ) const {
auto const polarangle { glm::radians( LocalRandom( inclination[ value_limit::min ], inclination[ value_limit::max ] ) ) }; // theta
auto const azimuthalangle { glm::radians( LocalRandom( -180, 180 ) ) }; // phi
@@ -69,9 +69,9 @@ smoke_source::particle_emitter::initialize( smoke_particle &Particle ) {
Particle.velocity = launchvector * launchvelocity;
Particle.rotation = glm::radians( LocalRandom( 0, 360 ) );
Particle.size = LocalRandom( size[ value_limit::min ], size[ value_limit::max ] );
Particle.opacity = LocalRandom( opacity[ value_limit::min ], opacity[ value_limit::max ] ) / Global.SmokeFidelity;
Particle.rotation = static_cast<float>(glm::radians( LocalRandom( 0, 360 ) ));
Particle.size = static_cast<float>(LocalRandom( size[ value_limit::min ], size[ value_limit::max ] ));
Particle.opacity = static_cast<float>(LocalRandom( opacity[ value_limit::min ], opacity[ value_limit::max ] ) / Global.SmokeFidelity);
Particle.age = 0;
}
@@ -81,7 +81,7 @@ smoke_source::deserialize( cParser &Input ) {
if( false == Input.ok() ) { return false; }
while( true == deserialize_mapping( Input ) ) {
; // all work done by while()
// all work done by while()
}
return true;
@@ -166,8 +166,8 @@ smoke_source::update( double const Timedelta, bool const Onlydespawn ) {
( ( false == Global.Smoke ) || ( true == Onlydespawn ) ) ?
0.f :
std::min<float>(
m_spawncount + ( m_spawnrate * Timedelta * Global.SmokeFidelity ),
m_max_particles ) );
static_cast<float>(m_spawncount + ( m_spawnrate * Timedelta * Global.SmokeFidelity )),
static_cast<float>(m_max_particles) ) );
// consider special spawn rate cases
if( m_ownertype == owner_type::vehicle ) {
@@ -183,7 +183,7 @@ smoke_source::update( double const Timedelta, bool const Onlydespawn ) {
0.f :
std::min<float>(
// m_spawncount + ( m_spawnrate * Timedelta * Global.SmokeFidelity ),
m_spawncount +(m_spawnrate * Timedelta * Global.SmokeFidelity * (((m_owner.vehicle->MoverParameters->enrot) / 4 ) * 0.01)), m_max_particles);
static_cast<float>(m_spawncount +(m_spawnrate * Timedelta * Global.SmokeFidelity * (((m_owner.vehicle->MoverParameters->enrot) / 4 ) * 0.01))), static_cast<float>(m_max_particles));
}
else
{
@@ -195,7 +195,7 @@ smoke_source::update( double const Timedelta, bool const Onlydespawn ) {
0.f :
std::min<float>(
// m_spawncount + ( m_spawnrate * Timedelta * Global.SmokeFidelity ),
m_spawncount + (m_spawnrate * Timedelta * Global.SmokeFidelity * ((((m_owner.vehicle->MoverParameters->DElist[m_owner.vehicle->MoverParameters->MainCtrlPosNo].RPM -m_owner.vehicle->MoverParameters->enrot) /60) *0.02) *(m_owner.vehicle->MoverParameters->EnginePower * 0.005))), m_max_particles);
static_cast<float>(m_spawncount + (m_spawnrate * Timedelta * Global.SmokeFidelity * ((((m_owner.vehicle->MoverParameters->DElist[m_owner.vehicle->MoverParameters->MainCtrlPosNo].RPM -m_owner.vehicle->MoverParameters->enrot) /60) *0.02) *(m_owner.vehicle->MoverParameters->EnginePower * 0.005)))), static_cast<float>(m_max_particles));
}
else
{
@@ -205,7 +205,7 @@ smoke_source::update( double const Timedelta, bool const Onlydespawn ) {
0.f :
std::min<float>(
// m_spawncount + ( m_spawnrate * Timedelta * Global.SmokeFidelity ),
m_spawncount + (m_spawnrate * Timedelta * Global.SmokeFidelity * ((((m_owner.vehicle->MoverParameters->DElist[m_owner.vehicle->MoverParameters->MainCtrlPosNo].RPM -m_owner.vehicle->MoverParameters->enrot) /60) * (sqrt(m_owner.vehicle->MoverParameters->Im) * 0.01) * 0.02) *(m_owner.vehicle->MoverParameters->EnginePower * 0.005))), m_max_particles);
static_cast<float>(m_spawncount + (m_spawnrate * Timedelta * Global.SmokeFidelity * ((((m_owner.vehicle->MoverParameters->DElist[m_owner.vehicle->MoverParameters->MainCtrlPosNo].RPM -m_owner.vehicle->MoverParameters->enrot) /60) * (sqrt(m_owner.vehicle->MoverParameters->Im) * 0.01) * 0.02) *(m_owner.vehicle->MoverParameters->EnginePower * 0.005)))), static_cast<float>(m_max_particles));
}
}
}
@@ -254,10 +254,8 @@ smoke_source::update( double const Timedelta, bool const Onlydespawn ) {
// if we still have pending requests after filling entire container replace older particles
if( m_spawncount >= 1.f ) {
// sort all particles from most to least transparent, oldest to youngest if it's a tie
std::sort(
std::begin( m_particles ),
std::end( m_particles ),
[]( smoke_particle const &Left, smoke_particle const &Right ) {
std::ranges::sort(
m_particles, []( smoke_particle const &Left, smoke_particle const &Right ) {
return ( Left.opacity != Right.opacity ?
Left.opacity < Right.opacity :
Left.age > Right.age ); } );
@@ -283,7 +281,7 @@ smoke_source::update( double const Timedelta, bool const Onlydespawn ) {
// determine bounding area from calculated bounding box
if( false == m_particles.empty() ) {
m_area.center = glm::mix(boundingbox[value_limit::min], boundingbox[value_limit::max], 0.5);
m_area.radius = 0.5 * ( glm::length( boundingbox[ value_limit::max ] - boundingbox[ value_limit::min ] ) );
m_area.radius = static_cast<float>(0.5 * ( glm::length( boundingbox[ value_limit::max ] - boundingbox[ value_limit::min ] ) ));
}
else {
m_area.center = location();
@@ -331,10 +329,9 @@ smoke_source::initialize( smoke_particle &Particle ) {
Particle.position = location();
if( m_ownertype == owner_type::vehicle ) {
Particle.opacity *= m_owner.vehicle->MoverParameters->dizel_fill;
auto const enginerevolutionsfactor { 1.5f }; // high engine revolutions increase initial particle velocity
switch( m_owner.vehicle->MoverParameters->EngineType ) {
case TEngineType::DieselElectric: {
Particle.opacity *= static_cast<float>(m_owner.vehicle->MoverParameters->dizel_fill);
if (m_owner.vehicle->MoverParameters->EngineType == TEngineType::DieselElectric)
{
if (m_owner.vehicle->MoverParameters->dizel_spinup == true)
{
Particle.velocity *= 0.38*(((m_owner.vehicle->MoverParameters->enrot)/2)*0.5); // / m_owner.vehicle->MoverParameters->dizel_fill *0.01)) ;
@@ -347,11 +344,6 @@ smoke_source::initialize( smoke_particle &Particle ) {
//Particle.velocity *= m_owner.vehicle->GetVelocity(); // / m_owner.vehicle->MoverParameters->dizel_fill *0.01)) ;
}
break;
}
default: {
break;
}
}
}
}
@@ -368,28 +360,23 @@ smoke_source::update( smoke_particle &Particle, bounding_box &Boundingbox, doubl
// crude smoke dispersion simulation
// http://www.auburn.edu/academic/forestry_wildlife/fire/smoke_guide/smoke_dispersion.htm
switch (m_ownertype)
if (m_ownertype == owner_type::vehicle)
{
case owner_type::vehicle:
Particle.velocity.y += static_cast<float>(( 0.025 * Particle.velocity.y ) * std::min( 0.f, Global.AirTemperature - 90 ) * Timedelta); // decelerate faster in cold weather
Particle.velocity.y -= static_cast<float>(( (0.05 * (pow(m_owner.vehicle->GetVelocity()*1,0.4))) * Particle.velocity.y ) * Global.Overcast * Timedelta); // decelerate faster with high air humidity and/or precipitation
}
else
{
Particle.velocity.y += ( 0.025 * Particle.velocity.y ) * std::min( 0.f, Global.AirTemperature - 90 ) * Timedelta; // decelerate faster in cold weather
Particle.velocity.y -= ( (0.05 * (pow(m_owner.vehicle->GetVelocity()*1,0.4))) * Particle.velocity.y ) * Global.Overcast * Timedelta; // decelerate faster with high air humidity and/or precipitation
break;
}
default:
{
Particle.velocity.y += ( 0.005 * Particle.velocity.y ) * std::min( 0.f, Global.AirTemperature - 10 ) * Timedelta; // decelerate faster in cold weather
Particle.velocity.y -= ( 0.050 * Particle.velocity.y ) * Global.Overcast * Timedelta; // decelerate faster with high air humidity and/or precipitation
Particle.velocity.y = std::max<float>( 0.25 * ( 2.f - Global.Overcast ), Particle.velocity.y ); // put a cap on deceleration
break;
}
}
Particle.velocity.y += static_cast<float>(( 0.005 * Particle.velocity.y ) * std::min( 0.f, Global.AirTemperature - 10 ) * Timedelta); // decelerate faster in cold weather
Particle.velocity.y -= static_cast<float>(( 0.050 * Particle.velocity.y ) * Global.Overcast * Timedelta); // decelerate faster with high air humidity and/or precipitation
Particle.velocity.y = std::max<float>( static_cast<float>(0.25 * ( 2.f - Global.Overcast )), Particle.velocity.y ); // put a cap on deceleration
}
Particle.position += Particle.velocity * static_cast<float>( Timedelta );
Particle.position += 0.1f * Particle.age * simulation::Environment.wind() * static_cast<float>( Timedelta );
// m_velocitymodifier.update( Particle.velocity, Timedelta );
Particle.age += Timedelta;
Particle.age += static_cast<float>(Timedelta);
// update bounding box
Boundingbox[ value_limit::min ] = glm::min( Boundingbox[ value_limit::min ], Particle.position - glm::dvec3{ Particle.size } );
@@ -467,21 +454,19 @@ particle_manager::find( std::string const &Template ) {
auto const templatename { ToLower( Template ) };
// try to locate specified rail profile...
auto const lookup { m_sourcetemplates.find( templatename ) };
if( lookup != m_sourcetemplates.end() ) {
if( auto const lookup { m_sourcetemplates.find( templatename ) }; lookup != m_sourcetemplates.end() ) {
// ...if it works, we're done...
return &(lookup->second);
}
// ... and if it fails try to add the template to the database from a data file
smoke_source source;
cParser parser(templatepath + templatename + ".txt", cParser::buffer_FILE);
if (source.deserialize(parser))
if (cParser parser(templatepath + templatename + ".txt", cParser::buffer_FILE); source.deserialize(parser))
{
// if deserialization didn't fail finish source setup...
source.m_opacitymodifier.bind( &Global.SmokeFidelity );
// ...then cache the source as template for future instances
m_sourcetemplates.emplace( templatename, source );
m_sourcetemplates.try_emplace( templatename, source );
// should be 'safe enough' to return lookup result directly afterwards
return &( m_sourcetemplates.find( templatename )->second );
}

View File

@@ -56,7 +56,7 @@ public:
return (
m_valuechangemodifier == nullptr ?
m_valuechange :
m_valuechange / *( m_valuechangemodifier ) ); }
m_valuechange / *m_valuechangemodifier ); }
private:
//types
@@ -122,7 +122,7 @@ private:
glm::vec3 color { 16.f / 255.f };
void deserialize( cParser &Input );
void initialize( smoke_particle &Particle );
void initialize( smoke_particle &Particle ) const;
};
using bounding_box = glm::dvec3[ 2 ]; // bounding box of owned particles
@@ -212,7 +212,7 @@ fixedstep_modifier<Type_>::update( Type_ &Variable, double const Timedelta ) con
auto const valuechange { (
m_valuechangemodifier == nullptr ?
m_valuechange :
m_valuechange / *( m_valuechangemodifier ) ) };
m_valuechange / *m_valuechangemodifier ) };
Variable += ( valuechange * static_cast<float>( Timedelta ) );
// clamp down to allowed value range
Variable = glm::max( Variable, m_valuelimits[ value_limit::min ] );

View File

@@ -29,9 +29,9 @@ void screenshot_manager::screenshot_save_thread( char *img, int w, int h )
stride = -w * 3;
}
char datetime[64];
std::array<char, 64> datetime{};
std::tm const tm_info = local_tm(std::time(nullptr));
strftime(datetime, 64, "%Y-%m-%d_%H-%M-%S", &tm_info);
strftime(datetime.data(), datetime.size(), "%Y-%m-%d_%H-%M-%S", &tm_info);
uint64_t perf;
#ifdef _WIN32
@@ -42,7 +42,7 @@ void screenshot_manager::screenshot_save_thread( char *img, int w, int h )
perf = ts.tv_nsec;
#endif
std::string filename = Global.screenshot_dir + "/" + std::string(datetime) +
std::string filename = Global.screenshot_dir + "/" + std::string(datetime.data()) +
"_" + std::to_string(perf) + ".png";
if (png_image_write_to_file(&png, filename.c_str(), 0, img, stride, nullptr) == 1)
@@ -55,7 +55,7 @@ void screenshot_manager::screenshot_save_thread( char *img, int w, int h )
void screenshot_manager::make_screenshot()
{
char *img = new char[Global.fb_size.x * Global.fb_size.y * 4];
auto img = new char[Global.fb_size.x * Global.fb_size.y * 4];
glReadPixels(0, 0, Global.fb_size.x, Global.fb_size.y, Global.gfx_usegles ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE, (GLvoid*)img);
//m7t: use pbo