38 ProceduralRoad::ProceduralRoad()
43 ProceduralRoad::~ProceduralRoad()
52 MeshManager::getSingleton().remove(msh->getName());
55 for (
int number : registeredCollTris)
61 void ProceduralRoad::finish(Ogre::SceneNode* snode)
64 computePoints(pts, lastpos, lastrot, lasttype, lastwidth, lastbwidth, lastbheight);
70 String entity_name = String(
"RoadSystem_Instance-").append(StringConverter::toString(mid));
71 String mesh_name = String(
"RoadSystem-").append(StringConverter::toString(mid));
73 snode->attachObject(ec);
76 "RoadSystem", mesh_name,
77 ec->getBoundingBox().getCenter(), ec->getMesh()->getBounds(),
78 nullptr, registeredCollTris[0], (
int)registeredCollTris.size());
81 void ProceduralRoad::addBlock(Vector3 pos, Quaternion rot,
RoadType type,
float width,
float bwidth,
float bheight,
int pillartype)
89 Vector3 leftv = pos + rot * Vector3(0, 0, bwidth + width / 2.0);
90 Vector3 rightv = pos + rot * Vector3(0, 0, -bwidth - width / 2.0);
93 if (dleft < bheight + 0.1 && dright < bheight + 0.1)
95 if (dleft < bheight + 0.1 && dright >= bheight + 0.1 && dright < 4.0)
97 if (dleft >= bheight + 0.1 && dleft < 4.0 && dright < bheight + 0.1)
99 if (dleft >= bheight + 0.1 && dleft < 4.0 && dright >= bheight + 0.1 && dright < 4.0)
118 computePoints(pts, pos, rot, type, width, bwidth, bheight);
119 computePoints(lpts, lastpos, lastrot, lasttype, lastwidth, lastbwidth, lastbheight);
166 Vector3 leftv = pos + rot * Vector3(0, 0, bwidth + width / 2.0);
167 Vector3 rightv = pos + rot * Vector3(0, 0, -bwidth - width / 2.0);
168 Vector3 middle = lpts[0] - ((lpts[0] + (pts[1] - lpts[0]) / 2) -
169 (lpts[7] + (pts[6] - lpts[7]) / 2)) * 0.5;
174 bool builtpillars =
true;
176 float sidefactor = 0.5;
179 if (pos.y - heightmiddle < 10)
181 if (heightleft >= heightright)
187 static int pillarcounter = 0;
195 if (pillarcounter % 5)
196 builtpillars =
false;
199 middle = lpts[0] - ((lpts[0] + (pts[1] - lpts[0]) / 2) -
200 (lpts[7] + (pts[6] - lpts[7]) / 2)) * sidefactor;
202 float width2 = len / 30;
204 if (pillartype == 2 && len > 20)
206 builtpillars =
false;
215 if (width2 >= 0.2 && builtpillars)
218 addQuad(middle + Vector3(-width2, -len, -width2),
219 middle + Vector3(-width2, 0, -width2),
220 middle + Vector3(width2, 0, -width2),
221 middle + Vector3(width2, -len, -width2),
224 addQuad(middle + Vector3(width2, -len, width2),
225 middle + Vector3(width2, 0, width2),
226 middle + Vector3(-width2, 0, width2),
227 middle + Vector3(-width2, -len, width2),
230 addQuad(middle + Vector3(-width2, -len, width2),
231 middle + Vector3(-width2, 0, width2),
232 middle + Vector3(-width2, 0, -width2),
233 middle + Vector3(-width2, -len, -width2),
236 addQuad(middle + Vector3(width2, -len, -width2),
237 middle + Vector3(width2, 0, -width2),
238 middle + Vector3(width2, 0, width2),
239 middle + Vector3(width2, -len, width2),
247 computePoints(pts, pos, rot, type, width, bwidth, bheight);
256 lastbheight = bheight;
261 Str<2000> msg; msg <<
"[RoR] Road Block |";
262 msg <<
" pos=(" << pos.x <<
" " << pos.y <<
" " << pos.z <<
")";
263 msg <<
" rot=(" << rot.x <<
" " << rot.y <<
" " << rot.z <<
")";
264 msg <<
" width=" << width;
265 msg <<
" bwidth=" << bwidth;
266 msg <<
" bheight=" << bheight;
267 msg <<
" type=" << (int)type;
268 for (
int i = 0; i < 8; ++i)
270 msg <<
"\n\t Point#" << i <<
": " << pts[i].x <<
" " << pts[i].y <<
" " << pts[i].z;
276 void ProceduralRoad::computePoints(Vector3* pts, Vector3 pos, Quaternion rot,
RoadType type,
float width,
float bwidth,
float bheight)
280 pts[1] = pos + rot * Vector3(0, -bheight, bwidth + width / 2.0);
281 pts[0] = baseOf(pts[1]);
282 pts[2] = pos + rot * Vector3(0, -bheight / 4.0, bwidth / 3.0 + width / 2.0);
283 pts[3] = pos + rot * Vector3(0, 0, width / 2.0);
284 pts[4] = pos + rot * Vector3(0, 0, -width / 2.0);
285 pts[5] = pos + rot * Vector3(0, -bheight / 4.0, -bwidth / 3.0 - width / 2.0);
286 pts[6] = pos + rot * Vector3(0, -bheight, -bwidth - width / 2.0);
287 pts[7] = baseOf(pts[6]);
291 pts[1] = pos + rot * Vector3(0, bheight, bwidth + width / 2.0);
292 pts[0] = baseOf(pts[1]);
293 pts[2] = pos + rot * Vector3(0, bheight, width / 2.0);
294 pts[3] = pos + rot * Vector3(0, 0, width / 2.0);
295 pts[4] = pos + rot * Vector3(0, 0, -width / 2.0);
296 pts[5] = pos + rot * Vector3(0, bheight, -width / 2.0);
297 pts[6] = pos + rot * Vector3(0, bheight, -bwidth - width / 2.0);
298 pts[7] = baseOf(pts[6]);
302 pts[1] = pos + rot * Vector3(0, -bheight, bwidth + width / 2.0);
303 pts[0] = baseOf(pts[1]);
304 pts[2] = pos + rot * Vector3(0, -bheight / 4.0, bwidth / 3.0 + width / 2.0);
305 pts[3] = pos + rot * Vector3(0, 0, width / 2.0);
306 pts[4] = pos + rot * Vector3(0, 0, -width / 2.0);
307 pts[5] = pos + rot * Vector3(0, bheight, -width / 2.0);
308 pts[6] = pos + rot * Vector3(0, bheight, -bwidth - width / 2.0);
309 pts[7] = baseOf(pts[6]);
313 pts[1] = pos + rot * Vector3(0, bheight, bwidth + width / 2.0);
314 pts[0] = baseOf(pts[1]);
315 pts[2] = pos + rot * Vector3(0, bheight, width / 2.0);
316 pts[3] = pos + rot * Vector3(0, 0, width / 2.0);
317 pts[4] = pos + rot * Vector3(0, 0, -width / 2.0);
318 pts[5] = pos + rot * Vector3(0, -bheight / 4.0, -bwidth / 3.0 - width / 2.0);
319 pts[6] = pos + rot * Vector3(0, -bheight, -bwidth - width / 2.0);
320 pts[7] = baseOf(pts[6]);
324 pts[0] = pos + rot * Vector3(0, -0.4, bwidth + width / 2.0);
325 pts[1] = pos + rot * Vector3(0, bheight, bwidth + width / 2.0);
326 pts[2] = pos + rot * Vector3(0, bheight, width / 2.0);
327 pts[3] = pos + rot * Vector3(0, 0, width / 2.0);
328 pts[4] = pos + rot * Vector3(0, 0, -width / 2.0);
329 pts[5] = pos + rot * Vector3(0, bheight, -width / 2.0);
330 pts[6] = pos + rot * Vector3(0, bheight, -bwidth - width / 2.0);
331 pts[7] = pos + rot * Vector3(0, -0.4, -bwidth - width / 2.0);
335 pts[0] = pos + rot * Vector3(0, -1.4, bwidth + width / 2.0);
336 pts[1] = pos + rot * Vector3(0, bheight, bwidth + width / 2.0);
337 pts[2] = pos + rot * Vector3(0, bheight, width / 2.0);
338 pts[3] = pos + rot * Vector3(0, 0, width / 2.0);
339 pts[4] = pos + rot * Vector3(0, 0, -width / 2.0);
340 pts[5] = pos + rot * Vector3(0, bheight, -width / 2.0);
341 pts[6] = pos + rot * Vector3(0, bheight, -bwidth - width / 2.0);
342 pts[7] = pos + rot * Vector3(0, -1.4, -bwidth - width / 2.0);
346 inline Vector3 ProceduralRoad::baseOf(Vector3 p)
355 return Vector3(p.x,
y, p.z);
358 void ProceduralRoad::addQuad(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4,
TextureFit texfit, Vector3 pos, Vector3 lastpos,
float width,
bool flip)
360 if (vertexcount + 3 >= MAX_VERTEX || tricount * 3 + 3 + 2 >= MAX_TRIS * 3)
363 textureFit(p1, p2, p3, p4, texfit, texf, pos, lastpos, width);
365 vertex[vertexcount] = p1;
366 tex[vertexcount] = texf[0];
367 vertex[vertexcount + 1] = p2;
368 tex[vertexcount + 1] = texf[1];
369 vertex[vertexcount + 2] = p3;
370 tex[vertexcount + 2] = texf[2];
371 vertex[vertexcount + 3] = p4;
372 tex[vertexcount + 3] = texf[3];
376 tris[tricount * 3] = vertexcount;
377 tris[tricount * 3 + 1] = vertexcount + 1;
378 tris[tricount * 3 + 2] = vertexcount + 3;
379 tris[tricount * 3 + 3] = vertexcount + 1;
380 tris[tricount * 3 + 3 + 1] = vertexcount + 2;
381 tris[tricount * 3 + 3 + 2] = vertexcount + 3;
385 tris[tricount * 3] = vertexcount;
386 tris[tricount * 3 + 1] = vertexcount + 1;
387 tris[tricount * 3 + 2] = vertexcount + 2;
388 tris[tricount * 3 + 3] = vertexcount;
389 tris[tricount * 3 + 3 + 1] = vertexcount + 2;
390 tris[tricount * 3 + 3 + 2] = vertexcount + 3;
397 addCollisionQuad(p1, p2, p3, p4, gm, flip);
403 void ProceduralRoad::textureFit(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4,
TextureFit texfit, Vector2* texc, Vector3 pos, Vector3 lastpos,
float width)
415 Vector3 pref2 = lastpos;
417 Vector3 bx = pref2 - pref1;
419 Vector3
by = Vector3::UNIT_Y;
420 Vector3 bz = bx.crossProduct(
by);
423 reverse.SetColumn(0, bx);
424 reverse.SetColumn(1,
by);
425 reverse.SetColumn(2, bz);
427 forward = reverse.Inverse();
429 for (i = 0; i < 4; i++)
431 Vector3 trv = forward * (ps[i] - pref1);
434 float ty = 0.746 - trv.y * 0.25 / 4.5;
438 texc[i] = Vector2(trv.x / 10.0, ty);
443 float ty = 0.496 - (trv.y - 0.7) * 0.25 / 4.5;
446 texc[i] = Vector2(trv.x / 10.0, ty);
450 float ty = 0.496 + trv.y * 0.25 / 4.5;
454 texc[i] = Vector2(trv.x / 10.0, ty);
467 Vector3 pref2 = lastpos;
469 for (i = 0; i < 4; i++)
474 Vector3 bx = pref2 - pref1;
476 Vector3
by = Vector3::UNIT_Y;
477 Vector3 bz = bx.crossProduct(
by);
480 reverse.SetColumn(0, bx);
481 reverse.SetColumn(1,
by);
482 reverse.SetColumn(2, bz);
484 forward = reverse.Inverse();
487 for (i = 0; i < 4; i++)
489 Vector3 trv = forward * (ps[i] - pref1);
494 texc[i] = Vector2(trv.x / 10.0, 0.621 + (trv.z - trvrefz) * 0.25 / 4.5);
526 texc[i] = Vector2(trv.x / 10.0, v1);
528 texc[i] = Vector2(trv.x / 10.0, v2);
534 for (i = 0; i < 4; i++)
535 texc[i] = Vector2(0, 0);
538 void ProceduralRoad::addCollisionQuad(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4,
ground_model_t* gm,
bool flip)
545 registeredCollTris.push_back(triID);
549 registeredCollTris.push_back(triID);
555 registeredCollTris.push_back(triID);
559 registeredCollTris.push_back(triID);
563 void ProceduralRoad::addCollisionQuad(Ogre::Vector3 p1, Ogre::Vector3 p2, Ogre::Vector3 p3, Ogre::Vector3 p4, std::string
const& gm_name,
bool flip )
568 this->addCollisionQuad(p1, p2, p3, p4, gm, flip);
573 fmt::format(
"ProceduralRoad::addCollisionQuad() - ground model '{}' does not exist", gm_name));
577 void ProceduralRoad::createMesh()
586 Ogre::String mesh_name = Ogre::String(
"RoadSystem-").append(Ogre::StringConverter::toString(mid));
587 msh = MeshManager::getSingleton().createManual(mesh_name, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
589 mainsub = msh->createSubMesh();
590 mainsub->setMaterialName(
"road2");
593 size_t vbufCount = (2 * 3 + 2) * vertexcount;
594 vertices = (
float*)malloc(vbufCount *
sizeof(
float));
597 for (i = 0; i < vertexcount; i++)
600 covertices[i].vertex = vertex[i];
602 covertices[i].normal = Vector3::ZERO;
603 aab.merge(vertex[i]);
607 size_t ibufCount = 3 * tricount;
610 for (i = 0; i < tricount && i * 3 + 2 < MAX_TRIS * 3; i++)
613 v1 = covertices[tris[i * 3 + 1]].vertex - covertices[tris[i * 3]].vertex;
614 v2 = covertices[tris[i * 3 + 2]].vertex - covertices[tris[i * 3]].vertex;
615 v1 = v1.crossProduct(v2);
617 covertices[tris[i * 3]].normal += v1;
618 covertices[tris[i * 3 + 1]].normal += v1;
619 covertices[tris[i * 3 + 2]].normal += v1;
622 for (i = 0; i < vertexcount; i++)
624 covertices[i].normal.normalise();
628 msh->sharedVertexData =
new VertexData();
629 msh->sharedVertexData->vertexCount = vertexcount;
632 VertexDeclaration* decl = msh->sharedVertexData->vertexDeclaration;
634 decl->addElement(0, offset, VET_FLOAT3, VES_POSITION);
635 offset += VertexElement::getTypeSize(VET_FLOAT3);
636 decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL);
637 offset += VertexElement::getTypeSize(VET_FLOAT3);
638 decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0);
639 offset += VertexElement::getTypeSize(VET_FLOAT2);
643 HardwareVertexBufferSharedPtr vbuf =
644 HardwareBufferManager::getSingleton().createVertexBuffer(
645 offset, msh->sharedVertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY);
648 vbuf->writeData(0, vbuf->getSizeInBytes(), vertices,
true);
651 VertexBufferBinding* bind = msh->sharedVertexData->vertexBufferBinding;
652 bind->setBinding(0, vbuf);
656 HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton().
658 HardwareIndexBuffer::IT_16BIT,
660 HardwareBuffer::HBU_STATIC_WRITE_ONLY);
663 ibuf->writeData(0, ibuf->getSizeInBytes(), tris,
true);
666 mainsub->useSharedVertices =
true;
667 mainsub->indexData->indexBuffer = ibuf;
668 mainsub->indexData->indexCount = ibufCount;
669 mainsub->indexData->indexStart = 0;
671 msh->_setBounds(aab,
true);