Procedural road object (help?)
by Dan Keller · in Torque Game Engine · 03/18/2008 (2:30 pm) · 62 replies
I made an object that automatically renders a curved road from a path. Well, it's more of a proof of concept, but it works fairly well. I'm having two problems, though:
*it ignores fog when rendering and sometimes doesn't render at all
*I have absolutely no idea how to get collision working.
Both of these are areas of the engine I know very little about. So here are the files. Can anyone help me on this?
fxRoad.h
fxRoad.cc
And yes, I know the object is re-calculated every frame, that's temporary.
Oh and thanks to Melv May for the fxRenderObject code that this is based on.

*it ignores fog when rendering and sometimes doesn't render at all
*I have absolutely no idea how to get collision working.
Both of these are areas of the engine I know very little about. So here are the files. Can anyone help me on this?
fxRoad.h
fxRoad.cc
And yes, I know the object is re-calculated every frame, that's temporary.
Oh and thanks to Melv May for the fxRenderObject code that this is based on.

About the author
Recent Threads
#2
03/18/2008 (5:27 pm)
CryEngine 2 ftw! Very good work so far. This should get fixed up and added to the next update.
#3
The code uses a method that doesnt seem exist in the path class: 'getPath(mNodes, loc)'
Did I just miss something? Or is this something you added in yourself?
Either way, it's looking good. There's quite a lot of stuff you could do with something like this. Keep up the good work.
03/18/2008 (6:15 pm)
I'd kinda like to mess with this, but it doesn't compile. The code uses a method that doesnt seem exist in the path class: 'getPath(mNodes, loc)'
Did I just miss something? Or is this something you added in yourself?
Either way, it's looking good. There's quite a lot of stuff you could do with something like this. Keep up the good work.
#4
ok in sim\simPath.h around line 43 add
then in simPath.cc around line 246 add
Sorry, I forgot about that.
03/18/2008 (7:37 pm)
OOPS!!!!!ok in sim\simPath.h around line 43 add
void getPath(Vector<Point3F>& positions, Point3F localTrans);
then in simPath.cc around line 246 add
void Path::getPath(Vector<Point3F>& positions, Point3F localTrans)
{
updatePath(); //may not be neccesary, but w/e
for (iterator itr = begin(); itr != end(); itr++)
{
Marker* pMarker = dynamic_cast<Marker*>(*itr);
if (pMarker != NULL)
{
Point3F pos;
pMarker->getTransform().getColumn(3, &pos);
positions.push_back(pos - localTrans);
}
}
}Sorry, I forgot about that.
#5
Thanks for the function, by the way. :D
03/20/2008 (2:14 am)
In regards to fog, I'd highly reccomend rummaging through the interior code, and probably just gutting a good bit of the fog stuff from there.Thanks for the function, by the way. :D
#6
I hope to see this come up as a resource... hell... fix it up nice, add some more features, make a realtime tool for it and sell it as a kit. People would buy it.
Also... you know what else this can do with a little modification? Steams of water.... think about it. ;)
03/20/2008 (12:49 pm)
@Dan Keller - Congratulations... and great job! I'm happy to see someone fixing a hole in Torque instead of bitching about it. :)I hope to see this come up as a resource... hell... fix it up nice, add some more features, make a realtime tool for it and sell it as a kit. People would buy it.
Also... you know what else this can do with a little modification? Steams of water.... think about it. ;)
#7
03/20/2008 (12:53 pm)
Oh... and for collision... look at how TSSTatic submits its trangles to the Opcode polysoup collision (its burried deep in tsMesh or something). Or just read the Opcode docs. It shouldn't be hard to get working... one day effort.
#8
And making streams with this is a great idea, I never even thought of that.
03/20/2008 (4:13 pm)
I looked at the fog code and couldn't make any sense out of it. Oh, and I tried implementing collision before, but it never worked. I posted it up here in the hopes that someone with more experience with these things could get it working.And making streams with this is a great idea, I never even thought of that.
#9
So taking it a step further, you could hook it into the road system and rig it like Crysis' roads, aka you can tell the terrain to match the road. So set your path and if it's a bit above the terrain, have the terrain pull up to match the road so it's nice and smooth. Same idea for streams.
Another idea may be to look at the TLK's projection code, and allow for texture projection straight to the terrain and the like for doing old dirt roads that are basically tire tracks over dirt.
Another implemenation, though not quite as straightforward: coastlines.
Set a path that follows around the coast and then have the coastline be rendered and move in and out following the path. Not quite so elegant as totally dynamic, but a heck of a lot cleaner and artist-definable to boot.
03/23/2008 (11:55 am)
Speaking on streams and stuff, to do that, you'd basically hook this into the deformable terrain resource, right?So taking it a step further, you could hook it into the road system and rig it like Crysis' roads, aka you can tell the terrain to match the road. So set your path and if it's a bit above the terrain, have the terrain pull up to match the road so it's nice and smooth. Same idea for streams.
Another idea may be to look at the TLK's projection code, and allow for texture projection straight to the terrain and the like for doing old dirt roads that are basically tire tracks over dirt.
Another implemenation, though not quite as straightforward: coastlines.
Set a path that follows around the coast and then have the coastline be rendered and move in and out following the path. Not quite so elegant as totally dynamic, but a heck of a lot cleaner and artist-definable to boot.
#10
03/23/2008 (1:48 pm)
Well i don't know about the deformable terrain stuff, but having it hug the surface you put it on should be easy. Instead of having the terrain deform to match the road... how about having the road matches the terrain. You just need to do a raycast for each vertex after you generate the basic path.
#11
@Jeff The projection sounds like a good idea, then I won't have to worry about collisions.
EDIT: Ok, I looked into the projection code, and it uses a ClippedPolyList. Doing it this way would be VERY expensive because the road object is often very large and it would have to collide against many polygons.
EDIT: So can anyone help me?
03/23/2008 (1:53 pm)
@Tom That's exactly what it does.@Jeff The projection sounds like a good idea, then I won't have to worry about collisions.
EDIT: Ok, I looked into the projection code, and it uses a ClippedPolyList. Doing it this way would be VERY expensive because the road object is often very large and it would have to collide against many polygons.
EDIT: So can anyone help me?
#12
03/23/2008 (2:19 pm)
Ok, to fix the problem where it doesn't always render, change onAdd tobool fxRoad::onAdd()
{
if(!Parent::onAdd()) return(false);
setGlobalBounds();
resetWorldBox();
setRenderTransform(mObjToWorld);
// Add to Scene.
addToScene();
// Return OK.
return(true);
}
#13
If i were you i would build my road geometry into as few as possble vertex buffers (or whatever its called in ogl) and keep a separate structure of road section info. It would keep the start/end vertex and rendering info for the section of road and a bounding box for it. You can then cull road sections that are not visible and do not need to be rendered. If done right you can then render several connected road sections at once if they are all visible... keeping your draw call count low (one of the most important performance implications of rendering).
03/23/2008 (2:52 pm)
@Dan - Heh... didn't even notice that castRay in there. Well getting that mess of code out of renderObject() would be important... which you know. If i were you i would build my road geometry into as few as possble vertex buffers (or whatever its called in ogl) and keep a separate structure of road section info. It would keep the start/end vertex and rendering info for the section of road and a bounding box for it. You can then cull road sections that are not visible and do not need to be rendered. If done right you can then render several connected road sections at once if they are all visible... keeping your draw call count low (one of the most important performance implications of rendering).
#14
03/28/2008 (1:38 pm)
Ok, but my biggest issue right now is getting collision working.
#15
04/14/2008 (2:59 pm)
I gotta ask, have you considered trying polysoup for this? Since it is setup for static objects it should be pretty easy to incorporate.
#16
04/14/2008 (4:00 pm)
One additional question for any TGEA users, anyone out there tried converting this yet?
#17
04/20/2008 (3:53 pm)
I am right now.
#18
04/20/2008 (5:13 pm)
Fantastic! Because if it is in TGEA, I can probably get Polysoup to work with in about a day.
#19
Here are the files:
tgea_fxRoad.h
tgea_fxRoad.cpp
04/21/2008 (5:41 pm)
Ok, I give up. I can't get it to work. Can someone else try?Here are the files:
tgea_fxRoad.h
tgea_fxRoad.cpp
#20
I did notice when comparing your two different versions some missing things you might want to add.
In void fxRoad::renderObject(SceneState* state, RenderInst*)
right after
replace the remainder of the function with this:
Now it is always possible that I have missed adding something vital that should make it work in someplace other than the code. So give it a try and let me know.
04/22/2008 (5:08 pm)
Well Dan I have been trying to give it a go, but so far no luck.I did notice when comparing your two different versions some missing things you might want to add.
In void fxRoad::renderObject(SceneState* state, RenderInst*)
right after
if (!mTextureHandle) return;
replace the remainder of the function with this:
MatrixF proj = GFX->getProjectionMatrix();
RectI viewport = GFX->getViewport();
state->setupBaseProjection();
GFX->pushWorldMatrix();
// Transform by the objects' transform e.g move it.
GFX->multWorld(getTransform());
// Setup our rendering state (alpha blending).
GFX->setAlphaBlendEnable( true );
GFX->setSrcBlend(GFXBlendSrcAlpha);
GFX->setDestBlend(GFXBlendInvSrcAlpha);
GFX->setTextureStageColorOp(0, GFXTOPDisable);
GFX->setTexture(0, mTextureHandle);
// Set Colour/Alpha.
PrimBuild::color4f(1,1,1,1);
PrimBuild::begin(GFXTriangleStrip, mNodes.size()*mDetail+4);
for (i = 0; i<=arraypt; i++) {
PrimBuild::texCoord2f(texcs[i].x, texcs[i].y);
PrimBuild::vertex3f(verts[i].x, verts[i].y, verts[i].z);
}
PrimBuild::end();
GFX->setTexture(0, mBorderTextureHandle); //border texture
PrimBuild::begin(GFXTriangleStrip, mNodes.size()*mDetail+4);
for (i = 0; i<=arraypt; i++) {
PrimBuild::texCoord2f(lBTexcs[i].x, lBTexcs[i].y);
PrimBuild::vertex3f(lBorderVerts[i].x, lBorderVerts[i].y, lBorderVerts[i].z);
}
PrimBuild::end();
PrimBuild::begin(GFXTriangleStrip, mNodes.size()*mDetail+4);
for (i = 0; i<=arraypt; i++) {
PrimBuild::texCoord2f(rBTexcs[i].x, rBTexcs[i].y);
PrimBuild::vertex3f(rBorderVerts[i].x, rBorderVerts[i].y, rBorderVerts[i].z);
}
PrimBuild::end();
GFX->setAlphaBlendEnable(false);
GFX->setTextureStageColorOp(0, GFXTOPDisable);
GFX->setProjectionMatrix( proj );
GFX->setViewport( viewport );
GFX->popWorldMatrix();
}Now it is always possible that I have missed adding something vital that should make it work in someplace other than the code. So give it a try and let me know.
Torque Owner Cinder Games
As for collision, perhaps you could somehow create this object as a TSSTatic, and use with polysoup.