41 #if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
42 #pragma GCC diagnostic ignored "-Wfloat-equal"
43 #endif //OGRE_PLATFORM_LINUX
49 0xF53E1837, 0x5F14C86B, 0x9EE3964C, 0xFA796D53,
50 0x32223FC3, 0x4D82BC98, 0xA0C7FA62, 0x63E2C982,
51 0x24994A5B, 0x1ECE7BEE, 0x292B38EF, 0xD5CD4E56,
52 0x514F4303, 0x7BE12B83, 0x7192F195, 0x82DC7300,
53 0x084380B4, 0x480B55D3, 0x5F430471, 0x13F75991,
54 0x3F9CF22C, 0x2FE0907A, 0xFD8E1E69, 0x7B1D5DE8,
55 0xD575A85C, 0xAD01C50A, 0x7EE00737, 0x3CE981E8,
56 0x0E447EFA, 0x23089DD6, 0xB59F149F, 0x13600EC7,
57 0xE802C8E6, 0x670921E4, 0x7207EFF0, 0xE74761B0,
58 0x69035234, 0xBFA40F19, 0xF63651A0, 0x29E64C26,
59 0x1F98CCA7, 0xD957007E, 0xE71DDC75, 0x3E729595,
60 0x7580B7CC, 0xD7FAF60B, 0x92484323, 0xA44113EB,
61 0xE4CBDE08, 0x346827C9, 0x3CF32AFA, 0x0B29BCF1,
62 0x6E29F7DF, 0xB01E71CB, 0x3BFBC0D1, 0x62EDC5B8,
63 0xB7DE789A, 0xA4748EC9, 0xE17A4C4F, 0x67E5BD03,
64 0xF3B33D1A, 0x97D8D3E9, 0x09121BC0, 0x347B2D2C,
65 0x79A1913C, 0x504172DE, 0x7F1F8483, 0x13AC3CF6,
66 0x7A2094DB, 0xC778FA12, 0xADF7469F, 0x21786B7B,
67 0x71A445D0, 0xA8896C1B, 0x656F62FB, 0x83A059B3,
68 0x972DFE6E, 0x4122000C, 0x97D9DA19, 0x17D5947B,
69 0xB1AFFD0C, 0x6EF83B97, 0xAF7F780B, 0x4613138A,
70 0x7C3E73A6, 0xCF15E03D, 0x41576322, 0x672DF292,
71 0xB658588D, 0x33EBEFA9, 0x938CBF06, 0x06B67381,
72 0x07F192C6, 0x2BDA5855, 0x348EE0E8, 0x19DBB6E3,
73 0x3222184B, 0xB69D5DBA, 0x7E760B88, 0xAF4D8154,
74 0x007A51AD, 0x35112500, 0xC9CD2D7D, 0x4F4FB761,
75 0x694772E3, 0x694C8351, 0x4A7E3AF5, 0x67D65CE1,
76 0x9287DE92, 0x2518DB3C, 0x8CB4EC06, 0xD154D38F,
77 0xE19A26BB, 0x295EE439, 0xC50A1104, 0x2153C6A7,
78 0x82366656, 0x0713BC2F, 0x6462215A, 0x21D9BFCE,
79 0xBA8EACE6, 0xAE2DF4C1, 0x2A8D5E80, 0x3F7E52D1,
80 0x29359399, 0xFEA1D19C, 0x18879313, 0x455AFA81,
81 0xFADFE838, 0x62609838, 0xD1028839, 0x0736E92F,
82 0x3BCA22A3, 0x1485B08A, 0x2DA7900B, 0x852C156D,
83 0xE8F24803, 0x00078472, 0x13F0D332, 0x2ACFD0CF,
84 0x5F747F5C, 0x87BB1E2F, 0xA7EFCB63, 0x23F432F0,
85 0xE6CE7C5C, 0x1F954EF6, 0xB609C91B, 0x3B4571BF,
86 0xEED17DC0, 0xE556CDA0, 0xA7846A8D, 0xFF105F94,
87 0x52B7CCDE, 0x0E33E801, 0x664455EA, 0xF2C70414,
88 0x73E7B486, 0x8F830661, 0x8B59E826, 0xBB8AEDCA,
89 0xF3D70AB9, 0xD739F2B9, 0x4A04C34A, 0x88D0F089,
90 0xE02191A2, 0xD89D9C78, 0x192C2749, 0xFC43A78F,
91 0x0AAC88CB, 0x9438D42D, 0x9E280F7A, 0x36063802,
92 0x38E8D018, 0x1C42A9CB, 0x92AAFF6C, 0xA24820C5,
93 0x007F077F, 0xCE5BC543, 0x69668D58, 0x10D6FF74,
94 0xBE00F621, 0x21300BBE, 0x2E9E8F46, 0x5ACEA629,
95 0xFA1F86C7, 0x52F206B8, 0x3EDF1A75, 0x6DA8D843,
96 0xCF719928, 0x73E3891F, 0xB4B95DD6, 0xB2A42D27,
97 0xEDA20BBF, 0x1A58DBDF, 0xA449AD03, 0x6DDEF22B,
98 0x900531E6, 0x3D3BFF35, 0x5B24ABA2, 0x472B3E4C,
99 0x387F2D75, 0x4D8DBA36, 0x71CB5641, 0xE3473F3F,
100 0xF6CD4B7F, 0xBF7D1428, 0x344B64D0, 0xC5CDFCB6,
101 0xFE2E0182, 0x2C37A673, 0xDE4EB7A3, 0x63FDC933,
102 0x01DC4063, 0x611F3571, 0xD167BFAF, 0x4496596F,
103 0x3DEE0689, 0xD8704910, 0x7052A114, 0x068C9EC5,
104 0x75D0E766, 0x4D54CC20, 0xB44ECDE2, 0x4ABC653E,
105 0x2C550A21, 0x1A52C0DB, 0xCFED03D0, 0x119BAFE2,
106 0x876A6133, 0xBC232088, 0x435BA1B2, 0xAE99BBFA,
107 0xBB4F08E4, 0xA62B5F49, 0x1DA4B695, 0x336B84DE,
108 0xDC813D31, 0x00C134FB, 0x397A98E6, 0x151F0E64,
109 0xD9EB3E69, 0xD3C7DF60, 0xD2F2C336, 0x2DDD067B,
110 0xBD122835, 0xB0B3BD3A, 0xB0D54E46, 0x8641F1E4,
111 0xA0B38F96, 0x51D39199, 0x37A6AD75, 0xDF84EE41,
112 0x3C034CBA, 0xACDA62FC, 0x11923B8B, 0x45EF170A,
115 using namespace Ogre;
120 , free_eventsource(0)
123 , m_terrain_size(terrn_size)
124 , collision_version(0)
125 , forcecampos(
Ogre::Vector3::ZERO)
155 group = ResourceGroupManager::getSingleton().findGroupContainingResource(filename);
162 Ogre::ConfigFile cfg;
167 cfg.loadDirect(filename);
169 cfg.loadFromResourceSystem(filename, group,
"\x09:=",
true);
171 catch (Ogre::Exception& e)
181 std::map<Ogre::String, ground_model_t>::iterator it;
184 if (!strlen(it->second.basename))
continue;
185 String bname = String(it->second.basename);
192 strncpy(thisgm->
name, it->first.c_str(), 255);
199 ErrorUtils::ShowError(
_L(
"Configuration error"),
_L(
"Your ground configuration is too old, please copy skeleton/config/ground_models.cfg to My Documents/Rigs of Rods/config"));
208 Ogre::ConfigFile::SectionIterator seci = cfg->getSectionIterator();
210 Ogre::String secName, kname, kvalue;
211 while (seci.hasMoreElements())
213 secName = seci.peekNextKey();
214 Ogre::ConfigFile::SettingsMultiMap *settings = seci.getNext();
216 if (!groundModel.empty() && secName != groundModel)
continue;
218 Ogre::ConfigFile::SettingsMultiMap::iterator i;
219 for (i = settings->begin(); i != settings->end(); ++i)
224 if (secName ==
"general" || secName ==
"config")
227 if (kname ==
"version") this->
collision_version = StringConverter::parseInt(kvalue);
252 if (kname ==
"adhesion velocity")
ground_models[secName].va = StringConverter::parseReal(kvalue);
253 else if (kname ==
"static friction coefficient")
ground_models[secName].ms = StringConverter::parseReal(kvalue);
254 else if (kname ==
"sliding friction coefficient")
ground_models[secName].mc = StringConverter::parseReal(kvalue);
255 else if (kname ==
"hydrodynamic friction")
ground_models[secName].t2 = StringConverter::parseReal(kvalue);
256 else if (kname ==
"stribeck velocity")
ground_models[secName].vs = StringConverter::parseReal(kvalue);
257 else if (kname ==
"alpha")
ground_models[secName].alpha = StringConverter::parseReal(kvalue);
258 else if (kname ==
"strength")
ground_models[secName].strength = StringConverter::parseReal(kvalue);
259 else if (kname ==
"base") strncpy(
ground_models[secName].basename, kvalue.c_str(), 255);
260 else if (kname ==
"fx_type")
262 if (kvalue ==
"PARTICLE")
264 else if (kvalue ==
"HARD")
266 else if (kvalue ==
"DUSTY")
268 else if (kvalue ==
"CLUMPY")
271 else if (kname ==
"fx_particle_name") strncpy(
ground_models[secName].particle_name, kvalue.c_str(), 255);
272 else if (kname ==
"fx_colour")
ground_models[secName].fx_colour = StringConverter::parseColourValue(kvalue);
273 else if (kname ==
"fx_particle_amount")
ground_models[secName].fx_particle_amount = StringConverter::parseInt(kvalue);
274 else if (kname ==
"fx_particle_min_velo")
ground_models[secName].fx_particle_min_velo = StringConverter::parseReal(kvalue);
275 else if (kname ==
"fx_particle_max_velo")
ground_models[secName].fx_particle_max_velo = StringConverter::parseReal(kvalue);
276 else if (kname ==
"fx_particle_fade")
ground_models[secName].fx_particle_fade = StringConverter::parseReal(kvalue);
277 else if (kname ==
"fx_particle_timedelta")
ground_models[secName].fx_particle_timedelta = StringConverter::parseReal(kvalue);
278 else if (kname ==
"fx_particle_velo_factor")
ground_models[secName].fx_particle_velo_factor = StringConverter::parseReal(kvalue);
279 else if (kname ==
"fx_particle_ttl")
ground_models[secName].fx_particle_ttl = StringConverter::parseReal(kvalue);
282 else if (kname ==
"fluid density")
ground_models[secName].fluid_density = StringConverter::parseReal(kvalue);
283 else if (kname ==
"flow consistency index")
ground_models[secName].flow_consistency_index = StringConverter::parseReal(kvalue);
284 else if (kname ==
"flow behavior index")
ground_models[secName].flow_behavior_index = StringConverter::parseReal(kvalue);
285 else if (kname ==
"solid ground level")
ground_models[secName].solid_ground_level = StringConverter::parseReal(kvalue);
286 else if (kname ==
"drag anisotropy")
ground_models[secName].drag_anisotropy = StringConverter::parseReal(kvalue);
291 if (!groundModel.empty())
break;
297 Ogre::Real min = pos.x - lo.x;
298 Ogre::Vector3 newPos = Ogre::Vector3(lo.x, pos.y, pos.z);
300 Ogre::Real t = pos.y - lo.y;
303 newPos = Ogre::Vector3(pos.x, lo.y, pos.z);
309 newPos = Ogre::Vector3(pos.x, pos.y, lo.z);
315 newPos = Ogre::Vector3(hi.x, pos.y, pos.z);
321 newPos = Ogre::Vector3(pos.x, hi.y, pos.z);
327 newPos = Ogre::Vector3(pos.x, pos.y, hi.z);
339 LOG(
"RoR was not compiled with PagedGeometry support. You cannot use Landuse maps with it.");
375 unsigned int hash = 0;
376 for (
int i=0; i < 4; i++)
378 hash ^=
sbox[((
unsigned char*)&cellid)[i]];
386 unsigned int cell_id = (cell_x << 16) + cell_z;
387 unsigned int pos =
hashfunc(cell_id);
389 hashtable[pos].emplace_back(cell_id, value);
395 unsigned int cellid = (cell_x << 16) + cell_z;
396 unsigned int pos =
hashfunc(cellid);
398 return static_cast<int>(pos);
401 int Collisions::addCollisionBox(
bool rotating,
bool virt, Vector3 pos, Ogre::Vector3 rot, Ogre::Vector3 l, Ogre::Vector3 h, Ogre::Vector3 sr,
const Ogre::String &eventname,
const Ogre::String &instancename,
bool forcecam, Ogre::Vector3 campos, Ogre::Vector3 sc , Ogre::Vector3 dr ,
CollisionEventFilter event_filter ,
int scripthandler )
403 Quaternion rotation = Quaternion(Degree(rot.x), Vector3::UNIT_X) * Quaternion(Degree(rot.y), Vector3::UNIT_Y) * Quaternion(Degree(rot.z), Vector3::UNIT_Z);
404 Quaternion direction = Quaternion(Degree(dr.x), Vector3::UNIT_X) * Quaternion(Degree(dr.y), Vector3::UNIT_Y) * Quaternion(Degree(dr.z), Vector3::UNIT_Z);
411 coll_box.
relo = l*sc;
412 coll_box.
rehi = h*sc;
421 coll_box.
virt = virt;
436 coll_box.
selfrot = Quaternion(Degree(sr.x), Vector3::UNIT_X) * Quaternion(Degree(sr.y), Vector3::UNIT_Y) * Quaternion(Degree(sr.z), Vector3::UNIT_Z);
445 if (!eventname.empty())
460 if (fabs(rot.x) < 0.0001f && fabs(rot.y) < 0.0001f && fabs(rot.z) < 0.0001f)
469 coll_box.
rot = rotation;
470 coll_box.
unrot = rotation.Inverse();
477 coll_box.
debug_verts[0] = Ogre::Vector3(l.x, l.y, l.z) * sc;
478 coll_box.
debug_verts[1] = Ogre::Vector3(h.x, l.y, l.z) * sc;
479 coll_box.
debug_verts[2] = Ogre::Vector3(l.x, h.y, l.z) * sc;
480 coll_box.
debug_verts[3] = Ogre::Vector3(h.x, h.y, l.z) * sc;
481 coll_box.
debug_verts[4] = Ogre::Vector3(l.x, l.y, h.z) * sc;
482 coll_box.
debug_verts[5] = Ogre::Vector3(h.x, l.y, h.z) * sc;
483 coll_box.
debug_verts[6] = Ogre::Vector3(l.x, h.y, h.z) * sc;
484 coll_box.
debug_verts[7] = Ogre::Vector3(h.x, h.y, h.z) * sc;
488 for (
int i=0; i < 8; i++)
496 for (
int i=0; i < 8; i++)
504 for (
int i=1; i < 8; i++)
515 coll_box.
lo = pos + coll_box.
relo;
516 coll_box.
hi = pos + coll_box.
rehi;
517 Vector3 d = (coll_box.
rehi - coll_box.
relo);
529 Vector3 ilo = Ogre::Vector3(coll_box.
lo / Ogre::Real(
CELL_SIZE));
530 Vector3 ihi = Ogre::Vector3(coll_box.
hi / Ogre::Real(
CELL_SIZE));
533 ilo.makeCeil(Ogre::Vector3(0.0f));
535 ihi.makeCeil(Ogre::Vector3(0.0f));
538 for (
int i = ilo.x; i <= ihi.x; i++)
540 for (
int j = ilo.z; j <= ihi.z; j++)
548 return coll_box_index;
564 Vector3 bz=bx.crossProduct(
by);
567 new_tri.
reverse.SetColumn(0, bx);
569 new_tri.
reverse.SetColumn(2, bz);
573 new_tri.
aab.merge(p1);
574 new_tri.
aab.merge(p2);
575 new_tri.
aab.merge(p3);
576 new_tri.
aab.setMinimum(new_tri.
aab.getMinimum() - 0.1f);
577 new_tri.
aab.setMaximum(new_tri.
aab.getMaximum() + 0.1f);
580 Ogre::Vector3 ilo(new_tri.
aab.getMinimum() / Ogre::Real(
CELL_SIZE));
581 Ogre::Vector3 ihi(new_tri.
aab.getMaximum() / Ogre::Real(
CELL_SIZE));
584 ilo.makeCeil(Ogre::Vector3(0.0f));
586 ihi.makeCeil(Ogre::Vector3(0.0f));
589 for (
int i = ilo.x; i <= ihi.x; i++)
591 for (
int j = ilo.z; j<=ihi.z; j++)
599 return new_tri_index;
604 #ifdef USE_ANGELSCRIPT
625 #endif //USE_ANGELSCRIPT
630 int steps = ray.getDirection().length() / (float)
CELL_SIZE;
634 for (
int i = 0; i <= steps; i++)
636 Vector3 pos = ray.getPoint((
float)i / (float)steps);
639 int refx = (int)(pos.x / (
float)
CELL_SIZE);
640 int refz = (int)(pos.z / (
float)
CELL_SIZE);
648 size_t num_elements =
hashtable[hash].size();
649 for (
size_t k = 0; k < num_elements; k++)
659 auto result = Ogre::Math::intersects(ray, ctri->
a, ctri->
b, ctri->
c);
660 if (result.first && result.second < 1.0f)
668 return std::make_pair(
false, 0.0f);
686 Ray ray(origin, -Vector3::UNIT_Y);
688 size_t num_elements =
hashtable[hash].size();
689 for (
size_t k = 0; k < num_elements; k++)
698 if (!cbox->
virt && surface_height < cbox->hi.y)
700 if (
x > cbox->
lo.x &&
z > cbox->
lo.z && x < cbox->hi.x && z < cbox->hi.z)
702 Vector3 pos = origin - cbox->
center;
703 Vector3 dir = -Vector3::UNIT_Y;
706 pos = cbox->
unrot * pos;
707 dir = cbox->
unrot * dir;
716 auto result = Ogre::Math::intersects(Ray(pos, dir), AxisAlignedBox(cbox->
relo, cbox->
rehi));
719 Vector3 hit = pos + dir * result.second;
726 hit = cbox->
rot * hit;
731 surface_height = std::max(surface_height, hit.y);
745 auto lo = ctri->
aab.getMinimum();
746 auto hi = ctri->
aab.getMaximum();
747 if (surface_height >= hi.y)
749 if (
x < lo.x || z < lo.z || x > hi.x ||
z > hi.z)
752 auto result = Ogre::Math::intersects(ray, ctri->
a, ctri->
b, ctri->
c);
755 if (origin.y - result.second < height)
757 surface_height = std::max(surface_height, origin.y - result.second);
763 return surface_height;
769 int refx = (int)(refpos->x / (
float)
CELL_SIZE);
770 int refz = (int)(refpos->z / (
float)
CELL_SIZE);
777 float minctridist = 100.0f;
778 Vector3 minctripoint;
780 bool contacted =
false;
781 bool isScriptCallbackEnvoked =
false;
783 size_t num_elements =
hashtable[hash].size();
784 for (
size_t k = 0; k < num_elements; k++)
792 if (!(*refpos > cbox->
lo && *refpos < cbox->hi))
798 Vector3 Pos = *refpos - cbox->
center;
801 Pos = cbox->
unrot * Pos;
810 if (Pos > cbox->
relo && Pos < cbox->rehi)
815 isScriptCallbackEnvoked =
true;
839 Pos = cbox->
rot * Pos;
841 *refpos = Pos + cbox->
center;
850 isScriptCallbackEnvoked =
true;
872 if (!ctri->
aab.contains(*refpos))
876 Vector3 point = ctri->
forward * (*refpos-ctri->
a);
878 if (point.x >= 0 && point.y >= 0 && (point.x + point.y) <= 1.0 && point.z < 0 && point.z > -0.1)
880 if (-point.z < minctridist)
883 minctridist = -point.z;
884 minctripoint = point;
890 if (envokeScriptCallbacks && !isScriptCallbackEnvoked)
901 *refpos = (minctri->
reverse * minctripoint) + minctri->
a;
932 unsigned int cell_id = (refx << 16) + refz;
938 float minctridist = 100.0;
939 Vector3 minctripoint;
941 bool contacted =
false;
942 bool isScriptCallbackEnvoked =
false;
944 size_t num_elements =
hashtable[hash].size();
945 for (
size_t k=0; k < num_elements; k++)
947 if (
hashtable[hash][k].cell_id != cell_id)
951 else if (
hashtable[hash][k].IsCollisionBox())
966 Pos = cbox->
unrot * Pos;
975 if (Pos > cbox->
relo && Pos < cbox->rehi)
988 float t = cbox->
rehi.z - Pos.z;
989 float min = Pos.z - cbox->
relo.z;
990 Vector3 normal = Vector3(0, 0, -1);
991 if (t < min) { min = t; normal = Vector3(0,0,1);};
992 t = Pos.x - cbox->
relo.x;
993 if (t < min) { min = t; normal = Vector3(-1,0,0);};
994 t = cbox->
rehi.x - Pos.x;
995 if (t < min) { min = t; normal = Vector3(1,0,0);};
996 t = Pos.y - cbox->
relo.y;
997 if (t < min) { min = t; normal = Vector3(0,-1,0);};
998 t = cbox->
rehi.y - Pos.y;
999 if (t < min) { min = t; normal = Vector3(0,1,0);};
1003 if (cbox->
refined) normal = cbox->
rot * normal;
1024 Vector3 normal = Vector3(0, 0, -1);
1025 if (t < min) {min = t; normal = Vector3(0,0,1);};
1027 if (t < min) {min = t; normal = Vector3(-1,0,0);};
1029 if (t < min) {min = t; normal = Vector3(1,0,0);};
1031 if (t < min) {min = t; normal = Vector3(0,-1,0);};
1033 if (t < min) {min = t; normal = Vector3(0,1,0);};
1037 if (cbox->
refined) normal = cbox->
rot * normal;
1061 if (point.x >= 0 && point.y >= 0 && (point.x + point.y) <= 1.0 && point.z < 0 && point.z > -0.1)
1063 if (-point.z < minctridist)
1066 minctridist = -point.z;
1067 minctripoint = point;
1080 Vector3 normal = minctri->
reverse * Vector3::UNIT_Z;
1095 const int cell_lo_x = (int)(aabb.getMinimum().x / (float)
CELL_SIZE);
1096 const int cell_lo_z = (int)(aabb.getMinimum().z / (float)
CELL_SIZE);
1097 const int cell_hi_x = (int)(aabb.getMaximum().x / (float)
CELL_SIZE);
1098 const int cell_hi_z = (int)(aabb.getMaximum().z / (float)
CELL_SIZE);
1101 for (
int refx = cell_lo_x; refx <= cell_hi_x; refx++)
1103 for (
int refz = cell_lo_z; refz <= cell_hi_z; refz++)
1106 const int hash = this->
hash_find(refx, refz);
1107 const unsigned int cell_id = (refx << 16) + refz;
1110 for (
size_t k = 0; k <
hashtable[hash].size(); k++)
1112 if (
hashtable[hash][k].cell_id != cell_id)
1116 else if (
hashtable[hash][k].IsCollisionBox())
1125 out_boxes.push_back(cbox);
1142 return Vector3::ZERO;
1154 return Quaternion::ZERO;
1173 return isInside(pos, cbox, border);
1178 if (!cbox)
return false;
1180 if (pos + border > cbox->
lo
1181 && pos - border < cbox->hi)
1186 Vector3 rpos = pos - cbox->
center;
1189 rpos = cbox->
unrot * rpos;
1199 if (rpos > cbox->
relo
1200 && rpos < cbox->rehi)
1230 Vector3 force = Vector3::ZERO;
1231 float Vnormal = velocity.dotProduct(normal);
1232 float Fnormal = node->
Forces.dotProduct(normal);
1237 float Vsquared = velocity.squaredLength();
1249 if (Vsquared > gm->
va * gm->
va)
1252 da_factor = Vsquared / (gm->
va * gm->
va);
1253 Fdrag += (Vnormal * m * (1.0f - gm->
drag_anisotropy) * da_factor) * normal;
1263 if (Fnormal < 0 && Fboyancy>-Fnormal)
1265 Fboyancy = -Fnormal;
1268 force += Fboyancy * normal;
1275 float Freaction = -Fnormal;
1280 Freaction -= (0.8f * Vnormal + 0.2f * penetration_depth / dt) * mass / dt;
1284 Vector3 slipf = node->
Forces - Fnormal * normal;
1285 Vector3 slip = velocity - Vnormal * normal;
1286 float slipv = slip.normalise();
1292 float msGreaction = gm->
ms * Greaction;
1293 if (slipv < gm->va && Greaction > 0.0f && slipf.squaredLength() <= msGreaction * msGreaction)
1296 float ff = -msGreaction * (1.0f -
approx_exp(-slipv / gm->
va));
1297 force += Freaction * normal + ff * slip - slipf;
1302 float ff = -(g + std::min(gm->
t2 * slipv, 5.0f)) * Greaction;
1303 force += Freaction * normal + ff * slip;
1316 LOG(
"COLL: Creating collision debug visualization ...");
1325 if (!area_limit.contains(Ogre::Vector3(
x, 0.f,
z)))
1330 const int hash =
hash_find(cellx, cellz);
1333 return c.
cell_id == (cellx << 16) + cellz;
1338 float groundheight = -9999;
1344 groundheight = std::max(groundheight,
App::GetGameContext()->GetTerrain()->GetHeightAt(x2,
z));
1345 groundheight = std::max(groundheight,
App::GetGameContext()->GetTerrain()->GetHeightAt(
x, z2));
1346 groundheight = std::max(groundheight,
App::GetGameContext()->GetTerrain()->GetHeightAt(x2, z2));
1347 groundheight += 0.1;
1350 if (percentd > 1) percentd = 1;
1353 String matName =
"mat-coll-dbg-"+
TOSTRING((
int)(percentd*100));
1357 SceneNode *mo_node = root_node->createChildSceneNode(
"collisionDebugVisualization_node"+cell_name);
1359 mo->begin(matName, Ogre::RenderOperation::OT_TRIANGLE_LIST);
1363 mo->textureCoord(0,0);
1366 mo->textureCoord(1,1);
1369 mo->textureCoord(1,0);
1373 mo->textureCoord(0,1);
1376 mo->textureCoord(1,1);
1379 mo->textureCoord(0,0);
1383 mo->setRenderingDistance(200.f);
1384 mo_node->attachObject(mo);
1388 String labelName =
"label_"+cell_name;
1396 mo_node->attachObject(mt);
1399 mo_node->setVisible(
true);
1402 out_nodes.push_back(mo_node);
1411 ent->setMaterialName(
"tracks/debug/collision/mesh");
1419 size_t vertex_count,index_count;
1423 getMeshInformation(ent->getMesh().getPointer(),vertex_count,vertices,index_count,indices, pos, q, scale);
1427 for (
int i=0; i<(int)index_count/3; i++)
1429 int triID =
addCollisionTri(vertices[indices[i*3]], vertices[indices[i*3+1]], vertices[indices[i*3+2]], gm);
1431 collTris->push_back(triID);
1470 size_t &index_count,
unsigned* &indices,
const Ogre::Vector3 &position,
1471 const Ogre::Quaternion &orient,
const Ogre::Vector3 &scale)
1473 vertex_count = index_count = 0;
1475 bool added_shared =
false;
1476 size_t current_offset = vertex_count;
1477 size_t shared_offset = vertex_count;
1478 size_t next_offset = vertex_count;
1479 size_t index_offset = index_count;
1484 for (
int i = 0;i < mesh->getNumSubMeshes();i++)
1486 SubMesh* submesh = mesh->getSubMesh(i);
1489 if (submesh->useSharedVertices)
1493 VertexData* vertex_data = mesh->sharedVertexData;
1494 vertex_count += vertex_data->vertexCount;
1495 added_shared =
true;
1499 VertexData* vertex_data = submesh->vertexData;
1500 vertex_count += vertex_data->vertexCount;
1504 Ogre::IndexData* index_data = submesh->indexData;
1505 index_count += index_data->indexCount;
1509 vertices =
new Vector3[vertex_count];
1510 indices =
new unsigned[index_count];
1512 added_shared =
false;
1515 for (
int i = 0;i < mesh->getNumSubMeshes();i++)
1517 SubMesh* submesh = mesh->getSubMesh(i);
1519 Ogre::VertexData* vertex_data = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData;
1520 if ((!submesh->useSharedVertices)||(submesh->useSharedVertices && !added_shared))
1522 if (submesh->useSharedVertices)
1524 added_shared =
true;
1525 shared_offset = current_offset;
1528 const Ogre::VertexElement* posElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
1529 Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(posElem->getSource());
1530 unsigned char* vertex =
static_cast<unsigned char*
>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
1533 for (
size_t j = 0; j < vertex_data->vertexCount; ++j, vertex += vbuf->getVertexSize())
1535 posElem->baseVertexPointerToElement(vertex, &pReal);
1543 pt = (orient * (pt * scale)) + position;
1545 vertices[current_offset + j].x = pt.x;
1546 vertices[current_offset + j].y = pt.y;
1547 vertices[current_offset + j].z = pt.z;
1550 next_offset += vertex_data->vertexCount;
1553 Ogre::IndexData* index_data = submesh->indexData;
1555 size_t numTris = index_data->indexCount / 3;
1556 unsigned short* pShort = 0;
1557 unsigned int* pInt = 0;
1558 Ogre::HardwareIndexBufferSharedPtr ibuf = index_data->indexBuffer;
1560 bool use32bitindexes = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT);
1562 if (use32bitindexes)
1563 pInt =
static_cast<unsigned int*
>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
1565 pShort =
static_cast<unsigned short*
>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
1567 for (
size_t k = 0; k < numTris; ++k)
1569 size_t offset = (submesh->useSharedVertices)?shared_offset:current_offset;
1571 unsigned int vindex = use32bitindexes? *pInt++ : *pShort++;
1572 indices[index_offset + 0] = vindex + (
unsigned int)offset;
1573 vindex = use32bitindexes? *pInt++ : *pShort++;
1574 indices[index_offset + 1] = vindex + (
unsigned int)offset;
1575 vindex = use32bitindexes? *pInt++ : *pShort++;
1576 indices[index_offset + 2] = vindex + (
unsigned int)offset;
1581 current_offset = next_offset;