realbasic-games
[Top] [All Lists]

Re: Getting the position of a object to match the x,y of the mouse.

To: "REALbasic Games" <REALbasic-Games at lists dot realsoftware dot com>
Subject: Re: Getting the position of a object to match the x,y of the mouse.
From: "Joseph J. Strout" <joe at realsoftware dot com>
Date: Sun, 25 Jan 2004 15:40:04 -0600
References: <p06010211bc3335350b1c at [192 dot 168 dot 0 dot 102]> <a05300b31bc33384c8f86 at [10 dot 10 dot 13 dot 3]> <p06010213bc334d5d14c4 at [192 dot 168 dot 0 dot 102]> <a05300b39bc3352dbc8f5 at [10 dot 10 dot 13 dot 3]> <p06010212bc39dcfdf4ed at [192 dot 168 dot 0 dot 101]>
At 2:52 PM -0600 1/25/04, Chris Dillman wrote:

Damn Im still getting no wear on this.

Joe if you get the time can you look into it?

OK, let's see what I can dig up.  ...Here we go:

Function ScreenToWorld(view as Rb3DSpace, X as Integer, Y As Integer) As Vector3D
   // Find the point in 3D space represented by the given
   // point in the 2D rendering.
   Dim dist As Double
   Dim screenPos As Vector3D
dist = Min(view.width, view.height) * 0.5 / tan(view.FieldOfView * kDegrees * 0.5) screenPos = New Vector3D
   screenPos.X = (view.width/2 - X)
   screenPos.Y = (view.height/2 - Y)
   screenPos.Z = dist
   screenPos = view.camera.orientation.Transform(screenPos)
   screenPos.Add view.camera.position
return screenPos
End Function

That gives you a position within the Hither plane that corresponds to the given X and Y.

Additionally, you may find this useful:

Function ScreenToYPlaneIntercept(view As Rb3DSpace, planeY as Double, X as Integer, Y As Integer) As Vector3D
   // Find the place at which a ray through the X,Y point in the
   // given view would intercept a horizontal plane at planeY.
Dim Q,V, out As Vector3D
   Dim t As Double
Q = ScreenToWorld(view, X, Y)
   V = Q.Minus(view.Camera.Position)
// The desired plane is a Y plane, with normal N=<0, 1, 0>
   // and offset (D) at -planeY.  The intersection of
   // this plane and a line Q+t*V occurs at:
   //  t = -(N.Dot(Q) + D) / (N.Dot(V))
   //
   // But for our simple Y plane, this reduces to:
   //  t = -(Q.y + D) / V.y
if v.y = 0 then
      return nil     // our ray is parallel to the floor, never intersects it
   end if
t = -(Q.y - planeY) / V.y
   return Q.Plus(V.Times(t))
End Function

This finds the position in a plane perpendicular to the Y axis, which is in line with a given X and Y on screen. Useful if you're placing or dragging items on a floor, and your floor is a Y plane.

Finally, if you need something even more general, here's the intersection of an arbitrary plane with a line through two points (for example, the camera position and a point found via ScreenToWorld above):

Function PlaneIntersection(planeNormal As Vector3D, planeD As Double, p0 As Vector3D, p1 As Vector3D) As Vector3D
   // Find the intersection of the line from p0 to p1 with the given plane.
// See Lengyel p. 85. Dim t As Double
   Dim V As Vector3D
V = p1.Minus(p0)
   t = -(planeNormal.dot(p0) + planeD) / (planeNormal.Dot(V))
   return p0.Plus(V.Times(t))
End Function


Enjoy,
- Joe

--
,------------------------------------------------------------------.
|    Joseph J. Strout           REAL Software, Inc.                |
|    joe at realsoftware dot com       http://www.realsoftware.com        |
`------------------------------------------------------------------'

- - -
Unsubscribe or switch delivery mode:
<http://support.realsoftware.com/listmanager/>

Search the archives of this list here:
<http://support.realsoftware.com/listarchives/lists.html>

<Prev in Thread] Current Thread [Next in Thread>