Code archives/3D Graphics - Misc/Faster/Smarter Screen-Coordinates > 3D Coordinates

This code has been declared by its author to be Public Domain code.

Download source code

Faster/Smarter Screen-Coordinates > 3D Coordinates by Streaksy2010
I just came up with this.

Here's two alternatives to CameraPick() that don't require any pickable geometry to return coordinates, and one of them is mega fast. Since they don't go by existing geometry you can specify depth (z) yourself - distance from camera if you like. No matter what depth you specify the returned coordinates will still be relative to the screen.



CameraPick3() is mega fast and doesn't use CameraPick().

CameraPick2() is another method I threw in. It does use CameraPick().

The both returh the exact same values. So they're acurate! =D



.
Global pickmesh,pastpickcam,cp3piv

Global Picked3X# ;Values returned from CameraPick3()
Global Picked3Y#
Global Picked3Z#






;test
Graphics3D 1024,768,32,2
SetBuffer BackBuffer()
dist#=10
light=CreateLight(2):LightRange light,20:PositionEntity light, 10,15,-10:AmbientLight 50,50,50
ball=CreateSphere(64):ScaleEntity ball,.025,1,.025:EntityColor ball,255,0,0:EntityShininess ball,.5
ball2=CreateSphere(64):ScaleEntity ball2,1,.025,.025:EntityColor ball2,0,0,255:EntityShininess ball2,.5
midball=CreateCube():ScaleEntity midball,.05,.05,.05:EntityColor midball,255,255,0:EntityShininess midball,.5

	cball1=CreateSphere(64):ScaleEntity cball1,.05,.05,.05:EntityColor cball1,155,255,155:EntityShininess cball1,.5
	cball2=CreateSphere(64):ScaleEntity cball2,.05,.05,.05:EntityColor cball2,155,255,155:EntityShininess cball2,.5
	cball3=CreateSphere(64):ScaleEntity cball3,.05,.05,.05:EntityColor cball3,155,255,155:EntityShininess cball3,.5
	cball4=CreateSphere(64):ScaleEntity cball4,.05,.05,.05:EntityColor cball4,155,255,155:EntityShininess cball4,.5

cam=CreateCamera()
	For rep=1 To 800 ;background spheres
	b=CreateSphere()
	EntityAlpha b,.5
	EntityColor b,Rnd(255),Rnd(255),Rnd(255)
	EntityShininess b,.5
	PositionEntity b,Rand(-50,50),Rand(-50,50),Rand(-50,50)
	Next
Repeat
Cls
	CameraPick2 cam,MouseX(),MouseY(),dist
	PositionEntity ball,PickedX(),PickedY(),PickedZ()
		CameraPick3 cam,MouseX(),MouseY(),dist
		PositionEntity ball2,Picked3X,Picked3Y,Picked3Z
PositionEntity midball,Picked3X,Picked3Y,Picked3Z

				cornerx1=MouseX()-100:cornery1=MouseY()-100
				cornerx2=MouseX()+100:cornery2=MouseY()-100
				cornerx3=MouseX()-100:cornery3=MouseY()+100
				cornerx4=MouseX()+100:cornery4=MouseY()+100
				CameraPick3 cam,cornerx1,cornery1,2:PositionEntity cball1,Picked3X,Picked3Y,Picked3Z
				CameraPick3 cam,cornerx2,cornery2,2:PositionEntity cball2,Picked3X,Picked3Y,Picked3Z
				CameraPick3 cam,cornerx3,cornery3,2:PositionEntity cball3,Picked3X,Picked3Y,Picked3Z
				CameraPick3 cam,cornerx4,cornery4,2:PositionEntity cball4,Picked3X,Picked3Y,Picked3Z
RenderWorld
				Rect cornerx1,cornery1,cornerx2-cornerx1,cornery3-cornery1,0 ;draw rectangle
				Line cornerx1,cornery1,cornerx4,cornery4
				Line cornerx2,cornery2,cornerx3,cornery3
Color 255,90,90:Text 20,5,"CameraPick2 cam,MouseX(),MouseY(),10   =   X="+PickedX()+", Y="+PickedY()+", Z="+PickedZ()
Color 90,90,255:Text 20,35,"CameraPick3 cam,MouseX(),MouseY(),10   =   X="+picked3x+", Y="+picked3y+", Z="+picked3z
Color 255,255,255:Text 40,60,"Use mouse buttons to control the depth, and cursor-keys left & right to turn camera"
If MouseDown(1) Then dist=dist+.5
If MouseDown(2) Then dist=dist-.5
If KeyDown(203) Then TurnEntity cam,0,1,0
If KeyDown(205) Then TurnEntity cam,0,-1,0
If dist<1.5 Then dist=1.5
If dist>30 Then dist=30
Flip
Until KeyHit(1)
End








; CAMERAPICK2()
;
;     PROS:
; * Changing the camera viewport doesn't require you to pass the new width and height
; * Results are returned to PickedX#(), PickedY#(), and PickedZ#(), as normal
;
;     CONS:
; * Relies on CameraPick() which means other pickable entities could cause conflicts,
;   affecting the resulting Z coordinate (but who cares)
; * Slower than CameraPick3()
;
Function CameraPick2(cm,x,y,z#=10)
If pickmesh=0 Then
pickmesh=CreateMesh()
srf=CreateSurface(pickmesh)
sz=100
v1=AddVertex(srf,-sz,-sz,0)
v2=AddVertex(srf,sz,-sz,0)
v3=AddVertex(srf,-sz,sz,0)
v4=AddVertex(srf,sz,sz,0)
AddTriangle srf,v1,v3,v4
AddTriangle srf,v1,v4,v2
EntityPickMode pickmesh,2
Else ShowEntity pickmesh
EndIf
	If cm<>lastpickcam Then
	lastpickcam=cm
	EntityParent pickmesh,cm
	PositionEntity pickmesh,0,0,z,0
	CameraPick cm,x,y
	EndIf
HideEntity pickmesh
End Function







; CAMERAPICK3() - Probably the best one
;
;     PROS:
; * Way fast
; * Doesn't rely on CameraPick() so there will be no conflicts with other pickable entities
;
;     CONS:
; * If the camera viewport has been changed, you must suply it's width and height
; * Results are returned to Picked3X#, Picked3Y# and Picked3Z# instead of the normal functions.  Not really a problem, though
;
Function CameraPick3#(cm,x,y,z#=10,sw=0,sh=0)
If sw=0 Then sw=GraphicsWidth()
If sh=0 Then sh=GraphicsHeight()
x=x-(sw/2):y=y-(sh/2)
If cp3piv=0 Then cp3piv=CreatePivot()
aspectratio#=Float(sh)/Float(sw)
ex#=(Float(x)/Float(sw))*(z*2)
ey#=-(Float(y)/Float(sh))*aspectratio*(z*2)
EntityParent cp3piv,cm
PositionEntity cp3piv,ex,ey,z,0
Picked3X=EntityX(cp3piv,1)
Picked3Y=EntityY(cp3piv,1)
Picked3Z=EntityZ(cp3piv,1)
End Function

Comments

None.

Code Archives Forum