hi guys,
I'm trying to check for intersections with meshes in my scene(to find out which tile the user clicked on). I am developing a fake isometric(ortho view) tile based game in c# and MDX. I found an example of how to do this in vb.net(intersecting teapot mesh). I played around with it in vb, added extra meshes and changed the view and projection matrices etc. just to mimic how I would be using it in my game. I can't however seem to get the ray picking to work now that I have converted the code. any ideas on where I could be going wrong?
here is the vb ver
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'=======Parameters
presentParams = New PresentParameters
presentParams.Windowed = True
presentParams.SwapEffect = SwapEffect.Discard
'=======Device
dev = New Direct3D.Device(0, DeviceType.Hardware, pic3d, CreateFlags.HardwareVertexProcessing, presentParams)
'=======Mesh
mesh = mesh.Teapot(dev)
mesh2 = mesh.Teapot(dev)
'=======Camera
dev.Transform.View = Matrix.LookAtLH(New Vector3(0.0F, 2.0F, 2.0F), New Vector3(0, 0, 0), New Vector3(0, 1, 0))
'dev.Transform.View = Matrix.LookAtLH(New Vector3(0.0F, 30.0F, 30.0F), New Vector3(1, 1, 0), New Vector3(0, 1, 0))
'dev.Transform.View = Matrix.LookAtLH(Me.Width / 35, Me.Height / 35, -1000.0F, 10000.0F)
dev.Transform.Projection = Matrix.OrthoLH(CSng(Math.PI / 4), 1.3333, 1, 100)
'=======Loop
Me.Show()
MainLoop()
End Sub
Private Sub MainLoop()
Do
Render()
Application.DoEvents()
Loop
End Sub
Private Sub Render()
dev.Clear(ClearFlags.Target, System.Drawing.Color.CornflowerBlue, 1.0F, 0)
dev.BeginScene()
'==========
vec1 = New Vector3(1.7, 0, 0)
vec2 = New Vector3(-1.7, 0, 0)
dev.Transform.World = Matrix.Translation(vec1)
mesh.DrawSubset(0)
dev.Transform.World = Matrix.Translation(vec2)
mesh2.DrawSubset(0)
'==========
dev.EndScene()
dev.Present()
End Sub
Private Sub Form1_Mousedown(ByVal sender As System.Object, ByVal e As _
System.Windows.Forms.MouseEventArgs) Handles pic3d.MouseDown
If e.Button = MouseButtons.Left Then
Intersect(e.X, e.Y, vec1, mesh)
Intersect(e.X, e.Y, vec2, mesh2)
End If
End Sub
Public Sub Intersect(ByVal x As Single, ByVal y As Single, ByVal t As Vector3, ByVal m As Direct3D.Mesh)
Dim Near As Vector3
Dim Far As Vector3
Dim Closest As IntersectInformation
Dim locMesh As Mesh
Dim tran As Vector3
Near = New Vector3(x, y, 0)
Far = New Vector3(x, y, 1)
tran = New Vector3(0, 0, 0)
locMesh = m
Near.Unproject(dev.Viewport, dev.Transform.Projection, dev.Transform.View, Matrix.Translation(t))
Far.Unproject(dev.Viewport, dev.Transform.Projection, dev.Transform.View, Matrix.Translation(t))
Far.Subtract(Near)
'=======================================================
' Here is where you check for an intersection
If locMesh.Intersect(Near, Far, Closest) Then
dev.RenderState.FillMode = FillMode.WireFrame
Else
'dev.RenderState.FillMode = FillMode.Solid
End If
End Sub
here is some important snippets from the c# ver
private void SetupCamera()
{
device.Transform.Projection = Matrix.OrthoLH(this.Width / 35, this.Height / 35,-1000.0f, 10000.0f);
//device.Transform.View = Matrix.LookAtLH(new Vector3(0f,0f, 18.0f), new Vector3(28f,28f,0), new Vector3(1,1,0));
device.Transform.View = Matrix.LookAtLH(new Vector3(0f,0f, 18.0f), new Vector3(28f,28f,0), new Vector3(1,1,0));
//device.RenderState.Ambient = Color.DarkBlue;
device.Lights[0].Type = LightType.Directional;
device.Lights[0].Diffuse = Color.White;
device.Lights[0].Direction = new Vector3(0, -1, -2);
device.Lights[0].Enabled = true;
}
protected override void OnMouseDown(MouseEventArgs e)
{
if(e.Button == MouseButtons.Left)
{
intersection(grassMesh);
}
}
private void intersection(StaticMesh staticMesh)
{
IntersectInformation closest = new IntersectInformation();
Vector3 near = new Vector3(xMousePos,yMousePos,0);
Vector3 far = new Vector3(xMousePos,yMousePos,1);
Vector3 vec = (Vector3) tilesCoOrd[0];
near.Unproject(device.Viewport,device.Transform.Projection,device.Transform.View,Matrix.Translation(vec));
far.Unproject(device.Viewport,device.Transform.Projection,device.Transform.View,Matrix.Translation(vec));
far.Subtract(near);
Mesh mesh = staticMesh.getMesh();
if( mesh.Intersect(near,far,out closest))
{
//handle intersection
}
}
I'm trying to check for intersections with meshes in my scene(to find out which tile the user clicked on). I am developing a fake isometric(ortho view) tile based game in c# and MDX. I found an example of how to do this in vb.net(intersecting teapot mesh). I played around with it in vb, added extra meshes and changed the view and projection matrices etc. just to mimic how I would be using it in my game. I can't however seem to get the ray picking to work now that I have converted the code. any ideas on where I could be going wrong?
here is the vb ver
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'=======Parameters
presentParams = New PresentParameters
presentParams.Windowed = True
presentParams.SwapEffect = SwapEffect.Discard
'=======Device
dev = New Direct3D.Device(0, DeviceType.Hardware, pic3d, CreateFlags.HardwareVertexProcessing, presentParams)
'=======Mesh
mesh = mesh.Teapot(dev)
mesh2 = mesh.Teapot(dev)
'=======Camera
dev.Transform.View = Matrix.LookAtLH(New Vector3(0.0F, 2.0F, 2.0F), New Vector3(0, 0, 0), New Vector3(0, 1, 0))
'dev.Transform.View = Matrix.LookAtLH(New Vector3(0.0F, 30.0F, 30.0F), New Vector3(1, 1, 0), New Vector3(0, 1, 0))
'dev.Transform.View = Matrix.LookAtLH(Me.Width / 35, Me.Height / 35, -1000.0F, 10000.0F)
dev.Transform.Projection = Matrix.OrthoLH(CSng(Math.PI / 4), 1.3333, 1, 100)
'=======Loop
Me.Show()
MainLoop()
End Sub
Private Sub MainLoop()
Do
Render()
Application.DoEvents()
Loop
End Sub
Private Sub Render()
dev.Clear(ClearFlags.Target, System.Drawing.Color.CornflowerBlue, 1.0F, 0)
dev.BeginScene()
'==========
vec1 = New Vector3(1.7, 0, 0)
vec2 = New Vector3(-1.7, 0, 0)
dev.Transform.World = Matrix.Translation(vec1)
mesh.DrawSubset(0)
dev.Transform.World = Matrix.Translation(vec2)
mesh2.DrawSubset(0)
'==========
dev.EndScene()
dev.Present()
End Sub
Private Sub Form1_Mousedown(ByVal sender As System.Object, ByVal e As _
System.Windows.Forms.MouseEventArgs) Handles pic3d.MouseDown
If e.Button = MouseButtons.Left Then
Intersect(e.X, e.Y, vec1, mesh)
Intersect(e.X, e.Y, vec2, mesh2)
End If
End Sub
Public Sub Intersect(ByVal x As Single, ByVal y As Single, ByVal t As Vector3, ByVal m As Direct3D.Mesh)
Dim Near As Vector3
Dim Far As Vector3
Dim Closest As IntersectInformation
Dim locMesh As Mesh
Dim tran As Vector3
Near = New Vector3(x, y, 0)
Far = New Vector3(x, y, 1)
tran = New Vector3(0, 0, 0)
locMesh = m
Near.Unproject(dev.Viewport, dev.Transform.Projection, dev.Transform.View, Matrix.Translation(t))
Far.Unproject(dev.Viewport, dev.Transform.Projection, dev.Transform.View, Matrix.Translation(t))
Far.Subtract(Near)
'=======================================================
' Here is where you check for an intersection
If locMesh.Intersect(Near, Far, Closest) Then
dev.RenderState.FillMode = FillMode.WireFrame
Else
'dev.RenderState.FillMode = FillMode.Solid
End If
End Sub
here is some important snippets from the c# ver
private void SetupCamera()
{
device.Transform.Projection = Matrix.OrthoLH(this.Width / 35, this.Height / 35,-1000.0f, 10000.0f);
//device.Transform.View = Matrix.LookAtLH(new Vector3(0f,0f, 18.0f), new Vector3(28f,28f,0), new Vector3(1,1,0));
device.Transform.View = Matrix.LookAtLH(new Vector3(0f,0f, 18.0f), new Vector3(28f,28f,0), new Vector3(1,1,0));
//device.RenderState.Ambient = Color.DarkBlue;
device.Lights[0].Type = LightType.Directional;
device.Lights[0].Diffuse = Color.White;
device.Lights[0].Direction = new Vector3(0, -1, -2);
device.Lights[0].Enabled = true;
}
protected override void OnMouseDown(MouseEventArgs e)
{
if(e.Button == MouseButtons.Left)
{
intersection(grassMesh);
}
}
private void intersection(StaticMesh staticMesh)
{
IntersectInformation closest = new IntersectInformation();
Vector3 near = new Vector3(xMousePos,yMousePos,0);
Vector3 far = new Vector3(xMousePos,yMousePos,1);
Vector3 vec = (Vector3) tilesCoOrd[0];
near.Unproject(device.Viewport,device.Transform.Projection,device.Transform.View,Matrix.Translation(vec));
far.Unproject(device.Viewport,device.Transform.Projection,device.Transform.View,Matrix.Translation(vec));
far.Subtract(near);
Mesh mesh = staticMesh.getMesh();
if( mesh.Intersect(near,far,out closest))
{
//handle intersection
}
}