Skip to content

Commit

Permalink
(3rd edition) Fixed huge FPS drop when nodes move far away from vehicle
Browse files Browse the repository at this point in the history
Fixed RigsOfRods#3058 - caused by 539a1b2

Changes:
* for eventbox triggering, only consider a bounding box around collision cab nodes. It makes more sense physically and also eliminates surprises, as loose cab nodes would be easily visible.
* ignore cabnodes farther than 15m
  • Loading branch information
ohlidalp committed Sep 3, 2023
1 parent 699e203 commit 008e77a
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 1 deletion.
11 changes: 11 additions & 0 deletions source/main/physics/Actor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1116,12 +1116,18 @@ void Actor::UpdateBoundingBoxes()
// Reset
ar_bounding_box = AxisAlignedBox::BOX_NULL;
ar_predicted_bounding_box = AxisAlignedBox::BOX_NULL;
ar_cabnodes_bounding_box = AxisAlignedBox::BOX_NULL;
for (size_t i = 0; i < ar_collision_bounding_boxes.size(); ++i)
{
ar_collision_bounding_boxes[i] = AxisAlignedBox::BOX_NULL;
ar_predicted_coll_bounding_boxes[i] = AxisAlignedBox::BOX_NULL;
}

// To avoid performance choking by overstretched bounding box (happens when vehicle drops some nodes),
// we set a maximum distance limit from the main camera.
const float CABNODE_MAX_CAMDIST = 15.f;
const Ogre::Vector3 mainCamPos = ar_nodes[ar_main_camera_node_pos].RelPosition;

// Update
for (int i = 0; i < ar_num_nodes; i++)
{
Expand All @@ -1130,6 +1136,11 @@ void Actor::UpdateBoundingBoxes()
int16_t cid = ar_nodes[i].nd_coll_bbox_id;

ar_bounding_box.merge(pos); // Current box
if (ar_nodes[i].nd_cab_node // Current cab-nodes box (for eventbox collisions)
&& (mainCamPos.squaredDistance(ar_nodes[i].RelPosition)) < (CABNODE_MAX_CAMDIST*CABNODE_MAX_CAMDIST)) // ... we compare squared distance for performance
{
ar_cabnodes_bounding_box.merge(pos);
}
ar_predicted_bounding_box.merge(pos); // Predicted box (current position)
ar_predicted_bounding_box.merge(pos + vel); // Predicted box (future position)
if (cid != node_t::INVALID_BBOX)
Expand Down
1 change: 1 addition & 0 deletions source/main/physics/Actor.h
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ class Actor : public RefCountingObject<Actor>
std::vector<Airbrake*> ar_airbrakes;
CmdKeyArray ar_command_key; //!< BEWARE: commandkeys are indexed 1-MAX_COMMANDS!
Ogre::AxisAlignedBox ar_bounding_box; //!< standard bounding box (surrounds all nodes of an actor)
Ogre::AxisAlignedBox ar_cabnodes_bounding_box; //!< bounding box around cab-triangle nodes only
Ogre::AxisAlignedBox ar_predicted_bounding_box;
float ar_initial_total_mass = 0.f;
std::vector<float> ar_initial_node_masses;
Expand Down
5 changes: 4 additions & 1 deletion source/main/physics/collision/Collisions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1088,8 +1088,11 @@ bool Collisions::nodeCollision(node_t *node, float dt)

void Collisions::findPotentialEventBoxes(Actor* actor, CollisionBoxPtrVec& out_boxes)
{
// NOTE: Only collision-cab nodes are considered for eventbox triggering!
// ----------------------------------------------------------------------

// Find collision cells occupied by the actor (remember 'Y' is 'up').
const AxisAlignedBox aabb = actor->ar_bounding_box;
const AxisAlignedBox aabb = actor->ar_cabnodes_bounding_box;
const int cell_lo_x = (int)(aabb.getMinimum().x / (float)CELL_SIZE);
const int cell_lo_z = (int)(aabb.getMinimum().z / (float)CELL_SIZE);
const int cell_hi_x = (int)(aabb.getMaximum().x / (float)CELL_SIZE);
Expand Down

0 comments on commit 008e77a

Please sign in to comment.