Rigs of Rods 2023.09
Soft-body Physics Simulation
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Loading...
Searching...
No Matches
ActorExport.cpp
Go to the documentation of this file.
1/*
2 This source file is part of Rigs of Rods
3 Copyright 2005-2012 Pierre-Michel Ricordel
4 Copyright 2007-2012 Thomas Fischer
5 Copyright 2013-2024 Petr Ohlidal
6
7 For more information, see http://www.rigsofrods.org/
8
9 Rigs of Rods is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License version 3, as
11 published by the Free Software Foundation.
12
13 Rigs of Rods is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with Rigs of Rods. If not, see <http://www.gnu.org/licenses/>.
20*/
21
22#include "Actor.h"
23#include "Application.h"
24#include "CacheSystem.h"
25#include "GameContext.h"
26#include "RigDef_File.h"
27
28#include <Ogre.h>
29
30using namespace RoR;
31using namespace RigDef;
32
34{
35 if (n == NODENUM_INVALID)
36 {
37 return RigDef::Node::Ref();
38 }
39
40 const BitMask_t nodeflags = RigDef::Node::Ref::REGULAR_STATE_IS_VALID;
41 if (actor->ar_nodes_name[n] != "")
42 {
43 return RigDef::Node::Ref(actor->ar_nodes_name[n], 0, nodeflags, 0);
44 }
45 else
46 {
47 return RigDef::Node::Ref(fmt::format("{}", actor->ar_nodes_id[n]), actor->ar_nodes_id[n], nodeflags, 0);
48 }
49}
50
51static bool IsActuallyShockBeam(const beam_t& beam)
52{
53 // Beams with attributes {SHOCK1 && BEAM_NORMAL} are actually wheel beams ~ don't ask.
54 return beam.bm_type == BEAM_HYDRO
55 && (beam.bounded == SHOCK1 || beam.bounded == SHOCK2 || beam.bounded == SHOCK3);
56}
57
58static void UpdateSetBeamDefaults(std::shared_ptr<BeamDefaults>& beam_defaults, Actor* actor, int i)
59{
60 float b_spring = actor->ar_beams[i].k;
61 float b_damp = actor->ar_beams[i].d;
62 float b_deform = actor->ar_beams[i].default_beam_deform;
63 float b_break = actor->ar_beams[i].initial_beam_strength;
64 float b_diameter = actor->ar_beams[i].default_beam_diameter;
65 if (IsActuallyShockBeam(actor->ar_beams[i]))
66 {
67 b_spring = actor->ar_beams[i].shock->sbd_spring;
68 b_damp = actor->ar_beams[i].shock->sbd_damp;
69 b_break = actor->ar_beams[i].shock->sbd_break;
70 }
71
72 if (beam_defaults->springiness != b_spring
73 || beam_defaults->damping_constant != b_damp
74 || beam_defaults->deformation_threshold != b_deform
75 || beam_defaults->breaking_threshold != b_break
76 || beam_defaults->visual_beam_diameter != b_diameter)
77 {
78 beam_defaults = std::shared_ptr<BeamDefaults>(new BeamDefaults);
79 beam_defaults->springiness = b_spring;
80 beam_defaults->damping_constant = b_damp;
81 beam_defaults->deformation_threshold = b_deform;
82 beam_defaults->breaking_threshold = b_break;
83 beam_defaults->visual_beam_diameter = b_diameter;
84 }
85}
86
87static void UpdateSetNodeDefaults(std::shared_ptr<NodeDefaults>& node_defaults, Actor* actor, NodeNum_t i)
88{
89 float n_loadweight = actor->ar_nodes_default_loadweights[i];
90 float n_friction = actor->ar_nodes[i].friction_coef;
91 float n_volume = actor->ar_nodes[i].volume_coef;
92 float n_surface = actor->ar_nodes[i].surface_coef;
93 if (node_defaults->load_weight != n_loadweight
94 || node_defaults->friction != n_friction
95 || node_defaults->surface != n_surface
96 || node_defaults->volume != n_volume)
97 {
98 node_defaults = std::shared_ptr<NodeDefaults>(new NodeDefaults);
99 node_defaults->load_weight = n_loadweight;
100 node_defaults->friction = n_friction;
101 node_defaults->surface = n_surface;
102 node_defaults->volume = n_volume;
103 }
104}
105
106static void UpdateSetInertiaDefaults(std::shared_ptr<Inertia>& inertia_defaults, Actor* actor, CmdKeyInertia& cmdkey_inertia)
107{
108 const float start_delay = cmdkey_inertia.GetStartDelay();
109 const float stop_delay = cmdkey_inertia.GetStopDelay();
110 const std::string startfn = cmdkey_inertia.GetStartFunction();
111 const std::string stopfn = cmdkey_inertia.GetStopFunction();
112
113 if (inertia_defaults->start_delay_factor != start_delay
114 || inertia_defaults->stop_delay_factor != stop_delay
115 || inertia_defaults->start_function != startfn
116 || inertia_defaults->stop_function != stopfn
117 )
118 {
119 inertia_defaults = std::shared_ptr<Inertia>(new Inertia);
120 inertia_defaults->start_delay_factor = start_delay;
121 inertia_defaults->stop_delay_factor = stop_delay;
122 inertia_defaults->start_function = startfn;
123 inertia_defaults->stop_function = stopfn;
124 }
125}
126
128{
129 // PROOF OF CONCEPT:
130 // * assumes 'section/end_section' is not used (=only root module exists)
131 // * uses dummy 'set_beam_defaults' and 'detacher_group' for the hookbeams (nodes with 'h' option)
132 // * doesn't separate out 'set_beam_defaults_scale' from 'set_beam_defaults'
133 // * uses only 'set_default_minimass', ignores global 'minimass'
134 // * ignores 'detacher_group' for the hookbeams (nodes with 'h' option)
135 // -------------------------------------------------------------------------
136
137
138
139 // Purge old data
140 m_used_actor_entry->actor_def->root_module->nodes.clear();
141 m_used_actor_entry->actor_def->root_module->beams.clear();
142 m_used_actor_entry->actor_def->root_module->cinecam.clear();
143 m_used_actor_entry->actor_def->root_module->wheels.clear();
144 m_used_actor_entry->actor_def->root_module->wheels2.clear();
145 m_used_actor_entry->actor_def->root_module->meshwheels.clear();
146 m_used_actor_entry->actor_def->root_module->meshwheels2.clear();
147 m_used_actor_entry->actor_def->root_module->flexbodywheels.clear();
148 m_used_actor_entry->actor_def->root_module->shocks.clear();
149 m_used_actor_entry->actor_def->root_module->shocks2.clear();
150 m_used_actor_entry->actor_def->root_module->shocks3.clear();
151 m_used_actor_entry->actor_def->root_module->hydros.clear();
152
153 // Prepare 'set_node_defaults' with builtin values.
154 auto node_defaults = std::shared_ptr<NodeDefaults>(new NodeDefaults); // comes pre-filled
155
156 // Prepare 'set_default_minimass' with builtin values.
157 auto default_minimass = std::shared_ptr<DefaultMinimass>(new DefaultMinimass());
158 default_minimass->min_mass_Kg = DEFAULT_MINIMASS;
159
160 // Prepare 'set_beam_defaults' with builtin values.
161 auto beam_defaults = std::shared_ptr<BeamDefaults>(new BeamDefaults);
162 beam_defaults->springiness = DEFAULT_SPRING;
163 beam_defaults->damping_constant = DEFAULT_DAMP;
164 beam_defaults->deformation_threshold = BEAM_DEFORM;
165 beam_defaults->breaking_threshold = BEAM_BREAK;
166 beam_defaults->visual_beam_diameter = DEFAULT_BEAM_DIAMETER;
167
168 // Prepare 'set_inertia_defaults' with builtin values.
169 auto inertia_defaults = std::shared_ptr<Inertia>(new Inertia);
170
171 // Prepare 'detacher_group' with builtin values.
172 int detacher_group = DEFAULT_DETACHER_GROUP;
173
174
175 // ~~~ Nodes ~~~
176
177 for (NodeNum_t i = 0; i < ar_num_nodes; i++)
178 {
179 if (ar_nodes[i].nd_rim_node || ar_nodes[i].nd_tyre_node || ar_nodes[i].nd_cinecam_node)
180 {
181 // Skip wheel nodes and cinecam nodes
182 continue;
183 }
184
185 UpdateSetNodeDefaults(node_defaults, this, i);
186
187 // Check if 'set_default_minimass' needs update.
188 if (default_minimass->min_mass_Kg != ar_minimass[i])
189 {
190 default_minimass = std::shared_ptr<DefaultMinimass>(new DefaultMinimass());
191 default_minimass->min_mass_Kg = ar_minimass[i];
192 }
193
194 // Build the node
195 RigDef::Node node;
196 node.node_defaults = node_defaults;
197 node.default_minimass = default_minimass;
198 node.beam_defaults = beam_defaults; // Needed for hookbeams (nodes with 'h' option)
199 node.detacher_group = detacher_group; // Needed for hookbeams (nodes with 'h' option)
200 if (ar_nodes_name[i] != "")
201 {
203 }
204 else
205 {
207 }
211 node.options = ar_nodes_options[i];
212
213 // Submit the node
214 m_used_actor_entry->actor_def->root_module->nodes.push_back(node);
215 }
216
217
218 // ~~~ Beams ~~~
219
220 for (int i = 0; i < ar_num_beams; i++)
221 {
222 if (!ar_beams_user_defined[i])
223 {
224 // Skip everything not from 'beams' (wheels/cinecam/hooknode/wings/rotators etc...)
225 continue;
226 }
227
228 UpdateSetBeamDefaults(beam_defaults, this, i);
229
230 // Check if 'detacher_group' needs update.
231 if (detacher_group != ar_beams[i].detacher_group)
232 {
233 detacher_group = ar_beams[i].detacher_group;
234 }
235
236 // Build the beam
237 RigDef::Beam beam;
238 beam.defaults = beam_defaults;
239 beam.detacher_group = detacher_group;
241
242 if (ar_beams[i].bounded == SUPPORTBEAM)
243 {
244 beam._has_extension_break_limit = true;
246 }
247 else if (ar_beams[i].bounded == ROPE)
248 {
250 }
251
252 if (ar_beams_invisible[i])
253 {
255 }
256
257 // Build refs to the nodes
258 beam.nodes[0] = BuildNodeRef(this, ar_beams[i].p1->pos);
259 beam.nodes[1] = BuildNodeRef(this, ar_beams[i].p2->pos);
260
261 // Submit the beam
262 m_used_actor_entry->actor_def->root_module->beams.push_back(beam);
263 }
264
265
266 // ~~~ Cinecam ~~~
267
268 for (NodeNum_t i = 0; i < ar_num_nodes; i++)
269 {
270 if (!ar_nodes[i].nd_cinecam_node)
271 {
272 // Skip everything but cinecam nodes
273 continue;
274 }
275
276 UpdateSetNodeDefaults(node_defaults, this, i);
277
278 // Find all beams that connect to the cinecam node
279 std::array<int, 8> cinecam_nodes = { -1, -1, -1, -1, -1, -1, -1, -1 };
280 int num_cinecam_nodes = 0;
281 int cinecam_beamid = -1;
282 for (int j = 0; j < ar_num_beams; j++)
283 {
284 if (ar_beams[j].p1->pos == i)
285 {
286 cinecam_beamid = j;
287 cinecam_nodes[num_cinecam_nodes++] = ar_beams[j].p2->pos;
288 }
289 else if (ar_beams[j].p2->pos == i)
290 {
291 cinecam_beamid = j;
292 cinecam_nodes[num_cinecam_nodes++] = ar_beams[j].p1->pos;
293 }
294 }
295 ROR_ASSERT(num_cinecam_nodes == 8);
296 ROR_ASSERT(cinecam_beamid != -1);
297
298 UpdateSetBeamDefaults(beam_defaults, this, cinecam_beamid);
299
300 // Build the cinecam (NOTE: no minimass/detacher_group)
301 RigDef::Cinecam cinecam;
302 cinecam.node_defaults = node_defaults;
303 cinecam.beam_defaults = beam_defaults;
304 cinecam.position = ar_nodes_spawn_offsets[i];
305 for (int n = 0; n < 8; n++)
306 {
307 cinecam.nodes[n] = BuildNodeRef(this, cinecam_nodes[n]);
308 }
309 cinecam.node_mass = ar_nodes[i].mass;
310 cinecam.spring = ar_beams[cinecam_beamid].k;
311 cinecam.damping = ar_beams[cinecam_beamid].d;
312
313 // Submit the cinecam
314 m_used_actor_entry->actor_def->root_module->cinecam.push_back(cinecam);
315 }
316
317
318 // ~~~ Wheels ~~~
319 for (int i = 0; i < ar_num_wheels; i++)
320 {
321 // PLEASE maintain the same order of arguments as the docs: https://docs.rigsofrods.org/vehicle-creation/fileformat-truck/#vehicle-specific
322
323 UpdateSetNodeDefaults(node_defaults, this, ar_wheels[i].wh_nodes[0]->pos);
324 UpdateSetBeamDefaults(beam_defaults, this, ar_wheels[i].wh_beam_start);
325 switch (ar_wheels[i].wh_arg_keyword)
326 {
327 case Keyword::WHEELS:
328 {
329 RigDef::Wheel wheel;
330 wheel.beam_defaults = beam_defaults;
331 wheel.node_defaults = node_defaults;
332 // radius
333 wheel.radius = ar_wheels[i].wh_radius;
334 // rays
336 // nodes
337 wheel.nodes[0] = BuildNodeRef(this, ar_wheels[i].wh_axis_node_0->pos);
338 wheel.nodes[1] = BuildNodeRef(this, ar_wheels[i].wh_axis_node_1->pos);
339 wheel.rigidity_node = BuildNodeRef(this, ar_wheels[i].wh_arg_rigidity_node);
340 // braking, propulsion
341 wheel.braking = ar_wheels[i].wh_braking;
343 // arm node
344 wheel.reference_arm_node = BuildNodeRef(this, (ar_wheels[i].wh_arm_node ? ar_wheels[i].wh_arm_node->pos : NODENUM_INVALID));
345 // mass
346 wheel.mass = ar_wheels[i].wh_mass;
347 // springiness, damping
350 // materials
353
354 m_used_actor_entry->actor_def->root_module->wheels.push_back(wheel);
355 break;
356 }
357 case Keyword::WHEELS2:
358 {
359 RigDef::Wheel2 wheel;
360 wheel.beam_defaults = beam_defaults;
361 wheel.node_defaults = node_defaults;
362 // radius
365 // rays
367 // nodes
368 wheel.nodes[0] = BuildNodeRef(this, ar_wheels[i].wh_axis_node_0->pos);
369 wheel.nodes[1] = BuildNodeRef(this, ar_wheels[i].wh_axis_node_1->pos);
370 wheel.rigidity_node = BuildNodeRef(this, ar_wheels[i].wh_arg_rigidity_node);
371 // braking, propulsion
372 wheel.braking = ar_wheels[i].wh_braking;
374 // arm node
375 wheel.reference_arm_node = BuildNodeRef(this, (ar_wheels[i].wh_arm_node ? ar_wheels[i].wh_arm_node->pos : NODENUM_INVALID));
376 // mass
377 wheel.mass = ar_wheels[i].wh_mass;
378 // springiness, damping
383 // materials
386
387 m_used_actor_entry->actor_def->root_module->wheels2.push_back(wheel);
388 break;
389 }
390 case Keyword::MESHWHEELS:
391 {
392 RigDef::MeshWheel wheel;
393 wheel.beam_defaults = beam_defaults;
394 wheel.node_defaults = node_defaults;
395 // radius
398 // rays
400 // nodes
401 wheel.nodes[0] = BuildNodeRef(this, ar_wheels[i].wh_axis_node_0->pos);
402 wheel.nodes[1] = BuildNodeRef(this, ar_wheels[i].wh_axis_node_1->pos);
403 wheel.rigidity_node = BuildNodeRef(this, ar_wheels[i].wh_arg_rigidity_node);
404 // braking, propulsion
405 wheel.braking = ar_wheels[i].wh_braking;
407 // arm node
408 wheel.reference_arm_node = BuildNodeRef(this, (ar_wheels[i].wh_arm_node ? ar_wheels[i].wh_arm_node->pos : NODENUM_INVALID));
409 // mass
410 wheel.mass = ar_wheels[i].wh_mass;
411 // springiness, damping
414 // media
415 wheel.side = ar_wheels[i].wh_arg_side;
418
419 m_used_actor_entry->actor_def->root_module->meshwheels.push_back(wheel);
420 break;
421 }
422 case Keyword::MESHWHEELS2:
423 {
424 RigDef::MeshWheel2 wheel;
425 wheel.beam_defaults = beam_defaults;
426 wheel.node_defaults = node_defaults;
427 // Special handling of 'set_beam_defaults' (these define rim params)
428 wheel.beam_defaults->springiness = ar_wheels[i].wh_arg_rim_spring;
429 wheel.beam_defaults->damping_constant = ar_wheels[i].wh_arg_rim_damping;
430
431 // radius
434 // rays
436 // nodes
437 wheel.nodes[0] = BuildNodeRef(this, ar_wheels[i].wh_axis_node_0->pos);
438 wheel.nodes[1] = BuildNodeRef(this, ar_wheels[i].wh_axis_node_1->pos);
439 wheel.rigidity_node = BuildNodeRef(this, ar_wheels[i].wh_arg_rigidity_node);
440 // braking, propulsion
441 wheel.braking = ar_wheels[i].wh_braking;
443 // arm node
444 wheel.reference_arm_node = BuildNodeRef(this, (ar_wheels[i].wh_arm_node ? ar_wheels[i].wh_arm_node->pos : NODENUM_INVALID));
445 // mass
446 wheel.mass = ar_wheels[i].wh_mass;
447 // springiness, damping
450 // media
451 wheel.side = ar_wheels[i].wh_arg_side;
454
455 m_used_actor_entry->actor_def->root_module->meshwheels2.push_back(wheel);
456 break;
457 }
458 case Keyword::FLEXBODYWHEELS:
459 {
461 wheel.beam_defaults = beam_defaults;
462 wheel.node_defaults = node_defaults;
463 // Special handling of 'set_beam_defaults' (these define rim params)
464 wheel.beam_defaults->springiness = ar_wheels[i].wh_arg_rim_spring;
465 wheel.beam_defaults->damping_constant = ar_wheels[i].wh_arg_rim_damping;
466
467 // radius
470 // rays
472 // nodes
473 wheel.nodes[0] = BuildNodeRef(this, ar_wheels[i].wh_axis_node_0->pos);
474 wheel.nodes[1] = BuildNodeRef(this, ar_wheels[i].wh_axis_node_1->pos);
475 wheel.rigidity_node = BuildNodeRef(this, ar_wheels[i].wh_arg_rigidity_node);
476 // braking, propulsion
477 wheel.braking = ar_wheels[i].wh_braking;
479 // arm node
480 wheel.reference_arm_node = BuildNodeRef(this, (ar_wheels[i].wh_arm_node ? ar_wheels[i].wh_arm_node->pos : NODENUM_INVALID));
481 // mass
482 wheel.mass = ar_wheels[i].wh_mass;
483 // springiness, damping
486 // media
487 wheel.side = ar_wheels[i].wh_arg_side;
490
491 m_used_actor_entry->actor_def->root_module->flexbodywheels.push_back(wheel);
492 break;
493 }
494 default:
495 ROR_ASSERT(false);
496 break;
497 }
498 }
499
500 // ~~~ Shocks ~~~
501
502 for (int i = 0; i < ar_num_beams; i++)
503 {
504 const beam_t& beam = ar_beams[i];
505 switch (beam.bounded)
506 {
508 {
509 if (!IsActuallyShockBeam(beam))
510 {
511 // This is actually a wheel beam - skip it.
512 continue;
513 }
514
515 UpdateSetBeamDefaults(beam_defaults, this, i);
516
517 RigDef::Shock def;
518 def.beam_defaults = beam_defaults;
519 def.nodes[0] = BuildNodeRef(this, beam.p1->pos);
520 def.nodes[1] = BuildNodeRef(this, beam.p2->pos);
521 def.short_bound = beam.shortbound;
522 def.long_bound = beam.longbound;
524
525 // shock1-specific
526 def.spring_rate = beam.k;
527 def.damping = beam.d;
528
529 // options
531 {
533 }
535 {
537 }
538 if (ar_beams_invisible[i])
539 {
541 }
542
543 m_used_actor_entry->actor_def->root_module->shocks.push_back(def);
544 break;
545 }
546
548 {
549 UpdateSetBeamDefaults(beam_defaults, this, i);
550
551 RigDef::Shock2 def;
552 def.beam_defaults = beam_defaults;
553 def.nodes[0] = BuildNodeRef(this, beam.p1->pos);
554 def.nodes[1] = BuildNodeRef(this, beam.p2->pos);
555 def.short_bound = beam.shortbound;
556 def.long_bound = beam.longbound;
558
559 // shock2-specific
560 def.beam_defaults->springiness = beam.shock->sbd_spring;
561 def.beam_defaults->damping_constant = beam.shock->sbd_damp ;
562 def.spring_in = beam.shock->springin ;
563 def.damp_in = beam.shock->dampin ;
564 def.spring_out = beam.shock->springout ;
565 def.damp_out = beam.shock->dampout ;
570
571 // options
572 if (ar_beams_invisible[i])
573 {
575 }
576
577 m_used_actor_entry->actor_def->root_module->shocks2.push_back(def);
578 break;
579 }
580
582 {
583 UpdateSetBeamDefaults(beam_defaults, this, i);
584
585 RigDef::Shock3 def;
586 def.beam_defaults = beam_defaults;
587 def.nodes[0] = BuildNodeRef(this, beam.p1->pos);
588 def.nodes[1] = BuildNodeRef(this, beam.p2->pos);
589 def.short_bound = beam.shortbound;
590 def.long_bound = beam.longbound;
592
593 // same as shock2
594 def.beam_defaults->springiness = beam.shock->sbd_spring;
595 def.beam_defaults->damping_constant = beam.shock->sbd_damp;
596 def.spring_in = beam.shock->springin;
597 def.damp_in = beam.shock->dampin;
598 def.spring_out = beam.shock->springout;
599 def.damp_out = beam.shock->dampout;
600
601 // shock3-specific
602 def.split_vel_in = beam.shock->splitin ;
603 def.damp_in_slow = beam.shock->dslowin ;
604 def.damp_in_fast = beam.shock->dfastin ;
605 def.split_vel_out = beam.shock->splitout ;
606 def.damp_out_slow = beam.shock->dslowout ;
607 def.damp_out_fast = beam.shock->dfastout ;
608
609 // options
610 if (ar_beams_invisible[i])
611 {
613 }
614
615 m_used_actor_entry->actor_def->root_module->shocks3.push_back(def);
616 break;
617 }
618
619 default: // Not a shock
620 break;
621 }
622 }
623
624 // ~~~ Hydros ~~~
625 for (hydrobeam_t& hydrobeam: ar_hydros)
626 {
627 int i = hydrobeam.hb_beam_index;
628 const beam_t& beam = ar_beams[i];
629 if (beam.bm_type != BEAM_HYDRO)
630 {
631 continue; // Should never happen.
632 }
633
634 UpdateSetBeamDefaults(beam_defaults, this, i);
635 UpdateSetInertiaDefaults(inertia_defaults, this, hydrobeam.hb_inertia);
636
637 RigDef::Hydro def;
638 def.beam_defaults = beam_defaults;
639 def.inertia_defaults = inertia_defaults;
640 def.nodes[0] = BuildNodeRef(this, beam.p1->pos);
641 def.nodes[1] = BuildNodeRef(this, beam.p2->pos);
642 def.lenghtening_factor = hydrobeam.hb_speed;
643
644 // HEADS UP: hydro options have quirks:
645 // * 'n' is not 'dummy' like elsewhere, but activates steering wheel input (n = normal)
646 // * 'i' makes beam invisible, but (!) also activates 'n' when first in the list. This is an old bug preserved for compatibility.
647 // * 'j' makes beam invisible without any side effects (unique to hydros)
648 // The exporter never uses 'i', just 'j' and 'n'.
649
650 // individual options
651 if (ar_beams_invisible[i])
652 {
654 }
655 if (BITMASK_IS_1(hydrobeam.hb_flags, HYDRO_FLAG_SPEED))
656 {
658 }
659 if (BITMASK_IS_1(hydrobeam.hb_flags, HYDRO_FLAG_ELEVATOR))
660 {
662 }
663 if (BITMASK_IS_1(hydrobeam.hb_flags, HYDRO_FLAG_RUDDER))
664 {
666 }
667 if (BITMASK_IS_1(hydrobeam.hb_flags, HYDRO_FLAG_AILERON))
668 {
670 }
671 if (BITMASK_IS_1(hydrobeam.hb_flags, HYDRO_FLAG_DIR))
672 {
674 }
675
676 // combined options
678 {
680 }
681 if (BITMASK_IS_1(hydrobeam.hb_flags, HYDRO_FLAG_REV_AILERON | HYDRO_FLAG_RUDDER))
682 {
684 }
685 if (BITMASK_IS_1(hydrobeam.hb_flags, HYDRO_FLAG_REV_ELEVATOR | HYDRO_FLAG_RUDDER))
686 {
688 }
689
690 m_used_actor_entry->actor_def->root_module->hydros.push_back(def);
691 }
692
693 // ~~~ Globals (update in-place) ~~~
694
695 m_used_actor_entry->actor_def->root_module->globals[0].dry_mass = ar_dry_mass;
696 m_used_actor_entry->actor_def->root_module->globals[0].cargo_mass = ar_load_mass;
697}
static void UpdateSetInertiaDefaults(std::shared_ptr< Inertia > &inertia_defaults, Actor *actor, CmdKeyInertia &cmdkey_inertia)
static bool IsActuallyShockBeam(const beam_t &beam)
static RigDef::Node::Ref BuildNodeRef(Actor *actor, NodeNum_t n)
static void UpdateSetBeamDefaults(std::shared_ptr< BeamDefaults > &beam_defaults, Actor *actor, int i)
static void UpdateSetNodeDefaults(std::shared_ptr< NodeDefaults > &node_defaults, Actor *actor, NodeNum_t i)
Central state/object manager and communications hub.
#define ROR_ASSERT(_EXPR)
Definition Application.h:40
#define BITMASK_IS_1(VAR, FLAGS)
Definition BitFlags.h:14
#define BITMASK_SET_1(VAR, FLAGS)
Definition BitFlags.h:17
uint32_t BitMask_t
Definition BitFlags.h:7
A database of user-installed content alias 'mods' (vehicles, terrains...)
Game state manager and message-queue provider.
Data structures representing 'truck' file format, see https://docs.rigsofrods.org/vehicle-creation/fi...
Abstract node ID (numbered or named) Node name is always available.
Definition RigDef_Node.h:45
Legacy parser resolved references on-the-fly and the condition to check named nodes was "are there an...
Definition RigDef_Node.h:78
Softbody object; can be anything from soda can to a space shuttle Constructed from a truck definition...
Definition Actor.h:55
std::vector< float > ar_minimass
minimum node mass in Kg - can be scaled in-game via NBUtil
Definition Actor.h:337
float ar_dry_mass
User-defined (editable via NBUtil); from 'globals' arg#1 - default for all nodes.
Definition Actor.h:320
std::vector< float > ar_nodes_override_loadweights
'nodes': 'l' flag and number.
Definition Actor.h:334
std::vector< bool > ar_beams_invisible
Used only by the exporter (for rendering, invisible beams simply get no mesh).
Definition Actor.h:351
wheel_t ar_wheels[MAX_WHEELS]
Definition Actor.h:384
node_t * ar_nodes
Definition Actor.h:330
std::vector< BitMask_t > ar_nodes_options
merged options from 'nodes' and 'set_node_defaults'
Definition Actor.h:336
std::vector< bool > ar_beams_user_defined
True for 'beams', false for wheels/cinecam/hooknode/wings/rotators etc...
Definition Actor.h:352
int * ar_nodes_id
Number in truck file, -1 for nodes generated by wheels/cinecam.
Definition Actor.h:331
std::vector< float > ar_nodes_default_loadweights
'set_node_defaults': load weight.
Definition Actor.h:333
float ar_load_mass
User-defined (editable via NBUtil); from 'globals' arg#2 - only applies to nodes with 'l' flag.
Definition Actor.h:322
void propagateNodeBeamChangesToDef()
Back-propagates changes done by N/B-utils UI to the def-document.
int ar_num_beams
Definition Actor.h:349
std::string * ar_nodes_name
Name in truck file, only if defined with 'nodes2'.
Definition Actor.h:332
CacheEntryPtr m_used_actor_entry
Required.
Definition Actor.h:668
int ar_num_nodes
Definition Actor.h:345
std::vector< hydrobeam_t > ar_hydros
Definition Actor.h:395
int ar_num_wheels
Definition Actor.h:385
Ogre::Vector3 * ar_nodes_spawn_offsets
Relative positions (incl. Tuning system tweaks) from the definition file, for spawn-like resetting (i...
Definition Actor.h:335
beam_t * ar_beams
Definition Actor.h:348
RigDef::DocumentPtr actor_def
Cached actor definition (aka truckfile) after first spawn.
Definition CacheSystem.h:91
Designed to be run in physics loop (2khz)
const std::string & GetStopFunction() const
float GetStartDelay() const
const std::string & GetStartFunction() const
float GetStopDelay() const
@ HYDRO_FLAG_DIR
Definition SimData.h:124
@ HYDRO_FLAG_SPEED
Definition SimData.h:123
@ HYDRO_FLAG_RUDDER
Definition SimData.h:126
@ HYDRO_FLAG_REV_ELEVATOR
Definition SimData.h:130
@ HYDRO_FLAG_AILERON
Definition SimData.h:125
@ HYDRO_FLAG_ELEVATOR
Definition SimData.h:127
@ HYDRO_FLAG_REV_AILERON
Definition SimData.h:128
static const float DEFAULT_SPRING
static const float DEFAULT_BEAM_DIAMETER
5 centimeters default beam width
static const int DEFAULT_DETACHER_GROUP
static const float BEAM_DEFORM
static const float DEFAULT_DAMP
static const float DEFAULT_MINIMASS
minimum node mass in Kg
static const float BEAM_BREAK
@ BEAM_HYDRO
Definition SimData.h:64
@ SHOCK3
shock3
Definition SimData.h:102
@ ROPE
Definition SimData.h:105
@ SUPPORTBEAM
Definition SimData.h:104
@ SHOCK2
shock2
Definition SimData.h:101
@ SHOCK1
either 'shock1' (with flag BEAM_HYDRO) or a wheel beam
Definition SimData.h:100
@ SHOCK_FLAG_LACTIVE
Definition SimData.h:190
@ SHOCK_FLAG_RACTIVE
Definition SimData.h:191
static const NodeNum_t NODENUM_INVALID
uint16_t NodeNum_t
Node position within Actor::ar_nodes; use RoR::NODENUM_INVALID as empty value.
Ogre::String material_name
RoR::WheelSide side
Ogre::String mesh_name
RoR::WheelBraking braking
unsigned int num_rays
std::shared_ptr< BeamDefaults > beam_defaults
std::shared_ptr< NodeDefaults > node_defaults
Node::Ref rigidity_node
RoR::WheelPropulsion propulsion
Node::Ref nodes[2]
Node::Ref reference_arm_node
static const BitMask_t OPTION_r_ROPE
BitMask_t options
bool _has_extension_break_limit
std::shared_ptr< BeamDefaults > defaults
float extension_break_limit
static const BitMask_t OPTION_i_INVISIBLE
Node::Ref nodes[2]
static const BitMask_t OPTION_s_SUPPORT
Ogre::Vector3 position
std::shared_ptr< BeamDefaults > beam_defaults
Node::Ref nodes[8]
std::shared_ptr< NodeDefaults > node_defaults
Ogre::String tyre_mesh_name
RoR::WheelSide side
Ogre::String rim_mesh_name
static const BitMask_t OPTION_e_INPUT_ELEVATOR
std::shared_ptr< Inertia > inertia_defaults
float lenghtening_factor
static const BitMask_t OPTION_s_DISABLE_ON_HIGH_SPEED
BitMask_t options
static const BitMask_t OPTION_h_INPUT_InvELEVATOR_RUDDER
static const BitMask_t OPTION_y_INPUT_InvAILERON_RUDDER
Node::Ref nodes[2]
static const BitMask_t OPTION_j_INVISIBLE
static const BitMask_t OPTION_v_INPUT_InvAILERON_ELEVATOR
static const BitMask_t OPTION_a_INPUT_AILERON
static const BitMask_t OPTION_r_INPUT_RUDDER
static const BitMask_t OPTION_n_INPUT_NORMAL
std::shared_ptr< BeamDefaults > beam_defaults
std::shared_ptr< BeamDefaults > beam_defaults
std::shared_ptr< DefaultMinimass > default_minimass
bool _has_load_weight_override
BitMask_t options
std::shared_ptr< NodeDefaults > node_defaults
float load_weight_override
Ogre::Vector3 position
BitMask_t options
Node::Ref nodes[2]
float short_bound
Maximum contraction limit, in percentage ( 1.00 = 100% )
float progress_factor_damp_out
Progression factor dampout, 0 = disabled, 1...x as multipliers, example:maximum dampingrate == spring...
float damp_out
damping value applied when shock extending
float progress_factor_damp_in
Progression factor for dampin. 0 = disabled, 1...x as multipliers, example:maximum dampingrate == spr...
std::shared_ptr< BeamDefaults > beam_defaults
float spring_in
Spring value applied when the shock is compressing.
float precompression
Changes compression or extension of the suspension when the truck spawns. This can be used to "level"...
float progress_factor_spring_out
Progression factor springout, 0 = disabled, 1...x as multipliers, example:maximum springrate == sprin...
float spring_out
spring value applied when shock extending
float long_bound
Maximum extension limit, in percentage ( 1.00 = 100% )
float damp_in
Damping value applied when the shock is compressing.
float progress_factor_spring_in
Progression factor for springin. A value of 0 disables this option. 1...x as multipliers,...
float damp_in_slow
Damping value applied when shock is commpressing slower than split in velocity.
float spring_in
Spring value applied when the shock is compressing.
float spring_out
Spring value applied when shock extending.
float damp_in
Damping value applied when the shock is compressing.
float split_vel_in
Split velocity in (m/s) - threshold for slow / fast damping during compression.
BitMask_t options
float precompression
Changes compression or extension of the suspension when the truck spawns. This can be used to "level"...
Node::Ref nodes[2]
std::shared_ptr< BeamDefaults > beam_defaults
float damp_out
Damping value applied when shock extending.
float long_bound
Maximum extension limit, in percentage ( 1.00 = 100% )
float short_bound
Maximum contraction limit, in percentage ( 1.00 = 100% )
float damp_out_slow
Damping value applied when shock is commpressing slower than split out velocity.
float damp_out_fast
Damping value applied when shock is commpressing faster than split out velocity.
float damp_in_fast
Damping value applied when shock is commpressing faster than split in velocity.
float split_vel_out
Split velocity in (m/s) - threshold for slow / fast damping during extension.
static const BitMask_t OPTION_L_ACTIVE_LEFT
std::shared_ptr< BeamDefaults > beam_defaults
float damping
The 'resistance to motion' of the shock. The best value is given by this equation: 2 * sqrt(suspended...
float spring_rate
The 'stiffness' of the shock. The higher the value, the less the shock will move for a given bump.
float precompression
Changes compression or extension of the suspension when the truck spawns. This can be used to "level"...
Node::Ref nodes[2]
float short_bound
Maximum contraction. The shortest length the shock can be, as a proportion of its original length....
float long_bound
Maximum extension. The longest length a shock can be, as a proportion of its original length....
static const BitMask_t OPTION_i_INVISIBLE
static const BitMask_t OPTION_R_ACTIVE_RIGHT
BitMask_t options
Ogre::String face_material_name
Ogre::String band_material_name
Ogre::String band_material_name
Ogre::String face_material_name
Simulation: An edge in the softbody structure.
Definition SimData.h:305
node_t * p1
Definition SimData.h:309
float k
tensile spring
Definition SimData.h:311
BeamType bm_type
Definition SimData.h:322
shock_t * shock
Definition SimData.h:332
float default_beam_deform
for reset
Definition SimData.h:335
float longbound
Definition SimData.h:329
int detacher_group
Attribute: detacher group number (integer)
Definition SimData.h:320
float initial_beam_strength
for reset
Definition SimData.h:334
float shortbound
Definition SimData.h:328
SpecialBeam bounded
Definition SimData.h:321
float d
damping factor
Definition SimData.h:312
float default_beam_diameter
for export only
Definition SimData.h:336
node_t * p2
Definition SimData.h:310
< beams updating length based on simulation variables, generally known as actuators.
Definition SimData.h:571
Ogre::Real mass
Definition SimData.h:271
Ogre::Real volume_coef
Definition SimData.h:275
Ogre::Real surface_coef
Definition SimData.h:274
Ogre::Real friction_coef
Definition SimData.h:273
NodeNum_t pos
This node's index in Actor::ar_nodes array.
Definition SimData.h:277
float sbd_damp
set beam default for damping
Definition SimData.h:375
float sprogin
shocks2
Definition SimData.h:362
float dampin
shocks2 & shocks3
Definition SimData.h:358
float sprogout
shocks2
Definition SimData.h:364
float sbd_break
set beam default for breaking threshold
Definition SimData.h:376
float splitin
shocks3
Definition SimData.h:367
float dfastin
shocks3
Definition SimData.h:369
float springout
shocks2 & shocks3
Definition SimData.h:359
float springin
shocks2 & shocks3
Definition SimData.h:357
float dampout
shocks2 & shocks3
Definition SimData.h:360
float dslowout
shocks3
Definition SimData.h:371
float dprogout
shocks2
Definition SimData.h:365
float splitout
shocks3
Definition SimData.h:370
float dslowin
shocks3
Definition SimData.h:368
float shock_precompression
Only for export.
Definition SimData.h:378
float sbd_spring
set beam default for spring
Definition SimData.h:374
float dfastout
shocks3
Definition SimData.h:372
float dprogin
shocks2
Definition SimData.h:363
float wh_arg_rim_spring
Not used by 'wheels' (1) and 'meshwheels' (1).
Definition SimData.h:429
int wh_arg_num_rays
Definition SimData.h:427
WheelPropulsion wh_propulsed
Definition SimData.h:410
Ogre::Real wh_rim_radius
Definition SimData.h:412
Ogre::Real wh_mass
Total rotational mass of the wheel.
Definition SimData.h:417
WheelSide wh_arg_side
Only for 'meshwheels*' and 'flexbodywheels'.
Definition SimData.h:433
std::string wh_arg_media1
Definition SimData.h:434
Ogre::Real wh_radius
Definition SimData.h:411
float wh_arg_rim_damping
Not used by 'wheels' (1) and 'meshwheels' (1).
Definition SimData.h:430
std::string wh_arg_media2
Definition SimData.h:435
WheelBraking wh_braking
Definition SimData.h:405
int wh_beam_start
BeamID to export 'set_beam_defaults' parameters from.
Definition SimData.h:436