Re: How to get 3D coordinates from screen coordinates?
- From: "Robert Dunlop [MS MVP]" <rdunlop@xxxxxxxx>
- Date: Fri, 29 Apr 2005 09:30:49 -0700
The point on the intersected triangle is easily calculated from the returned
barycentric coordinates (U,V) of the intersection and the three points that
make up the triangle. The point of intersection for U,V coordinates
returned from IntersectTri with points A,B, and C is:
A + U*(B-A) + V*(C-A)
As a shortcut to this operation you can use the Vector3.BaryCentric function
(parameters f=U and g=V).
--
Robert Dunlop
The X-Zone
http://www.directxzone.com/
Microsoft DirectX MVP
-------------
The opinions expressed in this message are my own personal views and do not
reflect the official views of the Microsoft Corporation.
The MVP program does not constitute employment or contractual obligation
with Microsoft.
"RP" <rpfi@xxxxxxxxxxxxxx> wrote in message
news:epGIbazSFHA.1384@xxxxxxxxxxxxxxxxxxxxxxx
> Hi,
>
> Thanks Iain for the reference, I already had seen your previous post but I
> thought I didn't have to use an intersection ray.
> Thanks Robert for the theory background that helps me to understand the
> process of using a vector ray to determine the intersection with a
> primitive depending of where it is drawn in the frustum.
> I updated my code, and now I can determine if a click on screen is in or
> out of a rectangle. I'm using the Geometry.IntersectTri to check both
> triangles of that rectangle, I'm not sure if it is the best way. but my
> major concern is how to get the x-coordinates and y-coordinates of that
> click on screen. I'm using the barycentric coordinates of the
> IntersectInformation but it becomes a little confusing, and I hope that
> will be another way to get the coordinates. The coordinates I'm refering
> are the same that are used to create the vertices in the verts array.
> In pseudo-code, I'm getting X and Y (this are the coordinates of my
> vertices, between -2 and 2 for both axis) from U and V like this:
>
> Triangle 1:
>
> X = width * V + vector[0].X
> Y = - X + height * U , if x >= 0
> Y = - X - height * U , if x < 0
>
> Triangle 2:
>
> Y = - height * V + vector[4].Y
> X = - Y + height * U , if y >=0
> X = - Y - height * U , if y < 0
>
> Resuming, is the Geometry.IntersectTri the best way to check rectangles?
> And, more important, after having a positive intersection, how can I
> retrieve the coordinates X,Y of the point where I clicked?
>
> Thanks for your support.
>
> Here is the code:
>
> using System;
> using System.ComponentModel;
> using System.Drawing;
> using System.Windows.Forms;
> using Microsoft.DirectX;
> using Microsoft.DirectX.Direct3D;
>
> namespace Chapter3Code
> {
> public class Form1 : Form
> {
> private CustomVertex.PositionColored[] verts = new
> CustomVertex.PositionColored[6];
>
> private static float camPosX = 0;
> private static float camPosY = 0;
> private static float camPosZ = -5;
> private Device device = null;
> private VertexBuffer vb = null;
> private Container components = null;
>
> public Form1()
> {
> InitializeComponent();
> this.SetStyle(ControlStyles.AllPaintingInWmPaint |
> ControlStyles.Opaque, true);
> }
>
> public void InitializeGraphics()
> {
> PresentParameters presentParams = new
> PresentParameters();
> presentParams.Windowed = true;
> presentParams.SwapEffect = SwapEffect.Discard;
> device = new Device(0, DeviceType.Hardware, this,
> CreateFlags.SoftwareVertexProcessing, presentParams);
> device.RenderState.FillMode = FillMode.WireFrame;
> vb = new VertexBuffer(typeof
> (CustomVertex.PositionColored), 6, device, Usage.Dynamic |
> Usage.WriteOnly, CustomVertex.PositionColored.Format, Pool.Default);
> vb.Created += new
> EventHandler(this.OnVertexBufferCreate);
> OnVertexBufferCreate(vb, null);
> }
>
> private void OnVertexBufferCreate(object sender, EventArgs e)
> {
> VertexBuffer buffer = (VertexBuffer) sender;
> verts[0].Position = new Vector3(-2, 2, 0.0f);
> verts[0].Color = Color.Aqua.ToArgb();
> verts[1].Position = new Vector3(-2, -2, 0.0f);
> verts[1].Color = Color.Black.ToArgb();
> verts[2].Position = new Vector3(2, -2, 0.0f);
> verts[2].Color = Color.Purple.ToArgb();
> verts[3].Position = new Vector3(-2, 2, 0.0f);
> verts[3].Color = Color.Aqua.ToArgb();
> verts[4].Position = new Vector3(2, 2, 0.0f);
> verts[4].Color = Color.Black.ToArgb();
> verts[5].Position = new Vector3(2, -2, 0.0f);
> verts[5].Color = Color.Purple.ToArgb();
> buffer.SetData(verts, 0, LockFlags.None);
> }
>
> private void SetupCamera()
> {
> device.RenderState.CullMode = Cull.None;
> device.Transform.Projection =
> Matrix.PerspectiveFovLH((float) Math.PI/4, this.Width/this.Height, 1,
> 100.0f);
> device.Transform.View = Matrix.LookAtLH(new
> Vector3(camPosX, camPosY, camPosZ), new Vector3(camPosX, camPosY, 0), new
> Vector3(0, 1, 0));
> device.RenderState.Lighting = false;
> }
>
> protected override void OnPaint(PaintEventArgs e)
> {
> device.Clear(ClearFlags.Target, Color.CornflowerBlue,
> 1.0f, 0);
> SetupCamera();
> // Draw a middle point for reference at point (0,0)
> device.BeginScene();
> device.VertexFormat =
> CustomVertex.PositionColored.Format;
> device.SetStreamSource(0, vb, 0);
> device.DrawPrimitives(PrimitiveType.TriangleList, 0, 2);
> device.EndScene();
> device.Present();
> this.Invalidate();
> }
>
> protected override void Dispose(bool disposing)
> {
> if (disposing)
> {
> if (components != null)
> {
> components.Dispose();
> }
> }
> base.Dispose(disposing);
> }
>
> #region Windows Form Designer generated code
>
> private void InitializeComponent()
> {
> this.components = new System.ComponentModel.Container();
> this.Size = new System.Drawing.Size(640, 480);
> this.Text = "Form1";
> }
>
> #endregion
>
> private static void Main()
> {
> using (Form1 frm = new Form1())
> {
> frm.Show();
> frm.InitializeGraphics();
> Application.Run(frm);
> }
> }
>
> protected override void OnMouseDown(MouseEventArgs e)
> {
> Console.WriteLine("---------------------");
> Console.WriteLine("(mouse) X=" + e.X);
> Console.WriteLine("(mouse) Y=" + e.Y);
>
> IntersectInformation inside;
> Vector3 near = new Vector3(e.X, e.Y, 0);
> Vector3 far = new Vector3(e.X, e.Y, 1);
> near.Unproject(device.Viewport,
> device.Transform.Projection, device.Transform.View,
> device.Transform.World);
> far.Unproject(device.Viewport,
> device.Transform.Projection, device.Transform.View,
> device.Transform.World);
> far.Subtract(near);
> if (Geometry.IntersectTri(verts[0].Position,
> verts[1].Position, verts[2].Position, near, far, out inside))
> {
> Console.WriteLine("dist=" + inside.Dist);
> Console.WriteLine("index=" + inside.FaceIndex);
> Console.WriteLine("U=" + inside.U);
> Console.WriteLine("V=" + inside.V);
> Console.WriteLine("IN-1");
>
> float xxx = inside.V*4 + verts[0].Position.X;
> Console.WriteLine("******XX=" + (xxx));
> if (xxx >= 0)
> Console.WriteLine("******YY=" + (-xxx +
> 4*inside.U));
> else
> Console.WriteLine("*****YY=" + (-xxx -
> 4*inside.U));
> Console.WriteLine("");
> }
> else if (Geometry.IntersectTri(verts[3].Position,
> verts[4].Position, verts[5].Position, near, far, out inside))
> {
> Console.WriteLine("dist=" + inside.Dist);
> Console.WriteLine("index=" + inside.FaceIndex);
> Console.WriteLine("U=" + inside.U);
> Console.WriteLine("V=" + inside.V);
> Console.WriteLine("IN-2");
> float yyy = -inside.V*4 + verts[4].Position.Y;
> Console.WriteLine("******YY=" + (yyy));
> if (yyy >= 0)
> Console.WriteLine("******XX=" + (-yyy +
> 4*inside.U));
> else
> Console.WriteLine("*****XX=" + (-yyy -
> 4*inside.U));
> }
> else
> {
> Console.WriteLine("OUT");
> }
>
> Console.WriteLine("---------------------");
> }
>
> protected override void OnKeyDown(KeyEventArgs e)
> {
> if (e.KeyCode == Keys.Subtract)
> camPosZ -= 1;
> else if (e.KeyCode == Keys.Add)
> camPosZ += 1;
> else if (e.KeyCode == Keys.Left)
> camPosX -= 1F;
> else if (e.KeyCode == Keys.Right)
> camPosX += 1F;
> else if (e.KeyCode == Keys.Up)
> camPosY += 1F;
> else if (e.KeyCode == Keys.Down)
> camPosY -= 1F;
> Console.WriteLine("----------------------------");
> Console.WriteLine("(cam) X=" + camPosX);
> Console.WriteLine("(cam) Y=" + camPosY);
> Console.WriteLine("(cam) Z=" + camPosZ);
> Console.WriteLine("----------------------------");
> }
>
> }
> }
>
>
>
>
>
.
- References:
- How to get 3D coordinates from screen coordinates?
- From: RP
- Re: How to get 3D coordinates from screen coordinates?
- From: Robert Dunlop [MS MVP]
- Re: How to get 3D coordinates from screen coordinates?
- From: RP
- How to get 3D coordinates from screen coordinates?
- Prev by Date: How to draw a polygon?
- Next by Date: Re: How to draw a polygon?
- Previous by thread: Re: How to get 3D coordinates from screen coordinates?
- Next by thread: Beginner D3D needs help!
- Index(es):
Relevant Pages
|