Rigs of Rods 2023.09
Soft-body Physics Simulation
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Loading...
Searching...
No Matches
Collisions.h
Go to the documentation of this file.
1/*
2 This source file is part of Rigs of Rods
3 Copyright 2005-2012 Pierre-Michel Ricordel
4 Copyright 2007-2012 Thomas Fischer
5 Copyright 2009 Lefteris Stamatogiannakis
6 Copyright 2013-2022 Petr Ohlidal
7
8 For more information, see http://www.rigsofrods.org/
9
10 Rigs of Rods is free software: you can redistribute it and/or modify
11 it under the terms of the GNU General Public License version 3, as
12 published by the Free Software Foundation.
13
14 Rigs of Rods is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with Rigs of Rods. If not, see <http://www.gnu.org/licenses/>.
21*/
22
23#pragma once
24
25#include "Application.h"
26#include "SimData.h" // for collision_box_t
27
28#include <mutex>
29#include <Ogre.h>
30#include <string>
31
32namespace RoR {
33
36
39
41{
42 std::string es_instance_name;
43 std::string es_box_name;
44 Ogre::Quaternion es_direction;
46 int es_cbox;
48};
49
51{
52 Ogre::Vector3 a;
53 Ogre::Vector3 b;
54 Ogre::Vector3 c;
55 Ogre::AxisAlignedBox aab;
56 Ogre::Matrix3 forward;
57 Ogre::Matrix3 reverse;
59 bool enabled;
60};
61typedef std::vector<collision_tri_t> CollisionTriVec;
62
65{
66 std::string mesh_name;
67 std::string source_name;
68 Ogre::Vector3 position = Ogre::Vector3::ZERO;
69 Ogre::Quaternion orientation = Ogre::Quaternion::IDENTITY;
70 Ogre::Vector3 scale = Ogre::Vector3::ZERO;
71 Ogre::AxisAlignedBox bounding_box;
75 int num_verts = 0;
76 int num_indices = 0;
77};
78typedef std::vector<collision_mesh_t> CollisionMeshVec;
79
81{
82public:
83
84 typedef std::vector<collision_box_t> CollisionBoxVec;
85
87 {
89 FX_HARD, // hard surface: rubber burning and sparks
90 FX_DUSTY, // dusty surface (with dust colour)
91 FX_CLUMPY, // throws clumps (e.g. snow, grass) with colour
93 };
94
95 Collisions(Ogre::Vector3 terrn_size);
97
98private:
99
105 {
106 static const int ELEMENT_TRI_BASE_INDEX = 1000000; // Effectively a maximum number of collision boxes
107
108 inline hash_coll_element_t(unsigned int cell_id_, int value): cell_id(cell_id_), element_index(value) {}
109
110 inline bool IsCollisionBox() const { return element_index < ELEMENT_TRI_BASE_INDEX; }
111 inline bool IsCollisionTri() const { return element_index >= ELEMENT_TRI_BASE_INDEX; }
112
113 unsigned int cell_id;
114
118 };
119
120 static const int LATEST_GROUND_MODEL_VERSION = 3;
121 static const int MAX_EVENT_SOURCE = 500;
122
123 // this is a power of two, change with caution
124 static const int HASH_POWER = 20;
125 static const int HASH_SIZE = 1 << HASH_POWER;
126
127 // terrain size is limited to 327km x 327km:
128 static const int CELL_SIZE = 2.0; // we divide through this
129 static const int MAXIMUM_CELL = 0x7FFF;
130
131 // collision boxes pool
132 CollisionBoxVec m_collision_boxes; // Formerly MAX_COLLISION_BOXES = 5000
133 std::vector<collision_box_t*> m_last_called_cboxes; // Only used for character, actors have their own cache `Actor::m_active_eventboxes`
134
135 // collision tris pool
136 CollisionTriVec m_collision_tris; // Formerly MAX_COLLISION_TRIS = 100000
137 CollisionMeshVec m_collision_meshes; // For diagnostics/editing only.
138
139 Ogre::AxisAlignedBox m_collision_aab; // Tight bounding box around all collision meshes
140
141 // collision hashtable
142 std::array<float, HASH_SIZE> hashtable_height;
143 std::vector<hash_coll_element_t> hashtable[HASH_SIZE];
144
145 // ground models
146 std::map<Ogre::String, ground_model_t> ground_models;
147
148 // event sources
151
152 bool permitEvent(Actor* actor, CollisionEventFilter filter);
153
156 unsigned int hashmask;
157
158 const Ogre::Vector3 m_terrain_size;
159
160 void hash_add(int cell_x, int cell_z, int value, float h);
161 int hash_find(int cell_x, int cell_z);
162 unsigned int hashfunc(unsigned int cellid);
163 void parseGroundConfig(Ogre::ConfigFile* cfg, Ogre::String groundModel = "");
164
165 Ogre::Vector3 calcCollidedSide(const Ogre::Vector3& pos, const Ogre::Vector3& lo, const Ogre::Vector3& hi);
166
167public:
168
169 // how many elements per cell? power of 2 minus 2 is better
170 static const int CELL_BLOCKSIZE = 126;
171
173 Ogre::Vector3 forcecampos;
175
176 Ogre::Vector3 getPosition(const Ogre::String& inst, const Ogre::String& box);
177 Ogre::Quaternion getDirection(const Ogre::String& inst, const Ogre::String& box);
178 collision_box_t* getBox(const Ogre::String& inst, const Ogre::String& box);
179 const int GetCellSize() const { return CELL_SIZE; }
180
181 std::pair<bool, Ogre::Real> intersectsTris(Ogre::Ray ray);
182
188 std::pair<bool, Ogre::Real> intersectsTerrain(Ogre::Ray ray);
189
190 float getSurfaceHeight(float x, float z);
191 float getSurfaceHeightBelow(float x, float z, float height);
192 bool collisionCorrect(Ogre::Vector3* refpos, bool envokeScriptCallbacks = true);
193 bool groundCollision(node_t* node, float dt);
194 bool isInside(Ogre::Vector3 pos, const Ogre::String& inst, const Ogre::String& box, float border = 0);
195 bool isInside(Ogre::Vector3 pos, collision_box_t* cbox, float border = 0);
196 bool nodeCollision(node_t* node, float dt);
197 void envokeScriptCallback(collision_box_t* cbox, node_t* node = 0); // Only invoke on main thread! Oterwise use `MSG_SIM_SCRIPT_CALLBACK_QUEUED`
198 void findPotentialEventBoxes(Actor* actor, CollisionBoxPtrVec& out_boxes);
199
201
202 int addCollisionBox(bool rotating, bool virt, Ogre::Vector3 pos, Ogre::Vector3 rot, Ogre::Vector3 l, Ogre::Vector3 h, Ogre::Vector3 sr, const Ogre::String& eventname, const Ogre::String& instancename, const Ogre::String& reverb_preset_name, bool forcecam, Ogre::Vector3 campos, Ogre::Vector3 sc = Ogre::Vector3::UNIT_SCALE, Ogre::Vector3 dr = Ogre::Vector3::ZERO, CollisionEventFilter event_filter = EVENT_ALL, int scripthandler = -1);
203 void addCollisionMesh(Ogre::String const& srcname, Ogre::String const& meshname, Ogre::Vector3 const& pos, Ogre::Quaternion const& q, Ogre::Vector3 const& scale, ground_model_t* gm = 0, std::vector<int>* collTris = 0);
204 void registerCollisionMesh(Ogre::String const& srcname, Ogre::String const& meshname, Ogre::Vector3 const& pos, Ogre::AxisAlignedBox bounding_box, ground_model_t* gm, int ctri_start, int ctri_count);
205 int addCollisionTri(Ogre::Vector3 p1, Ogre::Vector3 p2, Ogre::Vector3 p3, ground_model_t* gm);
206 void createCollisionDebugVisualization(Ogre::SceneNode* root_node, Ogre::AxisAlignedBox const& area_limit, std::vector<Ogre::SceneNode*>& out_nodes);
207 void removeCollisionBox(int number);
208 void removeCollisionTri(int number);
210
211 Ogre::AxisAlignedBox getCollisionAAB() { return m_collision_aab; };
212
213 // ground models things
214 int loadDefaultModels();
215 int loadGroundModelsConfigFile(Ogre::String filename);
216 std::map<Ogre::String, ground_model_t>* getGroundModels() { return &ground_models; };
217 void setupLandUse(const char* configfile);
218 ground_model_t* getGroundModelByString(const Ogre::String name);
219
220 void getMeshInformation(Ogre::Mesh* mesh, size_t& vertex_count, Ogre::Vector3* & vertices,
221 size_t& index_count, unsigned* & indices,
222 const Ogre::Vector3& position = Ogre::Vector3::ZERO,
223 const Ogre::Quaternion& orient = Ogre::Quaternion::IDENTITY, const Ogre::Vector3& scale = Ogre::Vector3::UNIT_SCALE);
224
229};
230
231Ogre::Vector3 primitiveCollision(node_t* node, Ogre::Vector3 velocity, float mass, Ogre::Vector3 normal, float dt, ground_model_t* gm, float penetration = 0);
232
235
236} // namespace RoR
Central state/object manager and communications hub.
#define ROR_ASSERT(_EXPR)
Definition Application.h:40
Core data structures for simulation; Everything affected by by either physics, network or user intera...
Softbody object; can be anything from soda can to a space shuttle Constructed from a truck definition...
Definition Actor.h:55
void registerCollisionMesh(Ogre::String const &srcname, Ogre::String const &meshname, Ogre::Vector3 const &pos, Ogre::AxisAlignedBox bounding_box, ground_model_t *gm, int ctri_start, int ctri_count)
Mark already generated collision tris as belonging to (virtual) mesh.
std::pair< bool, Ogre::Real > intersectsTris(Ogre::Ray ray)
collision_box_t * getBox(const Ogre::String &inst, const Ogre::String &box)
float getSurfaceHeightBelow(float x, float z, float height)
static const int CELL_SIZE
Definition Collisions.h:128
unsigned int hashmask
Definition Collisions.h:156
std::vector< hash_coll_element_t > hashtable[HASH_SIZE]
Definition Collisions.h:143
const Ogre::Vector3 m_terrain_size
Definition Collisions.h:158
int addCollisionBox(bool rotating, bool virt, Ogre::Vector3 pos, Ogre::Vector3 rot, Ogre::Vector3 l, Ogre::Vector3 h, Ogre::Vector3 sr, const Ogre::String &eventname, const Ogre::String &instancename, const Ogre::String &reverb_preset_name, bool forcecam, Ogre::Vector3 campos, Ogre::Vector3 sc=Ogre::Vector3::UNIT_SCALE, Ogre::Vector3 dr=Ogre::Vector3::ZERO, CollisionEventFilter event_filter=EVENT_ALL, int scripthandler=-1)
bool collisionCorrect(Ogre::Vector3 *refpos, bool envokeScriptCallbacks=true)
static const int LATEST_GROUND_MODEL_VERSION
Definition Collisions.h:120
bool nodeCollision(node_t *node, float dt)
void getMeshInformation(Ogre::Mesh *mesh, size_t &vertex_count, Ogre::Vector3 *&vertices, size_t &index_count, unsigned *&indices, const Ogre::Vector3 &position=Ogre::Vector3::ZERO, const Ogre::Quaternion &orient=Ogre::Quaternion::IDENTITY, const Ogre::Vector3 &scale=Ogre::Vector3::UNIT_SCALE)
int hash_find(int cell_x, int cell_z)
std::pair< bool, Ogre::Real > intersectsTerrain(Ogre::Ray ray)
Checks whether a Ray intersects the terrain.
Ogre::Vector3 getPosition(const Ogre::String &inst, const Ogre::String &box)
static const int MAXIMUM_CELL
Definition Collisions.h:129
int loadGroundModelsConfigFile(Ogre::String filename)
Ogre::Quaternion getDirection(const Ogre::String &inst, const Ogre::String &box)
int addCollisionTri(Ogre::Vector3 p1, Ogre::Vector3 p2, Ogre::Vector3 p3, ground_model_t *gm)
bool groundCollision(node_t *node, float dt)
void removeCollisionBox(int number)
std::map< Ogre::String, ground_model_t > * getGroundModels()
Definition Collisions.h:216
Ogre::AxisAlignedBox m_collision_aab
Definition Collisions.h:139
bool permitEvent(Actor *actor, CollisionEventFilter filter)
CollisionMeshVec const & getCollisionMeshes() const
Definition Collisions.h:227
ground_model_t * getGroundModelByString(const Ogre::String name)
void removeCollisionTri(int number)
CollisionBoxVec m_collision_boxes
Definition Collisions.h:132
unsigned int hashfunc(unsigned int cellid)
Returns index to 'hashtable'.
void findPotentialEventBoxes(Actor *actor, CollisionBoxPtrVec &out_boxes)
CollisionBoxVec const & getCollisionBoxes() const
Definition Collisions.h:226
static const int HASH_POWER
Definition Collisions.h:124
std::map< Ogre::String, ground_model_t > ground_models
Definition Collisions.h:146
eventsource_t eventsources[MAX_EVENT_SOURCE]
Definition Collisions.h:149
Ogre::AxisAlignedBox getCollisionAAB()
Definition Collisions.h:211
void parseGroundConfig(Ogre::ConfigFile *cfg, Ogre::String groundModel="")
std::array< float, HASH_SIZE > hashtable_height
Definition Collisions.h:142
void setupLandUse(const char *configfile)
ground_model_t * defaultgm
Definition Collisions.h:174
std::vector< collision_box_t > CollisionBoxVec
Definition Collisions.h:84
static const int HASH_SIZE
Definition Collisions.h:125
void hash_add(int cell_x, int cell_z, int value, float h)
float getSurfaceHeight(float x, float z)
Ogre::Vector3 forcecampos
Definition Collisions.h:173
std::vector< collision_box_t * > m_last_called_cboxes
Definition Collisions.h:133
const int GetCellSize() const
Definition Collisions.h:179
static const int CELL_BLOCKSIZE
Definition Collisions.h:170
Ogre::Vector3 calcCollidedSide(const Ogre::Vector3 &pos, const Ogre::Vector3 &lo, const Ogre::Vector3 &hi)
static const int MAX_EVENT_SOURCE
Definition Collisions.h:121
void clearEventCache()
Definition Collisions.h:209
eventsource_t & getEventSource(int pos)
Definition Collisions.h:225
void createCollisionDebugVisualization(Ogre::SceneNode *root_node, Ogre::AxisAlignedBox const &area_limit, std::vector< Ogre::SceneNode * > &out_nodes)
Landusemap * landuse
Definition Collisions.h:154
CollisionTriVec const & getCollisionTriangles() const
Definition Collisions.h:228
CollisionTriVec m_collision_tris
Definition Collisions.h:136
CollisionMeshVec m_collision_meshes
Definition Collisions.h:137
void finishLoadingTerrain()
bool isInside(Ogre::Vector3 pos, const Ogre::String &inst, const Ogre::String &box, float border=0)
void envokeScriptCallback(collision_box_t *cbox, node_t *node=0)
void addCollisionMesh(Ogre::String const &srcname, Ogre::String const &meshname, Ogre::Vector3 const &pos, Ogre::Quaternion const &q, Ogre::Vector3 const &scale, ground_model_t *gm=0, std::vector< int > *collTris=0)
generate collision tris from existing mesh resource
ground_model_t * defaultgroundgm
Definition Collisions.h:174
std::vector< collision_box_t * > CollisionBoxPtrVec
Definition SimData.h:700
Ogre::Vector3 primitiveCollision(node_t *node, Ogre::Vector3 velocity, float mass, Ogre::Vector3 normal, float dt, ground_model_t *gm, float penetration=0)
std::vector< collision_tri_t > CollisionTriVec
Definition Collisions.h:61
std::vector< collision_mesh_t > CollisionMeshVec
Definition Collisions.h:78
CollisionEventFilter
Specified in terrain object (.ODEF) file, syntax: 'event <type> <filter>'.
Definition SimData.h:47
@ EVENT_ALL
(default) ~ Triggered by any node on any vehicle
Definition SimData.h:49
hash_coll_element_t(unsigned int cell_id_, int value)
Definition Collisions.h:108
int element_index
Values below ELEMENT_TRI_BASE_INDEX are collision box indices (Collisions::m_collision_boxes),...
Definition Collisions.h:117
Records which collision triangles belong to which mesh.
Definition Collisions.h:65
Ogre::Vector3 scale
Definition Collisions.h:70
std::string source_name
Definition Collisions.h:67
Ogre::Vector3 position
Definition Collisions.h:68
Ogre::Quaternion orientation
Definition Collisions.h:69
std::string mesh_name
Definition Collisions.h:66
Ogre::AxisAlignedBox bounding_box
Definition Collisions.h:71
ground_model_t * ground_model
Definition Collisions.h:72
Ogre::Matrix3 reverse
Definition Collisions.h:57
Ogre::Matrix3 forward
Definition Collisions.h:56
ground_model_t * gm
Definition Collisions.h:58
Ogre::Vector3 a
Definition Collisions.h:52
Ogre::AxisAlignedBox aab
Definition Collisions.h:55
Ogre::Vector3 b
Definition Collisions.h:53
Ogre::Vector3 c
Definition Collisions.h:54
< Scripting
Definition Collisions.h:41
int es_script_handler
AngelScript function ID.
Definition Collisions.h:45
std::string es_box_name
Specified in ODEF file as "event".
Definition Collisions.h:43
int es_cbox
Collision box ID.
Definition Collisions.h:46
Ogre::Quaternion es_direction
Definition Collisions.h:44
std::string es_instance_name
Specified by user when calling "GameScript::spawnObject()".
Definition Collisions.h:42
Surface friction properties.
Definition SimData.h:704
Physics: A vertex in the softbody structure.
Definition SimData.h:260