IS SceneNode picking done using BB?
IS SceneNode picking done using BB?
Hi consider from the above image solid is "Object", and rectangle is "Bounding Box". When i pick the object, its selecting using their bounding box. So that if i click out side also object is selectiong. And in uncoved area of object i have another object to pic, that object is not selecting.
How can is solve thas problem?
Solution which i have:
1. Oriented bounding box
2. Picking by object triangles
Can any one please give solution for this....
thanks in advance...
Gol solution
Thanks guys, got solution for object picking using object triangles
update and add the following code to CSceneCollisionManager in Irrlicht.
void CSceneCollisionManager::getPickedNodeBB(ISceneNode* root,
const core::line3df& ray,
s32 bits,
bool bNoDebugObjects,
f32& outbestdistance,
ISceneNode*& outbestnode)
{
core::vector3df edges[8];
const core::list<ISceneNode*>& children = root->getChildren();
core::list<ISceneNode*>::Iterator it = children.begin();
for (; it != children.end(); ++it)
{
ISceneNode* current = *it;
if (current->isVisible() &&
(bNoDebugObjects ? !current->isDebugObject() : true) &&
(bits==0 || (bits != 0 && (current->getID() & bits))))
{
// get world to object space transform
core::matrix4 mat;
if (!current->getAbsoluteTransformation().getInverse(mat))
continue;
// transform vector from world space to object space
core::line3df line(ray);
mat.transformVect(line.start);
mat.transformVect(line.end);
const core::aabbox3df& box = current->getBoundingBox();
scene::ITriangleSelector *lSelector = current->getTriangleSelector();
if(lSelector){
core::vector3df intersection;
core::triangle3df tri;
//std::cout<<"On Checking: "<<current->getName()<<std::endl;
if(getCollisionPointSSTL(line,lSelector,intersection,tri,&mat))
{
f32 distance = 0.0f;
f32 t = intersection.getDistanceFromSQ(line.start);
if (t > distance)
distance = t;
if (distance < outbestdistance)
{
outbestnode = current;
outbestdistance = distance;
}
}
}
// do intersection test in object space
/*if (box.intersectsWithLine(line))
{
box.getEdges(edges);
f32 distance = 0.0f;
for (s32 e=0; e<8; ++e)
{
f32 t = edges[e].getDistanceFromSQ(line.start);
if (t > distance)
distance = t;
}
if (distance < outbestdistance)
{
outbestnode = current;
outbestdistance = distance;
}
}*/
}
getPickedNodeBB(current, ray, bits, bNoDebugObjects, outbestdistance, outbestnode);
}
}
///New code
bool CSceneCollisionManager::getCollisionPointNew(const core::line3d<f32>& ray,
ITriangleSelector* selector, core::vector3df& outIntersection,
core::triangle3df& outTriangle,core::matrix4* transform)
{
if (!selector)
{
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
return false;
}
s32 totalcnt = selector->getTriangleCount();
Triangles.set_used(totalcnt);
s32 cnt = 0;
selector->getTriangles(Triangles.pointer(), totalcnt, cnt, ray,transform);
core::vector3df linevect = ray.getVector().normalize();
core::vector3df intersection;
f32 nearest = 9999999999999.0f;
bool found = false;
f32 tmp, tmp2;
f32 raylength = (f32)ray.getLengthSQ();
for (s32 i=0; i<cnt; ++i)
{
if (Triangles.getIntersectionWithLine(ray.start, linevect, intersection))
{
tmp = (f32)intersection.getDistanceFromSQ(ray.start);
tmp2 = (f32)intersection.getDistanceFromSQ(ray.end);
if (tmp < raylength && tmp2 < raylength &&
tmp < nearest)
{
nearest = tmp;
outTriangle = Triangles;
outIntersection = intersection;
found = true;
}
}
}
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
return found;
}
Node: Set TriangleSelector for each object...
update and add the following code to CSceneCollisionManager in Irrlicht.
void CSceneCollisionManager::getPickedNodeBB(ISceneNode* root,
const core::line3df& ray,
s32 bits,
bool bNoDebugObjects,
f32& outbestdistance,
ISceneNode*& outbestnode)
{
core::vector3df edges[8];
const core::list<ISceneNode*>& children = root->getChildren();
core::list<ISceneNode*>::Iterator it = children.begin();
for (; it != children.end(); ++it)
{
ISceneNode* current = *it;
if (current->isVisible() &&
(bNoDebugObjects ? !current->isDebugObject() : true) &&
(bits==0 || (bits != 0 && (current->getID() & bits))))
{
// get world to object space transform
core::matrix4 mat;
if (!current->getAbsoluteTransformation().getInverse(mat))
continue;
// transform vector from world space to object space
core::line3df line(ray);
mat.transformVect(line.start);
mat.transformVect(line.end);
const core::aabbox3df& box = current->getBoundingBox();
scene::ITriangleSelector *lSelector = current->getTriangleSelector();
if(lSelector){
core::vector3df intersection;
core::triangle3df tri;
//std::cout<<"On Checking: "<<current->getName()<<std::endl;
if(getCollisionPointSSTL(line,lSelector,intersection,tri,&mat))
{
f32 distance = 0.0f;
f32 t = intersection.getDistanceFromSQ(line.start);
if (t > distance)
distance = t;
if (distance < outbestdistance)
{
outbestnode = current;
outbestdistance = distance;
}
}
}
// do intersection test in object space
/*if (box.intersectsWithLine(line))
{
box.getEdges(edges);
f32 distance = 0.0f;
for (s32 e=0; e<8; ++e)
{
f32 t = edges[e].getDistanceFromSQ(line.start);
if (t > distance)
distance = t;
}
if (distance < outbestdistance)
{
outbestnode = current;
outbestdistance = distance;
}
}*/
}
getPickedNodeBB(current, ray, bits, bNoDebugObjects, outbestdistance, outbestnode);
}
}
///New code
bool CSceneCollisionManager::getCollisionPointNew(const core::line3d<f32>& ray,
ITriangleSelector* selector, core::vector3df& outIntersection,
core::triangle3df& outTriangle,core::matrix4* transform)
{
if (!selector)
{
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
return false;
}
s32 totalcnt = selector->getTriangleCount();
Triangles.set_used(totalcnt);
s32 cnt = 0;
selector->getTriangles(Triangles.pointer(), totalcnt, cnt, ray,transform);
core::vector3df linevect = ray.getVector().normalize();
core::vector3df intersection;
f32 nearest = 9999999999999.0f;
bool found = false;
f32 tmp, tmp2;
f32 raylength = (f32)ray.getLengthSQ();
for (s32 i=0; i<cnt; ++i)
{
if (Triangles.getIntersectionWithLine(ray.start, linevect, intersection))
{
tmp = (f32)intersection.getDistanceFromSQ(ray.start);
tmp2 = (f32)intersection.getDistanceFromSQ(ray.end);
if (tmp < raylength && tmp2 < raylength &&
tmp < nearest)
{
nearest = tmp;
outTriangle = Triangles;
outIntersection = intersection;
found = true;
}
}
}
_IRR_IMPLEMENT_MANAGED_MARSHALLING_BUGFIX;
return found;
}
Node: Set TriangleSelector for each object...