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;
933 unsigned int cell_id = (refx << 16) + refz;
939 float minctridist = 100.0;
940 Vector3 minctripoint;
942 bool contacted =
false;
943 bool isScriptCallbackEnvoked =
false;
945 size_t num_elements =
hashtable[hash].size();
946 for (
size_t k=0; k < num_elements; k++)
948 if (
hashtable[hash][k].cell_id != cell_id)
952 else if (
hashtable[hash][k].IsCollisionBox())
967 Pos = cbox->
unrot * Pos;
976 if (Pos > cbox->
relo && Pos < cbox->rehi)
989 float t = cbox->
rehi.z - Pos.z;
990 float min = Pos.z - cbox->
relo.z;
991 Vector3 normal = Vector3(0, 0, -1);
992 if (t < min) { min = t; normal = Vector3(0,0,1);};
993 t = Pos.x - cbox->
relo.x;
994 if (t < min) { min = t; normal = Vector3(-1,0,0);};
995 t = cbox->
rehi.x - Pos.x;
996 if (t < min) { min = t; normal = Vector3(1,0,0);};
997 t = Pos.y - cbox->
relo.y;
998 if (t < min) { min = t; normal = Vector3(0,-1,0);};
999 t = cbox->
rehi.y - Pos.y;
1000 if (t < min) { min = t; normal = Vector3(0,1,0);};
1004 if (cbox->
refined) normal = cbox->
rot * normal;
1025 Vector3 normal = Vector3(0, 0, -1);
1026 if (t < min) {min = t; normal = Vector3(0,0,1);};
1028 if (t < min) {min = t; normal = Vector3(-1,0,0);};
1030 if (t < min) {min = t; normal = Vector3(1,0,0);};
1032 if (t < min) {min = t; normal = Vector3(0,-1,0);};
1034 if (t < min) {min = t; normal = Vector3(0,1,0);};
1038 if (cbox->
refined) normal = cbox->
rot * normal;
1062 if (point.x >= 0 && point.y >= 0 && (point.x + point.y) <= 1.0 && point.z < 0 && point.z > -0.1)
1064 if (-point.z < minctridist)
1067 minctridist = -point.z;
1068 minctripoint = point;
1081 Vector3 normal = minctri->
reverse * Vector3::UNIT_Z;
1096 const int cell_lo_x = (int)(aabb.getMinimum().x / (float)
CELL_SIZE);
1097 const int cell_lo_z = (int)(aabb.getMinimum().z / (float)
CELL_SIZE);
1098 const int cell_hi_x = (int)(aabb.getMaximum().x / (float)
CELL_SIZE);
1099 const int cell_hi_z = (int)(aabb.getMaximum().z / (float)
CELL_SIZE);
1102 for (
int refx = cell_lo_x; refx <= cell_hi_x; refx++)
1104 for (
int refz = cell_lo_z; refz <= cell_hi_z; refz++)
1107 const int hash = this->
hash_find(refx, refz);
1108 const unsigned int cell_id = (refx << 16) + refz;
1111 for (
size_t k = 0; k <
hashtable[hash].size(); k++)
1113 if (
hashtable[hash][k].cell_id != cell_id)
1117 else if (
hashtable[hash][k].IsCollisionBox())
1126 out_boxes.push_back(cbox);
1143 return Vector3::ZERO;
1155 return Quaternion::ZERO;
1174 return isInside(pos, cbox, border);
1179 if (!cbox)
return false;
1181 if (pos + border > cbox->
lo
1182 && pos - border < cbox->hi)
1187 Vector3 rpos = pos - cbox->
center;
1190 rpos = cbox->
unrot * rpos;
1200 if (rpos > cbox->
relo
1201 && rpos < cbox->rehi)
1231 Vector3 force = Vector3::ZERO;
1232 float Vnormal = velocity.dotProduct(normal);
1233 float Fnormal = node->
Forces.dotProduct(normal);
1238 float Vsquared = velocity.squaredLength();
1250 if (Vsquared > gm->
va * gm->
va)
1253 da_factor = Vsquared / (gm->
va * gm->
va);
1254 Fdrag += (Vnormal * m * (1.0f - gm->
drag_anisotropy) * da_factor) * normal;
1264 if (Fnormal < 0 && Fboyancy>-Fnormal)
1266 Fboyancy = -Fnormal;
1269 force += Fboyancy * normal;
1276 float Freaction = -Fnormal;
1281 Freaction -= (0.8f * Vnormal + 0.2f * penetration_depth / dt) * mass / dt;
1285 Vector3 slipf = node->
Forces - Fnormal * normal;
1286 Vector3 slip = velocity - Vnormal * normal;
1287 float slipv = slip.normalise();
1293 float msGreaction = gm->
ms * Greaction;
1294 if (slipv < gm->va && Greaction > 0.0f && slipf.squaredLength() <= msGreaction * msGreaction)
1297 float ff = -msGreaction * (1.0f -
approx_exp(-slipv / gm->
va));
1298 force += Freaction * normal + ff * slip - slipf;
1303 float ff = -(g + std::min(gm->
t2 * slipv, 5.0f)) * Greaction;
1304 force += Freaction * normal + ff * slip;
1317 LOG(
"COLL: Creating collision debug visualization ...");
1326 if (!area_limit.contains(Ogre::Vector3(
x, 0.f,
z)))
1331 const int hash =
hash_find(cellx, cellz);
1334 return c.
cell_id == (cellx << 16) + cellz;
1339 float groundheight = -9999;
1345 groundheight = std::max(groundheight,
App::GetGameContext()->GetTerrain()->GetHeightAt(x2,
z));
1346 groundheight = std::max(groundheight,
App::GetGameContext()->GetTerrain()->GetHeightAt(
x, z2));
1347 groundheight = std::max(groundheight,
App::GetGameContext()->GetTerrain()->GetHeightAt(x2, z2));
1348 groundheight += 0.1;
1351 if (percentd > 1) percentd = 1;
1354 String matName =
"mat-coll-dbg-"+
TOSTRING((
int)(percentd*100));
1358 SceneNode *mo_node = root_node->createChildSceneNode(
"collisionDebugVisualization_node"+cell_name);
1360 mo->begin(matName, Ogre::RenderOperation::OT_TRIANGLE_LIST);
1364 mo->textureCoord(0,0);
1367 mo->textureCoord(1,1);
1370 mo->textureCoord(1,0);
1374 mo->textureCoord(0,1);
1377 mo->textureCoord(1,1);
1380 mo->textureCoord(0,0);
1384 mo->setRenderingDistance(200.f);
1385 mo_node->attachObject(mo);
1389 String labelName =
"label_"+cell_name;
1397 mo_node->attachObject(mt);
1400 mo_node->setVisible(
true);
1403 out_nodes.push_back(mo_node);
1412 ent->setMaterialName(
"tracks/debug/collision/mesh");
1420 size_t vertex_count,index_count;
1424 getMeshInformation(ent->getMesh().getPointer(),vertex_count,vertices,index_count,indices, pos, q, scale);
1428 for (
int i=0; i<(int)index_count/3; i++)
1430 int triID =
addCollisionTri(vertices[indices[i*3]], vertices[indices[i*3+1]], vertices[indices[i*3+2]], gm);
1432 collTris->push_back(triID);
1471 size_t &index_count,
unsigned* &indices,
const Ogre::Vector3 &position,
1472 const Ogre::Quaternion &orient,
const Ogre::Vector3 &scale)
1474 vertex_count = index_count = 0;
1476 bool added_shared =
false;
1477 size_t current_offset = vertex_count;
1478 size_t shared_offset = vertex_count;
1479 size_t next_offset = vertex_count;
1480 size_t index_offset = index_count;
1485 for (
int i = 0;i < mesh->getNumSubMeshes();i++)
1487 SubMesh* submesh = mesh->getSubMesh(i);
1490 if (submesh->useSharedVertices)
1494 VertexData* vertex_data = mesh->sharedVertexData;
1495 vertex_count += vertex_data->vertexCount;
1496 added_shared =
true;
1500 VertexData* vertex_data = submesh->vertexData;
1501 vertex_count += vertex_data->vertexCount;
1505 Ogre::IndexData* index_data = submesh->indexData;
1506 index_count += index_data->indexCount;
1510 vertices =
new Vector3[vertex_count];
1511 indices =
new unsigned[index_count];
1513 added_shared =
false;
1516 for (
int i = 0;i < mesh->getNumSubMeshes();i++)
1518 SubMesh* submesh = mesh->getSubMesh(i);
1520 Ogre::VertexData* vertex_data = submesh->useSharedVertices ? mesh->sharedVertexData : submesh->vertexData;
1521 if ((!submesh->useSharedVertices)||(submesh->useSharedVertices && !added_shared))
1523 if (submesh->useSharedVertices)
1525 added_shared =
true;
1526 shared_offset = current_offset;
1529 const Ogre::VertexElement* posElem = vertex_data->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
1530 Ogre::HardwareVertexBufferSharedPtr vbuf = vertex_data->vertexBufferBinding->getBuffer(posElem->getSource());
1531 unsigned char* vertex =
static_cast<unsigned char*
>(vbuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
1534 for (
size_t j = 0; j < vertex_data->vertexCount; ++j, vertex += vbuf->getVertexSize())
1536 posElem->baseVertexPointerToElement(vertex, &pReal);
1544 pt = (orient * (pt * scale)) + position;
1546 vertices[current_offset + j].x = pt.x;
1547 vertices[current_offset + j].y = pt.y;
1548 vertices[current_offset + j].z = pt.z;
1551 next_offset += vertex_data->vertexCount;
1554 Ogre::IndexData* index_data = submesh->indexData;
1556 size_t numTris = index_data->indexCount / 3;
1557 unsigned short* pShort = 0;
1558 unsigned int* pInt = 0;
1559 Ogre::HardwareIndexBufferSharedPtr ibuf = index_data->indexBuffer;
1561 bool use32bitindexes = (ibuf->getType() == Ogre::HardwareIndexBuffer::IT_32BIT);
1563 if (use32bitindexes)
1564 pInt =
static_cast<unsigned int*
>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
1566 pShort =
static_cast<unsigned short*
>(ibuf->lock(Ogre::HardwareBuffer::HBL_READ_ONLY));
1568 for (
size_t k = 0; k < numTris; ++k)
1570 size_t offset = (submesh->useSharedVertices)?shared_offset:current_offset;
1572 unsigned int vindex = use32bitindexes? *pInt++ : *pShort++;
1573 indices[index_offset + 0] = vindex + (
unsigned int)offset;
1574 vindex = use32bitindexes? *pInt++ : *pShort++;
1575 indices[index_offset + 1] = vindex + (
unsigned int)offset;
1576 vindex = use32bitindexes? *pInt++ : *pShort++;
1577 indices[index_offset + 2] = vindex + (
unsigned int)offset;
1582 current_offset = next_offset;