Page 1 of 1

Algorithm for Mouse position on the screen to 3D world ??

Posted: Mon Sep 19, 2011 7:13 pm
by marc_256
I lost two weeks with previous problem,
but now I made the next step in my virtual 3D world generator.

I use canvas gadget for creating my 3D mesh wireframe viewer.
All looks good if I build a 2D image (screen) from 3D mesh data.

But the next step is to find/select a vertex/edge on the screen by clicking with the mouse on the screen.
I did not found an answer in my 3D books that I brought, so,
Is there someone who knows an algorithm to converting
a mouse screen 2D XY-position to 3D world XYZ-coordinates ??

They call it a 3D ray...or something like that.

Thanks,
Marc,

PS: I hope to post some examples in the near future ... ??

Re: Algorithm for Mouse position on the screen to 3D world ?

Posted: Mon Sep 19, 2011 8:30 pm
by gnasen
I think you use perspective in your 3D view? If so, you should have a projection and a view matrix with the necessary data to calculate the ray like here:
http://stackoverflow.com/questions/2093 ... ay-picking

The next step would be the ray interesection, I think I wrote a code some time ago to do this, I will have a look for it.

Re: Algorithm for Mouse position on the screen to 3D world ?

Posted: Wed Sep 21, 2011 8:50 am
by Comtois
before PointPick() or MousePick() exist in PB, i used this code

Code: Select all

Structure s_Rayon
	*Objet.s_Body                  ;Adresse de l'objet en collision avec le rayon
	Origine.s_Vecteur              ;Origine du rayon
	Direction.s_Vecteur            ;Vecteur directeur du rayon
	;Informations collisions
 	CollisionDetectee.l             
 	DistanceLaPlusCourte.f
 	PointIntersection.s_Vecteur	   
EndStructure	

Structure s_Souris
  Clic.l
  Pos2D.POINT
  Pos3D.s_Vecteur
  Rayon.s_Rayon
 EndStructure

;Ecran
Screen\Width = 1024
Screen\Width_2 = Screen\Width  / 2
Screen\Height = 768
Screen\Height_2 = Screen\Height / 2
;Calcul de l'angle pour les projections
Angle = (#Focale * 0.0174533) / 2.0
Screen\d = (Screen\Height / (2 * Tan(Angle)))

;Get the camera's matrice (axis)

Procedure CalculMatriceCamera(No.l)
  Define.s_Vecteur x, y, z, p, SceneY

  SceneY\x = 0
  SceneY\y = 1
  SceneY\z = 0
 
  ;La camera est toujours orientée ver l'entity #Cube.
  ;Il est aussi possible de définir un point de la scène se trouvant 
  ;dans la direction de la caméra.
  
  ;Calcule l'axe z de la caméra (la caméra pointe vers l'entity)
  z\x = EntityX(No) - CameraX(0)
  z\y = EntityY(No) - CameraY(0)
  z\z = EntityZ(No) - CameraZ(0)
  Normalise(@z)

  ;Calcul l'axe x de la caméra de façon à ce qu'il soit perpendulaire aux axes z et Y de la Scène
  PRODUIT_VECTORIEL(x, z, SceneY); dot product
  Normalise(@x)
 
  ;Calcule l'axe Y de la caméra de façon à ce qu'il soit perpendiculaire aux axes z et x
  PRODUIT_VECTORIEL(y, z, x)
  Normalise(@y)
 
  ;Ligne Colonne
  MatriceCamera(0,0) = x\x
  MatriceCamera(0,1) = x\y
  MatriceCamera(0,2) = x\z 
 
  MatriceCamera(1,0) = y\x
  MatriceCamera(1,1) = y\y
  MatriceCamera(1,2) = y\z 
 
  MatriceCamera(2,0) = z\x
  MatriceCamera(2,1) = z\y
  MatriceCamera(2,2) = z\z 
EndProcedure

;Get MouseRay
Procedure P2D_P3D(*Mulot.s_Souris)
  Define.f X1, Y1, Z1
  
  CalculMatriceCamera(#Cube)
  
  ;Conversion position souris en 3D
  X1 = (*Mulot\Pos2D\x - Screen\Width_2) 
  Y1 = (*Mulot\Pos2D\y - Screen\Height_2) 
  Z1 = Screen\d 

  ;Retour dans le repère de la scène
  *Mulot\Pos3D\x = (MatriceCamera(0,0) * X1) + (MatriceCamera(1,0) * Y1) + (MatriceCamera(2,0) * Z1)
  *Mulot\Pos3D\y = (MatriceCamera(0,1) * X1) + (MatriceCamera(1,1) * Y1) + (MatriceCamera(2,1) * Z1)
  *Mulot\Pos3D\z = (MatriceCamera(0,2) * X1) + (MatriceCamera(1,2) * Y1) + (MatriceCamera(2,2) * Z1) 
  *Mulot\Pos3D\x  + CameraX(0) 
  *Mulot\Pos3D\y  + CameraY(0) 
  *Mulot\Pos3D\z  + CameraZ(0) 
  
  ;Calcul le rayon passant par la souris
  ;Origine du rayon
  *Mulot\Rayon\Origine\x = CameraX(0)
  *Mulot\Rayon\Origine\y = CameraY(0)
  *Mulot\Rayon\Origine\z = CameraZ(0)
 
  ;Direction du rayon
  *Mulot\Rayon\Direction\x = *Mulot\Pos3D\x - CameraX(0)
  *Mulot\Rayon\Direction\y = *Mulot\Pos3D\y - CameraY(0)
  *Mulot\Rayon\Direction\z = *Mulot\Pos3D\z - CameraZ(0)
  
  Normalise(*Mulot\Rayon\Direction)
EndProcedure 
And then, as gnasen said, you have to control ray intersection.
Example here :
http://www.purebasic.fr/english/viewtop ... 16&t=46749

Re: Algorithm for Mouse position on the screen to 3D world ?

Posted: Wed Sep 21, 2011 9:16 am
by marc_256
Hi gnasen and Comtois,

I was working very late yesterday evening,
(for a bug I had in a 3D formula)
stupid + sign instead of a - sign :evil:
but I found it so :D

I go test your software, thanks for helping here ...

Marc,

Let you know if it works ...