1010#include < chrono_vsg/utils/ChShapeBuilderVSG.h>
1111
1212#include < algorithm>
13+ #include < array>
1314#include < cmath>
1415#include < iostream>
1516#include < limits>
@@ -116,9 +117,7 @@ static chrono::ChColor PointTypeColor(int point_type) {
116117 return {0 .05f , 0 .05f , 0 .05f }; // intermediate node -- near black
117118}
118119
119- // / Attempt to match the Google Turbo colour map (Mikhailov, 2019).
120- // / Input @p t is clamped to [0, 1]. Returns an opaque RGBA colour.
121- static vsg::vec4 TurboColormap (float t) {
120+ vsg::vec4 MooringLinesViz::TurboColormap (float t) {
122121 t = std::clamp (t, 0 .0f , 1 .0f );
123122
124123 // Polynomial coefficients fitted to the 256-entry Turbo LUT.
@@ -174,44 +173,44 @@ void MooringLinesViz::Update(const std::vector<MooringLineVizData>& lines,
174173 if (!initialized_) return ;
175174 const size_t count = std::min (lines.size (), line_meshes_.size ());
176175
177- // Adaptive range: min fixed at 0 (all fields are non-negative magnitudes ),
176+ // Adaptive range: min fixed at 0 (tension magnitude is non-negative),
178177 // max uses high-water-mark behaviour -- snaps to new peaks instantly but
179178 // decays very slowly so the colour scale stays stable.
180179 if (color_enabled && !range_locked) {
181180 float frame_max = 0 .0f ;
182181 for (size_t li = 0 ; li < count; ++li) {
183- for (double s : lines[li].node_tensions ) {
184- frame_max = std::max (frame_max, static_cast <float >(s ));
182+ for (double t : lines[li].node_tensions ) {
183+ frame_max = std::max (frame_max, static_cast <float >(t ));
185184 }
186185 }
187186
188187 const float padded_max = frame_max * (1 .0f + kRangePadding );
189188
190- if (!adaptive_initialized_ ) {
191- adaptive_max_ = std::max (padded_max, 1 .0f );
192- adaptive_initialized_ = true ;
189+ if (!range_initialized_ ) {
190+ tension_max_ = std::max (padded_max, 1 .0f );
191+ range_initialized_ = true ;
193192 hold_frames_remaining_ = kRangeHoldFrames ;
194- } else if (padded_max > adaptive_max_ ) {
195- adaptive_max_ = padded_max;
193+ } else if (padded_max > tension_max_ ) {
194+ tension_max_ = padded_max;
196195 hold_frames_remaining_ = kRangeHoldFrames ;
197196 } else if (hold_frames_remaining_ > 0 ) {
198197 --hold_frames_remaining_;
199198 } else {
200- adaptive_max_ += kRangeDecayAlpha * (padded_max - adaptive_max_ );
199+ tension_max_ += kRangeDecayAlpha * (padded_max - tension_max_ );
201200 }
202201
203- adaptive_min_ = 0 .0f ;
202+ tension_min_ = 0 .0f ;
204203
205- if (adaptive_max_ < 1e-6f ) {
206- adaptive_max_ = 1 .0f ;
204+ if (tension_max_ < 1e-6f ) {
205+ tension_max_ = 1 .0f ;
207206 }
208207 }
209208
210209 for (size_t li = 0 ; li < count; ++li) {
211210 if (lines[li].node_positions .size () < 2 ) continue ;
212211 if (!line_meshes_[li].vertices ) continue ;
213212 UpdateTubeMesh (lines[li], line_meshes_[li],
214- color_enabled, adaptive_min_, adaptive_max_ );
213+ color_enabled, tension_min_, tension_max_ );
215214 }
216215}
217216
@@ -391,20 +390,26 @@ void MooringLinesViz::UpdateTubeMesh(const MooringLineVizData& line_data,
391390 const size_t ring_verts = num_nodes * static_cast <size_t >(kSides );
392391 if (lm.vertices ->size () < ring_verts + 2 ) return ;
393392
394- const bool has_scalars =
393+ const bool has_tensions =
395394 color_enabled && lm.colors &&
396395 line_data.node_tensions .size () == num_nodes;
397396 const float inv_range =
398397 (range_max - range_min > 1e-12f ) ? 1 .0f / (range_max - range_min)
399398 : 1 .0f ;
400399
401- std::vector<double > cos_table (kSides );
402- std::vector<double > sin_table (kSides );
403- for (int s = 0 ; s < kSides ; ++s) {
404- const double angle = 2.0 * M_PI * s / kSides ;
405- cos_table[s] = std::cos (angle);
406- sin_table[s] = std::sin (angle);
407- }
400+ // kSides is a compile-time constant, so the trig table never changes.
401+ static const auto cos_table = [] {
402+ std::array<double , kSides > t{};
403+ for (int s = 0 ; s < kSides ; ++s)
404+ t[s] = std::cos (2.0 * M_PI * s / kSides );
405+ return t;
406+ }();
407+ static const auto sin_table = [] {
408+ std::array<double , kSides > t{};
409+ for (int s = 0 ; s < kSides ; ++s)
410+ t[s] = std::sin (2.0 * M_PI * s / kSides );
411+ return t;
412+ }();
408413
409414 for (size_t ni = 0 ; ni < num_nodes; ++ni) {
410415 const vsg::dvec3 tang = Tangent (pts, ni);
@@ -416,7 +421,7 @@ void MooringLinesViz::UpdateTubeMesh(const MooringLineVizData& line_data,
416421 const auto centre_z = static_cast <float >(pts[ni][2 ]);
417422
418423 vsg::vec4 col = kDefaultCableColorVec4 ;
419- if (has_scalars ) {
424+ if (has_tensions ) {
420425 const float t =
421426 (static_cast <float >(line_data.node_tensions [ni]) - range_min)
422427 * inv_range;
@@ -467,7 +472,7 @@ void MooringLinesViz::UpdateTubeMesh(const MooringLineVizData& line_data,
467472 if (lm.colors ) {
468473 vsg::vec4 cap0_col = kDefaultCableColorVec4 ;
469474 vsg::vec4 capN_col = kDefaultCableColorVec4 ;
470- if (has_scalars ) {
475+ if (has_tensions ) {
471476 cap0_col = TurboColormap (
472477 (static_cast <float >(line_data.node_tensions .front ()) - range_min)
473478 * inv_range);
0 commit comments