Sunday, June 04, 2006

Intersection tests

I was able to realise intersection tests with my 3D objects. I needed this for mouse interaction, because oviously it is needed to know if the mouse position matches the objects projection. This is not as easy as in 2D because it is actually not known where the object is displayed on the screen (due to the perspective view). Therefore a ray representing your mouse position has to be intersected with the object, currently represented by a bounding box.

First, I needed to get the parameters of the ray. I knew that the origin would be on (0,0,0) because this is the position of the viewer. Getting the direction was somehow more complicated. I figured out that the ray should be pointing at the projection of your mouseclick on the far plane. To shorten a long story, here is the code used for the inital calculations:

self.nearPlaneDist = 1.0
self.farPlaneDist = 100.0
self.perspectiveAngle = 45.0
self.aspectRatio = float(self.width)/float(self.height)
global pi
self.farPlaneHeight = self.farPlaneDist*2.0/tan(pi/2.0-self.perspectiveAngle*pi/360.0)
self.farPlaneWidth = self.farPlaneHeight*self.aspectRatio

and the actual ray is calculated this way:

# project mouse click position on far plane
xclick = float(event.pos[0]-self.width/2)*self.farPlaneWidth/float(self.width)
yclick = float(-event.pos[1]+self.height/2)*self.farPlaneHeight/float(self.height)
for obj in self.objects:
zhit = obj.intersectRay(Vector(0,0,0), Vector(xclick, yclick, -self.farPlaneDist).norm())

Having the ray, I needed to realise the intersection. For this I found an algorithm in "Real Time Rendering" (T. Möller, E. Haines) which I implemented as method in Object3D. It has 2 parameters (origin o, direction d) to specify the ray, its return value is 0 if no intersection was detected or the distance of the origin to the nearest point of intersection. This is handy if more than one objects are intersected, to find out which one was the nearest.

The output of the current test program looks just like the image shown in the last blog entry but now the cubes change their rotation direction if you click them. Additionally the distance of the intersection gets printed on the console, like this:
HIT! ( 19.4144860387 )
HIT! ( 14.6633880786 )
HIT! ( 10.6484258135 )
HIT! ( 21.4056345149 )
HIT! ( 16.9268217722 )

The test program is viewed by running Object3D.

3 Comments:

Anonymous Anonymous said...

Greets to the webmaster of this wonderful site. Keep working. Thank you.
»

6:25 AM  
Anonymous Anonymous said...

Greets to the webmaster of this wonderful site. Keep working. Thank you.
»

9:19 AM  
Anonymous Anonymous said...

I find some information here.

2:48 PM  

Post a Comment

<< Home