best way to determine which mesh buffer has been clicked?
best way to determine which mesh buffer has been clicked?
Hi,
I have some code written that will give me the ISceneNode object that has been clicked and it works great. However, I plan to have all my models in one ms3d file where I use meshbuffers to deal each individual object inside my scene.
Is the best way to do this to draw an invisible box around each meshbuffer and then add it to the scene so that I know what has been clicked?
Thanks
I have some code written that will give me the ISceneNode object that has been clicked and it works great. However, I plan to have all my models in one ms3d file where I use meshbuffers to deal each individual object inside my scene.
Is the best way to do this to draw an invisible box around each meshbuffer and then add it to the scene so that I know what has been clicked?
Thanks
I have something that appears to work. For each meshbuffer/joint within my scene node I create a SphereSceneNode based on the position and size of the meshbuffers bounding box and set the material to vertexalpha and then make it invisible. Then I create a triangle selector for it so that I can use getSceneNodeAndCollisionPointFromRay to determine if I have a collision from the ray cast from my camera. This way I can determine which object in my model scene has been selected.
This seems to work pretty good, I am just wondering if this is the best way or if there are any other ways to this better?
This seems to work pretty good, I am just wondering if this is the best way or if there are any other ways to this better?
Code: Select all
mynode->getMesh()->getMeshBuffer(materialindex)->getBoundingBox();
sphere = smgr->addSphereSceneNode(1.0, 16, mynode, 999, box.getCenter(), core::vector3df(0,0,0), box.getExtent()/1.5);
sphere->setMaterialType(EMT_TRANSPARENT_VERTEX_ALPHA);
smgr->getMeshManipulator()->setVertexColorAlpha(sphere->getMesh(), 0);
scene::ITriangleSelector* selector = 0;
selector = smgr->createTriangleSelector(sphere->getMesh(), sphere);
sphere->setTriangleSelector(selector);
selector->drop();
-
- Admin
- Posts: 14143
- Joined: Wed Apr 19, 2006 9:20 pm
- Location: Oldenburg(Oldb), Germany
- Contact:
No, that's definitely not a good idea. Better use a dummy scene node which has no geometry to render at all. You'd be even better off with a cube node. But every node with geometry will send the geometry to the gpu, whether it is transparent or not. You can disable the color mask and depth buffer in order to avoid any rendering (should be faster than the alpha test) but it's still overhead.
Initially that is what I tried to do. I load my model and then I scale it so that it is the size that I want.hybrid wrote:Why not just use a bbox test, as it's much faster and the geometry of the sphere is far from the actual geometry from the scene node.
When I call mynode->setDebugDataVisible(scene::EDS_BBOX_ALL); all of the bounding boxes look perfect.
So I called getBoundingBox on my mesh buffer (as shown below) it does return a box of the correct size because I called draw3DBox later and it showed up properly. However when I called intersectsWithLine on my bbox it never returns true. I can never get it to return true.
Code: Select all
aabbox3df box = mynode->getMesh()->getMeshBuffer(2)->getBoundingBox();
...
core::line3d<f32> ray;
ray.start = cam->getPosition();
ray.end = ray.start + (cam->getTarget() - ray.start).normalize() * 30000.0f;
if(box.intersectsWithLine(ray))
{
//never gets here using the bounding box!
}
Thanks
Just in case anyone else needs the code. Here is what I did to test for a collision between a ray cast from the camera and a meshbuffer bounding box.
Cheers all!
Code: Select all
IAnimatedMesh* mesh = smgr->getMesh("../../media/test3.x");
IAnimatedMeshSceneNode* mynode = smgr->addAnimatedMeshSceneNode( mesh, 0);
aabbox3df box = mynode->getMesh()->getMeshBuffer(2)->getBoundingBox();
...
core::line3d<f32> ray;
ray.start = cam->getPosition();
ray.end = ray.start + (cam->getTarget() - ray.start).normalize() * 30000.0f;
matrix4 matrix;
mynode->getAbsoluteTransformation().getInverse(matrix);
matrix.transformVect(ray.start);
matrix.transformVect(ray.end);
if(box.intersectsWithLine(ray))
{
//we have a collision
}