Re: Picking/object selection in directx
- From: "Robert Dunlop" <rdunlop@xxxxxxxx>
- Date: Wed, 1 Nov 2006 18:31:32 -0800
"fury" <hohums@xxxxxxxxx> wrote in message news:1162427707.207540.312260@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
I'm trying to find an effecient way of selecting meshes for a directx
program. My requirements are:
1) Pixel perfect.
2) Efficient
3) Memory efficient
4) Objects need to highlight when the mouse is over them. Therefore
this needs to be done within about 5 frames.
5) There will be many objects on screen.
6) DirectX 9, up to shader 2
7) Per object.
8) Each object has 2000 - 4000 polygons.
9) Simple if possible.
Here's the list of things I've thought of. I'd appresiate your comments
and suggestions.
Note that for all of these the first step is to do a ray verse AABB to
get down to object level.
1) Build a scene graph tree (AABB tree) for each object and raycast
traverse down to the smallest nodes. Then do a standard raycast
against the triangle.
- The issue I have with this is that it uses a lot of memory and we
might as well use our collision library.
One method I've used to trim down this task uses bounding spheres pre-calculated for each object, and tests them against the line segment under the cursor spanning the near clipping plane to the far clipping plane. At render time I've already done some coarse trimming to limit the rendering to likely visible objects, so already I've trimmed down the number of tests that may need performed. For each rendered object, I transform its center to world space (the line segment under the cursor is already transformed to world space at this point) and check the distance from the nearest point to the line segment to see if it is within the radius of the sphere. It's a fairly inexpensive test once you simplify it to eliminate square roots from the problem, it looks something like this (pseudocode):
// vNear is intersection of cursor with near plane in world space
// vFar is intersection of cursor with far plane in world space
Vec3 vRay=normalize(vFar-vNear);
float rayLen=Length(vFar-vNear);
// inside render loop....
Vec3 vCent=TransformVec3(mesh.center,mesh.worldMatrix);
Vec3 vh=vCent-vNear;
float a=dot(vh,vRay);
if (a<0.0f)
a=0.0f;
else if (a>rayLen)
a=rayLen;
Vec3 vClosest=vNear+vRay*a;
float vToCenter=vCent-vClosest;
if (sqRad>=dot(vToCenter,vToCenter))
// possible hit, test this mesh
In the above equation, "a" equals the distance from the ray's near plane intersection to the point on the ray nearest the center of the sphere. If this point is outside the line segment contained in the frustum, we constrain it to the near or far end of the segment. "dot(vToCenter,vToCenter)" then calculates the square of the distance from the closest point on the line segment to the center of the bounding sphere. If it is less than or equal to the square of the bounding sphere radius, we have a possible hit.
--
Robert Dunlop
Microsoft DirectX MVP 1998-2006
http://rdunlop.spaces.msn.com/
-------------
The X-Zone
http://www.directxzone.com/
.
- References:
- Picking/object selection in directx
- From: fury
- Picking/object selection in directx
- Prev by Date: Re: Problem rendering a list of triangle and a mesh
- Next by Date: DirectDrawEnumerateEx for Primay HAL ???
- Previous by thread: Picking/object selection in directx
- Next by thread: Re: Picking/object selection in directx
- Index(es):
Relevant Pages
|