Jump to content

  • Log In with Google      Sign In   
  • Create Account


Mesh Picking Accuracy Problem


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
1 reply to this topic

#1 porters   Members   -  Reputation: 117

Like
0Likes
Like

Posted 04 December 2012 - 07:57 PM

Hi,

I'm having some accuracy issues with my mesh picking code. The problem im getting is that sometimes a mesh behind another mesh will be selected, instead of the front-most mesh.

Just some quick background as to how my meshes have been created and rendered. My application essentially renders a bunch of beams and columns in a 3D model (CAD type application). The beams and columns are my meshes. The mesh is created at the world original with a standard length of 1000mm. I store a transformation matrix for each beam mesh (that i call the world transform matrix) that is passed to the shader. The shader uses the world transformation matrix to scale, rotate and translate the mesh into the correct world position.

Since my meshes vertices are not defined in the correct world positions (remember that each mesh is created at the origin with a standard length), I had to do something a bit different for my picking calculations. I essenitally multiplied my beam world transform matrix by the camera world-view-projection (WVP) matrix. I then use this combined matrix in my Vector3.Unproject method to determien the ray position and direction.

For the most part, my code works really well. However, there are a few beams that are not selected correctly. I have uploaded some images showing the problem. The image showing the picking working as it should can be found here (correctIMG), the image showing incorrect behaviour can be found here (incorrectIMG). A beam that has been highlighted/selected is drawn in white. The white cross-hair denotes my mouse cursor location. Also see my picking code below (VB.Net).

Any help would be great. Thanks.

Private Sub HighlightBeam(ByVal e As Point)
	  
If D3Ddev Is Nothing Then
			Return
		End If

		'local variables
		Dim beam As elemental.Beam = Nothing
		Dim prop As elemental.BeamProperty = Nothing
		Dim selectedBeamID As Integer = Nothing
		Dim IsHit As Boolean = False
		Dim hitSuccess As Boolean = False
		Dim WVP As Matrix = Nothing
		Dim vp As Viewport = Me.Model.Camera.Viewport
		Dim octNode As elemental.OctNode = Nothing
		Dim beamMesh As Mesh = Nothing
		Dim hitDistance As Single = 0.0F
		Dim prevHitDistance As Single = Single.MaxValue


		'perform hit tests for all objects contained in the model bounding box
		For Each octNodeID In Me.Model.Octree.SelectedOctNodeList
		  
		 'select the current octnode
			octNode = Me.Model.Octree.OctNodeTable(octNodeID)
		  
		 'do nothing if the octnode contains no beams
			If octNode.BeamIDList Is Nothing OrElse octNode.BeamIDList.Count = 0 Then
				Continue For
			End If
		  
		'loop through beams contained in this octnode
			For Each beamID In octNode.BeamIDList
			  
				'retrieve beam
				beam = Me.Model.BeamTable(beamID)
				prop = Me.Model.BeamPropertyTable(beam.BeamPropertyID)
			  
				'perform no action if beam is hidden
				If Not beam.IsVisible Then
					Continue For
				End If
			  
			  'get the beam mesh template.
				If prop.SectionType = elemental.BeamSectionType.ISection Then
					beamMesh = Me.Model.GetISectionMesh(prop.ID, 1)
				ElseIf prop.SectionType = elemental.BeamSectionType.CircularHollow Then
					beamMesh = Me.Model.GetCHSMesh(prop.ID, Me.Model.Settings.Beams.CircleFacets, Me.Model.Settings.Beams.CurveSegments)
				ElseIf prop.SectionType = elemental.BeamSectionType.LipChannel Then
					beamMesh = Me.Model.GetLipChannelMesh(prop.ID, 1)
				ElseIf prop.SectionType = elemental.BeamSectionType.LSection Then
					beamMesh = Me.Model.GetLSectionMesh(prop.ID, 1)
				ElseIf prop.SectionType = elemental.BeamSectionType.CircularSolid Then
					beamMesh = Me.Model.GetCircularSolidMesh(prop.ID, Me.Model.Settings.Beams.CircleFacets, Me.Model.Settings.Beams.CurveSegments)
				Else
					'dispose unmanaged resources
					beamMesh.Dispose()
					Return
				End If

				'direction of the ray.
				Dim rayPos As New Vector3(e.X, e.Y, 0.0F)
				Dim rayDir As New Vector3(e.X, e.Y, 1.0F)


				'world-view-projection transform
				WVP = beam.WorldTransform * Me.Model.Camera.WVP

				'ray data
				rayPos = Vector3.Unproject(rayPos, vp.X, vp.Y, vp.Width, vp.Height, vp.MinZ, vp.MaxZ, WVP)
				rayDir = Vector3.Unproject(rayDir, vp.X, vp.Y, vp.Width, vp.Height, vp.MinZ, vp.MaxZ, WVP)
				rayDir = Vector3.Subtract(rayDir, rayPos)
				rayDir = Vector3.Normalize(rayDir)


				'hit test
				IsHit = beamMesh.Intersects(New Ray(rayPos, rayDir), hitDistance)
				'on hit occurence, record the selected beam ID
				If IsHit Then

					'record that a hit was observed
					hitSuccess = True


					'if beam is closer than the previous hit success, select this beam instead
					If hitDistance < prevHitDistance Then

						'track hit distance for all selected members to determine which one is in front of the other
						prevHitDistance = hitDistance
						selectedBeamID = beam.ID
					End If
				End If

				'dispose unmanaged resources
				beamMesh.Dispose()


			Next beamID

		Next octNodeID


		'on hit success, update selected beams
		If hitSuccess Then

			'unhighlight the last highlighted beam
			If Highlight_LastHighlightedBeamID <> 0 Then
				Me.Model.BeamTable(Highlight_LastHighlightedBeamID).IsHighlighted = False
			End If


			'update selected beam table
			If Not Me.Model.BeamTable(selectedBeamID).IsHighlighted Then
				Highlight_LastHighlightedBeamID = selectedBeamID
				Me.Model.BeamTable(selectedBeamID).IsHighlighted = True
			End If
		Else

			'unhighlight the last highlighted beam
			If Highlight_LastHighlightedBeamID <> 0 Then
				Me.Model.BeamTable(Highlight_LastHighlightedBeamID).IsHighlighted = False
				Highlight_LastHighlightedBeamID = 0
			End If
		End If
	End Sub


Sponsor:

#2 porters   Members   -  Reputation: 117

Like
0Likes
Like

Posted 05 December 2012 - 01:32 AM

Found the problem, although i don't really understand why it was a problem.

Basically i deleted the line : rayDir = Vector3.Normalize(rayDir)

So i don't normalized the ray direction at all anymore.

Now it works perfectly. Go figure.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS