38 ProceduralRoad::ProceduralRoad()
43 ProceduralRoad::~ProceduralRoad()
52 MeshManager::getSingleton().remove(msh->getName());
55 for (
int number : registeredCollTris)
61 void ProceduralRoad::finish(Ogre::SceneNode* groupingSceneNode)
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 = groupingSceneNode->createChildSceneNode();
74 snode->attachObject(ec);
79 "RoadSystem", mesh_name,
80 ec->getBoundingBox().getCenter(), ec->getMesh()->getBounds(),
81 nullptr, registeredCollTris[0], (
int)registeredCollTris.size());
85 void ProceduralRoad::addBlock(Vector3 pos, Quaternion rot,
RoadType type,
float width,
float bwidth,
float bheight,
int pillartype)
93 Vector3 leftv = pos + rot * Vector3(0, 0, bwidth + width / 2.0);
94 Vector3 rightv = pos + rot * Vector3(0, 0, -bwidth - width / 2.0);
97 if (dleft < bheight + 0.1 && dright < bheight + 0.1)
99 if (dleft < bheight + 0.1 && dright >= bheight + 0.1 && dright < 4.0)
101 if (dleft >= bheight + 0.1 && dleft < 4.0 && dright < bheight + 0.1)
103 if (dleft >= bheight + 0.1 && dleft < 4.0 && dright >= bheight + 0.1 && dright < 4.0)
122 computePoints(pts, pos, rot, type, width, bwidth, bheight);
123 computePoints(lpts, lastpos, lastrot, lasttype, lastwidth, lastbwidth, lastbheight);
170 Vector3 leftv = pos + rot * Vector3(0, 0, bwidth + width / 2.0);
171 Vector3 rightv = pos + rot * Vector3(0, 0, -bwidth - width / 2.0);
172 Vector3 middle = lpts[0] - ((lpts[0] + (pts[1] - lpts[0]) / 2) -
173 (lpts[7] + (pts[6] - lpts[7]) / 2)) * 0.5;
178 bool builtpillars =
true;
180 float sidefactor = 0.5;
183 if (pos.y - heightmiddle < 10)
185 if (heightleft >= heightright)
191 static int pillarcounter = 0;
199 if (pillarcounter % 5)
200 builtpillars =
false;
203 middle = lpts[0] - ((lpts[0] + (pts[1] - lpts[0]) / 2) -
204 (lpts[7] + (pts[6] - lpts[7]) / 2)) * sidefactor;
206 float width2 = len / 30;
208 if (pillartype == 2 && len > 20)
210 builtpillars =
false;
219 if (width2 >= 0.2 && builtpillars)
222 addQuad(middle + Vector3(-width2, -len, -width2),
223 middle + Vector3(-width2, 0, -width2),
224 middle + Vector3(width2, 0, -width2),
225 middle + Vector3(width2, -len, -width2),
228 addQuad(middle + Vector3(width2, -len, width2),
229 middle + Vector3(width2, 0, width2),
230 middle + Vector3(-width2, 0, width2),
231 middle + Vector3(-width2, -len, width2),
234 addQuad(middle + Vector3(-width2, -len, width2),
235 middle + Vector3(-width2, 0, width2),
236 middle + Vector3(-width2, 0, -width2),
237 middle + Vector3(-width2, -len, -width2),
240 addQuad(middle + Vector3(width2, -len, -width2),
241 middle + Vector3(width2, 0, -width2),
242 middle + Vector3(width2, 0, width2),
243 middle + Vector3(width2, -len, width2),
251 computePoints(pts, pos, rot, type, width, bwidth, bheight);
260 lastbheight = bheight;
265 Str<2000> msg; msg <<
"[RoR] Road Block |";
266 msg <<
" pos=(" << pos.x <<
" " << pos.y <<
" " << pos.z <<
")";
267 msg <<
" rot=(" << rot.x <<
" " << rot.y <<
" " << rot.z <<
")";
268 msg <<
" width=" << width;
269 msg <<
" bwidth=" << bwidth;
270 msg <<
" bheight=" << bheight;
271 msg <<
" type=" << (int)type;
272 for (
int i = 0; i < 8; ++i)
274 msg <<
"\n\t Point#" << i <<
": " << pts[i].x <<
" " << pts[i].y <<
" " << pts[i].z;
280 void ProceduralRoad::computePoints(Vector3* pts, Vector3 pos, Quaternion rot,
RoadType type,
float width,
float bwidth,
float bheight)
284 pts[1] = pos + rot * Vector3(0, -bheight, bwidth + width / 2.0);
285 pts[0] = baseOf(pts[1]);
286 pts[2] = pos + rot * Vector3(0, -bheight / 4.0, bwidth / 3.0 + width / 2.0);
287 pts[3] = pos + rot * Vector3(0, 0, width / 2.0);
288 pts[4] = pos + rot * Vector3(0, 0, -width / 2.0);
289 pts[5] = pos + rot * Vector3(0, -bheight / 4.0, -bwidth / 3.0 - width / 2.0);
290 pts[6] = pos + rot * Vector3(0, -bheight, -bwidth - width / 2.0);
291 pts[7] = baseOf(pts[6]);
295 pts[1] = pos + rot * Vector3(0, bheight, bwidth + width / 2.0);
296 pts[0] = baseOf(pts[1]);
297 pts[2] = pos + rot * Vector3(0, bheight, width / 2.0);
298 pts[3] = pos + rot * Vector3(0, 0, width / 2.0);
299 pts[4] = pos + rot * Vector3(0, 0, -width / 2.0);
300 pts[5] = pos + rot * Vector3(0, bheight, -width / 2.0);
301 pts[6] = pos + rot * Vector3(0, bheight, -bwidth - width / 2.0);
302 pts[7] = baseOf(pts[6]);
306 pts[1] = pos + rot * Vector3(0, -bheight, bwidth + width / 2.0);
307 pts[0] = baseOf(pts[1]);
308 pts[2] = pos + rot * Vector3(0, -bheight / 4.0, bwidth / 3.0 + width / 2.0);
309 pts[3] = pos + rot * Vector3(0, 0, width / 2.0);
310 pts[4] = pos + rot * Vector3(0, 0, -width / 2.0);
311 pts[5] = pos + rot * Vector3(0, bheight, -width / 2.0);
312 pts[6] = pos + rot * Vector3(0, bheight, -bwidth - width / 2.0);
313 pts[7] = baseOf(pts[6]);
317 pts[1] = pos + rot * Vector3(0, bheight, bwidth + width / 2.0);
318 pts[0] = baseOf(pts[1]);
319 pts[2] = pos + rot * Vector3(0, bheight, width / 2.0);
320 pts[3] = pos + rot * Vector3(0, 0, width / 2.0);
321 pts[4] = pos + rot * Vector3(0, 0, -width / 2.0);
322 pts[5] = pos + rot * Vector3(0, -bheight / 4.0, -bwidth / 3.0 - width / 2.0);
323 pts[6] = pos + rot * Vector3(0, -bheight, -bwidth - width / 2.0);
324 pts[7] = baseOf(pts[6]);
328 pts[0] = pos + rot * Vector3(0, -0.4, bwidth + width / 2.0);
329 pts[1] = pos + rot * Vector3(0, bheight, bwidth + width / 2.0);
330 pts[2] = pos + rot * Vector3(0, bheight, width / 2.0);
331 pts[3] = pos + rot * Vector3(0, 0, width / 2.0);
332 pts[4] = pos + rot * Vector3(0, 0, -width / 2.0);
333 pts[5] = pos + rot * Vector3(0, bheight, -width / 2.0);
334 pts[6] = pos + rot * Vector3(0, bheight, -bwidth - width / 2.0);
335 pts[7] = pos + rot * Vector3(0, -0.4, -bwidth - width / 2.0);
339 pts[0] = pos + rot * Vector3(0, -1.4, bwidth + width / 2.0);
340 pts[1] = pos + rot * Vector3(0, bheight, bwidth + width / 2.0);
341 pts[2] = pos + rot * Vector3(0, bheight, width / 2.0);
342 pts[3] = pos + rot * Vector3(0, 0, width / 2.0);
343 pts[4] = pos + rot * Vector3(0, 0, -width / 2.0);
344 pts[5] = pos + rot * Vector3(0, bheight, -width / 2.0);
345 pts[6] = pos + rot * Vector3(0, bheight, -bwidth - width / 2.0);
346 pts[7] = pos + rot * Vector3(0, -1.4, -bwidth - width / 2.0);
350 inline Vector3 ProceduralRoad::baseOf(Vector3 p)
359 return Vector3(p.x,
y, p.z);
362 void ProceduralRoad::addQuad(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4,
TextureFit texfit, Vector3 pos, Vector3 lastpos,
float width,
bool flip)
364 if (vertexcount + 3 >= MAX_VERTEX || tricount * 3 + 3 + 2 >= MAX_TRIS * 3)
367 textureFit(p1, p2, p3, p4, texfit, texf, pos, lastpos, width);
369 vertex[vertexcount] = p1;
370 tex[vertexcount] = texf[0];
371 vertex[vertexcount + 1] = p2;
372 tex[vertexcount + 1] = texf[1];
373 vertex[vertexcount + 2] = p3;
374 tex[vertexcount + 2] = texf[2];
375 vertex[vertexcount + 3] = p4;
376 tex[vertexcount + 3] = texf[3];
380 tris[tricount * 3] = vertexcount;
381 tris[tricount * 3 + 1] = vertexcount + 1;
382 tris[tricount * 3 + 2] = vertexcount + 3;
383 tris[tricount * 3 + 3] = vertexcount + 1;
384 tris[tricount * 3 + 3 + 1] = vertexcount + 2;
385 tris[tricount * 3 + 3 + 2] = vertexcount + 3;
389 tris[tricount * 3] = vertexcount;
390 tris[tricount * 3 + 1] = vertexcount + 1;
391 tris[tricount * 3 + 2] = vertexcount + 2;
392 tris[tricount * 3 + 3] = vertexcount;
393 tris[tricount * 3 + 3 + 1] = vertexcount + 2;
394 tris[tricount * 3 + 3 + 2] = vertexcount + 3;
401 addCollisionQuad(p1, p2, p3, p4, gm, flip);
407 void ProceduralRoad::textureFit(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4,
TextureFit texfit, Vector2* texc, Vector3 pos, Vector3 lastpos,
float width)
419 Vector3 pref2 = lastpos;
421 Vector3 bx = pref2 - pref1;
423 Vector3
by = Vector3::UNIT_Y;
424 Vector3 bz = bx.crossProduct(
by);
427 reverse.SetColumn(0, bx);
428 reverse.SetColumn(1,
by);
429 reverse.SetColumn(2, bz);
431 forward = reverse.Inverse();
433 for (i = 0; i < 4; i++)
435 Vector3 trv = forward * (ps[i] - pref1);
438 float ty = 0.746 - trv.y * 0.25 / 4.5;
442 texc[i] = Vector2(trv.x / 10.0, ty);
447 float ty = 0.496 - (trv.y - 0.7) * 0.25 / 4.5;
450 texc[i] = Vector2(trv.x / 10.0, ty);
454 float ty = 0.496 + trv.y * 0.25 / 4.5;
458 texc[i] = Vector2(trv.x / 10.0, ty);
471 Vector3 pref2 = lastpos;
473 for (i = 0; i < 4; i++)
478 Vector3 bx = pref2 - pref1;
480 Vector3
by = Vector3::UNIT_Y;
481 Vector3 bz = bx.crossProduct(
by);
484 reverse.SetColumn(0, bx);
485 reverse.SetColumn(1,
by);
486 reverse.SetColumn(2, bz);
488 forward = reverse.Inverse();
491 for (i = 0; i < 4; i++)
493 Vector3 trv = forward * (ps[i] - pref1);
498 texc[i] = Vector2(trv.x / 10.0, 0.621 + (trv.z - trvrefz) * 0.25 / 4.5);
530 texc[i] = Vector2(trv.x / 10.0, v1);
532 texc[i] = Vector2(trv.x / 10.0, v2);
538 for (i = 0; i < 4; i++)
539 texc[i] = Vector2(0, 0);
542 void ProceduralRoad::addCollisionQuad(Vector3 p1, Vector3 p2, Vector3 p3, Vector3 p4,
ground_model_t* gm,
bool flip)
549 registeredCollTris.push_back(triID);
553 registeredCollTris.push_back(triID);
559 registeredCollTris.push_back(triID);
563 registeredCollTris.push_back(triID);
567 void ProceduralRoad::addCollisionQuad(Ogre::Vector3 p1, Ogre::Vector3 p2, Ogre::Vector3 p3, Ogre::Vector3 p4, std::string
const& gm_name,
bool flip )
572 this->addCollisionQuad(p1, p2, p3, p4, gm, flip);
577 fmt::format(
"ProceduralRoad::addCollisionQuad() - ground model '{}' does not exist", gm_name));
581 void ProceduralRoad::createMesh()
590 Ogre::String mesh_name = Ogre::String(
"RoadSystem-").append(Ogre::StringConverter::toString(mid));
591 msh = MeshManager::getSingleton().createManual(mesh_name, ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
593 mainsub = msh->createSubMesh();
594 mainsub->setMaterialName(
"road2");
597 size_t vbufCount = (2 * 3 + 2) * vertexcount;
598 vertices = (
float*)malloc(vbufCount *
sizeof(
float));
601 for (i = 0; i < vertexcount; i++)
604 covertices[i].vertex = vertex[i];
606 covertices[i].normal = Vector3::ZERO;
607 aab.merge(vertex[i]);
611 size_t ibufCount = 3 * tricount;
614 for (i = 0; i < tricount && i * 3 + 2 < MAX_TRIS * 3; i++)
617 v1 = covertices[tris[i * 3 + 1]].vertex - covertices[tris[i * 3]].vertex;
618 v2 = covertices[tris[i * 3 + 2]].vertex - covertices[tris[i * 3]].vertex;
619 v1 = v1.crossProduct(v2);
621 covertices[tris[i * 3]].normal += v1;
622 covertices[tris[i * 3 + 1]].normal += v1;
623 covertices[tris[i * 3 + 2]].normal += v1;
626 for (i = 0; i < vertexcount; i++)
628 covertices[i].normal.normalise();
632 msh->sharedVertexData =
new VertexData();
633 msh->sharedVertexData->vertexCount = vertexcount;
636 VertexDeclaration* decl = msh->sharedVertexData->vertexDeclaration;
638 decl->addElement(0, offset, VET_FLOAT3, VES_POSITION);
639 offset += VertexElement::getTypeSize(VET_FLOAT3);
640 decl->addElement(0, offset, VET_FLOAT3, VES_NORMAL);
641 offset += VertexElement::getTypeSize(VET_FLOAT3);
642 decl->addElement(0, offset, VET_FLOAT2, VES_TEXTURE_COORDINATES, 0);
643 offset += VertexElement::getTypeSize(VET_FLOAT2);
647 HardwareVertexBufferSharedPtr vbuf =
648 HardwareBufferManager::getSingleton().createVertexBuffer(
649 offset, msh->sharedVertexData->vertexCount, HardwareBuffer::HBU_STATIC_WRITE_ONLY);
652 vbuf->writeData(0, vbuf->getSizeInBytes(), vertices,
true);
655 VertexBufferBinding* bind = msh->sharedVertexData->vertexBufferBinding;
656 bind->setBinding(0, vbuf);
660 HardwareIndexBufferSharedPtr ibuf = HardwareBufferManager::getSingleton().
662 HardwareIndexBuffer::IT_16BIT,
664 HardwareBuffer::HBU_STATIC_WRITE_ONLY);
667 ibuf->writeData(0, ibuf->getSizeInBytes(), tris,
true);
670 mainsub->useSharedVertices =
true;
671 mainsub->indexData->indexBuffer = ibuf;
672 mainsub->indexData->indexCount = ibufCount;
673 mainsub->indexData->indexStart = 0;
675 msh->_setBounds(aab,
true);