71 #include <fmt/format.h> 
   72 #include "half/half.hpp" 
   96     this->DisjoinInterActorBeams(); 
 
   99     ar_node_to_beam_connections.clear();
 
  100     ar_node_to_node_connections.clear();
 
  103     if (ar_dashboard != 
nullptr)
 
  106         ar_dashboard = 
nullptr;
 
  116     for (
int i = 0; i < ar_num_soundsources; i++)
 
  118         if (ar_soundsources[i].ssi)
 
  121             ar_soundsources[i].ssi = 
nullptr;
 
  124     ar_num_soundsources = 0;
 
  127     if (ar_autopilot != 
nullptr)
 
  130         ar_autopilot = 
nullptr;
 
  133     if (m_fusealge_airfoil)
 
  134         delete m_fusealge_airfoil;
 
  135     m_fusealge_airfoil = 
nullptr;
 
  137     if (m_replay_handler)
 
  138         delete m_replay_handler;
 
  139     m_replay_handler = 
nullptr;
 
  142     ar_vehicle_ai = 
nullptr; 
 
  145     if (m_deletion_scene_nodes.size() > 0)
 
  147         for (
unsigned int i = 0; i < m_deletion_scene_nodes.size(); i++)
 
  151                 if (!m_deletion_scene_nodes[i])
 
  153                 m_deletion_scene_nodes[i]->removeAndDestroyAllChildren();
 
  162         m_deletion_scene_nodes.clear();
 
  165     if (m_deletion_entities.size() > 0)
 
  167         for (
unsigned int i = 0; i < m_deletion_entities.size(); i++)
 
  171                 if (!m_deletion_entities[i])
 
  173                 m_deletion_entities[i]->detachAllObjectsFromBone();
 
  182         m_deletion_entities.clear();
 
  189     for (
int i = 0; i < ar_num_wings; i++)
 
  195                 delete ar_wings[i].fa;
 
  196             if (ar_wings[i].cnode)
 
  198                 ar_wings[i].cnode->removeAndDestroyAllChildren();
 
  210     for (
int i = 0; i < ar_num_aeroengines; i++)
 
  212         if (ar_aeroengines[i])
 
  213             delete ar_aeroengines[i];
 
  217     for (
int i = 0; i < ar_num_screwprops; i++)
 
  219         if (ar_screwprops[i])
 
  221             delete ar_screwprops[i];
 
  222             ar_screwprops[i] = 
nullptr;
 
  231     ar_airbrakes.clear();
 
  234     for (
int i = 0; i < ar_num_wheels; ++i)
 
  236         delete m_skid_trails[i];
 
  237         m_skid_trails[i] = 
nullptr;
 
  241     for (
size_t i = 0; i < this->ar_flares.size(); i++)
 
  245             if (ar_flares[i].snode)
 
  247                 ar_flares[i].snode->removeAndDestroyAllChildren();
 
  250             if (ar_flares[i].bbs)
 
  252             if (ar_flares[i].light)
 
  261     this->ar_flares.clear();
 
  264     for (std::vector<RailGroup*>::iterator it = m_railgroups.begin(); it != m_railgroups.end(); it++)
 
  268     m_railgroups.clear();
 
  270     if (m_intra_point_col_detector)
 
  272         delete m_intra_point_col_detector;
 
  273         m_intra_point_col_detector = 
nullptr;
 
  276     if (m_inter_point_col_detector)
 
  278         delete m_inter_point_col_detector;
 
  279         m_inter_point_col_detector = 
nullptr;
 
  283         delete m_transfer_case;
 
  285     for (
int i = 0; i < m_num_axle_diffs; ++i)
 
  287         if (m_axle_diffs[i] != 
nullptr)
 
  288             delete m_axle_diffs[i];
 
  290     m_num_axle_diffs = 0;
 
  292     for (
int i = 0; i < m_num_wheel_diffs; ++i)
 
  294         if (m_wheel_diffs[i] != 
nullptr)
 
  295             delete m_wheel_diffs[i];
 
  297     m_num_wheel_diffs = 0;
 
  301     m_wheel_node_count = 0;
 
  306     delete[] ar_rotators;
 
  311     ar_state = ActorState::DISPOSED;
 
  316 void Actor::scaleTruck(
float value)
 
  318     if (ar_state == ActorState::DISPOSED)
 
  325     for (
int i = 0; i < ar_num_beams; i++)
 
  328         ar_beams[i].d *= value;
 
  329         ar_beams[i].L *= value;
 
  330         ar_beams[i].refL *= value;
 
  335         hbeam.hb_ref_length *= value;
 
  336         hbeam.hb_speed *= value;
 
  339     Vector3 refpos = ar_nodes[0].AbsPosition;
 
  340     Vector3 relpos = ar_nodes[0].RelPosition;
 
  341     for (
int i = 1; i < ar_num_nodes; i++)
 
  343         ar_initial_node_positions[i] = refpos + (ar_initial_node_positions[i] - refpos) * value;
 
  344         ar_nodes[i].AbsPosition = refpos + (ar_nodes[i].AbsPosition - refpos) * value;
 
  345         ar_nodes[i].RelPosition = relpos + (ar_nodes[i].RelPosition - relpos) * value;
 
  346         ar_nodes[i].Velocity *= value;
 
  347         ar_nodes[i].Forces *= value;
 
  348         ar_nodes[i].mass *= value;
 
  350     updateSlideNodePositions();
 
  352     m_gfx_actor->ScaleActor(relpos, value);
 
  356 float Actor::getRotation()
 
  358     if (ar_state == ActorState::DISPOSED)
 
  361     Vector3 dir = getDirection();
 
  363     return atan2(dir.dotProduct(Vector3::UNIT_X), dir.dotProduct(-Vector3::UNIT_Z));
 
  366 Vector3 Actor::getDirection()
 
  368     return ar_main_camera_dir_corr * this->GetCameraDir();
 
  371 Vector3 Actor::getPosition()
 
  373     return m_avg_node_position; 
 
  376 Ogre::Quaternion  Actor::getOrientation()
 
  378     Ogre::Vector3 localZ = ar_main_camera_dir_corr * -this->GetCameraDir();
 
  379     Ogre::Vector3 localX = ar_main_camera_dir_corr * this->GetCameraRoll();
 
  380     Ogre::Vector3 localY = localZ.crossProduct(localX);
 
  381     return Ogre::Quaternion(localX, localY, localZ);
 
  384 void Actor::pushNetwork(
char* data, 
int size)
 
  390     update.
node_data.resize(m_net_node_buf_size);
 
  391     update.
wheel_data.resize(ar_num_wheels * 
sizeof(
float));
 
  404         memcpy(update.
node_data.data(), ptr, m_net_node_buf_size);
 
  405         ptr += m_net_node_buf_size;
 
  408         for (
int i = 0; i < ar_num_wheels; i++)
 
  410             float wspeed = *(
float*)(ptr);
 
  412             ptr += 
sizeof(float);
 
  416         for (
size_t i = 0; i < m_prop_anim_key_states.size(); i++)
 
  419             char byte = *(ptr + (i / 8));
 
  420             char mask = char(1) << (7 - (i % 8));
 
  421             m_prop_anim_key_states[i].anim_active = (
byte & mask);
 
  426         if (!m_net_initialized)
 
  434             strncpy(reg.
name, ar_filename.c_str(), 128);
 
  443             text << info.
username << 
_L(
" content mismatch: ") << reg.name;
 
  450             m_net_initialized = 
true;
 
  452         RoR::LogFormat(
"[RoR|Network] Stream mismatch, filename: '%s'", ar_filename.c_str());
 
  457     if (!m_net_initialized)
 
  461         int rnow = std::max(0, tnow + 
App::GetGameContext()->GetActorManager()->GetNetTimeOffset(ar_net_source_id));
 
  462         if (oob->
time > rnow + 100)
 
  468     m_net_updates.push_back(update);
 
  469 #endif // USE_SOCKETW 
  472 void Actor::calcNetwork()
 
  476     if (m_net_updates.size() < 2)
 
  480     int rnow = std::max(0, tnow + 
App::GetGameContext()->GetActorManager()->GetNetTimeOffset(ar_net_source_id));
 
  483     int index_offset = 0;
 
  484     for (
int i = 0; i < m_net_updates.size() - 1; i++)
 
  487         if (oob->
time > rnow)
 
  494     char*        netb1 = (
char*)        m_net_updates[index_offset    ].node_data.data();
 
  495     char*        netb2 = (
char*)        m_net_updates[index_offset + 1].node_data.data();
 
  496     float*     net_rp1 = (
float*)       m_net_updates[index_offset    ].wheel_data.data();
 
  497     float*     net_rp2 = (
float*)       m_net_updates[index_offset + 1].wheel_data.data();
 
  499     float tratio = (float)(rnow - oob1->
time) / (float)(oob2->
time - oob1->
time);
 
  503         m_net_updates.clear();
 
  506     else if (tratio > 1.0f)
 
  510     else if (index_offset == 0 && (m_net_updates.size() > 5 || (tratio < 0.125f && m_net_updates.size() > 2)))
 
  515     half_float::half* halfb1 = 
reinterpret_cast<half_float::half*
>(netb1 + 
sizeof(float) * 3);
 
  516     half_float::half* halfb2 = 
reinterpret_cast<half_float::half*
>(netb2 + 
sizeof(float) * 3);
 
  517     Vector3 p1ref = Vector3::ZERO;
 
  518     Vector3 p2ref = Vector3::ZERO;
 
  519     Vector3 p1 = Vector3::ZERO;
 
  520     Vector3 p2 = Vector3::ZERO;
 
  522     for (
int i = 0; i < m_net_first_wheel_node; i++)
 
  527             p1.x = ((
float*)netb1)[0];
 
  528             p1.y = ((
float*)netb1)[1];
 
  529             p1.z = ((
float*)netb1)[2];
 
  532             p2.x = ((
float*)netb2)[0];
 
  533             p2.y = ((
float*)netb2)[1];
 
  534             p2.z = ((
float*)netb2)[2];
 
  540             const int bufpos = (i - 1) * 3;
 
  541             const Vector3 p1rel(halfb1[bufpos + 0], halfb1[bufpos + 1], halfb1[bufpos + 2]);
 
  542             const Vector3 p2rel(halfb2[bufpos + 0], halfb2[bufpos + 1], halfb2[bufpos + 2]);
 
  549         ar_nodes[i].AbsPosition = p1 + tratio * (p2 - p1);
 
  550         ar_nodes[i].RelPosition = ar_nodes[i].AbsPosition - ar_origin;
 
  551         ar_nodes[i].Velocity    = (p2 - p1) * 1000.0f / (
float)(oob2->
time - oob1->
time);
 
  554     for (
int i = 0; i < ar_num_wheels; i++)
 
  556         float rp = net_rp1[i] + tratio * (net_rp2[i] - net_rp1[i]);
 
  558         Vector3 axis = ar_wheels[i].wh_axis_node_1->RelPosition - ar_wheels[i].wh_axis_node_0->RelPosition;
 
  560         Plane pplan = Plane(axis, ar_wheels[i].wh_axis_node_0->AbsPosition);
 
  561         Vector3 ortho = -pplan.projectVector(ar_wheels[i].wh_near_attach_node->AbsPosition) - ar_wheels[i].wh_axis_node_0->AbsPosition;
 
  562         Vector3 ray = ortho.crossProduct(axis);
 
  564         ray *= ar_wheels[i].wh_radius;
 
  565         float drp = Math::TWO_PI / (ar_wheels[i].wh_num_nodes / 2);
 
  566         for (
int j = 0; j < ar_wheels[i].wh_num_nodes / 2; j++)
 
  568             Vector3 uray = Quaternion(Radian(rp - drp * j), axis) * ray;
 
  570             ar_wheels[i].wh_nodes[j * 2 + 0]->AbsPosition = ar_wheels[i].wh_axis_node_0->AbsPosition + uray;
 
  571             ar_wheels[i].wh_nodes[j * 2 + 0]->RelPosition = ar_wheels[i].wh_nodes[j * 2]->AbsPosition - ar_origin;
 
  573             ar_wheels[i].wh_nodes[j * 2 + 1]->AbsPosition = ar_wheels[i].wh_axis_node_1->AbsPosition + uray;
 
  574             ar_wheels[i].wh_nodes[j * 2 + 1]->RelPosition = ar_wheels[i].wh_nodes[j * 2 + 1]->AbsPosition - ar_origin;
 
  577         ray *= ar_wheels[i].wh_rim_radius;
 
  578         for (
int j = 0; j < ar_wheels[i].wh_num_rim_nodes / 2; j++)
 
  580             Vector3 uray = Quaternion(Radian(rp - drp * j), axis) * ray;
 
  582             ar_wheels[i].wh_rim_nodes[j * 2 + 0]->AbsPosition = ar_wheels[i].wh_axis_node_0->AbsPosition + uray;
 
  583             ar_wheels[i].wh_rim_nodes[j * 2 + 0]->RelPosition = ar_wheels[i].wh_rim_nodes[j * 2]->AbsPosition - ar_origin;
 
  585             ar_wheels[i].wh_rim_nodes[j * 2 + 1]->AbsPosition = ar_wheels[i].wh_axis_node_1->AbsPosition + uray;
 
  586             ar_wheels[i].wh_rim_nodes[j * 2 + 1]->RelPosition = ar_wheels[i].wh_rim_nodes[j * 2 + 1]->AbsPosition - ar_origin;
 
  589     this->UpdateBoundingBoxes();
 
  590     this->calculateAveragePosition();
 
  599     ar_wheel_speed = netwspeed;
 
  609     if (ar_num_aeroengines > 0)
 
  631         ar_engine->pushNetworkState(engspeed, engforce, engclutch, gear, running, contact, automode);
 
  636         toggleCustomParticles();
 
  642     this->setLightStateMask(oob1->
lightmask);
 
  654     for (
int i = 0; i < index_offset; i++)
 
  656         m_net_updates.pop_front();
 
  659     m_net_initialized = 
true;
 
  664     float total_tyre = 0.f; 
int num_tyre = 0;
 
  665     float total_loaded = 0.f; 
int num_loaded = 0;
 
  666     float total_override = 0.f; 
int num_override = 0;
 
  695     LOG(
fmt::format(
"Node masses: total: {} kg, tyre ({} nodes): {} kg, loaded ({} nodes): {} kg, override ({} nodes): {} kg",
 
  697         num_tyre, total_tyre, 
 
  698         num_loaded, total_loaded, 
 
  699         num_override, total_override));
 
  702 void Actor::recalculateNodeMasses()
 
  709         LOG(
fmt::format(
"recalculateNodeMasses() - before reset (dry mass: {} kg, loaded mass: {} kg, prev. calculated total mass: {} kg",
 
  710             ar_dry_mass, ar_load_mass, ar_total_mass));
 
  715     for (
int i = 0; i < ar_num_nodes; i++)
 
  717         if (!ar_nodes[i].nd_tyre_node)
 
  719             if (!ar_nodes[i].nd_loaded_mass)
 
  722                 ar_nodes[i].mass = 0;
 
  724             else if (!ar_nodes[i].nd_override_mass)
 
  727                 ar_nodes[i].mass = ar_load_mass / (float)ar_masscount;
 
  732                 ar_nodes[i].mass = ar_nodes_override_loadweights[i];
 
  739     for (
int i = 0; i < ar_num_beams; i++)
 
  743             Real half_newlen = ar_beams[i].refL / 2.0;
 
  744             if (!ar_beams[i].p1->nd_tyre_node)
 
  746             if (!ar_beams[i].p2->nd_tyre_node)
 
  751     for (
int i = 0; i < ar_num_beams; i++)
 
  755             Real half_mass = ar_beams[i].refL * ar_dry_mass / len / 2.0f;
 
  756             if (!ar_beams[i].p1->nd_tyre_node)
 
  757                 ar_beams[i].p1->mass += half_mass;
 
  758             if (!ar_beams[i].p2->nd_tyre_node)
 
  759                 ar_beams[i].p2->mass += half_mass;
 
  765         LOG(
fmt::format(
"recalculateNodeMasses() - average linear density (total beam len: {}m)", len));
 
  770     for (std::vector<rope_t>::iterator it = ar_ropes.begin(); it != ar_ropes.end(); it++)
 
  772         it->rp_beam->p2->mass = 100.0f;
 
  776     for (
int i = 0; i < this->ar_num_cinecams; ++i)
 
  779         ar_nodes[ar_cinecam_node[i]].mass = m_definition->root_module->cinecam[i].node_mass;
 
  784         LOG(
"recalculateNodeMasses() - ropes and cinecams");
 
  789     for (
int i = 0; i < ar_num_nodes; i++)
 
  791         if (!ar_nodes[i].nd_tyre_node &&
 
  792             !(ar_minimass_skip_loaded_nodes && ar_nodes[i].nd_loaded_mass) &&
 
  793             ar_nodes[i].mass < ar_minimass[i])
 
  798                 snprintf(buf, 300, 
"Node '%d' mass (%f Kg) is too light. Resetting to 'minimass' (%f Kg)", i, ar_nodes[i].mass, ar_minimass[i]);
 
  801             ar_nodes[i].mass = ar_minimass[i];
 
  807         LOG(
fmt::format(
"recalculateNodeMasses() - minimass (ar_minimass_skip_loaded_nodes: {})",
 
  808             ar_minimass_skip_loaded_nodes));
 
  813     for (
int i = 0; i < ar_num_nodes; i++)
 
  817             String msg = 
"Node " + 
TOSTRING(i) + 
" : " + 
TOSTRING((
int)ar_nodes[i].mass) + 
" kg";
 
  818             if (ar_nodes[i].nd_loaded_mass)
 
  820                 if (ar_nodes[i].nd_override_mass)
 
  821                     msg += 
" (overriden by node mass)";
 
  823                     msg += 
" (normal load node: " + 
TOSTRING(ar_load_mass) + 
" kg / " + 
TOSTRING(ar_masscount) + 
" nodes)";
 
  827         ar_total_mass += ar_nodes[i].mass;
 
  829     LOG(
"TOTAL VEHICLE MASS: " + 
TOSTRING((
int)ar_total_mass) +
" kg");
 
  832 float Actor::getTotalMass(
bool withLocked)
 
  834     if (ar_state == ActorState::DISPOSED)
 
  838         return ar_total_mass; 
 
  840     float mass = ar_total_mass;
 
  842     for (
ActorPtr& actor : ar_linked_actors)
 
  844         mass += actor->ar_total_mass;
 
  850 void Actor::DetermineLinkedActors()
 
  855     ar_linked_actors.clear();
 
  858     std::map<ActorPtr, bool> lookup_table; 
 
  860     lookup_table.insert(std::pair<ActorPtr, bool>(
this, 
false));
 
  866         for (
auto it_actor = lookup_table.begin(); it_actor != lookup_table.end(); ++it_actor)
 
  868             if (!it_actor->second) 
 
  873                     auto actor_pair = inter_actor_link.second;
 
  874                     if (actor == actor_pair.first || actor == actor_pair.second)
 
  876                         auto other_actor = (actor != actor_pair.first) ? actor_pair.first : actor_pair.second;
 
  877                         auto ret = lookup_table.insert(std::pair<ActorPtr, bool>(other_actor, 
false));
 
  880                             ar_linked_actors.push_back(other_actor);
 
  885                 it_actor->second = 
true; 
 
  891 int Actor::getWheelNodeCount()
 const 
  893     return m_wheel_node_count;
 
  896 void Actor::calcNodeConnectivityGraph()
 
  900     ar_node_to_node_connections.resize(ar_num_nodes, std::vector<int>());
 
  901     ar_node_to_beam_connections.resize(ar_num_nodes, std::vector<int>());
 
  903     for (i = 0; i < ar_num_beams; i++)
 
  905         if (ar_beams[i].p1 != NULL && ar_beams[i].p2 != NULL && ar_beams[i].p1->pos >= 0 && ar_beams[i].p2->pos >= 0)
 
  907             ar_node_to_node_connections[ar_beams[i].p1->pos].push_back(ar_beams[i].p2->pos);
 
  908             ar_node_to_beam_connections[ar_beams[i].p1->pos].push_back(i);
 
  909             ar_node_to_node_connections[ar_beams[i].p2->pos].push_back(ar_beams[i].p1->pos);
 
  910             ar_node_to_beam_connections[ar_beams[i].p2->pos].push_back(i);
 
  915 bool Actor::Intersects(
ActorPtr actor, Vector3 offset)
 
  917     Vector3 bb_min = ar_bounding_box.getMinimum() + offset;
 
  918     Vector3 bb_max = ar_bounding_box.getMaximum() + offset;
 
  919     AxisAlignedBox bb = AxisAlignedBox(bb_min, bb_max);
 
  925     for (
int i = 0; i < ar_num_beams; i++)
 
  927         if (!(ar_beams[i].p1->nd_contacter || ar_beams[i].p1->nd_contactable) ||
 
  928             !(ar_beams[i].p2->nd_contacter || ar_beams[i].p2->nd_contactable))
 
  931         Vector3 origin = ar_beams[i].p1->AbsPosition + offset;
 
  932         Vector3 target = ar_beams[i].p2->AbsPosition + offset;
 
  934         Ray ray(origin, target - origin);
 
  943             auto result = Ogre::Math::intersects(ray, a, b, c);
 
  944             if (result.first && result.second < 1.0f)
 
  961         Ray ray(origin, target - origin);
 
  963         for (
int j = 0; j < ar_num_collcabs; j++)
 
  965             int index = ar_collcabs[j] * 3;
 
  966             Vector3 a = ar_nodes[ar_cabs[index + 0]].AbsPosition + offset;
 
  967             Vector3 b = ar_nodes[ar_cabs[index + 1]].AbsPosition + offset;
 
  968             Vector3 c = ar_nodes[ar_cabs[index + 2]].AbsPosition + offset;
 
  970             auto result = Ogre::Math::intersects(ray, a, b, c);
 
  971             if (result.first && result.second < 1.0f)
 
  981 Vector3 Actor::calculateCollisionOffset(Vector3 direction)
 
  983     if (direction == Vector3::ZERO)
 
  984         return Vector3::ZERO;
 
  986     Real max_distance = direction.normalise();
 
  989     Vector3 collision_offset = Vector3::ZERO;
 
  991     while (collision_offset.length() < max_distance)
 
  993         Vector3 bb_min = ar_bounding_box.getMinimum() + collision_offset;
 
  994         Vector3 bb_max = ar_bounding_box.getMaximum() + collision_offset;
 
  995         AxisAlignedBox bb = AxisAlignedBox(bb_min, bb_max);
 
  997         bool collision = 
false;
 
 1003             if (!bb.intersects(actor->ar_bounding_box))
 
 1007             if (m_intra_point_col_detector)
 
 1009                 for (
int i = 0; i < actor->ar_num_collcabs; i++)
 
 1011                     int tmpv = actor->ar_collcabs[i] * 3;
 
 1012                     node_t* no = &actor->ar_nodes[actor->ar_cabs[tmpv]];
 
 1013                     node_t* na = &actor->ar_nodes[actor->ar_cabs[tmpv + 1]];
 
 1014                     node_t* nb = &actor->ar_nodes[actor->ar_cabs[tmpv + 2]];
 
 1016                     m_intra_point_col_detector->query(no->
AbsPosition - collision_offset,
 
 1019                         actor->ar_collision_range * 3.0f);
 
 1021                     if (collision = !m_intra_point_col_detector->hit_list.empty())
 
 1029             float proximity = std::max(.05f, std::sqrt(std::max(m_min_camera_radius, actor->m_min_camera_radius)) / 50.f);
 
 1032             for (
int i = 0; i < ar_num_nodes; i++)
 
 1034                 if (!ar_nodes[i].nd_contacter && !ar_nodes[i].nd_contactable)
 
 1037                 Vector3 query_position = ar_nodes[i].AbsPosition + collision_offset;
 
 1039                 for (
int j = 0; j < actor->ar_num_nodes; j++)
 
 1041                     if (!actor->ar_nodes[j].nd_contacter && !actor->ar_nodes[j].nd_contactable)
 
 1044                     if (collision = query_position.squaredDistance(actor->ar_nodes[j].AbsPosition) < proximity)
 
 1057         if (!collision && m_inter_point_col_detector)
 
 1059             for (
int i = 0; i < ar_num_collcabs; i++)
 
 1061                 int tmpv = ar_collcabs[i] * 3;
 
 1062                 node_t* no = &ar_nodes[ar_cabs[tmpv]];
 
 1063                 node_t* na = &ar_nodes[ar_cabs[tmpv + 1]];
 
 1064                 node_t* nb = &ar_nodes[ar_cabs[tmpv + 2]];
 
 1066                 m_inter_point_col_detector->query(no->
AbsPosition + collision_offset,
 
 1069                     ar_collision_range * 3.0f);
 
 1071                 if (collision = !m_inter_point_col_detector->hit_list.empty())
 
 1083                 if (collision = this->Intersects(actor, collision_offset))
 
 1091         collision_offset += direction * 0.05f;
 
 1094     return collision_offset;
 
 1097 void Actor::resolveCollisions(Ogre::Vector3 direction)
 
 1099     if (m_intra_point_col_detector)
 
 1100         m_intra_point_col_detector->UpdateIntraPoint(
true);
 
 1102     if (m_inter_point_col_detector)
 
 1103         m_inter_point_col_detector->UpdateInterPoint(
true);
 
 1105     Vector3 offset = calculateCollisionOffset(direction);
 
 1107     if (offset == Vector3::ZERO)
 
 1111     offset += 0.2f * Vector3(offset.x, 0.0f, offset.z).normalisedCopy();
 
 1113     resetPosition(ar_nodes[0].AbsPosition.x + offset.x, ar_nodes[0].AbsPosition.z + offset.z, 
false, this->getMinHeight() + offset.y);
 
 1116 void Actor::resolveCollisions(
float max_distance, 
bool consider_up)
 
 1118     if (m_intra_point_col_detector)
 
 1119         m_intra_point_col_detector->UpdateIntraPoint(
true);
 
 1121     if (m_inter_point_col_detector)
 
 1122         m_inter_point_col_detector->UpdateInterPoint(
true);
 
 1124     Vector3 u = Vector3::UNIT_Y;
 
 1125     Vector3 f = Vector3(getDirection().
x, 0.0f, getDirection().
z).normalisedCopy();
 
 1126     Vector3 l = u.crossProduct(f);
 
 1129     Vector3 left  = calculateCollisionOffset(+l * max_distance);
 
 1130     Vector3 right = calculateCollisionOffset(-l * left.length());
 
 1131     Vector3 lateral = left.length() < right.length() * 1.1f ? left : right;
 
 1133     Vector3 front = calculateCollisionOffset(+f * lateral.length());
 
 1134     Vector3 back  = calculateCollisionOffset(-f * front.length());
 
 1135     Vector3 sagittal = front.length() < back.length() * 1.1f ? front : back;
 
 1137     Vector3 offset = lateral.length() < sagittal.length() * 1.2f ? lateral : sagittal;
 
 1141         Vector3 up = calculateCollisionOffset(+u * offset.length());
 
 1142         if (up.length() * 1.2f < offset.length())
 
 1146     if (offset == Vector3::ZERO)
 
 1150     offset += 0.2f * Vector3(offset.x, 0.0f, offset.z).normalisedCopy();
 
 1152     resetPosition(ar_nodes[0].AbsPosition.x + offset.x, ar_nodes[0].AbsPosition.z + offset.z, 
true, this->getMinHeight() + offset.y);
 
 1155 void Actor::calculateAveragePosition()
 
 1160         m_avg_node_position = ar_nodes[ar_custom_camera_node].AbsPosition;
 
 1162     else if (ar_extern_camera_mode == ExtCameraMode::CINECAM && ar_num_cinecams > 0)
 
 1165         m_avg_node_position = ar_nodes[ar_cinecam_node[0]].AbsPosition;
 
 1167     else if (ar_extern_camera_mode == ExtCameraMode::NODE && ar_extern_camera_node != 
NODENUM_INVALID)
 
 1170         m_avg_node_position = ar_nodes[ar_extern_camera_node].AbsPosition;
 
 1175         Vector3 aposition = Vector3::ZERO;
 
 1176         for (
int n = 0; n < ar_num_nodes; n++)
 
 1178             aposition += ar_nodes[n].AbsPosition;
 
 1180         m_avg_node_position = aposition / ar_num_nodes;
 
 1190 void Actor::UpdateBoundingBoxes()
 
 1193     ar_bounding_box = AxisAlignedBox::BOX_NULL;
 
 1194     ar_predicted_bounding_box = AxisAlignedBox::BOX_NULL;
 
 1195     ar_evboxes_bounding_box = AxisAlignedBox::BOX_NULL;
 
 1196     for (
size_t i = 0; i < ar_collision_bounding_boxes.size(); ++i)
 
 1198         ar_collision_bounding_boxes[i] = AxisAlignedBox::BOX_NULL;
 
 1199         ar_predicted_coll_bounding_boxes[i] = AxisAlignedBox::BOX_NULL;
 
 1204     const float CABNODE_MAX_CAMDIST = 15.f;
 
 1205     const Ogre::Vector3 mainCamPos = ar_nodes[ar_main_camera_node_pos].RelPosition;
 
 1208     for (
int i = 0; i < ar_num_nodes; i++)
 
 1210         Vector3 vel = ar_nodes[i].Velocity;
 
 1211         Vector3 pos = ar_nodes[i].AbsPosition;
 
 1212         int16_t cid = ar_nodes[i].nd_coll_bbox_id;
 
 1214         ar_bounding_box.merge(pos);                                  
 
 1215         if (mainCamPos.squaredDistance(ar_nodes[i].RelPosition) < (CABNODE_MAX_CAMDIST*CABNODE_MAX_CAMDIST))
 
 1217             ar_evboxes_bounding_box.merge(pos);
 
 1219         ar_predicted_bounding_box.merge(pos);                        
 
 1220         ar_predicted_bounding_box.merge(pos + vel);                  
 
 1221         if (cid != node_t::INVALID_BBOX)
 
 1223             ar_collision_bounding_boxes[cid].merge(pos);
 
 1224             ar_predicted_coll_bounding_boxes[cid].merge(pos);
 
 1225             ar_predicted_coll_bounding_boxes[cid].merge(pos + vel);
 
 1232     for (
size_t i = 0; i < ar_collision_bounding_boxes.size(); ++i)
 
 1239 void Actor::UpdatePhysicsOrigin()
 
 1241     if (ar_nodes[0].RelPosition.squaredLength() > 10000.0)
 
 1243         Vector3 offset = ar_nodes[0].RelPosition;
 
 1244         ar_origin += offset;
 
 1245         for (
int i = 0; i < ar_num_nodes; i++)
 
 1247             ar_nodes[i].RelPosition -= offset;
 
 1252 void Actor::ResetAngle(
float rot)
 
 1255     Vector3 origin = ar_nodes[ar_main_camera_node_pos].AbsPosition;
 
 1259     matrix.FromEulerAnglesXYZ(Radian(0), Radian(-rot + m_spawn_rotation), Radian(0));
 
 1261     for (
int i = 0; i < ar_num_nodes; i++)
 
 1264         ar_nodes[i].AbsPosition -= origin;
 
 1265         ar_nodes[i].AbsPosition = matrix * ar_nodes[i].AbsPosition;
 
 1266         ar_nodes[i].AbsPosition += origin;
 
 1267         ar_nodes[i].RelPosition = ar_nodes[i].AbsPosition - this->ar_origin;
 
 1270     this->UpdateBoundingBoxes();
 
 1271     calculateAveragePosition();
 
 1274 void Actor::updateInitPosition()
 
 1276     for (
int i = 0; i < ar_num_nodes; i++)
 
 1278         ar_initial_node_positions[i] = ar_nodes[i].AbsPosition;
 
 1282 void Actor::resetPosition(
float px, 
float pz, 
bool setInitPosition, 
float miny)
 
 1285     Vector3 offset = Vector3(px, ar_nodes[0].AbsPosition.y, pz) - ar_nodes[0].AbsPosition;
 
 1286     for (
int i = 0; i < ar_num_nodes; i++)
 
 1288         ar_nodes[i].AbsPosition += offset;
 
 1289         ar_nodes[i].RelPosition = ar_nodes[i].AbsPosition - ar_origin;
 
 1293     float vertical_offset = miny - this->getMinHeight();
 
 1296         vertical_offset += std::max(0.0f, 
App::GetGameContext()->GetTerrain()->getWater()->GetStaticWaterHeight() - miny);
 
 1298     for (
int i = 1; i < ar_num_nodes; i++)
 
 1300         if (ar_nodes[i].nd_no_ground_contact)
 
 1303         vertical_offset += std::max(0.0f, terrainHeight - (ar_nodes[i].AbsPosition.y + vertical_offset));
 
 1305     for (
int i = 0; i < ar_num_nodes; i++)
 
 1307         ar_nodes[i].AbsPosition.y += vertical_offset;
 
 1308         ar_nodes[i].RelPosition = ar_nodes[i].AbsPosition - ar_origin;
 
 1312     float mesh_offset = 0.0f;
 
 1313     for (
int i = 0; i < ar_num_nodes; i++)
 
 1315         if (mesh_offset >= 1.0f)
 
 1317         if (ar_nodes[i].nd_no_ground_contact)
 
 1319         float offset = mesh_offset;
 
 1320         while (offset < 1.0f)
 
 1322             Vector3 query = ar_nodes[i].AbsPosition + Vector3(0.0f, offset, 0.0f);
 
 1323             if (!
App::GetGameContext()->GetTerrain()->GetCollisions()->collisionCorrect(&query, 
false))
 
 1325                 mesh_offset = offset;
 
 1331     for (
int i = 0; i < ar_num_nodes; i++)
 
 1333         ar_nodes[i].AbsPosition.y += mesh_offset;
 
 1334         ar_nodes[i].RelPosition = ar_nodes[i].AbsPosition - ar_origin;
 
 1337     resetPosition(Vector3::ZERO, setInitPosition);
 
 1340 void Actor::resetPosition(Ogre::Vector3 translation, 
bool setInitPosition)
 
 1343     if (translation != Vector3::ZERO)
 
 1345         Vector3 offset = translation - ar_nodes[0].AbsPosition;
 
 1346         for (
int i = 0; i < ar_num_nodes; i++)
 
 1348             ar_nodes[i].AbsPosition += offset;
 
 1349             ar_nodes[i].RelPosition = ar_nodes[i].AbsPosition - ar_origin;
 
 1353     if (setInitPosition)
 
 1355         for (
int i = 0; i < ar_num_nodes; i++)
 
 1357             ar_initial_node_positions[i] = ar_nodes[i].AbsPosition;
 
 1361     this->UpdateBoundingBoxes();
 
 1362     calculateAveragePosition();
 
 1365 void Actor::softRespawn(Ogre::Vector3 spawnpos, Ogre::Quaternion spawnrot)
 
 1368     this->SyncReset( 
false);
 
 1371     ar_origin = spawnpos;
 
 1372     for (
NodeNum_t i = 0; i < ar_num_nodes; i++)
 
 1374         ar_nodes[i].AbsPosition = spawnpos + ar_nodes_spawn_offsets[i];
 
 1375         ar_nodes[i].RelPosition = ar_nodes_spawn_offsets[i];
 
 1376         ar_nodes[i].Forces = Ogre::Vector3::ZERO;
 
 1377         ar_nodes[i].Velocity = Ogre::Vector3::ZERO;
 
 1382     for (
NodeNum_t i = 0; i < ar_num_nodes; i++)
 
 1384         ar_nodes[i].AbsPosition = spawnpos + spawnrot * (ar_nodes[i].AbsPosition - spawnpos);
 
 1385         ar_nodes[i].RelPosition = ar_nodes[i].AbsPosition - ar_origin;
 
 1389 void Actor::mouseMove(
NodeNum_t node, Vector3 pos, 
float force)
 
 1391     m_mouse_grab_node = node;
 
 1392     m_mouse_grab_move_force = force * std::pow(ar_total_mass / 3000.0f, 0.75f);
 
 1393     m_mouse_grab_pos = pos;
 
 1396 void Actor::toggleWheelDiffMode()
 
 1398     for (
int i = 0; i < m_num_wheel_diffs; ++i)
 
 1400         m_wheel_diffs[i]->ToggleDifferentialMode();
 
 1404 void Actor::toggleAxleDiffMode()
 
 1406     for (
int i = 0; i < m_num_axle_diffs; ++i)
 
 1408         m_axle_diffs[i]->ToggleDifferentialMode();
 
 1412 void Actor::displayAxleDiffMode()
 
 1414     if (m_num_axle_diffs == 0)
 
 1417                 _L(
"No inter-axle differential installed on current vehicle!"), 
"error.png");
 
 1421         String message = 
"";
 
 1422         for (
int i = 0; i < m_num_axle_diffs; ++i)
 
 1424             if (m_axle_diffs[i])
 
 1429                 int a1 = m_axle_diffs[i]->di_idx_1 + 1;
 
 1430                 int a2 = m_axle_diffs[i]->di_idx_2 + 1;
 
 1432                 message += m_axle_diffs[i]->GetDifferentialTypeName();
 
 1436                 "Inter-axle differentials:\n" + message, 
"cog.png");
 
 1440 void Actor::displayWheelDiffMode()
 
 1442     if (m_num_wheel_diffs == 0)
 
 1445                 _L(
"No inter-wheel differential installed on current vehicle!"), 
"error.png");
 
 1449         String message = 
"";
 
 1450         for (
int i = 0; i < m_num_wheel_diffs; ++i)
 
 1452             if (m_wheel_diffs[i])
 
 1457                 message += 
_L(
"Axle ") + 
TOSTRING(i + 1) + 
": ";
 
 1458                 message += m_wheel_diffs[i]->GetDifferentialTypeName();
 
 1462                 "Inter-wheel differentials:\n" + message, 
"cog.png");
 
 1466 void Actor::displayTransferCaseMode()
 
 1468     if (m_transfer_case)
 
 1471                 _L(
"Transfercase switched to: ") + this->getTransferCaseName(), 
"cog.png");
 
 1476                 _L(
"No transfercase installed on current vehicle!"), 
"error.png");
 
 1480 void Actor::toggleTransferCaseMode()
 
 1482     if (!ar_engine || !m_transfer_case || m_transfer_case->tr_ax_2 < 0 || !m_transfer_case->tr_2wd)
 
 1485     if (m_transfer_case->tr_4wd_mode && !m_transfer_case->tr_2wd_lo)
 
 1487         for (
int i = 0; i < m_transfer_case->tr_gear_ratios.size(); i++)
 
 1489             this->toggleTransferCaseGearRatio();
 
 1490             if (m_transfer_case->tr_gear_ratios[0] == 1.0f)
 
 1495     m_transfer_case->tr_4wd_mode = !m_transfer_case->tr_4wd_mode;
 
 1497     if (m_transfer_case->tr_4wd_mode)
 
 1499         ar_wheels[m_wheel_diffs[m_transfer_case->tr_ax_2]->di_idx_1].wh_propulsed = WheelPropulsion::FORWARD;
 
 1500         ar_wheels[m_wheel_diffs[m_transfer_case->tr_ax_2]->di_idx_2].wh_propulsed = WheelPropulsion::FORWARD;
 
 1501         m_num_proped_wheels += 2;
 
 1505         ar_wheels[m_wheel_diffs[m_transfer_case->tr_ax_2]->di_idx_1].wh_propulsed = WheelPropulsion::FORWARD;
 
 1506         ar_wheels[m_wheel_diffs[m_transfer_case->tr_ax_2]->di_idx_2].wh_propulsed = WheelPropulsion::FORWARD;
 
 1507         m_num_proped_wheels -= 2;
 
 1511 void Actor::toggleTransferCaseGearRatio()
 
 1513     if (!ar_engine || !m_transfer_case || m_transfer_case->tr_gear_ratios.size() < 2)
 
 1516     if (m_transfer_case->tr_4wd_mode || m_transfer_case->tr_2wd_lo)
 
 1518         auto gear_ratios = &m_transfer_case->tr_gear_ratios;
 
 1519         std::rotate(gear_ratios->begin(), gear_ratios->begin() + 1, gear_ratios->end());
 
 1521         ar_engine->setTCaseRatio(m_transfer_case->tr_gear_ratios[0]);
 
 1525 String Actor::getTransferCaseName()
 
 1528     if (m_transfer_case)
 
 1530         name += m_transfer_case->tr_4wd_mode ? 
"4WD " : 
"2WD ";
 
 1531         if (m_transfer_case->tr_gear_ratios[0] > 1.0f)
 
 1532             name += 
"Lo (" + 
TOSTRING(m_transfer_case->tr_gear_ratios[0]) + 
":1)";
 
 1539 Ogre::Vector3 Actor::getRotationCenter()
 
 1541     Vector3 sum = Vector3::ZERO;
 
 1542     std::vector<Vector3> positions;
 
 1543     for (
int i = 0; i < ar_num_nodes; i++)
 
 1545         Vector3 pos = ar_nodes[i].AbsPosition;
 
 1546         const auto it = std::find_if(positions.begin(), positions.end(),
 
 1547             [pos](
const Vector3 ref) { return pos.positionEquals(ref, 0.01f); });
 
 1548         if (it == positions.end())
 
 1551             positions.push_back(pos);
 
 1554     return sum / positions.size();
 
 1557 float Actor::getMinHeight(
bool skip_virtual_nodes)
 
 1559     float height = std::numeric_limits<float>::max(); 
 
 1560     for (
int i = 0; i < ar_num_nodes; i++)
 
 1562         if (!skip_virtual_nodes || !ar_nodes[i].nd_no_ground_contact)
 
 1564             height = std::min(ar_nodes[i].AbsPosition.y, height);
 
 1567     return (!skip_virtual_nodes || height < std::numeric_limits<float>::max()) ? height : getMinHeight(
false);
 
 1570 float Actor::getMaxHeight(
bool skip_virtual_nodes)
 
 1572     float height = std::numeric_limits<float>::min(); 
 
 1573     for (
int i = 0; i < ar_num_nodes; i++)
 
 1575         if (!skip_virtual_nodes || !ar_nodes[i].nd_no_ground_contact)
 
 1577             height = std::max(height, ar_nodes[i].AbsPosition.y);
 
 1580     return (!skip_virtual_nodes || height > std::numeric_limits<float>::min()) ? height : getMaxHeight(
false);
 
 1583 float Actor::getHeightAboveGround(
bool skip_virtual_nodes)
 
 1585     float agl = std::numeric_limits<float>::max(); 
 
 1586     for (
int i = 0; i < ar_num_nodes; i++)
 
 1588         if (!skip_virtual_nodes || !ar_nodes[i].nd_no_ground_contact)
 
 1590             Vector3 pos = ar_nodes[i].AbsPosition;
 
 1594     return (!skip_virtual_nodes || agl < std::numeric_limits<float>::max()) ? agl : getHeightAboveGround(
false);
 
 1597 float Actor::getHeightAboveGroundBelow(
float height, 
bool skip_virtual_nodes)
 
 1599     float agl = std::numeric_limits<float>::max(); 
 
 1600     for (
int i = 0; i < ar_num_nodes; i++)
 
 1602         if (!skip_virtual_nodes || !ar_nodes[i].nd_no_ground_contact)
 
 1604             Vector3 pos = ar_nodes[i].AbsPosition;
 
 1608     return (!skip_virtual_nodes || agl < std::numeric_limits<float>::max()) ? agl : getHeightAboveGroundBelow(height, 
false);
 
 1611 void Actor::reset(
bool keep_position)
 
 1613     if (ar_state == ActorState::DISPOSED)
 
 1618     rq->
amr_type  = (keep_position) ? ActorModifyRequest::Type::RESET_ON_SPOT : ActorModifyRequest::Type::RESET_ON_INIT_POS;
 
 1622 void Actor::SoftReset()
 
 1626     float agl = this->getHeightAboveGroundBelow(this->getMaxHeight(
true), 
true);
 
 1630         agl = std::min(this->getMinHeight(
true) - 
App::GetGameContext()->GetTerrain()->getWater()->GetStaticWaterHeight(), agl);
 
 1635         Vector3 translation = -agl * Vector3::UNIT_Y;
 
 1636         this->resetPosition(ar_nodes[0].AbsPosition + translation, 
false);
 
 1637         for (
ActorPtr& actor : ar_linked_actors)
 
 1639             actor->resetPosition(actor->ar_nodes[0].AbsPosition + translation, 
false);
 
 1643     m_ongoing_reset = 
true;
 
 1646 void Actor::SyncReset(
bool reset_position)
 
 1650     m_reset_timer.reset();
 
 1652     m_camera_local_gforces_cur = Vector3::ZERO;
 
 1653     m_camera_local_gforces_max = Vector3::ZERO;
 
 1655     ar_hydro_dir_state = 0.0;
 
 1656     ar_hydro_aileron_state = 0.0;
 
 1657     ar_hydro_rudder_state = 0.0;
 
 1658     ar_hydro_elevator_state = 0.0;
 
 1659     ar_hydro_dir_wheel_display = 0.0;
 
 1661     ar_fusedrag = Vector3::ZERO;
 
 1663     ar_parking_brake = 
false;
 
 1664     ar_trailer_parking_brake = 
false;
 
 1665     ar_avg_wheel_speed = 0.0f;
 
 1666     ar_wheel_speed = 0.0f;
 
 1667     ar_wheel_spin = 0.0f;
 
 1670     ar_origin = Vector3::ZERO;
 
 1671     float cur_rot = getRotation();
 
 1672     Vector3 cur_position = ar_nodes[0].AbsPosition;
 
 1674     this->DisjoinInterActorBeams(); 
 
 1676     for (
int i = 0; i < ar_num_nodes; i++)
 
 1678         ar_nodes[i].AbsPosition = ar_initial_node_positions[i];
 
 1679         ar_nodes[i].RelPosition = ar_nodes[i].AbsPosition - ar_origin;
 
 1680         ar_nodes[i].Velocity = Vector3::ZERO;
 
 1681         ar_nodes[i].Forces = Vector3::ZERO;
 
 1684     for (
int i = 0; i < ar_num_beams; i++)
 
 1686         ar_beams[i].maxposstress    = ar_beams[i].default_beam_deform;
 
 1687         ar_beams[i].maxnegstress    = -ar_beams[i].default_beam_deform;
 
 1688         ar_beams[i].minmaxposnegstress = ar_beams[i].default_beam_deform;
 
 1689         ar_beams[i].strength        = ar_beams[i].initial_beam_strength;
 
 1690         ar_beams[i].L               = ar_beams[i].refL;
 
 1691         ar_beams[i].stress          = 0.0;
 
 1692         ar_beams[i].bm_broken       = 
false;
 
 1693         ar_beams[i].bm_disabled     = 
false;
 
 1696     this->applyNodeBeamScales();
 
 1700     for (
auto& h : ar_hooks)
 
 1702         h.hk_beam->bm_disabled = 
true; 
 
 1705     for (
auto& t : ar_ties)
 
 1707         t.ti_locked_ropable = 
nullptr; 
 
 1708         t.ti_beam->bm_disabled = 
true; 
 
 1713     for (
auto& r : ar_ropables)
 
 1715         r.attached_ties = 0;
 
 1716         r.attached_ropes = 0;
 
 1719     for (
int i = 0; i < ar_num_wheels; i++)
 
 1721         ar_wheels[i].wh_speed = 0.0;
 
 1722         ar_wheels[i].wh_torque = 0.0;
 
 1723         ar_wheels[i].wh_avg_speed = 0.0;
 
 1724         ar_wheels[i].wh_is_detached = 
false;
 
 1731             ar_engine->startEngine();
 
 1733         ar_engine->setWheelSpin(0.0f);
 
 1736     int num_axle_diffs = (m_transfer_case && m_transfer_case->tr_4wd_mode) ? m_num_axle_diffs + 1 : m_num_axle_diffs;
 
 1737     for (
int i = 0; i < num_axle_diffs; i++)
 
 1738         m_axle_diffs[i]->di_delta_rotation = 0.0f;
 
 1739     for (
int i = 0; i < m_num_wheel_diffs; i++)
 
 1740         m_wheel_diffs[i]->di_delta_rotation = 0.0f;
 
 1741     for (
int i = 0; i < ar_num_aeroengines; i++)
 
 1742         ar_aeroengines[i]->reset();
 
 1743     for (
int i = 0; i < ar_num_screwprops; i++)
 
 1744         ar_screwprops[i]->reset();
 
 1745     for (
int i = 0; i < ar_num_rotators; i++)
 
 1746         ar_rotators[i].angle = 0.0;
 
 1747     for (
int i = 0; i < ar_num_wings; i++)
 
 1748         ar_wings[i].fa->broken = 
false;
 
 1750         this->ar_autopilot->reset();
 
 1752         m_buoyance->sink = 
false;
 
 1756         hydrobeam.hb_inertia.ResetCmdKeyDelay();
 
 1759     this->GetGfxActor()->ResetFlexbodies();
 
 1762     if (!reset_position)
 
 1764         this->ResetAngle(cur_rot);
 
 1765         this->resetPosition(cur_position, 
false);
 
 1766         float agl = this->getHeightAboveGroundBelow(this->getMaxHeight(
true), 
true);
 
 1769             agl = std::min(this->getMinHeight(
true) - 
App::GetGameContext()->GetTerrain()->getWater()->GetStaticWaterHeight(), agl);
 
 1773             this->resetPosition(ar_nodes[0].AbsPosition - agl * Vector3::UNIT_Y, 
false);
 
 1778         this->UpdateBoundingBoxes();
 
 1779         this->calculateAveragePosition();
 
 1784         ar_command_key[i].commandValue = 0.0;
 
 1785         ar_command_key[i].triggerInputValue = 0.0f;
 
 1786         ar_command_key[i].playerInputValue = 0.0f;
 
 1787         for (
auto& b : ar_command_key[i].beams)
 
 1789             b.cmb_state->auto_moving_mode = 0;
 
 1790             b.cmb_state->pressed_center_mode = 
false;
 
 1794     this->resetSlideNodes();
 
 1795     if (m_slidenodes_locked)
 
 1797         this->toggleSlideNodeLock(); 
 
 1800     m_ongoing_reset = 
true;
 
 1803 void Actor::applyNodeBeamScales()
 
 1805     for (
int i = 0; i < ar_num_beams; i++)
 
 1807         if ((ar_beams[i].p1->nd_tyre_node || ar_beams[i].p1->nd_rim_node) ||
 
 1808             (ar_beams[i].p2->nd_tyre_node || ar_beams[i].p2->nd_rim_node))
 
 1810             ar_beams[i].k = ar_initial_beam_defaults[i].first * ar_nb_wheels_scale.first;
 
 1811             ar_beams[i].d = ar_initial_beam_defaults[i].second * ar_nb_wheels_scale.second;
 
 1813         else if (ar_beams[i].bounded == 
SHOCK1 || ar_beams[i].bounded == 
SHOCK2 || ar_beams[i].bounded == 
SHOCK3)
 
 1815             ar_beams[i].k = ar_initial_beam_defaults[i].first * ar_nb_shocks_scale.first;;
 
 1816             ar_beams[i].d = ar_initial_beam_defaults[i].second * ar_nb_shocks_scale.second;
 
 1820             ar_beams[i].k = ar_initial_beam_defaults[i].first * ar_nb_beams_scale.first;
 
 1821             ar_beams[i].d = ar_initial_beam_defaults[i].second * ar_nb_beams_scale.second;
 
 1826 void Actor::ForceFeedbackStep(
int steps)
 
 1828     m_force_sensors.out_body_forces = m_force_sensors.accu_body_forces / steps;
 
 1829     if (!ar_hydros.empty()) 
 
 1831         m_force_sensors.out_hydros_forces = (m_force_sensors.accu_hydros_forces / steps) / ar_hydros.size();    
 
 1835 void Actor::HandleAngelScriptEvents(
float dt)
 
 1837 #ifdef USE_ANGELSCRIPT 
 1839     if (m_water_contact && !m_water_contact_old)
 
 1841         m_water_contact_old = m_water_contact;
 
 1844 #endif // USE_ANGELSCRIPT 
 1847 void Actor::searchBeamDefaults()
 
 1851     auto old_beams_scale = ar_nb_beams_scale;
 
 1852     auto old_shocks_scale = ar_nb_shocks_scale;
 
 1853     auto old_wheels_scale = ar_nb_wheels_scale;
 
 1855     if (ar_nb_initialized)
 
 1857         ar_nb_beams_scale.first   = Math::RangeRandom(ar_nb_beams_k_interval.first,  ar_nb_beams_k_interval.second);
 
 1858         ar_nb_beams_scale.second  = Math::RangeRandom(ar_nb_beams_d_interval.first,  ar_nb_beams_d_interval.second);
 
 1859         ar_nb_shocks_scale.first  = Math::RangeRandom(ar_nb_shocks_k_interval.first, ar_nb_shocks_k_interval.second);
 
 1860         ar_nb_shocks_scale.second = Math::RangeRandom(ar_nb_shocks_d_interval.first, ar_nb_shocks_d_interval.second);
 
 1861         ar_nb_wheels_scale.first  = Math::RangeRandom(ar_nb_wheels_k_interval.first, ar_nb_wheels_k_interval.second);
 
 1862         ar_nb_wheels_scale.second = Math::RangeRandom(ar_nb_wheels_d_interval.first, ar_nb_wheels_d_interval.second);
 
 1866         ar_nb_beams_scale.first   = Math::Clamp(1.0f, ar_nb_beams_k_interval.first,  ar_nb_beams_k_interval.second);
 
 1867         ar_nb_beams_scale.second  = Math::Clamp(1.0f, ar_nb_beams_d_interval.first,  ar_nb_beams_d_interval.second);
 
 1868         ar_nb_shocks_scale.first  = Math::Clamp(1.0f, ar_nb_shocks_k_interval.first, ar_nb_shocks_k_interval.second);
 
 1869         ar_nb_shocks_scale.second = Math::Clamp(1.0f, ar_nb_shocks_d_interval.first, ar_nb_shocks_d_interval.second);
 
 1870         ar_nb_wheels_scale.first  = Math::Clamp(1.0f, ar_nb_wheels_k_interval.first, ar_nb_wheels_k_interval.second);
 
 1871         ar_nb_wheels_scale.second = Math::Clamp(1.0f, ar_nb_wheels_d_interval.first, ar_nb_wheels_d_interval.second);
 
 1872         ar_nb_reference = std::vector<float>(ar_nb_reference.size(), std::numeric_limits<float>::max());
 
 1873         ar_nb_optimum   = std::vector<float>(ar_nb_reference.size(), std::numeric_limits<float>::max());
 
 1876     this->applyNodeBeamScales();
 
 1878     m_ongoing_reset = 
false;
 
 1879     this->CalcForcesEulerPrepare(
true);
 
 1880     for (
int i = 0; i < ar_nb_skip_steps; i++)
 
 1882         this->CalcForcesEulerCompute(i == 0, ar_nb_skip_steps);
 
 1883         if (m_ongoing_reset)
 
 1886     m_ongoing_reset = 
true;
 
 1888     float sum_movement = 0.0f;
 
 1889     float movement = 0.0f;
 
 1890     float sum_velocity = 0.0f;
 
 1891     float velocity = 0.0f;
 
 1892     float sum_stress = 0.0f;
 
 1893     float stress = 0.0f;
 
 1895     for (
int k = 0; k < ar_nb_measure_steps; k++)
 
 1897         this->CalcForcesEulerCompute(
false, ar_nb_measure_steps);
 
 1898         for (
int i = 0; i < ar_num_nodes; i++)
 
 1900             float v = ar_nodes[i].Velocity.length();
 
 1901             sum_movement += v / (float)ar_nb_measure_steps;
 
 1902             movement = std::max(movement, v);
 
 1904         for (
int i = 0; i < ar_num_beams; i++)
 
 1906             Vector3 dis = (ar_beams[i].p1->RelPosition - ar_beams[i].p2->RelPosition).normalisedCopy();
 
 1907             float v = (ar_beams[i].p1->Velocity - ar_beams[i].p2->Velocity).dotProduct(dis);
 
 1908             sum_velocity += std::abs(v) / (float)ar_nb_measure_steps;
 
 1909             velocity = std::max(velocity, std::abs(v));
 
 1910             sum_stress += std::abs(ar_beams[i].stress) / (float)ar_nb_measure_steps;
 
 1911             stress = std::max(stress, std::abs(ar_beams[i].stress));
 
 1912             if (k == 0 && ar_beams[i].bm_broken)
 
 1917         if (sum_broken > ar_nb_reference[6] ||
 
 1918                 stress > ar_nb_reference[0] ||     velocity > ar_nb_reference[2] ||     movement > ar_nb_optimum[4] ||
 
 1919             sum_stress > ar_nb_reference[1] || sum_velocity > ar_nb_reference[3] || sum_movement > ar_nb_optimum[5] * 2.f)
 
 1921             ar_nb_beams_scale  = old_beams_scale;
 
 1922             ar_nb_shocks_scale = old_shocks_scale;
 
 1923             ar_nb_wheels_scale = old_wheels_scale;
 
 1930     ar_nb_optimum = {stress, sum_stress, velocity, sum_velocity, movement, sum_movement, (float)sum_broken};
 
 1931     if (!ar_nb_initialized)
 
 1933         ar_nb_reference = ar_nb_optimum;
 
 1935     ar_nb_initialized = 
true;
 
 1938 void Actor::HandleInputEvents(
float dt)
 
 1940     if (!m_ongoing_reset)
 
 1943     if (m_anglesnap_request > 0)
 
 1945         float rotation = Radian(getRotation()).valueDegrees();
 
 1946         float target_rotation = std::round(rotation / m_anglesnap_request) * m_anglesnap_request;
 
 1947         m_rotation_request = -Degree(target_rotation - rotation).valueRadians();
 
 1948     m_rotation_request_center = getRotationCenter();
 
 1949         m_anglesnap_request = 0;
 
 1952     if (m_rotation_request != 0.0f)
 
 1954         Quaternion rot = Quaternion(Radian(m_rotation_request), Vector3::UNIT_Y);
 
 1956         for (
int i = 0; i < ar_num_nodes; i++)
 
 1958             ar_nodes[i].AbsPosition -= m_rotation_request_center;
 
 1959             ar_nodes[i].AbsPosition = rot * ar_nodes[i].AbsPosition;
 
 1960             ar_nodes[i].AbsPosition += m_rotation_request_center;
 
 1961             ar_nodes[i].RelPosition = ar_nodes[i].AbsPosition - ar_origin;
 
 1962             ar_nodes[i].Velocity = rot * ar_nodes[i].Velocity;
 
 1963             ar_nodes[i].Forces = rot * ar_nodes[i].Forces;
 
 1966         m_rotation_request = 0.0f;
 
 1967         this->UpdateBoundingBoxes();
 
 1968         calculateAveragePosition();
 
 1971     if (m_translation_request != Vector3::ZERO)
 
 1973         for (
int i = 0; i < ar_num_nodes; i++)
 
 1975             ar_nodes[i].AbsPosition += m_translation_request;
 
 1976             ar_nodes[i].RelPosition = ar_nodes[i].AbsPosition - ar_origin;
 
 1979         m_translation_request = Vector3::ZERO;
 
 1980         UpdateBoundingBoxes();
 
 1981         calculateAveragePosition();
 
 1985 void Actor::sendStreamSetup()
 
 1996     Ogre::StringUtil::splitFilename(m_used_actor_entry->resource_bundle_path, bname, bpath);
 
 1997     std::string bq_filename = 
fmt::format(
"{}:{}", bname, ar_filename);
 
 1998     strncpy(reg.
name, bq_filename.c_str(), 128);
 
 2001     if (m_used_skin_entry != 
nullptr)
 
 2003         strncpy(reg.
skin, m_used_skin_entry->dname.c_str(), 60);
 
 2009 #endif // USE_SOCKETW 
 2015 void Actor::sendStreamData()
 
 2019     if (ar_net_timer.getMilliseconds() - ar_net_last_update_time < 100)
 
 2022     ar_net_last_update_time = ar_net_timer.getMilliseconds();
 
 2033     unsigned int packet_len = 0;
 
 2050             if (ar_engine->hasContact())
 
 2052             if (ar_engine->isRunning())
 
 2055             switch (ar_engine->getAutoMode())
 
 2069         if (ar_num_aeroengines > 0)
 
 2071             float rpm = ar_aeroengines[0]->getRPM();
 
 2076         send_oob->
brake = ar_brake;
 
 2081         if (getCustomParticleMode())
 
 2084         if (ar_parking_brake)
 
 2086         if (m_tractioncontrol)
 
 2088         if (m_antilockbrake)
 
 2102         float* send_nodes = (
float *)ptr;
 
 2103         packet_len += m_net_total_buffer_size;
 
 2109         Vector3& refpos = ar_nodes[0].AbsPosition;
 
 2110         send_nodes[0] = refpos.x;
 
 2111         send_nodes[1] = refpos.y;
 
 2112         send_nodes[2] = refpos.z;
 
 2114         ptr += 
sizeof(float) * 3;
 
 2117         half_float::half* sbuf = (half_float::half*)ptr;
 
 2118         for (i = 1; i < m_net_first_wheel_node; i++)
 
 2120             Ogre::Vector3 relpos = ar_nodes[i].AbsPosition - ar_nodes[0].AbsPosition;
 
 2121             sbuf[(i-1) * 3 + 0] = 
static_cast<half_float::half
>(relpos.x);
 
 2122             sbuf[(i-1) * 3 + 1] = 
static_cast<half_float::half
>(relpos.y);
 
 2123             sbuf[(i-1) * 3 + 2] = 
static_cast<half_float::half
>(relpos.z);
 
 2125             ptr += 
sizeof(half_float::half) * 3; 
 
 2129         float* wfbuf = (
float*)ptr;
 
 2130         for (i = 0; i < ar_num_wheels; i++)
 
 2132             wfbuf[i] = ar_wheels[i].wh_net_rp;
 
 2134         ptr += ar_num_wheels * 
sizeof(float);
 
 2137         for (
size_t i = 0; i < m_prop_anim_key_states.size(); i++)
 
 2139             if (m_prop_anim_key_states[i].anim_active)
 
 2142                 char& dst_byte = *(ptr + (i / 8));
 
 2143                 char mask = ((char)m_prop_anim_key_states[i].anim_active) << (7 - (i % 8));
 
 2153 void Actor::CalcAnimators(
hydrobeam_t const& hydrobeam, 
float &cstate, 
int &div)
 
 2160         for (spi = 0; spi < ar_num_screwprops; spi++)
 
 2161             if (ar_screwprops[spi])
 
 2162                 ctmp += ar_screwprops[spi]->getRudder();
 
 2175         for (spi = 0; spi < ar_num_screwprops; spi++)
 
 2176             if (ar_screwprops[spi])
 
 2177                 ctmp += ar_screwprops[spi]->getThrottle();
 
 2188         if (m_num_wheel_diffs && m_wheel_diffs[0])
 
 2190             String name = m_wheel_diffs[0]->GetDifferentialTypeName();
 
 2193             if (name == 
"Split")
 
 2195             if (name == 
"Locked")
 
 2207         float heading = getRotation();
 
 2209         cstate = (heading * 57.29578f) / 360.0f;
 
 2216         float torque = ar_engine->getCrankFactor();
 
 2219         if (torque >= ar_anim_previous_crank)
 
 2220             cstate -= torque / 10.0f;
 
 2224         if (cstate <= -1.0f)
 
 2226         ar_anim_previous_crank = torque;
 
 2234         int shifter = ar_engine->getGear();
 
 2235         if (shifter > m_previous_gear)
 
 2238             ar_anim_shift_timer = 0.2f;
 
 2240         if (shifter < m_previous_gear)
 
 2243             ar_anim_shift_timer = -0.2f;
 
 2245         m_previous_gear = shifter;
 
 2247         if (ar_anim_shift_timer > 0.0f)
 
 2251             if (ar_anim_shift_timer < 0.0f)
 
 2252                 ar_anim_shift_timer = 0.0f;
 
 2254         if (ar_anim_shift_timer < 0.0f)
 
 2258             if (ar_anim_shift_timer > 0.0f)
 
 2259                 ar_anim_shift_timer = 0.0f;
 
 2268         int shifter = ar_engine->getGear();
 
 2273         else if (shifter < 0)
 
 2279             cstate -= int((shifter - 1.0) / 2.0);
 
 2287         int shifter = ar_engine->getGear();
 
 2295             cstate = shifter % 2;
 
 2303         int shifter = ar_engine->getGear();
 
 2304         int numgears = ar_engine->getNumGears();
 
 2305         cstate -= (shifter + 2.0) / (numgears + 2.0);
 
 2312         float pbrake = ar_parking_brake;
 
 2320         float speedo = ar_wheel_speed / ar_guisettings_speedo_max_kph;
 
 2321         cstate -= speedo * 3.0f;
 
 2328         float tacho = ar_engine->getRPM() / ar_engine->getShiftUpRPM();
 
 2336         float turbo = ar_engine->getTurboPSI() * 3.34;
 
 2337         cstate -= turbo / 67.0f;
 
 2351         float accel = ar_engine->getAcc();
 
 2352         cstate -= accel + 0.06f;
 
 2360         float clutch = ar_engine->getClutch();
 
 2361         cstate -= fabs(1.0f - clutch);
 
 2372             float pcent = ar_aeroengines[aenum]->getRPMpc();
 
 2374                 angle = -5.0 + pcent * 1.9167;
 
 2375             else if (pcent < 110.0)
 
 2376                 angle = 110.0 + (pcent - 60.0) * 4.075;
 
 2379             cstate -= angle / 314.0f;
 
 2384             float throttle = ar_aeroengines[aenum]->getThrottle();
 
 2390             if (ar_aeroengines[aenum]->getType() == AeroEngineType::AE_XPROP)
 
 2398             if (ar_aeroengines[aenum]->getType() == AeroEngineType::AE_XPROP)
 
 2401                 cstate = tp->
pitch / 120.0f;
 
 2407             if (!ar_aeroengines[aenum]->getIgnition())
 
 2411             if (ar_aeroengines[aenum]->isFailed())
 
 2420         float ground_speed_kt = ar_nodes[0].Velocity.length() * 1.9438;
 
 2421         float altitude = ar_nodes[0].AbsPosition.y;
 
 2422         float sea_level_pressure = 101325; 
 
 2423         float airpressure = sea_level_pressure * pow(1.0 - 0.0065 * altitude / 288.15, 5.24947); 
 
 2424         float airdensity = airpressure * 0.0000120896;
 
 2425         float kt = ground_speed_kt * sqrt(airdensity / 1.225);
 
 2426         cstate -= kt / 100.0f;
 
 2433         float vvi = ar_nodes[0].Velocity.y * 196.85;
 
 2435         cstate -= vvi / 6000.0f;
 
 2438         if (cstate <= -1.0f)
 
 2449             float altimeter = (ar_nodes[0].AbsPosition.y * 1.1811) / 360.0f;
 
 2450             int alti_int = int(altimeter);
 
 2451             float alti_mod = (altimeter - alti_int);
 
 2458             float alti = ar_nodes[0].AbsPosition.y * 1.1811 / 3600.0f;
 
 2459             int alti_int = int(alti);
 
 2460             float alti_mod = (alti - alti_int);
 
 2462             if (cstate <= -1.0f)
 
 2469             float alti = ar_nodes[0].AbsPosition.y * 1.1811 / 36000.0f;
 
 2471             if (cstate <= -1.0f)
 
 2481         if (ar_num_wings > 4)
 
 2482             aoa = (ar_wings[4].fa->aoa) / 25.0f;
 
 2483         if ((ar_nodes[0].Velocity.length() * 1.9438) < 10.0f)
 
 2486         if (cstate <= -1.0f)
 
 2496         Vector3 rollv = this->GetCameraRoll();
 
 2497         Vector3 dirv = this->GetCameraDir();
 
 2498         Vector3 upv = dirv.crossProduct(-rollv);
 
 2499         float rollangle = asin(rollv.dotProduct(Vector3::UNIT_Y));
 
 2501         rollangle = Math::RadiansToDegrees(rollangle);
 
 2504             rollangle = 180.0f - rollangle;
 
 2505         cstate = rollangle / 180.0f;
 
 2509             cstate = cstate - 2.0f;
 
 2516         Vector3 dirv = this->GetCameraDir();
 
 2517         float pitchangle = asin(dirv.dotProduct(Vector3::UNIT_Y));
 
 2519         cstate = (Math::RadiansToDegrees(pitchangle) / 90.0f);
 
 2526         float airbrake = ar_airbrake_intensity;
 
 2528         cstate -= airbrake / 5.0f;
 
 2542 void Actor::CalcCabCollisions()
 
 2544     for (
int i = 0; i < ar_num_nodes; i++)
 
 2546         ar_nodes[i].nd_has_mesh_contact = 
false;
 
 2548     if (m_intra_point_col_detector != 
nullptr)
 
 2550         m_intra_point_col_detector->UpdateIntraPoint();
 
 2552             *m_intra_point_col_detector,
 
 2556             ar_intra_collcabrate,
 
 2559             *ar_submesh_ground_model);
 
 2563 void Actor::CalcShocks2(
int i, Real difftoBeamL, Real& k, Real& d, Real v)
 
 2567         k = ar_beams[i].shock->springout;
 
 2568         d = ar_beams[i].shock->dampout;
 
 2570         float logafactor = 1.0f;
 
 2571         if (ar_beams[i].longbound != 0.0f)
 
 2573             logafactor = difftoBeamL / (ar_beams[i].longbound * ar_beams[i].L);
 
 2574             logafactor = std::min(logafactor * logafactor, 1.0f);
 
 2576         k += ar_beams[i].shock->sprogout * k * logafactor;
 
 2577         d += ar_beams[i].shock->dprogout * d * logafactor;
 
 2581         k = ar_beams[i].shock->springin;
 
 2582         d = ar_beams[i].shock->dampin;
 
 2584         float logafactor = 1.0f;
 
 2585         if (ar_beams[i].shortbound != 0.0f)
 
 2587             logafactor = difftoBeamL / (ar_beams[i].shortbound * ar_beams[i].L);
 
 2588             logafactor = std::min(logafactor * logafactor, 1.0f);
 
 2590         k += ar_beams[i].shock->sprogin * k * logafactor;
 
 2591         d += ar_beams[i].shock->dprogin * d * logafactor;
 
 2596         float beamsLep = ar_beams[i].L * 0.8f;
 
 2597         float longboundprelimit = ar_beams[i].longbound * beamsLep;
 
 2598         float shortboundprelimit = -ar_beams[i].shortbound * beamsLep;
 
 2599         if (difftoBeamL > longboundprelimit)
 
 2602             k = ar_beams[i].shock->springout;
 
 2603             d = ar_beams[i].shock->dampout;
 
 2605             float logafactor = 1.0f;
 
 2606             if (ar_beams[i].longbound != 0.0f)
 
 2608                 logafactor = difftoBeamL / (ar_beams[i].longbound * ar_beams[i].L);
 
 2609                 logafactor = std::min(logafactor * logafactor, 1.0f);
 
 2611             k += ar_beams[i].shock->sprogout * k * logafactor;
 
 2612             d += ar_beams[i].shock->dprogout * d * logafactor;
 
 2615             if (ar_beams[i].longbound != 0.0f)
 
 2617                 logafactor = ((difftoBeamL - longboundprelimit) * 5.0f) / (ar_beams[i].longbound * ar_beams[i].L);
 
 2618                 logafactor = std::min(logafactor * logafactor, 1.0f);
 
 2620             k += (k + 100.0f) * ar_beams[i].shock->sprogout * logafactor;
 
 2621             d += (d + 100.0f) * ar_beams[i].shock->dprogout * logafactor;
 
 2625                 k = ar_beams[i].shock->springin;
 
 2626                 d = ar_beams[i].shock->dampin;
 
 2629         else if (difftoBeamL < shortboundprelimit)
 
 2632             k = ar_beams[i].shock->springin;
 
 2633             d = ar_beams[i].shock->dampin;
 
 2635             float logafactor = 1.0f;
 
 2636             if (ar_beams[i].shortbound != 0.0f)
 
 2638                 logafactor = difftoBeamL / (ar_beams[i].shortbound * ar_beams[i].L);
 
 2639                 logafactor = std::min(logafactor * logafactor, 1.0f);
 
 2641             k += ar_beams[i].shock->sprogin * k * logafactor;
 
 2642             d += ar_beams[i].shock->dprogin * d * logafactor;
 
 2645             if (ar_beams[i].shortbound != 0.0f)
 
 2647                 logafactor = ((difftoBeamL - shortboundprelimit) * 5.0f) / (ar_beams[i].shortbound * ar_beams[i].L);
 
 2648                 logafactor = std::min(logafactor * logafactor, 1.0f);
 
 2650             k += (k + 100.0f) * ar_beams[i].shock->sprogout * logafactor;
 
 2651             d += (d + 100.0f) * ar_beams[i].shock->dprogout * logafactor;
 
 2655                 k = ar_beams[i].shock->springout;
 
 2656                 d = ar_beams[i].shock->dampout;
 
 2659         if (difftoBeamL > ar_beams[i].longbound * ar_beams[i].L || difftoBeamL < -ar_beams[i].shortbound * ar_beams[i].L)
 
 2662             k = std::max(k, ar_beams[i].shock->sbd_spring);
 
 2663             d = std::max(d, ar_beams[i].shock->sbd_damp);
 
 2666     else if (difftoBeamL > ar_beams[i].longbound * ar_beams[i].L || difftoBeamL < -ar_beams[i].shortbound * ar_beams[i].L)
 
 2669         k = ar_beams[i].shock->sbd_spring;
 
 2670         d = ar_beams[i].shock->sbd_damp;
 
 2674 void Actor::CalcShocks3(
int i, Real difftoBeamL, Real &k, Real& d, Real v)
 
 2676     if (difftoBeamL > ar_beams[i].longbound * ar_beams[i].L)
 
 2678         float interp_ratio =  difftoBeamL - ar_beams[i].longbound  * ar_beams[i].L;
 
 2679         k += (ar_beams[i].shock->sbd_spring - k) * interp_ratio;
 
 2680         d += (ar_beams[i].shock->sbd_damp   - d) * interp_ratio;
 
 2682     else if (difftoBeamL < -ar_beams[i].shortbound * ar_beams[i].L)
 
 2684         float interp_ratio = -difftoBeamL - ar_beams[i].shortbound * ar_beams[i].L;
 
 2685         k += (ar_beams[i].shock->sbd_spring - k) * interp_ratio;
 
 2686         d += (ar_beams[i].shock->sbd_damp   - d) * interp_ratio;
 
 2690         v = Math::Clamp(std::abs(v), +0.15f, +20.0f);
 
 2691         k = ar_beams[i].shock->springout;
 
 2692         d = ar_beams[i].shock->dampout * ar_beams[i].shock->dslowout * std::min(v,        ar_beams[i].shock->splitout) +
 
 2693             ar_beams[i].shock->dampout * ar_beams[i].shock->dfastout * std::max(0.0f, v - ar_beams[i].shock->splitout);
 
 2698         v = Math::Clamp(std::abs(v), +0.15f, +20.0f);
 
 2699         k = ar_beams[i].shock->springin;
 
 2700         d = ar_beams[i].shock->dampin  * ar_beams[i].shock->dslowin  * std::min(v,        ar_beams[i].shock->splitin ) +
 
 2701             ar_beams[i].shock->dampin  * ar_beams[i].shock->dfastin  * std::max(0.0f, v - ar_beams[i].shock->splitin );
 
 2706 void Actor::CalcTriggers(
int i, Real difftoBeamL, 
bool trigger_hooks)
 
 2712         if (difftoBeamL > ar_beams[i].longbound * ar_beams[i].L || difftoBeamL < -ar_beams[i].shortbound * ar_beams[i].L) 
 
 2714             ar_beams[i].shock->trigger_switch_state -= dt;
 
 2715             if (ar_beams[i].shock->trigger_switch_state <= 0.0f) 
 
 2716                 ar_beams[i].shock->trigger_switch_state = 0.0f;
 
 2719                 for (
int scount = i + 1; scount <= i + ar_beams[i].shock->trigger_cmdshort; scount++) 
 
 2723                         if (m_trigger_debug_enabled && !ar_beams[scount].shock->trigger_enabled && ar_beams[i].shock->last_debug_state != 1)
 
 2725                             LOG(
" Trigger disabled. Blocker BeamID " + 
TOSTRING(i) + 
" enabled trigger " + 
TOSTRING(scount));
 
 2726                             ar_beams[i].shock->last_debug_state = 1;
 
 2728                         ar_beams[scount].shock->trigger_enabled = 
false; 
 
 2734                 for (
int scount = i + 1; scount <= i + ar_beams[i].shock->trigger_cmdlong; scount++) 
 
 2738                         if (m_trigger_debug_enabled && ar_beams[scount].shock->trigger_enabled && ar_beams[i].shock->last_debug_state != 9)
 
 2740                             LOG(
" Trigger enabled. Inverted Blocker BeamID " + 
TOSTRING(i) + 
" disabled trigger " + 
TOSTRING(scount));
 
 2741                             ar_beams[i].shock->last_debug_state = 9;
 
 2743                         ar_beams[scount].shock->trigger_enabled = 
true; 
 
 2749                 ar_command_key[ar_beams[i].shock->trigger_cmdshort].trigger_cmdkeyblock_state = 
false; 
 
 2750                 if (m_trigger_debug_enabled && ar_beams[i].shock->last_debug_state != 2)
 
 2752                     LOG(
" F-key trigger block released. Blocker BeamID " + 
TOSTRING(i) + 
" Released F" + 
TOSTRING(ar_beams[i].shock->trigger_cmdshort));
 
 2753                     ar_beams[i].shock->last_debug_state = 2;
 
 2758                 if (!ar_beams[i].shock->trigger_switch_state)
 
 2760                     for (
int scount = 0; scount < ar_num_shocks; scount++)
 
 2762                         int short1 = ar_beams[ar_shocks[scount].beamid].shock->trigger_cmdshort; 
 
 2763                         int short2 = ar_beams[i].shock->trigger_cmdshort; 
 
 2764                         int long1 = ar_beams[ar_shocks[scount].beamid].shock->trigger_cmdlong; 
 
 2765                         int long2 = ar_beams[i].shock->trigger_cmdlong; 
 
 2766                         int tmpi = ar_beams[ar_shocks[scount].beamid].shock->beamid; 
 
 2767                         if (((short1 == short2 && long1 == long2) || (short1 == long2 && long1 == short2)) && i != tmpi) 
 
 2769                             int tmpcmdkey = ar_beams[ar_shocks[scount].beamid].shock->trigger_cmdlong;
 
 2770                             ar_beams[ar_shocks[scount].beamid].shock->trigger_cmdlong = ar_beams[ar_shocks[scount].beamid].shock->trigger_cmdshort;
 
 2771                             ar_beams[ar_shocks[scount].beamid].shock->trigger_cmdshort = tmpcmdkey;
 
 2772                             ar_beams[i].shock->trigger_switch_state = ar_beams[i].shock->trigger_boundary_t; 
 
 2773                             if (m_trigger_debug_enabled && ar_beams[i].shock->last_debug_state != 3)
 
 2775                                 LOG(
" Trigger F-key commands switched. Switch BeamID " + 
TOSTRING(i)+ 
" switched commands of Trigger BeamID " + 
TOSTRING(ar_beams[ar_shocks[scount].beamid].shock->beamid) + 
" to cmdShort: F" + 
TOSTRING(ar_beams[ar_shocks[scount].beamid].shock->trigger_cmdshort) + 
", cmdlong: F" + 
TOSTRING(ar_beams[ar_shocks[scount].beamid].shock->trigger_cmdlong));
 
 2776                                 ar_beams[i].shock->last_debug_state = 3;
 
 2784                 if (difftoBeamL > ar_beams[i].longbound * ar_beams[i].L) 
 
 2793                             rq->
alr_type = ActorLinkingRequestType::HOOK_UNLOCK;
 
 2806                             rq->
alr_type = ActorLinkingRequestType::HOOK_LOCK;
 
 2814                         engineTriggerHelper(ar_beams[i].shock->trigger_cmdshort, 
EngineTriggerType(ar_beams[i].shock->trigger_cmdlong), 1.0f);
 
 2819                         if (!ar_command_key[ar_beams[i].shock->trigger_cmdlong].trigger_cmdkeyblock_state) 
 
 2822                                 ar_command_key[ar_beams[i].shock->trigger_cmdshort].triggerInputValue = 1; 
 
 2824                                 ar_command_key[ar_beams[i].shock->trigger_cmdlong].triggerInputValue = 1;
 
 2825                             if (m_trigger_debug_enabled && ar_beams[i].shock->last_debug_state != 4)
 
 2827                                 LOG(
" Trigger Longbound activated. Trigger BeamID " + 
TOSTRING(i) + 
" Triggered F" + 
TOSTRING(ar_beams[i].shock->trigger_cmdlong));
 
 2828                                 ar_beams[i].shock->last_debug_state = 4;
 
 2842                             rq->
alr_type = ActorLinkingRequestType::HOOK_UNLOCK;
 
 2855                             rq->
alr_type = ActorLinkingRequestType::HOOK_LOCK;
 
 2865                         engineTriggerHelper(ar_beams[i].shock->trigger_cmdshort, 
EngineTriggerType(ar_beams[i].shock->trigger_cmdlong), triggerValue);
 
 2870                         if (!ar_command_key[ar_beams[i].shock->trigger_cmdshort].trigger_cmdkeyblock_state) 
 
 2873                                 ar_command_key[ar_beams[i].shock->trigger_cmdshort].triggerInputValue = 0; 
 
 2875                                 ar_command_key[ar_beams[i].shock->trigger_cmdshort].triggerInputValue = 1;
 
 2877                             if (m_trigger_debug_enabled && ar_beams[i].shock->last_debug_state != 5)
 
 2879                                 LOG(
" Trigger Shortbound activated. Trigger BeamID " + 
TOSTRING(i) + 
" Triggered F" + 
TOSTRING(ar_beams[i].shock->trigger_cmdshort));
 
 2880                                 ar_beams[i].shock->last_debug_state = 5;
 
 2891                 if (ar_beams[i].longbound - ar_beams[i].shortbound > 0.0f)
 
 2893                     float diffPercentage = difftoBeamL / ar_beams[i].L;
 
 2894                     float triggerValue = (diffPercentage - ar_beams[i].shortbound) / (ar_beams[i].longbound - ar_beams[i].shortbound);
 
 2896                     triggerValue = std::max(0.0f, triggerValue);
 
 2897                     triggerValue = std::min(triggerValue, 1.0f);
 
 2901                         engineTriggerHelper(ar_beams[i].shock->trigger_cmdshort, 
EngineTriggerType(ar_beams[i].shock->trigger_cmdlong), triggerValue);
 
 2906                         ar_command_key[ar_beams[i].shock->trigger_cmdshort].triggerInputValue = triggerValue;
 
 2907                         ar_command_key[ar_beams[i].shock->trigger_cmdlong].triggerInputValue = triggerValue;
 
 2913                 for (
int scount = i + 1; scount <= i + ar_beams[i].shock->trigger_cmdlong; scount++) 
 
 2917                         if (m_trigger_debug_enabled && ar_beams[scount].shock->trigger_enabled && ar_beams[i].shock->last_debug_state != 6)
 
 2919                             LOG(
" Trigger enabled. Blocker BeamID " + 
TOSTRING(i) + 
" disabled trigger " + 
TOSTRING(scount));
 
 2920                             ar_beams[i].shock->last_debug_state = 6;
 
 2922                         ar_beams[scount].shock->trigger_enabled = 
true; 
 
 2928                 for (
int scount = i + 1; scount <= i + ar_beams[i].shock->trigger_cmdshort; scount++) 
 
 2932                         if (m_trigger_debug_enabled && !ar_beams[scount].shock->trigger_enabled && ar_beams[i].shock->last_debug_state != 10)
 
 2934                             LOG(
" Trigger disabled. Inverted Blocker BeamID " + 
TOSTRING(i) + 
" enabled trigger " + 
TOSTRING(scount));
 
 2935                             ar_beams[i].shock->last_debug_state = 10;
 
 2937                         ar_beams[scount].shock->trigger_enabled = 
false; 
 
 2943                 ar_beams[i].shock->trigger_switch_state = 0.0f; 
 
 2944                 if (m_trigger_debug_enabled && ar_beams[i].shock->last_debug_state != 7)
 
 2946                     LOG(
" Trigger switch reset. Switch BeamID " + 
TOSTRING(i));
 
 2947                     ar_beams[i].shock->last_debug_state = 7;
 
 2950             else if ((ar_beams[i].shock->flags & 
SHOCK_FLAG_TRG_CMD_BLOCKER) && !ar_command_key[ar_beams[i].shock->trigger_cmdshort].trigger_cmdkeyblock_state) 
 
 2952                 ar_command_key[ar_beams[i].shock->trigger_cmdshort].trigger_cmdkeyblock_state = 
true; 
 
 2953                 if (m_trigger_debug_enabled && ar_beams[i].shock->last_debug_state != 8)
 
 2955                     LOG(
" F-key trigger blocked. Blocker BeamID " + 
TOSTRING(i) + 
" Blocked F" + 
TOSTRING(ar_beams[i].shock->trigger_cmdshort));
 
 2956                     ar_beams[i].shock->last_debug_state = 8;
 
 2963 void Actor::setAirbrakeIntensity(
float intensity)
 
 2965     ar_airbrake_intensity = intensity;
 
 2968         ab->updatePosition((
float)ar_airbrake_intensity / 5.0);
 
 2973 void Actor::updateSkidmarks()
 
 2975     for (
int i = 0; i < ar_num_wheels; i++)
 
 2977         if (!m_skid_trails[i])
 
 2980         for (
int j = 0; j < ar_wheels[i].wh_num_nodes; j++)
 
 2982             auto n = ar_wheels[i].wh_nodes[j];
 
 2983             if (!n || !n->nd_has_ground_contact || n->nd_last_collision_gm == 
nullptr ||
 
 2984                     n->nd_last_collision_gm->fx_type != Collisions::FX_HARD)
 
 2988             if (n->nd_avg_collision_slip > 6.f && n->nd_last_collision_slip.squaredLength() > 9.f)
 
 2990                 m_skid_trails[i]->update(n->AbsPosition, j, n->nd_avg_collision_slip, n->nd_last_collision_gm->name);
 
 2997 void Actor::prepareInside(
bool inside)
 
 3005         MaterialPtr seatmat = (MaterialPtr)(MaterialManager::getSingleton().getByName(
"driversseat"));
 
 3006         seatmat->setDepthWriteEnabled(
false);
 
 3007         seatmat->setSceneBlending(SBT_TRANSPARENT_ALPHA);
 
 3013             ar_dashboard->setVisible(
false);
 
 3019         MaterialPtr seatmat = (MaterialPtr)(MaterialManager::getSingleton().getByName(
"driversseat"));
 
 3020         seatmat->setDepthWriteEnabled(
true);
 
 3021         seatmat->setSceneBlending(SBT_REPLACE);
 
 3032         m_gfx_actor->SetCastShadows(!inside);
 
 3036 void Actor::toggleHeadlights()
 
 3040     if (ar_state == ActorState::LOCAL_SIMULATED && 
this == player_actor.
GetRef() && ar_forward_commands)
 
 3044             if (actor->ar_state == ActorState::LOCAL_SIMULATED && 
this != actor.GetRef() && actor->ar_import_commands)
 
 3053     m_gfx_actor->SetCabLightsActive(this->getHeadlightsVisible());
 
 3058 void Actor::forceAllFlaresOff()
 
 3060     for (
size_t i = 0; i < ar_flares.size(); i++)
 
 3062         ar_flares[i].snode->setVisible(
false);
 
 3066 void Actor::updateFlareStates(
float dt)
 
 3068     if (m_flares_mode == GfxFlaresMode::NONE) { 
return; }
 
 3070     for (
size_t i = 0; i < this->ar_flares.size(); i++)
 
 3073         if (ar_flares[i].blinkdelay != 0)
 
 3075             ar_flares[i].blinkdelay_curr -= dt;
 
 3076             if (ar_flares[i].blinkdelay_curr <= 0)
 
 3078                 ar_flares[i].blinkdelay_curr = ar_flares[i].blinkdelay;
 
 3079                 ar_flares[i].blinkdelay_state = !ar_flares[i].blinkdelay_state;
 
 3084             ar_flares[i].blinkdelay_state = 
true;
 
 3088         bool isvisible = 
false;
 
 3089         switch (ar_flares[i].fl_type)
 
 3100         case FlareType::DASHBOARD: isvisible = ar_dashboard->_getBool(ar_flares[i].dashboard_link); 
break;
 
 3101         case FlareType::USER: isvisible = this->getCustomLightVisible(ar_flares[i].controlnumber); 
break;
 
 3105         isvisible = isvisible && ar_flares[i].blinkdelay_state;
 
 3108         switch (ar_flares[i].fl_type)
 
 3110             case FlareType::BLINKER_LEFT: m_blinker_left_lit = isvisible; 
break;
 
 3111             case FlareType::BLINKER_RIGHT: m_blinker_right_lit = isvisible; 
break;
 
 3116         if (ar_flares[i].uses_inertia)
 
 3118             ar_flares[i].intensity = ar_flares[i].inertia.CalcSimpleDelay(isvisible, dt);
 
 3122             ar_flares[i].intensity = (float)isvisible;
 
 3129     if (this->getBlinkType() == blink)
 
 3132         setBlinkType(blink);
 
 3137     if (ar_state == ActorState::DISPOSED)
 
 3169 void Actor::autoBlinkReset()
 
 3174     if (this->getBlinkType() == 
BLINK_LEFT && ar_hydro_dir_state < -blink_lock_range)
 
 3177         m_blinker_autoreset = 
true;
 
 3180     if (this->getBlinkType() == 
BLINK_LEFT && m_blinker_autoreset && ar_hydro_dir_state > -blink_lock_range)
 
 3184         m_blinker_autoreset = 
false;
 
 3188     if (this->getBlinkType() == 
BLINK_RIGHT && ar_hydro_dir_state > blink_lock_range)
 
 3189         m_blinker_autoreset = 
true;
 
 3191     if (this->getBlinkType() == 
BLINK_RIGHT && m_blinker_autoreset && ar_hydro_dir_state < blink_lock_range)
 
 3194         m_blinker_autoreset = 
false;
 
 3204         this->toggleHeadlights();
 
 3206         this->beaconsToggle();
 
 3215     this->setBlinkType(btype);
 
 3218     m_lightmask = lightmask;
 
 3224     BITMASK_SET_1(lightmask, m_lightmask & m_flaregroups_no_import);
 
 3226     BITMASK_SET_0(lightmask, ~m_lightmask & m_flaregroups_no_import);
 
 3228     this->setLightStateMask(lightmask);
 
 3231 void Actor::toggleCustomParticles()
 
 3233     if (ar_state == ActorState::DISPOSED)
 
 3236     ar_cparticles_active = !ar_cparticles_active;
 
 3242 void Actor::updateSoundSources()
 
 3247     for (
int i = 0; i < ar_num_soundsources; i++)
 
 3250         ar_soundsources[i].ssi->setPosition(ar_nodes[ar_soundsources[i].nodenum].AbsPosition);
 
 3251         ar_soundsources[i].ssi->setVelocity(ar_nodes[ar_soundsources[i].nodenum].Velocity);
 
 3259 void Actor::updateVisual(
float dt)
 
 3261     Vector3 ref(Vector3::UNIT_Y);
 
 3263     updateSoundSources();
 
 3267     if (ar_driveable == 
AIRPLANE && ar_state != ActorState::LOCAL_SLEEPING)
 
 3270         m_avionic_chatter_timer -= dt;
 
 3271         if (m_avionic_chatter_timer < 0)
 
 3274             m_avionic_chatter_timer = Math::RangeRandom(11, 30);
 
 3280     float autoaileron = 0;
 
 3281     float autorudder = 0;
 
 3282     float autoelevator = 0;
 
 3285         ar_autopilot->UpdateIls();
 
 3286         autoaileron = ar_autopilot->getAilerons();
 
 3287         autorudder = ar_autopilot->getRudder();
 
 3288         autoelevator = ar_autopilot->getElevator();
 
 3289         ar_autopilot->gpws_update(ar_posnode_spawn_height);
 
 3291     autoaileron += ar_aileron;
 
 3292     autorudder += ar_rudder;
 
 3293     autoelevator += ar_elevator;
 
 3294     if (autoaileron < -1.0)
 
 3296     if (autoaileron > 1.0)
 
 3298     if (autorudder < -1.0)
 
 3300     if (autorudder > 1.0)
 
 3302     if (autoelevator < -1.0)
 
 3303         autoelevator = -1.0;
 
 3304     if (autoelevator > 1.0)
 
 3306     for (
int i = 0; i < ar_num_wings; i++)
 
 3308         if (ar_wings[i].fa->type == 
'a')
 
 3309             ar_wings[i].fa->setControlDeflection(autoaileron);
 
 3310         if (ar_wings[i].fa->type == 
'b')
 
 3311             ar_wings[i].fa->setControlDeflection(-autoaileron);
 
 3312         if (ar_wings[i].fa->type == 
'r')
 
 3313             ar_wings[i].fa->setControlDeflection(autorudder);
 
 3314         if (ar_wings[i].fa->type == 
'e' || ar_wings[i].fa->type == 
'S' || ar_wings[i].fa->type == 
'T')
 
 3315             ar_wings[i].fa->setControlDeflection(autoelevator);
 
 3316         if (ar_wings[i].fa->type == 
'f')
 
 3317             ar_wings[i].fa->setControlDeflection(
FLAP_ANGLES[ar_aerial_flap]);
 
 3318         if (ar_wings[i].fa->type == 
'c' || ar_wings[i].fa->type == 
'V')
 
 3319             ar_wings[i].fa->setControlDeflection((autoaileron + autoelevator) / 2.0);
 
 3320         if (ar_wings[i].fa->type == 
'd' || ar_wings[i].fa->type == 
'U')
 
 3321             ar_wings[i].fa->setControlDeflection((-autoaileron + autoelevator) / 2.0);
 
 3322         if (ar_wings[i].fa->type == 
'g')
 
 3323             ar_wings[i].fa->setControlDeflection((autoaileron + 
FLAP_ANGLES[ar_aerial_flap]) / 2.0);
 
 3324         if (ar_wings[i].fa->type == 
'h')
 
 3325             ar_wings[i].fa->setControlDeflection((-autoaileron + 
FLAP_ANGLES[ar_aerial_flap]) / 2.0);
 
 3326         if (ar_wings[i].fa->type == 
'i')
 
 3327             ar_wings[i].fa->setControlDeflection((-autoelevator + autorudder) / 2.0);
 
 3328         if (ar_wings[i].fa->type == 
'j')
 
 3329             ar_wings[i].fa->setControlDeflection((autoelevator + autorudder) / 2.0);
 
 3330         ar_wings[i].fa->updateVerticesPhysics(); 
 
 3333     ar_hydro_aileron_command = autoaileron;
 
 3334     ar_hydro_rudder_command = autorudder;
 
 3335     ar_hydro_elevator_command = autoelevator;
 
 3343     auto pos = std::find(ar_inter_beams.begin(), ar_inter_beams.end(), beam);
 
 3345     if (pos == ar_inter_beams.end())
 
 3347         ar_inter_beams.push_back(beam);
 
 3352     std::pair<ActorPtr, ActorPtr> actor_pair(
this, other);
 
 3356     if (linked_before != linked_now)
 
 3359         this->DetermineLinkedActors();
 
 3360         for (
ActorPtr& actor : this->ar_linked_actors)
 
 3361             actor->DetermineLinkedActors();
 
 3368         for (
ActorPtr& actor : this->ar_linked_actors)
 
 3386     auto pos = std::find(ar_inter_beams.begin(), ar_inter_beams.end(), beam);
 
 3388     if (pos != ar_inter_beams.end())
 
 3390         ar_inter_beams.erase(pos);
 
 3402     if (linked_before != linked_now)
 
 3405         this->DetermineLinkedActors();
 
 3406         for (
ActorPtr& actor : this->ar_linked_actors)
 
 3407             actor->DetermineLinkedActors();
 
 3411         if (other->
ar_state != ActorState::DISPOSED)
 
 3432 void Actor::DisjoinInterActorBeams()
 
 3440     this->hookToggle(-1, ActorLinkingRequestType::HOOK_RESET); 
 
 3441     this->ropeToggle(-1, ActorLinkingRequestType::ROPE_RESET); 
 
 3442     this->tieToggle(-1, ActorLinkingRequestType::TIE_RESET); 
 
 3447         if (other_actor->ar_state != ActorState::LOCAL_SIMULATED)
 
 3451         other_actor->hookToggle(-1, ActorLinkingRequestType::HOOK_RESET, 
NODENUM_INVALID, ar_instance_id); 
 
 3452         other_actor->tieToggle(-1, ActorLinkingRequestType::TIE_RESET, ar_instance_id); 
 
 3453         other_actor->ropeToggle(-1, ActorLinkingRequestType::ROPE_RESET, ar_instance_id); 
 
 3462     bool istied = 
false;
 
 3464     for (std::vector<tie_t>::iterator it = ar_ties.begin(); it != ar_ties.end(); it++)
 
 3467         if (group != -1 && (it->ti_group != -1 && it->ti_group != group))
 
 3471         if (mode == ActorLinkingRequestType::TIE_RESET
 
 3472             && forceunlock_filter != 
ACTORINSTANCEID_INVALID && it->ti_locked_actor && it->ti_locked_actor->ar_instance_id != forceunlock_filter)
 
 3480             istied = !it->ti_beam->bm_disabled;
 
 3483             it->ti_tied = 
false;
 
 3484             it->ti_tying = 
false;
 
 3485             if (it->ti_locked_ropable)
 
 3486                 it->ti_locked_ropable->attached_ties--;
 
 3488             it->ti_beam->p2 = &ar_nodes[0];
 
 3489             it->ti_beam->bm_inter_actor = 
false;
 
 3490             it->ti_beam->bm_disabled = 
true;
 
 3491             if (it->ti_locked_actor != 
this)
 
 3493                 this->RemoveInterActorBeam(it->ti_beam, mode); 
 
 3495             it->ti_locked_actor = 
nullptr;
 
 3500     if (!istied && mode == ActorLinkingRequestType::TIE_TOGGLE)
 
 3502         for (std::vector<tie_t>::iterator it = ar_ties.begin(); it != ar_ties.end(); it++)
 
 3505             if (group != -1 && (it->ti_group != -1 && it->ti_group != group))
 
 3511                 float mindist = it->ti_beam->refL;
 
 3512                 node_t* nearest_node = 0;
 
 3518                     if (actor->ar_state == ActorState::LOCAL_SLEEPING ||
 
 3519                         (actor == 
this && it->ti_no_self_lock))
 
 3525                     for (std::vector<ropable_t>::iterator itr = actor->ar_ropables.begin(); itr != actor->ar_ropables.end(); itr++)
 
 3528                         if (!itr->multilock && itr->attached_ties > 0)
 
 3532                         if (
this == actor.GetRef() && itr->node->pos == it->ti_beam->p1->pos)
 
 3536                         float dist = (it->ti_beam->p1->AbsPosition - itr->node->AbsPosition).length();
 
 3540                             nearest_node = itr->node;
 
 3541                             nearest_actor = actor;
 
 3542                             locktedto = &(*itr);
 
 3550                     it->ti_beam->bm_disabled = 
false;
 
 3552                     it->ti_locked_actor = nearest_actor;
 
 3553                     it->ti_beam->p2 = nearest_node;
 
 3554                     it->ti_beam->bm_inter_actor = nearest_actor != 
this;
 
 3555                     it->ti_beam->stress = 0;
 
 3556                     it->ti_beam->L = it->ti_beam->refL;
 
 3558                     it->ti_tying = 
true;
 
 3559                     it->ti_locked_ropable = locktedto;
 
 3561                     if (it->ti_beam->bm_inter_actor)
 
 3563                         this->AddInterActorBeam(it->ti_beam, nearest_actor, mode); 
 
 3579     for (std::vector<rope_t>::iterator it = ar_ropes.begin(); it != ar_ropes.end(); it++)
 
 3582         if (group != -1 && (it->rp_group != -1 && it->rp_group != group))
 
 3586         if (mode == ActorLinkingRequestType::ROPE_RESET
 
 3587             && forceunlock_filter != 
ACTORINSTANCEID_INVALID && it->rp_locked_actor && it->rp_locked_actor->ar_instance_id != forceunlock_filter)
 
 3597             if (it->rp_locked_ropable)
 
 3598                 it->rp_locked_ropable->attached_ropes--;
 
 3599             if (it->rp_locked_actor != 
this)
 
 3601                 this->RemoveInterActorBeam(it->rp_beam, mode); 
 
 3603             it->rp_locked_actor = 
nullptr;
 
 3604             it->rp_locked_ropable = 
nullptr;
 
 3606         else if (mode == ActorLinkingRequestType::ROPE_TOGGLE) 
 
 3610             float mindist = it->rp_beam->L;
 
 3616                 if (actor->ar_state == ActorState::LOCAL_SLEEPING)
 
 3619                 for (std::vector<ropable_t>::iterator itr = actor->ar_ropables.begin(); itr != actor->ar_ropables.end(); itr++)
 
 3622                     if (!itr->multilock && itr->attached_ropes > 0)
 
 3626                     float dist = (it->rp_beam->p1->AbsPosition - itr->node->AbsPosition).length();
 
 3630                         nearest_actor = actor;
 
 3640                 it->rp_locked_ropable = rop;
 
 3642                 if (nearest_actor != 
this)
 
 3644                      this->AddInterActorBeam(it->rp_beam, nearest_actor, mode); 
 
 3653     ROR_ASSERT(mode == ActorLinkingRequestType::HOOK_LOCK || mode == ActorLinkingRequestType::HOOK_UNLOCK
 
 3654             || mode == ActorLinkingRequestType::HOOK_TOGGLE || mode == ActorLinkingRequestType::HOOK_MOUSE_TOGGLE
 
 3655             || mode == ActorLinkingRequestType::HOOK_RESET);
 
 3658     for (std::vector<hook_t>::iterator it = ar_hooks.begin(); it != ar_hooks.end(); it++)
 
 3660         if (mode == ActorLinkingRequestType::HOOK_MOUSE_TOGGLE && it->hk_hook_node->pos != mousenode)
 
 3665         if (mode == ActorLinkingRequestType::HOOK_TOGGLE && group == -1)
 
 3668             if (it->hk_group <= -2)
 
 3671         if (mode == ActorLinkingRequestType::HOOK_LOCK && group == -2)
 
 3674             if (it->hk_group >= -1 || !it->hk_autolock)
 
 3677         if (mode == ActorLinkingRequestType::HOOK_UNLOCK && group == -2)
 
 3680             if (it->hk_group >= -1 || !it->hk_autolock)
 
 3683         if ((mode == ActorLinkingRequestType::HOOK_LOCK || mode == ActorLinkingRequestType::HOOK_UNLOCK) && group <= -3)
 
 3686             if (it->hk_group != group)
 
 3689         if ((mode == ActorLinkingRequestType::HOOK_LOCK || mode == ActorLinkingRequestType::HOOK_UNLOCK) && group >= -1)
 
 3693         if (mode == ActorLinkingRequestType::HOOK_LOCK && it->hk_timer > 0.0f)
 
 3700         if (mode == ActorLinkingRequestType::HOOK_RESET
 
 3701             && forceunlock_filter != 
ACTORINSTANCEID_INVALID && it->hk_locked_actor && it->hk_locked_actor->ar_instance_id != forceunlock_filter)
 
 3706         ActorPtr prev_locked_actor = it->hk_locked_actor; 
 
 3709         if ((mode != ActorLinkingRequestType::HOOK_UNLOCK && mode != ActorLinkingRequestType::HOOK_RESET) && it->hk_locked == 
UNLOCKED)
 
 3713             float mindist = it->hk_lockrange;
 
 3714             float distance = 100000000.0f;
 
 3718                 if (actor->ar_state == ActorState::LOCAL_SLEEPING)
 
 3720                 if (
this == actor.GetRef() && !it->hk_selflock)
 
 3723                 node_t* nearest_node = 
nullptr;
 
 3724                 for (
int i = 0; i < actor->ar_num_nodes; i++)
 
 3727                     if (actor->ar_nodes[i].nd_lockgroup == 9999)
 
 3731                     if (
this == actor.GetRef() && i == it->hk_hook_node->pos)
 
 3735                     if (it->hk_lockgroup != -1 && it->hk_lockgroup != actor->ar_nodes[i].nd_lockgroup)
 
 3739                     float n2n_distance = (it->hk_hook_node->AbsPosition - actor->ar_nodes[i].AbsPosition).length();
 
 3740                     if (n2n_distance < mindist)
 
 3742                         if (distance >= n2n_distance)
 
 3745                             distance = n2n_distance;
 
 3746                             nearest_node = &actor->ar_nodes[i];
 
 3753                     it->hk_lock_node = nearest_node;
 
 3754                     it->hk_locked_actor = actor;
 
 3757                     if (it->hk_beam->bm_disabled)
 
 3759                         it->hk_beam->p2 = it->hk_lock_node;
 
 3760                         it->hk_beam->bm_inter_actor = (it->hk_locked_actor != 
nullptr);
 
 3761                         it->hk_beam->L = (it->hk_hook_node->AbsPosition - it->hk_lock_node->AbsPosition).length();
 
 3762                         it->hk_beam->bm_disabled = 
false;
 
 3763                         this->AddInterActorBeam(it->hk_beam, it->hk_locked_actor, mode); 
 
 3769         else if ((it->hk_locked == 
LOCKED || it->hk_locked == 
PRELOCK) && (mode != ActorLinkingRequestType::HOOK_LOCK || !it->hk_beam->bm_inter_actor))
 
 3773             this->RemoveInterActorBeam(it->hk_beam, mode); 
 
 3774             if (it->hk_group <= -2)
 
 3777                 it->hk_timer = (mode == ActorLinkingRequestType::HOOK_RESET) ? 0.f : it->hk_timer_preset;
 
 3779             it->hk_lock_node = 0;
 
 3780             it->hk_locked_actor = 0;
 
 3782             it->hk_beam->p2 = &ar_nodes[0];
 
 3783             it->hk_beam->bm_inter_actor = 
false;
 
 3784             it->hk_beam->L = (ar_nodes[0].AbsPosition - it->hk_hook_node->AbsPosition).length();
 
 3785             it->hk_beam->bm_disabled = 
true;
 
 3790 void Actor::parkingbrakeToggle()
 
 3792     if (ar_state == ActorState::DISPOSED)
 
 3795     ar_parking_brake = !ar_parking_brake;
 
 3797     if (ar_parking_brake)
 
 3805 void Actor::antilockbrakeToggle()
 
 3807     if (ar_state == ActorState::DISPOSED)
 
 3811         alb_mode = !alb_mode;
 
 3814 void Actor::tractioncontrolToggle()
 
 3816     if (ar_state == ActorState::DISPOSED)
 
 3823 void Actor::beaconsToggle()
 
 3825     if (ar_state == ActorState::DISPOSED)
 
 3828     if (m_flares_mode == GfxFlaresMode::NONE)
 
 3839 void Actor::muteAllSounds()
 
 3842     if (ar_state == ActorState::DISPOSED)
 
 3845     for (
int i = 0; i < ar_num_soundsources; i++)
 
 3847         if (ar_soundsources[i].ssi)
 
 3848             ar_soundsources[i].ssi->setEnabled(
false);
 
 3850 #endif // USE_OPENAL 
 3853 void Actor::unmuteAllSounds()
 
 3856     if (ar_state == ActorState::DISPOSED)
 
 3859     for (
int i = 0; i < ar_num_soundsources; i++)
 
 3861         bool enabled = (ar_soundsources[i].type == -2 || ar_soundsources[i].type == ar_current_cinecam);
 
 3862         ar_soundsources[i].ssi->setEnabled(enabled);
 
 3864 #endif // USE_OPENAL 
 3867 void Actor::NotifyActorCameraChanged()
 
 3871     if (ar_state == ActorState::DISPOSED)
 
 3874     for (
int i = 0; i < ar_num_soundsources; i++)
 
 3876         bool enabled = (ar_soundsources[i].type == -2 || ar_soundsources[i].type == ar_current_cinecam);
 
 3877         ar_soundsources[i].ssi->setEnabled(enabled);
 
 3879 #endif // USE_OPENAL 
 3887 int Actor::GetNumActiveConnectedBeams(
int nodeid)
 
 3889     int totallivebeams = 0;
 
 3890     for (
unsigned int ni = 0; ni < ar_node_to_beam_connections[nodeid].size(); ++ni)
 
 3892         if (!ar_beams[ar_node_to_beam_connections[nodeid][ni]].bm_disabled && !ar_beams[ar_node_to_beam_connections[nodeid][ni]].bounded)
 
 3895     return totallivebeams;
 
 3898 bool Actor::isTied()
 
 3900     for (std::vector<tie_t>::iterator it = ar_ties.begin(); it != ar_ties.end(); it++)
 
 3906 bool Actor::isLocked()
 
 3908     for (std::vector<hook_t>::iterator it = ar_hooks.begin(); it != ar_hooks.end(); it++)
 
 3909         if (it->hk_locked == 
LOCKED)
 
 3914 void Actor::updateDashBoards(
float dt)
 
 3925         int gear = ar_engine->getGear();
 
 3928         int numGears = (int)ar_engine->getNumGears();
 
 3931         String str = String();
 
 3944         int cg = ar_engine->getAutoShift();
 
 3947             str = ((cg == 
Engine::REAR) ? 
"#ffffff" : 
"#868686") + String(
"R\n");
 
 3948             str += ((cg == 
Engine::NEUTRAL) ? 
"#ff0012" : 
"#8a000a") + String(
"N\n");
 
 3949             str += ((cg == 
Engine::DRIVE) ? 
"#12ff00" : 
"#248c00") + String(
"D\n");
 
 3950             str += ((cg == 
Engine::TWO) ? 
"#ffffff" : 
"#868686") + String(
"2\n");
 
 3951             str += ((cg == 
Engine::ONE) ? 
"#ffffff" : 
"#868686") + String(
"1");
 
 3956             str = 
"#b8b8b8M\na\nn\nu";
 
 3961         int autoGear = ar_engine->getAutoShift();
 
 3965         float clutch = ar_engine->getClutch();
 
 3969         float acc = ar_engine->getAcc();
 
 3973         float rpm = ar_engine->getRPM();
 
 3977         float turbo = ar_engine->getTurboPSI() * 3.34f; 
 
 3981         bool ign = (ar_engine->hasContact() && !ar_engine->isRunning());
 
 3985         bool batt = (ar_engine->hasContact() && !ar_engine->isRunning());
 
 3989         bool cw = (fabs(ar_engine->getTorque()) >= ar_engine->getClutchForce() * 10.0f);
 
 3994     ar_dashboard->setFloat(
DD_BRAKE, ar_brake);
 
 3996     Vector3 cam_dir  = this->GetCameraDir();
 
 3997     Vector3 cam_roll = this->GetCameraRoll();
 
 4000     float velocity = ar_nodes[0].Velocity.length();
 
 4001     if (cam_dir != Vector3::ZERO)
 
 4003         velocity = cam_dir.dotProduct(ar_nodes[0].Velocity);
 
 4007     float cur_speed_kph = ar_wheel_speed * 3.6f;
 
 4008     float smooth_kph = (cur_speed_kph * 0.3) + (ar_dashboard->_getFloat(
DD_ENGINE_SPEEDO_KPH) * 0.7);
 
 4012     float cur_speed_mph = ar_wheel_speed * 2.23693629f;
 
 4013     float smooth_mph = (cur_speed_mph * 0.3) + (ar_dashboard->_getFloat(
DD_ENGINE_SPEEDO_MPH) * 0.7);
 
 4017     if (cam_roll != Vector3::ZERO)
 
 4019         float angle = asin(cam_roll.dotProduct(Vector3::UNIT_Y));
 
 4025         float f = Radian(angle).valueDegrees();
 
 4026         ar_dashboard->setFloat(
DD_ROLL, f);
 
 4030     if (this->ar_has_active_shocks)
 
 4033         float roll_corr = - m_stabilizer_shock_ratio * 10.0f;
 
 4036         bool corr_active = (m_stabilizer_shock_request > 0);
 
 4041     if (cam_dir != Vector3::ZERO)
 
 4043         float angle = asin(cam_dir.dotProduct(Vector3::UNIT_Y));
 
 4049         float f = Radian(angle).valueDegrees();
 
 4050         ar_dashboard->setFloat(
DD_PITCH, f);
 
 4057     bool locked = isLocked();
 
 4058     ar_dashboard->setBool(
DD_LOCKED, locked);
 
 4061     bool low_pres = !ar_engine_hydraulics_ready;
 
 4069         int dash_tc_mode = 1; 
 
 4072             if (m_tractioncontrol)
 
 4083         int dash_alb_mode = 1; 
 
 4086             if (m_antilockbrake)
 
 4098         if (fabs(ar_command_key[0].commandValue) > 0.000001f)
 
 4106     if (ar_num_screwprops)
 
 4111             float throttle = ar_screwprops[i]->getThrottle();
 
 4114             float steering = ar_screwprops[i]->getRudder();
 
 4119         float depth = this->getHeightAboveGround();
 
 4123         Vector3 hdir = this->GetCameraDir();
 
 4124         float knots = hdir.dotProduct(ar_nodes[ar_main_camera_node_pos].Velocity) * 1.9438f; 
 
 4129     if (ar_num_aeroengines)
 
 4133             float throttle = ar_aeroengines[i]->getThrottle();
 
 4136             bool failed = ar_aeroengines[i]->isFailed();
 
 4139             float pcent = ar_aeroengines[i]->getRPMpc();
 
 4147         for (
int i = 0; i < ar_num_wings && i < 
DD_MAX_WING; i++)
 
 4150             float aoa = ar_wings[i].fa->aoa;
 
 4156     if (ar_num_wings || ar_num_aeroengines)
 
 4160             float ground_speed_kt = ar_nodes[0].Velocity.length() * 1.9438f; 
 
 4163             float altitude = ar_nodes[0].AbsPosition.y;
 
 4165             float sea_level_pressure = 101325; 
 
 4167             float airpressure = sea_level_pressure * pow(1.0f - 0.0065f * altitude / 288.15f, 5.24947f); 
 
 4168             float airdensity = airpressure * 0.0000120896f; 
 
 4170             float knots = ground_speed_kt * sqrt(airdensity / 1.225f); 
 
 4176             float alt = ar_nodes[0].AbsPosition.y * 1.1811f; 
 
 4180             sprintf(altc, 
"%03u", (
int)(ar_nodes[0].AbsPosition.y / 30.48f)); 
 
 4189     if (!m_hud_features_ok)
 
 4191         bool hasEngine = (ar_engine != 
nullptr);
 
 4192         bool hasturbo = 
false;
 
 4193         bool autogearVisible = 
false;
 
 4197             hasturbo = ar_engine->hasTurbo();
 
 4214         ar_dashboard->setEnabled(
DD_TIES_MODE, !ar_ties.empty());
 
 4215         ar_dashboard->setEnabled(
DD_LOCKED, !ar_hooks.empty());
 
 4219         ar_dashboard->updateFeatures();
 
 4220         m_hud_features_ok = 
true;
 
 4246     ar_dashboard->setBool(
DD_SIGNAL_WARNING,   m_blinker_right_lit && m_blinker_left_lit);
 
 4255     Vector3 rollv=curr_truck->ar_nodes[curr_truck->ar_camera_node_pos[0]].RelPosition-curr_truck->ar_nodes[curr_truck->ar_camera_node_roll[0]].RelPosition;
 
 4257     float rollangle=asin(rollv.dotProduct(Vector3::UNIT_Y));
 
 4260     Vector3 dirv=curr_truck->ar_nodes[curr_truck->ar_camera_node_pos[0]].RelPosition-curr_truck->ar_nodes[curr_truck->ar_camera_node_dir[0]].RelPosition;
 
 4262     float pitchangle=asin(dirv.dotProduct(Vector3::UNIT_Y));
 
 4263     Vector3 upv=dirv.crossProduct(-rollv);
 
 4264     if (upv.y<0) rollangle=3.14159-rollangle;
 
 4270     Vector3 idir=curr_truck->ar_nodes[curr_truck->ar_camera_node_pos[0]].RelPosition-curr_truck->ar_nodes[curr_truck->ar_camera_node_dir[0]].RelPosition;
 
 4272     float dirangle=atan2(idir.dotProduct(Vector3::UNIT_X), idir.dotProduct(-Vector3::UNIT_Z));
 
 4274     if (curr_truck->autopilot)
 
 4279         curr_truck->autopilot->getRadioFix(localizers, free_localizer, &vdev, &hdev);
 
 4280         if (hdev>15) hdev=15;
 
 4281         if (hdev<-15) hdev=-15;
 
 4283         if (vdev>15) vdev=15;
 
 4284         if (vdev<-15) vdev=-15;
 
 4289     float vvi=curr_truck->ar_nodes[0].Velocity.y*196.85;
 
 4290     if (vvi<1000.0 && vvi>-1000.0) angle=vvi*0.047;
 
 4291     if (vvi>1000.0 && vvi<6000.0) angle=47.0+(vvi-1000.0)*0.01175;
 
 4292     if (vvi>6000.0) angle=105.75;
 
 4293     if (vvi<-1000.0 && vvi>-6000.0) angle=-47.0+(vvi+1000.0)*0.01175;
 
 4294     if (vvi<-6000.0) angle=-105.75;
 
 4298     if (curr_truck->aeroengines[0]->getType() == AeroEngineType::AE_XPROP)
 
 4305         if (pcent<60.0) angle=-5.0+pcent*1.9167;
 
 4306         else if (pcent<110.0) angle=110.0+(pcent-60.0)*4.075;
 
 4311     if (ftp>1 && curr_truck->aeroengines[1]->getType() == AeroEngineType::AE_XPROP)
 
 4318         if (pcent<60.0) angle=-5.0+pcent*1.9167;
 
 4319         else if (pcent<110.0) angle=110.0+(pcent-60.0)*4.075;
 
 4324     if (ftp>2 && curr_truck->aeroengines[2]->getType() == AeroEngineType::AE_XPROP)
 
 4331         if (pcent<60.0) angle=-5.0+pcent*1.9167;
 
 4332         else if (pcent<110.0) angle=110.0+(pcent-60.0)*4.075;
 
 4337     if (ftp>3 && curr_truck->aeroengines[3]->getType() == AeroEngineType::AE_XPROP)
 
 4344         if (pcent<60.0) angle=-5.0+pcent*1.9167;
 
 4345         else if (pcent<110.0) angle=110.0+(pcent-60.0)*4.075;
 
 4358     ar_dashboard->
update(dt);
 
 4361 void Actor::calculateLocalGForces()
 
 4363     Vector3 cam_dir  = this->GetCameraDir();
 
 4364     Vector3 cam_roll = this->GetCameraRoll();
 
 4365     Vector3 cam_up   = cam_dir.crossProduct(cam_roll);
 
 4369     float vertacc = m_camera_gforces.dotProduct(cam_up) + gravity;
 
 4370     float longacc = m_camera_gforces.dotProduct(cam_dir);
 
 4371     float latacc  = m_camera_gforces.dotProduct(cam_roll);
 
 4373     m_camera_local_gforces_cur = Vector3(vertacc, longacc, latacc) / gravity;
 
 4376     if (m_reset_timer.getMilliseconds() > 500)
 
 4378         m_camera_local_gforces_max.makeCeil(-m_camera_local_gforces_cur);
 
 4379         m_camera_local_gforces_max.makeCeil(+m_camera_local_gforces_cur);
 
 4391             ar_engine->setClutch(triggerValue);
 
 4394         ar_brake = triggerValue;
 
 4398             ar_engine->setAcc(triggerValue);
 
 4405             ar_engine->shift(1);
 
 4409             ar_engine->shift(-1);
 
 4418     unsigned int vector_index,
 
 4423     : ar_nb_optimum(7, std::numeric_limits<float>::max())
 
 4424     , ar_nb_reference(7, std::numeric_limits<float>::max())
 
 4425     , m_tyre_pressure(this)
 
 4426     , ar_nb_beams_scale(std::make_pair(1.0f, 1.0f))
 
 4427     , ar_nb_shocks_scale(std::make_pair(1.0f, 1.0f))
 
 4428     , ar_nb_wheels_scale(std::make_pair(1.0f, 1.0f))
 
 4429     , ar_nb_beams_k_interval(std::make_pair(0.1f, 2.0f))
 
 4430     , ar_nb_beams_d_interval(std::make_pair(0.1f, 2.0f))
 
 4431     , ar_nb_shocks_k_interval(std::make_pair(0.1f, 8.0f))
 
 4432     , ar_nb_shocks_d_interval(std::make_pair(0.1f, 8.0f))
 
 4433     , ar_nb_wheels_k_interval(std::make_pair(1.0f, 1.0f))
 
 4434     , ar_nb_wheels_d_interval(std::make_pair(1.0f, 1.0f))
 
 4437     , m_avg_node_position_prev(rq.asr_position)
 
 4439     , m_avg_node_position(rq.asr_position)
 
 4440     , ar_instance_id(actor_id)
 
 4441     , ar_vector_index(vector_index)
 
 4442     , m_avg_proped_wheel_radius(0.2f)
 
 4443     , ar_filename(rq.asr_cache_entry->fname)
 
 4444     , m_section_config(rq.asr_config)
 
 4445     , m_used_actor_entry(rq.asr_cache_entry)
 
 4446     , m_used_skin_entry(rq.asr_skin_entry)
 
 4447     , m_working_tuneup_def(rq.asr_working_tuneup)
 
 4450     , ar_update_physics(false)
 
 4451     , ar_disable_aerodyn_turbulent_drag(false)
 
 4452     , ar_engine_hydraulics_ready(true) 
 
 4453     , ar_guisettings_use_engine_max_rpm(false)
 
 4454     , ar_hydro_speed_coupling(false)
 
 4455     , ar_collision_relevant(false)
 
 4456     , ar_is_police(false)
 
 4457     , ar_rescuer_flag(false)
 
 4458     , ar_forward_commands(false)
 
 4459     , ar_import_commands(false)
 
 4460     , ar_toggle_ropes(false)
 
 4461     , ar_toggle_ties(false)
 
 4464     , m_hud_features_ok(false)
 
 4465     , m_slidenodes_locked(false)
 
 4466     , m_net_initialized(false)
 
 4467     , m_water_contact(false)
 
 4468     , m_water_contact_old(false)
 
 4469     , m_has_command_beams(false)
 
 4470     , ar_cparticles_active(false)
 
 4471     , m_beam_break_debug_enabled(false)
 
 4472     , m_beam_deform_debug_enabled(false)
 
 4473     , m_trigger_debug_enabled(false)
 
 4474     , m_disable_default_sounds(false)
 
 4475     , m_disable_smoke(false)
 
 4555     for (
int i = 0; i < 
ar_flares.size(); i++)
 
 4557         if (
ar_flares[i].controlnumber == number)
 
 4566     for (
int i = 0; i < 
ar_flares.size(); i++)
 
 4606         return Ogre::MaterialPtr(); 
 
 4611     std::vector<std::string> names;
 
 4614         names.push_back(it->first);
 
 4627         return Ogre::Vector3::ZERO;
 
 4658     std::stringstream buf;
 
 4660     buf << 
"[nodes]" << std::endl;
 
 4670             << 
", loaded:"           << (int)(
ar_nodes[i].nd_loaded_mass)
 
 4672             << 
" wheel_rim:"         << (int)
ar_nodes[i].nd_rim_node
 
 4674             << 
" (set_node_defaults)" 
 4688     buf << 
"[beams]" << std::endl;
 
 4692             << 
"  "                  << std::setw(4) << i 
 
 4696             << 
" (set_beam_defaults/scale)" 
 4697             << 
" spring:"            << std::setw(8) << 
ar_beams[i].
k  
 4698             << 
", damp:"             << std::setw(8) << 
ar_beams[i].
d  
 4708     Ogre::DataStreamPtr outStream = Ogre::ResourceGroupManager::getSingleton().createResource(fileName, 
RGN_LOGS, 
true);
 
 4709     std::string text = buf.str();
 
 4710     outStream->write(text.c_str(), text.length());
 
 4718         if (state.eventlock_present)
 
 4721             if (ev_active && (ev_active != state.event_active_prev))
 
 4723                 state.anim_active = !state.anim_active;
 
 4729             state.anim_active = ev_active;
 
 4731         state.event_active_prev = ev_active;
 
 4819             "Cannot change simulation attributes in multiplayer mode.");
 
 4921     default: 
return 0.f;