Thank you for the answers. These are elegant, simple and useful solutions.
I have experimented a bit in meantime and it seems that I found some sort of alternative without using UDT. Of course, the use of UDT is much more flexible, but in very simple cases I may encode the property of the object directly in the ID.
#option_explicit
// object kind ID
#constant kind_of_Floor 0x01
#constant kind_of_Wall 0x02
#constant kind_of_Crate 0x03
#constant kind_of_Barrel 0x04
global lastObjectID as integer = 0 // used for incremental IDs
// returns incremental ID with encoded kind of object
function NextObjectID (objectKind as integer)
local result as integer
inc lastObjectID
result=(lastObjectID << 8) || objectKind
endfunction result
// returns kind ID of given object
function GetObjectKind (obj as integer)
local result as integer
result=obj && 0xFF
endfunction result
// returns kind name of given object
function GetObjectKindName (obj as integer)
local result as string
select obj && 0xFF
case kind_of_Floor: exitfunction("Floor") : endcase
case kind_of_Wall: exitfunction("Wall") : endcase
case kind_of_Crate: exitfunction("Crate") : endcase
case kind_of_Barrel: exitfunction("Barrel"): endcase
case default: result="???": endcase
endselect
endfunction result
// setup window
SetWindowSize(800,600,0)
SetVirtualResolution(800,600)
SetAntialiasMode(1)
SetVSync(1)
global cx as float: global cy as float: global cz as float // camera position
global vx as float: global vy as float: global vz as float // raycast vector
global px as float: global py as float // pointer position
global obj as integer // temp object id
global indicated as integer // indicated object id
global text as integer // info text
// create a few objects of diffrent kinds
obj = NextObjectID( kind_of_Wall ): CreateObjectPlane(obj,10,10)
SetObjectPosition(obj,0,0,5): SetObjectColor(obj,200,100,100,255)
obj = NextObjectID( kind_of_Wall ): CreateObjectPlane(obj,10,10)
SetObjectPosition(obj,5,0,0): SetObjectRotation(obj,0,90,0)
SetObjectColor(obj,100,100,200,255)
obj = NextObjectID( kind_of_Floor ): CreateObjectPlane(obj,10,10)
SetObjectPosition(obj,0,-5,0): SetObjectRotation(obj,90,0,0)
SetObjectColor(obj,100,200,100,255)
obj = NextObjectID( kind_of_Barrel ): CreateObjectCylinder(obj,2,2,12)
SetObjectPosition(obj,-4,0,-4): SetObjectRotation(obj,0,0,0)
SetObjectColor(obj,100,100,100,255)
obj = NextObjectID( kind_of_Crate ): CreateObjectBox(obj,3,3,3)
SetObjectPosition(obj,0,2,0): SetObjectColor(obj,0,200,200,255)
// prepare camera
SetCameraPosition( 1, -9,7,-9 ): SetCameraRotation( 1, 30,45,0 )
cx = GetCameraX(1) : cy = GetCameraY(1) : cz = GetCameraZ(1)
text = CreateText(""): SetTextSize( text,30 )
// main loop
repeat
RotateObjectLocalY(obj,10*GetFrameTime())
px = GetPointerX()
py = GetPointerY()
vx = Get3DVectorXFromScreen( px,py )*1000
vy = Get3DVectorYFromScreen( px,py )*1000
vz = Get3DVectorZFromScreen( px,py )*1000
ObjectRayCast( 0, cx,cy,cz, vx,vy,vz )
if GetObjectRayCastNumHits() then indicated = GetObjectRayCastHitID(0) else indicated = 0
if indicated
SetTextString( text, GetObjectKindName(indicated) + " : 0x" + Hex(indicated) )
SetTextPosition( text, px, py+20 )
SetTextVisible( text, 1 )
else
SetTextVisible( text, 0 )
endif
Print(Round(ScreenFPS()))
Sync()
until GetRawKeyPressed(27)
The advantage is that it does not require searching in additional data structures, but there are also disadvantages - it can only be a simple identifier and this should not be used in parallel with the automatically generated ID of the objects (there may be a conflict above ID 100,000). Anyway, at the moment the use of UDT seems to be the best practice.