Quote: "Hi
It seems it doesnt always work with an ortho camera (fov =0)?"
You need to take into account the distance of the camera from the origin point
Function Distance3D(x1, y1, z1, x2, y2, z2)
result as integer
part1 = Pow((x2 - x1), 2)
part2 = Pow((y2 - y1), 2)
part3 = Pow((z2 - z1), 2)
underRadical = part1 + part2 + part3
result = Sqrt(underRadical)
EndFunction result
Function Object_RayCast(object_id, mouse_x, mouse_y)
unit_x# = Get3DVectorXFromScreen(mouse_x, mouse_y)
unit_y# = Get3DVectorYFromScreen(mouse_x, mouse_y)
unit_z# = Get3DVectorZFromScreen(mouse_x, mouse_y)
cam_x# = GetCameraX(1)
cam_y# = GetCameraY(1)
cam_z# = GetCameraZ(1)
dist=Distance3D(cam_x#, cam_y#, cam_z#, 0, 0, 0)*2
start_x# = unit_x# + cam_x#
start_y# = unit_y# + cam_y#
start_z# = unit_z# + cam_z#
end_x# = dist*unit_x# + cam_x#
end_y# = dist*unit_y# + cam_y#
end_z# = dist*unit_z# + cam_z#
hit_object_id = ObjectRayCast(object_id, start_x#, start_y#, start_z#, end_x#, end_y#, end_z#)
EndFunction hit_object_id
Here is a working example using both ortho and freeflight camera
#Constant KEY_A GetRawKeyState(65)
#Constant KEY_D GetRawKeyState(68)
#Constant KEY_S GetRawKeyState(83)
#Constant KEY_W GetRawKeyState(87)
#Constant KEY_R GetRawKeyPressed(82)
#Constant KEY_SHIFT GetRawKeyState(16)
// create some spheres and position them randomly
for i = 1 to 100
CreateObjectSphere(i,20,16,16)
SetObjectPosition(i, random(0,500), random(0,500), random(0,500))
SetObjectColor(i,0,255,0,255)
next i
// position the camera and have it look at the centre of the "map"
SetCameraPosition(1,0,500,0)
SetCameraLookAt(1,0,0,0,0)
do
// toggle freeflight
if KEY_R
if g_View.free_flight
g_View.free_flight=0
// reset camera position
SetCameraPosition(1,100,200,-100)
SetCameraLookAt(1,100,0,100,0)
else
g_View.free_flight=1
endif
endif
// handle view movement
if g_View.free_flight
View_HandleFreeFlightMovement()
else
View_HandleFixedMovement()
endif
// get the position of the pointer (mouse)
pointer_x = GetPointerX()
pointer_y = GetPointerY()
// determine which object has been hit
object_hit = Object_RayCast(0, pointer_x, pointer_y)
// if an object has been hit then turn it red
if object_hit <> 0
// select object
if GetRawMouseLeftPressed()
// turn all the objects green
for i = 1 to 100
if GetObjectExists(i)
SetObjectColor(i,0,255,0,255)
endif
next i
// turn selected object red
SetObjectColor(object_hit,255,0,0,255)
endif
// delete object
if GetRawMouseRightPressed()
DeleteObject(object_hit)
endif
endif
Print( "Click & Drag to rotate camera" )
Print( "WSAD: Move Camera XZ" )
Print( "Mouse Wheel: Move Camera Y" )
Print( "LMB: Select object" )
Print( "RMB: Delete object" )
Print( "R: Free Flight ("+Str(g_View.free_flight)+")" )
Sync()
loop
// View helper functions
Type t_View
drag_start_x as float
drag_start_y as float
drag_ang_x as float
drag_ang_y as float
free_flight
EndType
Global g_View as t_View
Function View_HandleFreeFlightMovement()
if KEY_A then MoveCameraLocalX(1, -10)
if KEY_D then MoveCameraLocalX(1, 10)
if KEY_S then MoveCameraLocalZ(1, -10)
if KEY_W then MoveCameraLocalZ(1, 10)
if GetRawMouseWheelDelta()>0 then MoveCameraLocalY(1, 10)
if GetRawMouseWheelDelta()<0 then MoveCameraLocalY(1, -10)
if ( GetPointerPressed())
g_View.drag_start_x = GetPointerX()
g_View.drag_start_y = GetPointerY()
g_View.drag_ang_x = GetCameraAngleX(1)
g_View.drag_ang_y = GetCameraAngleY(1)
endif
diff_x as float
diff_y as float
new_x as float
if ( GetPointerState() = 1 )
diff_x = (GetPointerX() - g_View.drag_start_x)/12.0
diff_y = (GetPointerY() - g_View.drag_start_y)/12.0
new_x = g_View.drag_ang_x + diff_y
if ( new_x > 89 ) then new_x = 89
if ( new_x < -89 ) then new_x = -89
SetCameraRotation( 1, new_x, g_View.drag_ang_y + diff_x, 0 )
endif
EndFunction
Function View_HandleFixedMovement()
if KEY_A then MoveCameraLocalX(1, -10)
if KEY_D then MoveCameraLocalX(1, 10)
if KEY_S then MoveCameraLocalY(1, -10)
if KEY_W then MoveCameraLocalY(1, 10)
mouse_speed=100
if KEY_SHIFT
mouse_speed=60
endif
if GetRawMouseWheelDelta()>0 then MoveCameraLocalZ(1, mouse_speed )
if GetRawMouseWheelDelta()<0 then MoveCameraLocalZ(1, -mouse_speed )
EndFunction
Function Distance3D(x1, y1, z1, x2, y2, z2)
result as integer
part1 = Pow((x2 - x1), 2)
part2 = Pow((y2 - y1), 2)
part3 = Pow((z2 - z1), 2)
underRadical = part1 + part2 + part3
result = Sqrt(underRadical)
EndFunction result
Function Object_RayCast(object_id, mouse_x, mouse_y)
unit_x# = Get3DVectorXFromScreen(mouse_x, mouse_y)
unit_y# = Get3DVectorYFromScreen(mouse_x, mouse_y)
unit_z# = Get3DVectorZFromScreen(mouse_x, mouse_y)
cam_x# = GetCameraX(1)
cam_y# = GetCameraY(1)
cam_z# = GetCameraZ(1)
dist=Distance3D(cam_x#, cam_y#, cam_z#, 0, 0, 0)*2
start_x# = unit_x# + cam_x#
start_y# = unit_y# + cam_y#
start_z# = unit_z# + cam_z#
end_x# = dist*unit_x# + cam_x#
end_y# = dist*unit_y# + cam_y#
end_z# = dist*unit_z# + cam_z#
hit_object_id = ObjectRayCast(object_id, start_x#, start_y#, start_z#, end_x#, end_y#, end_z#)
EndFunction hit_object_id
Quote: "I know that 'GetSpriteHit(x,y) that works with sprites, ....... but is there a 'GetObjectHit(x,y) ' equivalent that works with objects?"
A little reshuffle of the first 2 functions I posted here gives exactly that
Function GetObjectHit(mouse_x, mouse_y)
unit_x# = Get3DVectorXFromScreen(mouse_x, mouse_y)
unit_y# = Get3DVectorYFromScreen(mouse_x, mouse_y)
unit_z# = Get3DVectorZFromScreen(mouse_x, mouse_y)
cam_x# = GetCameraX(1)
cam_y# = GetCameraY(1)
cam_z# = GetCameraZ(1)
part1 = Pow((0 - cam_x#), 2)
part2 = Pow((0 - cam_y#), 2)
part3 = Pow((0 - cam_z#), 2)
underRadical = part1 + part2 + part3
dist=Sqrt(underRadical)*2
start_x# = unit_x# + cam_x#
start_y# = unit_y# + cam_y#
start_z# = unit_z# + cam_z#
end_x# = dist*unit_x# + cam_x#
end_y# = dist*unit_y# + cam_y#
end_z# = dist*unit_z# + cam_z#
hit_object_id = ObjectRayCast(0, start_x#, start_y#, start_z#, end_x#, end_y#, end_z#)
EndFunction hit_object_id