Re: How to get 3D coordinates from screen coordinates?

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



Thanks
The BaryCentric function works just fine

"Robert Dunlop [MS MVP]" <rdunlop@xxxxxxxx> wrote in message
news:uFV%239iNTFHA.2096@xxxxxxxxxxxxxxxxxxxxxxx
> 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("----------------------------");
>> }
>>
>> }
>> }
>>
>>
>>
>>
>>
>
>


.



Relevant Pages

  • robust 3D triangle-triangle intersection test
    ... I wonder if there's any robust 3D triangle-triangle intersection predicate? ... It seems that the most widely used 3D triangle-triangle intersection routine is Tomas Moller's routine. ... For example, Moller's routine can correctly report the intersection for the above example based on certain epsilons, but will likely to fail on some other triangle pairs. ...
    (comp.graphics.algorithms)
  • Re: Families of Straight Lines
    ... Since every point of intersection ... Add the two diagonals; the ... the triangle case. ... If all intersection points are collinear then the configuration is ...
    (sci.math)
  • Ray-Triangle intersection, more details
    ... The tree dots are delimiting an invisible triangle "hovering" over the ... Intersection basically works, infact if you move the cursors in the ... var e1 = vec3.create; ...
    (comp.graphics.api.opengl)
  • Re: Detecting mouse click on a particular triangle
    ... Given that this is terrain geometry, you should be able to optimize ... intersection testing to only search a limited portion of the geometry. ... intersection as the selected triangle without having to search further. ...
    (microsoft.public.win32.programmer.directx.graphics)
  • Re: How to get 3D coordinates from screen coordinates?
    ... The point on the intersected triangle is easily calculated from the returned ... The point of intersection for U,V coordinates ... > triangles of that rectangle, I'm not sure if it is the best way. ... I'm using the barycentric coordinates of the ...
    (microsoft.public.win32.programmer.directx.managed)