How do I render the bounding box of an object?
by Ka Wang Wu · in Torque Game Engine Advanced · 12/05/2007 (9:26 am) · 7 replies
Heya, I'm back needing more help :)
Basically I've been implementing this resource:
http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=7335
I've confirmed that it works EXCEPT for the TGEA specific part, which is rendering a bounding box. I tried a suggestion that I found in the comments however it didn't work.
What I've tried is basically modifying the ShapeBase::renderObject(..) method in ShapeBase.cpp but to not avail. Currently the code looks like this:
I also tried removing the conditional for the bounding box code to confirm that the shapebase objects actually ues this method. However nothing actually rendered with a bounding box when I did that. So now I'm not sure how to get the bounding box rendering.
If anyone knows any other good way of giving visual feedback then that works fine too. I just thought bounding box was the easiest to implement.
EDIT: I tried this in both release and debug. Just in case someone thinks I compiled one version and used the other ;) oh, and like I said. the selected object is the correct one. I tried moving it to 0,0,0 and that worked fine.
Basically I've been implementing this resource:
http://www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=7335
I've confirmed that it works EXCEPT for the TGEA specific part, which is rendering a bounding box. I tried a suggestion that I found in the comments however it didn't work.
What I've tried is basically modifying the ShapeBase::renderObject(..) method in ShapeBase.cpp but to not avail. Currently the code looks like this:
void ShapeBase::renderObject( SceneState *state, RenderInst *ri )
{
RectI viewport = GFX->getViewport();
MatrixF proj = GFX->getProjectionMatrix();
// object selection additions
// if we have been selected, then render a circle around us
GameConnection* conn = GameConnection::getConnectionToServer();
ShapeBase* selectedObj = NULL;
if (conn)
selectedObj = conn->getSelectedObject();
S32 selectedId = -1;
if (selectedObj != NULL)
selectedId = selectedObj->getId();
// Debugging Bounding Box
// object selection change - added || (get() == selectedId) to existing statement
// if (!mShapeInstance || gShowBoundingBox) {
if (!mShapeInstance || gShowBoundingBox || (getId() == selectedId))
{
GFX->pushWorldMatrix();
GFX->multWorld( getRenderTransform() );
Point3F box1, box2;
box1 = (mObjBox.max - mObjBox.min) * 0.5;
box2 = (mObjBox.min + mObjBox.max) * 0.5;
wireCube( box1, box2 );
GFX->popWorldMatrix();
}
}I also tried removing the conditional for the bounding box code to confirm that the shapebase objects actually ues this method. However nothing actually rendered with a bounding box when I did that. So now I'm not sure how to get the bounding box rendering.
If anyone knows any other good way of giving visual feedback then that works fine too. I just thought bounding box was the easiest to implement.
EDIT: I tried this in both release and debug. Just in case someone thinks I compiled one version and used the other ;) oh, and like I said. the selected object is the correct one. I tried moving it to 0,0,0 and that worked fine.
#2
Should be the more appropriate place as it is called for sure.
Not sure if wireCube is actually implementated as none of the TGE basic shape functions is implemented.
12/06/2007 (9:41 am)
Check the prepRenderImage function. Should be the more appropriate place as it is called for sure.
Not sure if wireCube is actually implementated as none of the TGE basic shape functions is implemented.
#3
How does the editor display a bounding box if it isn't implemented?
looks like it's implemented
12/06/2007 (9:53 am)
Oh, one would assume they would at least call the render method :)How does the editor display a bounding box if it isn't implemented?
void ShapeBase::wireCube(const Point3F& size, const Point3F& pos)
{
GFX->drawWireCube( size, pos, ColorI( 255, 255, 255 ) );
/*
glDisable(GL_CULL_FACE);
for(int i = 0; i < 6; i++) {
glBegin(GL_LINE_LOOP);
for(int vert = 0; vert < 4; vert++) {
int idx = cubeFaces[i][vert];
glVertex3f(cubePoints[idx].x * size.x + pos.x, cubePoints[idx].y * size.y + pos.y, cubePoints[idx].z * size.z + pos.z);
}
glEnd();
}
*/
}looks like it's implemented
#4
And how it does it: most likely setting a field on the object either through C++ code or by setting it on the script object side (which I would assume more likely to happen)
12/06/2007 (10:31 am)
Yupp in that case it is implemented for the shapebase. Good thing.And how it does it: most likely setting a field on the object either through C++ code or by setting it on the script object side (which I would assume more likely to happen)
#5
I also changed the other instance of it in the prepRenderImage function. now a bounding box is created around the player. however all other objects don't seem to get a bounding box. I thought every other type of object was a subclass of ShapeBase?
I'm mostly interested in getting a bounding box around interiors. I am able to select them as the ID I get in the select corresponds to their ID. However their bounding box won't show up.. same for.. well.. every other object that isn't the player.
I tried adding similar code to tsstatic.cpp's prepRenderImage function but to no avail... and I can't even find the code that renders interiors.
*sigh*
seems a lot easier to do in TGE ... since I don't really understand the code I changed, heh.
12/06/2007 (10:37 am)
Ok, I changed the bounding box code in the prepRenderImage function. It looks like this nowif( gShowBoundingBox || (getId()==selectedId))
{
RenderInst *ri = gRenderInstManager.allocInst();
ri->obj = this;
ri->state = state;
ri->type = RenderInstManager::RIT_Object;
ri->mountedObjIdx = -1;
gRenderInstManager.addInst( ri );
}I also changed the other instance of it in the prepRenderImage function. now a bounding box is created around the player. however all other objects don't seem to get a bounding box. I thought every other type of object was a subclass of ShapeBase?
I'm mostly interested in getting a bounding box around interiors. I am able to select them as the ID I get in the select corresponds to their ID. However their bounding box won't show up.. same for.. well.. every other object that isn't the player.
I tried adding similar code to tsstatic.cpp's prepRenderImage function but to no avail... and I can't even find the code that renders interiors.
*sigh*
seems a lot easier to do in TGE ... since I don't really understand the code I changed, heh.
#6
So basically I opened the editor's .cpp files and did a search on "renderSelection" and found the following:
I assume this corresponds to the both boxes in World Editor.. now I just gotta see how to call them..
12/06/2007 (10:45 am)
Oh, thanks for the hint on the world editor. I dug around the creator scripts and found the following in EditorGui.cs:EWorldEditor.renderSelectionBox = getPrefSetting($pref::WorldEditor::renderSelectionBox, true);
So basically I opened the editor's .cpp files and did a search on "renderSelection" and found the following:
void WorldEditor::renderSelectionWorldBox(Selection & sel)
{
if(!mRenderSelectionBox)
return;
//
if(!sel.size())
return;
// build the world bounds
Box3F selBox = sel[0]->getWorldBox();
U32 i;
for(i = 1; i < sel.size(); i++)
{
const Box3F & wBox = sel[i]->getWorldBox();
selBox.min.setMin(wBox.min);
selBox.max.setMax(wBox.max);
}
//
PrimBuild::color( mSelectionBoxColor );
GFX->setCullMode( GFXCullNone );
GFX->setAlphaBlendEnable( false );
GFX->setTextureStageColorOp( 0, GFXTOPDisable );
GFX->setZEnable( true );
// create the box points
Point3F projPnts[8];
for(i = 0; i < 8; i++)
{
Point3F pnt;
pnt.set(BoxPnts[i].x ? selBox.max.x : selBox.min.x,
BoxPnts[i].y ? selBox.max.y : selBox.min.y,
BoxPnts[i].z ? selBox.max.z : selBox.min.z);
projPnts[i] = pnt;
}
// do the box
for(U32 j = 0; j < 6; j++)
{
PrimBuild::begin( GFXLineStrip, 4 );
for(U32 k = 0; k < 4; k++)
{
PrimBuild::vertex3fv( projPnts[BoxVerts[j][k]] );
}
PrimBuild::end();
}
GFX->setZEnable( true );
}
void WorldEditor::renderObjectBox(SceneObject * obj, const ColorI & col)
{
GFX->setCullMode( GFXCullNone );
GFX->setTextureStageColorOp( 0, GFXTOPDisable );
GFX->setZEnable( true );
PrimBuild::color( col );
// project the points...
Box3F box = obj->getObjBox();
MatrixF mat = obj->getTransform();
VectorF scale = obj->getScale();
Point3F projPnts[8];
for(U32 i = 0; i < 8; i++)
{
Point3F pnt;
pnt.set(BoxPnts[i].x ? box.max.x : box.min.x,
BoxPnts[i].y ? box.max.y : box.min.y,
BoxPnts[i].z ? box.max.z : box.min.z);
// scale it
pnt.convolve(scale);
mat.mulP(pnt, &projPnts[i]);
}
// do the box
for(U32 j = 0; j < 6; j++)
{
PrimBuild::begin( GFXLineStrip, 4 );
for(U32 k = 0; k < 4; k++)
{
PrimBuild::vertex3fv( projPnts[BoxVerts[j][k]] );
}
PrimBuild::end();
}
GFX->setZEnable( true );
}I assume this corresponds to the both boxes in World Editor.. now I just gotta see how to call them..
#7
however it's still only the player that seems to render the bounding box even though the code is in the shapeBase's prepRenderImage function.
hmm.. it would seem as if tsStatic overrides the prepRenderImage so I guess I should add some code for that and interiors. For anyone that's looking to do the same thing the interior's render code is in interiorInstance.cpp.
looks like I need to abstract that bounding box code a little or at least move it to SceneObject.
12/06/2007 (12:26 pm)
Ok, I was able to get the world editor code to work.however it's still only the player that seems to render the bounding box even though the code is in the shapeBase's prepRenderImage function.
hmm.. it would seem as if tsStatic overrides the prepRenderImage so I guess I should add some code for that and interiors. For anyone that's looking to do the same thing the interior's render code is in interiorInstance.cpp.
looks like I need to abstract that bounding box code a little or at least move it to SceneObject.
Torque Owner Ka Wang Wu