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:
@@ -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];
|
||||
|
||||
@@ -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 ) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 */ }
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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 ) {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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 ] );
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user