50 const Vector3 &normal,
51 const node_t &surface_point,
52 const std::vector<int> &neighbour_node_ids,
55 auto sign = [](
float x){
return (
x >= 0) ? 1 : -1; };
63 int face_indicator = weight *
sign(distance);
66 if (neighbour_node_ids.size() > weight) {
67 for (
auto id : neighbour_node_ids) {
68 const auto neighbour_distance = normal.dotProduct(nodes[
id].AbsPosition - surface_point.
AbsPosition);
69 face_indicator +=
sign(neighbour_distance);
74 return (face_indicator < 0);
91 const auto distance = local.
distance;
92 return (coord.alpha >= 0) && (coord.beta >= 0) && (coord.gamma >= 0) && (std::abs(distance) <= margin);
99 const float alpha,
const float beta,
const float gamma,
100 const Vector3 &normal,
106 const float tr_mass = na.
mass * alpha + nb.
mass * beta + no.
mass * gamma;
107 const float mass = remote ? hitnode.
mass : (hitnode.
mass * tr_mass) / (hitnode.
mass + tr_mass);
109 auto forcevec =
primitiveCollision(&hitnode, velocity, mass, normal, dt, &submesh_ground_model, penetration_depth);
111 hitnode.
Forces += forcevec;
112 na.
Forces -= forcevec * alpha;
113 nb.
Forces -= forcevec * beta;
114 no.
Forces -= forcevec * gamma;
119 const int free_collcab,
int collcabs[],
int cabs[],
121 const float collrange,
124 for (
int i=0; i<free_collcab; i++)
126 if (inter_collcabrate[i].rate > 0)
129 inter_collcabrate[i].
rate--;
132 inter_collcabrate[i].
rate = std::min(inter_collcabrate[i].distance, 12);
135 int tmpv = collcabs[i]*3;
136 const auto no = &nodes[cabs[tmpv]];
137 const auto na = &nodes[cabs[tmpv+1]];
138 const auto nb = &nodes[cabs[tmpv+2]];
140 interPointCD.
query(no->AbsPosition
142 , nb->AbsPosition, collrange);
147 const Triangle triangle(na->AbsPosition, nb->AbsPosition, no->AbsPosition);
164 const auto local_point = transform(hitnode.
AbsPosition);
170 inter_collcabrate[i].
rate = 0;
172 const auto coord = local_point.barycentric;
173 auto distance = local_point.distance;
174 auto normal = triangle.
normal();
183 distance = -distance;
186 const auto penetration_depth = collrange - distance;
188 const bool remote = (hit_actor->
ar_state == ActorState::NETWORKED_OK);
191 coord.beta, coord.gamma, normal, dt, remote, submesh_ground_model);
195 na->nd_has_mesh_contact =
true;
196 nb->nd_has_mesh_contact =
true;
197 no->nd_has_mesh_contact =
true;
204 inter_collcabrate[i].
rate++;
211 const int free_collcab,
int collcabs[],
int cabs[],
213 const float collrange,
216 for (
int i=0; i<free_collcab; i++)
218 if (intra_collcabrate[i].rate > 0)
221 intra_collcabrate[i].
rate--;
224 if (intra_collcabrate[i].distance > 0)
226 intra_collcabrate[i].
rate = std::min(intra_collcabrate[i].distance, 12);
230 int tmpv = collcabs[i]*3;
231 const auto no = &nodes[cabs[tmpv]];
232 const auto na = &nodes[cabs[tmpv+1]];
233 const auto nb = &nodes[cabs[tmpv+2]];
235 intraPointCD.
query(no->AbsPosition
237 , nb->AbsPosition, collrange);
239 bool collision =
false;
244 const Triangle triangle(na->AbsPosition, nb->AbsPosition, no->AbsPosition);
250 node_t& hitnode = nodes[hitnode_num];
254 if (no == &hitnode || na == &hitnode || nb == &hitnode)
continue;
257 const auto local_point = transform(hitnode.
AbsPosition);
265 const auto coord = local_point.barycentric;
266 auto distance = local_point.distance;
267 auto normal = triangle.
normal();
274 distance = -distance;
277 const auto penetration_depth = collrange - distance;
280 coord.beta, coord.gamma, normal, dt,
false, submesh_ground_model);
287 intra_collcabrate[i].
rate = -20000;
291 intra_collcabrate[i].
rate++;
Central state/object manager and communications hub.
float sign(const float x)
void ResolveCollisionForces(const float penetration_depth, node_t &hitnode, node_t &na, node_t &nb, node_t &no, const float alpha, const float beta, const float gamma, const Vector3 &normal, const float dt, const bool remote, ground_model_t &submesh_ground_model)
Calculate collision forces and apply them to the collision node and the three vertex nodes of the col...
static bool InsideTriangleTest(const CartesianToTriangleTransform::TriangleCoord &local, const float margin)
Test if a point given in triangle local coordinates lies within the triangle itself.
static bool BackfaceCollisionTest(const float distance, const Vector3 &normal, const node_t &surface_point, const std::vector< int > &neighbour_node_ids, const node_t nodes[])
Determine on which side of a triangle an occuring collision takes place.
Game state manager and message-queue provider.
Core data structures for simulation; Everything affected by by either physics, network or user intera...
std::vector< std::vector< int > > ar_node_to_node_connections
const ActorPtr & GetActorById(ActorInstanceID_t actor_id)
ActorManager * GetActorManager()
void query(const Ogre::Vector3 &vec1, const Ogre::Vector3 &vec2, const Ogre::Vector3 &vec3, const float enlargeBB)
std::vector< PointidID_t > hit_list
std::vector< pointid_t > hit_pointid_list
std::unordered_set< ActorInstanceID_t > hit_list_actorset
Represents a triangle in three-dimensional space.
Ogre::Vector3 normal() const
Return normal vector of the triangle.
Ogre::Vector3 primitiveCollision(node_t *node, Ogre::Vector3 velocity, float mass, Ogre::Vector3 normal, float dt, ground_model_t *gm, float penetration=0)
void ResolveIntraActorCollisions(const float dt, PointColDetector &intraPointCD, const int free_collcab, int collcabs[], int cabs[], collcab_rate_t intra_collcabrate[], node_t nodes[], const float collrange, ground_model_t &submesh_ground_model)
void ResolveInterActorCollisions(const float dt, PointColDetector &interPointCD, const int free_collcab, int collcabs[], int cabs[], collcab_rate_t inter_collcabrate[], node_t nodes[], const float collrange, ground_model_t &submesh_ground_model)
GameContext * GetGameContext()
int ActorInstanceID_t
Unique sequentially generated ID of an actor in session. Use ActorManager::GetActorById()
uint16_t NodeNum_t
Node position within Actor::ar_nodes; use RoR::NODENUM_INVALID as empty value.
int PointidID_t
index to PointColDetector::hit_pointid_list, use RoR::POINTIDID_INVALID as empty value.
Surface friction properties.
Physics: A vertex in the softbody structure.
Ogre::Vector3 AbsPosition
absolute position in the world (shaky)
bool nd_has_mesh_contact
Physics state.
ground_model_t * nd_last_collision_gm
Physics state; last collision 'ground model' (surface definition)
bool nd_tyre_node
Attr; This node is part of a tyre (note some wheel types don't use rim nodes at all)