I want to perform a mini-demo-game, about an automatic ship, or car, etc., capable of running or flying within any circuit in an efficient manner and without colliding with the walls of the circuit, i.e. another human player could compete with the algorithm, and furthermore, this mini-demo-game would eventually open another competition, a challenge between algorithms.
I have been searching throughout the 3D manual to see if there is any function that helps me know the distance to the surface of a 3D entity, given a point in space (or within the entity itself), and a ray (unitary vector to set the direction).
I originally thought this would be easely available via RayCast(), or RayPick(), etc., but what these functions provide is the location, in world coordinates, of the centroid of the entity, not the location of the collision point of the ray with the skin at the entity, which is exactly what is wanted.
If you find this interesting, just comment.
Any trick to know distance to the surface of an entity?
- Psychophanta
- Always Here
- Posts: 5153
- Joined: Wed Jun 11, 2003 9:33 pm
- Location: Anare
- Contact:
Re: Any trick to know distance to the surface of an entity?
Raycast gives back the surface point with pickX(), Y, Z, also can get the normals if you need that too.
Edit:
I don't think you need that, but for completeness the distance formula:
d = SQRT((x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1) + (z2 - z1)*(z2 - z1))
Edit 2:
I forgot that I'm still on 6.11, so maybe I'm wrong regarding the most recent version, or for linux for example.
Edit 3:
I cooked a spaghetti that works with my version. It's not nice, has unnecessary remainder code, but has the requested distance
calculation.
Edit 4:
Fixed the code, as raycast was misused.
Edit:
I don't think you need that, but for completeness the distance formula:
d = SQRT((x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1) + (z2 - z1)*(z2 - z1))
Edit 2:
I forgot that I'm still on 6.11, so maybe I'm wrong regarding the most recent version, or for linux for example.
Edit 3:
I cooked a spaghetti that works with my version. It's not nice, has unnecessary remainder code, but has the requested distance
calculation.
Edit 4:
Fixed the code, as raycast was misused.
Code: Select all
Structure maincamerastructure
ID.i
x.f
y.f
z.f
ax.f
ay.f
az.f
tax.f
tay.f
taz.f
speed.f
EndStructure
#Vectorlength=25
#castlength=1000
#maxcamspeed = 5
#mincamspeed = 0
Global Dim sysfont(370):Global Dim fontimport.i(370)
#USED_CHARACTERS="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()-_=+[{]};:',<.>/?"+Chr(34)
Define i.i : For i = 1 To Len(#USED_CHARACTERS) :fontImport(Asc(Mid(#USED_CHARACTERS,i,1)))=1 : Next i
Global maincamera.maincamerastructure
Global distance.f
Global vvectrornormalid.i,castvectorid.i
Global mousesensitivity.f=0.05
Global.f mdy,mdx
Procedure.f lerp(a.f,b.f,t.f)
ProcedureReturn(((1.0-t.f)*a) + (b*t))
EndProcedure
Procedure.f smooth(x.f,targetx.f)
ProcedureReturn((0.9*x.f)+(0.1*targetx.f))
EndProcedure
Procedure init()
InitEngine3D()
InitSprite()
OpenWindow(0,10,10,800,600,"")
OpenWindowedScreen(WindowID(0),0,0,800,600)
InitMouse()
InitKeyboard()
Restore petskii_font
Define x.i,i.i,j.i,sprline.a
For x= 1 To 370
If fontimport(x)=1
sysfont(x)=CreateSprite(-1,8,12,#PB_Sprite_AlphaBlending)
StartDrawing(SpriteOutput(sysfont(x)))
DrawingMode(#PB_2DDrawing_AllChannels)
For j=0 To 11
Read.a sprline
For i=0 To 7
If sprline&%1 :Plot(i,j,RGBA(255,255,255,255)): Else : Plot(i,j,RGBA(0,0,0,0)) : EndIf
sprline>>1
Next i
Next j
StopDrawing()
ZoomSprite(sysfont(x),16,24)
EndIf
Next x
EndProcedure
Procedure checkevents()
Repeat
Until WindowEvent()=0
EndProcedure
Procedure textout(x,y,text.s,color.i) : Define.i textlength,i,character
textlength.i = Len(text.s)
For i = 1 To textlength
character.i = Asc(Mid(text.s,i,1))
If IsSprite(sysfont(character))
DisplayTransparentSprite(sysfont(character),(x+((i-1) * 16)),(y),255,color.i)
EndIf
Next i
EndProcedure
Procedure setupcamera()
maincamera\ID = CreateCamera(#PB_Any,0,0,100,100)
MoveCamera(maincamera\ID,1,1,1,#PB_Absolute)
maincamera\x =CameraX(maincamera\ID)
maincamera\y =CameraY(maincamera\ID)
maincamera\z =CameraZ(maincamera\ID)
maincamera\ax = 0
maincamera\ay = 0
maincamera\az = 0
maincamera\tax = maincamera\ax
maincamera\tay = maincamera\ay
maincamera\taz = maincamera\az
EndProcedure
Procedure updatecamera()
maincamera\tax = maincamera\tax+mdy
maincamera\tay = maincamera\tay-mdx
maincamera\ax = smooth(maincamera\ax,maincamera\tax)
maincamera\ay = smooth(maincamera\ay,maincamera\tay)
maincamera\az = (maincamera\tay-maincamera\ay)/4
RotateCamera(maincamera\id,maincamera\ax,maincamera\ay,maincamera\az,#PB_Absolute)
EndProcedure
Procedure createenvironment()
mesh_A=CreatePlane(#PB_Any,10000,10000,1,1,1,1)
mesh_B=CreateCube(#PB_Any,50)
texture_A = CreateTexture(#PB_Any,256,256)
StartDrawing(TextureOutput(texture_A))
Box(0,0,255,255,RGB(10,128,10))
StopDrawing()
material_A=CreateMaterial(#PB_Any,TextureID(texture_A))
texture_B = CreateTexture(#PB_Any,256,256)
StartDrawing(TextureOutput(texture_B))
Box(0,0,255,255,RGB(128,128,10))
Box(50,50,150,150,RGB(128,10,10))
StopDrawing()
material_B=CreateMaterial(#PB_Any,TextureID(texture_B))
surface = CreateEntity(#PB_Any,MeshID(mesh_A),MaterialID(material_A),0,0,0)
RotateEntity(surface,0,180,0)
Dim cubes(100)
For i=1 To 100
cubes(i)=CreateEntity(#PB_Any,MeshID(mesh_B),MaterialID(material_B),-1000+Random(2000),25,-1000+Random(2000))
RotateEntity(cubes(i),0,Random(360),0)
Next i
setupcamera()
EndProcedure
Procedure rc()
MoveCamera(maincamera\id,CameraX(maincamera\id)+(CameraDirectionX(maincamera\id)*maincamera\speed),CameraY(maincamera\id)+(CameraDirectionY(maincamera\id)*maincamera\speed),CameraZ(maincamera\id)+(CameraDirectionZ(maincamera\id)*maincamera\speed),#PB_Absolute)
tx.f=(CameraDirectionX(maincamera\id)*#castlength)
ty.f=(CameraDirectionY(maincamera\id)*#castlength)
tz.f=(CameraDirectionZ(maincamera\id)*#castlength)
rayhitbool = RayCast(CameraX(mainCamera\ID), CameraY(mainCamera\ID), CameraZ(maincamera\id), tX, ty, tz,-1)
If rayhitbool
CreateLine3D(vvectornormalid, PickX(), PickY(), PickZ(), RGB(255,0,0), PickX() + NormalX()*#vectorlength, PickY() + NormalY()*#vectorlength, PickZ() + NormalZ()*#vectorlength, RGB(255,255,127))
distance=Sqr( (CameraX(maincamera\id)-PickX())*(CameraX(maincamera\id)-PickX()) + (CameraY(maincamera\id)-PickY())*(CameraY(maincamera\id)-PickY()) + (CameraZ(maincamera\id)-PickZ())*(CameraZ(maincamera\id)-PickZ()) )
EndIf
EndProcedure
Procedure checkinput()
ExamineKeyboard()
ExamineMouse()
mdx=MouseDeltaX()*mousesensitivity
mdy=-MouseDeltaY()*mousesensitivity
If MouseButton(#PB_MouseButton_Right)
maincamera\speed=smooth(maincamera\speed,#maxcamspeed)
Else
maincamera\speed=smooth(maincamera\speed,#mincamspeed)
EndIf
If KeyboardPushed(#PB_Key_Escape)
CloseScreen()
CloseWindow(0)
End
EndIf
EndProcedure
Procedure render()
rc()
RenderWorld()
textout(10,10,"Last hit Distance in units = "+StrF(distance,5),RGB(127,127,255))
;textout(10,30,"dirx = "+StrF(CameraDirectionX(maincamera\id),5),RGB(255,127,127))
;textout(10,50,"diry = "+StrF(CameraDirectionY(maincamera\id),5),RGB(255,127,127))
;textout(10,70,"dirz = "+StrF(CameraDirectionZ(maincamera\id),5),RGB(255,127,127))
;textout(10,100,"x = "+StrF(CameraX(maincamera\id),5),RGB(255,255,127))
;textout(10,120,"y = "+StrF(CameraY(maincamera\id),5),RGB(255,255,127))
;textout(10,140,"z = "+StrF(CameraZ(maincamera\id),5),RGB(255,255,127))
textout(10,580,"Right Mouse to move",RGB(255,255,127))
textout(550,580,"Escape to quit",RGB(255,127,127))
FlipBuffers()
EndProcedure
Procedure Run()
init()
createenvironment()
Repeat
checkevents()
checkinput()
updatecamera()
render()
ForEver
EndProcedure
run()
DataSection
petskii_font:
Data.a $00,$00,$38,$38,$38,$38,$38,$38,$00,$38,$00,$00,$00,$00,$EE,$EE,$EE,$00,$00,$00,$00,$00,$00,$00,$00,$00,$EE,$EE,$EE,$FF,$EE,$FF,$EE,$EE,$00,$00,$00,$00,$38,$38,$FC,$0E,$7C,$E0,$7E,$38,$00,$00
Data.a $00,$00,$CE,$CE,$EE,$70,$38,$1C,$EE,$E6,$00,$00,$00,$00,$7C,$7C,$EE,$7C,$3C,$EE,$EE,$FC,$00,$00,$00,$00,$E0,$E0,$70,$38,$00,$00,$00,$00,$00,$00,$00,$00,$70,$70,$38,$1C,$1C,$1C,$38,$70,$00,$00
Data.a $00,$00,$1C,$1C,$38,$70,$70,$70,$38,$1C,$00,$00,$00,$00,$00,$00,$EE,$7C,$FF,$7C,$EE,$00,$00,$00,$00,$00,$00,$00,$38,$38,$FE,$38,$38,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$38,$38,$1C,$00
Data.a $00,$00,$00,$00,$00,$00,$FE,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$38,$38,$00,$00,$00,$00,$00,$00,$C0,$E0,$70,$38,$1C,$0E,$00,$00,$00,$00,$7C,$7C,$EE,$FE,$FE,$EE,$EE,$7C,$00,$00
Data.a $00,$00,$38,$38,$38,$3C,$38,$38,$38,$FE,$00,$00,$00,$00,$7C,$7C,$EE,$E0,$70,$1C,$0E,$FE,$00,$00,$00,$00,$7C,$7C,$EE,$E0,$78,$E0,$EE,$7C,$00,$00,$00,$00,$E0,$E0,$F0,$F8,$EE,$FE,$E0,$E0,$00,$00
Data.a $00,$00,$FE,$FE,$0E,$7E,$E0,$E0,$EE,$7C,$00,$00,$00,$00,$7C,$7C,$EE,$0E,$7E,$EE,$EE,$7C,$00,$00,$00,$00,$FE,$FE,$EE,$70,$38,$38,$38,$38,$00,$00,$00,$00,$7C,$7C,$EE,$EE,$7C,$EE,$EE,$7C,$00,$00
Data.a $00,$00,$7C,$7C,$EE,$EE,$FC,$E0,$EE,$7C,$00,$00,$00,$00,$38,$38,$38,$00,$00,$00,$38,$38,$00,$00,$00,$00,$38,$38,$38,$00,$00,$00,$38,$38,$1C,$00,$00,$00,$F0,$F0,$38,$1C,$0E,$1C,$38,$F0,$00,$00
Data.a $00,$00,$00,$00,$00,$FE,$00,$FE,$00,$00,$00,$00,$00,$00,$1E,$1E,$38,$70,$E0,$70,$38,$1E,$00,$00,$00,$00,$7C,$7C,$EE,$E0,$70,$38,$00,$38,$00,$00,$00,$00,$7C,$7C,$EE,$FE,$FE,$0E,$CE,$7C,$00,$00
Data.a $00,$00,$38,$38,$7C,$EE,$FE,$EE,$EE,$EE,$00,$00,$00,$00,$7E,$7E,$EE,$EE,$7E,$EE,$EE,$7E,$00,$00,$00,$00,$7C,$7C,$EE,$0E,$0E,$0E,$EE,$7C,$00,$00,$00,$00,$3E,$3E,$7E,$EE,$EE,$EE,$7E,$3E,$00,$00
Data.a $00,$00,$FE,$FE,$0E,$0E,$3E,$0E,$0E,$FE,$00,$00,$00,$00,$FE,$FE,$0E,$0E,$3E,$0E,$0E,$0E,$00,$00,$00,$00,$7C,$7C,$EE,$0E,$FE,$EE,$EE,$7C,$00,$00,$00,$00,$EE,$EE,$EE,$EE,$FE,$EE,$EE,$EE,$00,$00
Data.a $00,$00,$7C,$7C,$38,$38,$38,$38,$38,$7C,$00,$00,$00,$00,$F8,$F8,$70,$70,$70,$70,$7E,$3C,$00,$00,$00,$00,$EE,$EE,$7E,$3E,$1E,$3E,$7E,$EE,$00,$00,$00,$00,$0E,$0E,$0E,$0E,$0E,$0E,$0E,$FE,$00,$00
Data.a $00,$00,$CE,$CE,$FE,$FE,$FE,$CE,$CE,$CE,$00,$00,$00,$00,$EE,$EE,$FE,$FE,$FE,$FE,$EE,$EE,$00,$00,$00,$00,$7C,$7C,$EE,$EE,$EE,$EE,$EE,$7C,$00,$00,$00,$00,$7E,$7E,$EE,$EE,$7E,$0E,$0E,$0E,$00,$00
Data.a $00,$00,$7C,$7C,$EE,$EE,$EE,$EE,$7C,$F0,$00,$00,$00,$00,$7E,$7E,$EE,$EE,$7E,$3E,$7E,$EE,$00,$00,$00,$00,$7C,$7C,$EE,$0E,$7C,$E0,$EE,$7C,$00,$00,$00,$00,$FE,$FE,$38,$38,$38,$38,$38,$38,$00,$00
Data.a $00,$00,$EE,$EE,$EE,$EE,$EE,$EE,$EE,$7C,$00,$00,$00,$00,$EE,$EE,$EE,$EE,$EE,$EE,$7C,$38,$00,$00,$00,$00,$CE,$CE,$CE,$CE,$FE,$FE,$FE,$CE,$00,$00,$00,$00,$EE,$EE,$EE,$7C,$38,$7C,$EE,$EE,$00,$00
Data.a $00,$00,$EE,$EE,$EE,$EE,$7C,$38,$38,$38,$00,$00,$00,$00,$FE,$FE,$E0,$70,$38,$1C,$0E,$FE,$00,$00,$00,$00,$7C,$7C,$1C,$1C,$1C,$1C,$1C,$7C,$00,$00,$00,$00,$7C,$7C,$70,$70,$70,$70,$70,$7C,$00,$00
Data.a $00,$00,$38,$38,$7C,$FE,$38,$38,$38,$38,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$FF,$00,$00,$00,$00,$00,$00,$00,$7C,$E0,$FC,$EE,$FC,$00,$00,$00,$00,$00,$00,$0E,$0E,$7E,$EE,$EE,$7E,$00,$00
Data.a $00,$00,$00,$00,$00,$7C,$0E,$0E,$0E,$7C,$00,$00,$00,$00,$00,$00,$E0,$E0,$FC,$EE,$EE,$FC,$00,$00,$00,$00,$00,$00,$00,$7C,$EE,$FE,$0E,$7C,$00,$00,$00,$00,$00,$00,$F0,$38,$FC,$38,$38,$38,$00,$00
Data.a $00,$00,$00,$00,$00,$FC,$EE,$EE,$FC,$E0,$7E,$00,$00,$00,$0E,$0E,$0E,$7E,$EE,$EE,$EE,$EE,$00,$00,$00,$00,$38,$38,$00,$3C,$38,$38,$38,$7C,$00,$00,$00,$00,$00,$00,$70,$00,$70,$70,$70,$70,$3C,$00
Data.a $00,$00,$0E,$0E,$0E,$0E,$7E,$3E,$7E,$EE,$00,$00,$00,$00,$3C,$3C,$38,$38,$38,$38,$38,$7C,$00,$00,$00,$00,$00,$00,$00,$EE,$FE,$FE,$FE,$CE,$00,$00,$00,$00,$00,$00,$00,$7E,$EE,$EE,$EE,$EE,$00,$00
Data.a $00,$00,$00,$00,$00,$7C,$EE,$EE,$EE,$7C,$00,$00,$00,$00,$00,$00,$00,$7E,$EE,$EE,$7E,$0E,$0E,$00,$00,$00,$00,$00,$00,$FC,$EE,$EE,$FC,$E0,$E0,$00,$00,$00,$00,$00,$00,$7E,$EE,$0E,$0E,$0E,$00,$00
Data.a $00,$00,$00,$00,$00,$FC,$0E,$7C,$E0,$7E,$00,$00,$00,$00,$00,$00,$38,$FE,$38,$38,$38,$F0,$00,$00,$00,$00,$00,$00,$00,$EE,$EE,$EE,$EE,$FC,$00,$00,$00,$00,$00,$00,$00,$EE,$EE,$EE,$7C,$38,$00,$00
Data.a $00,$00,$00,$00,$00,$CE,$FE,$FE,$FC,$FC,$00,$00,$00,$00,$00,$00,$00,$EE,$7C,$38,$7C,$EE,$00,$00,$00,$00,$00,$00,$00,$EE,$EE,$EE,$FC,$70,$3E,$00,$00,$00,$00,$00,$00,$FE,$70,$38,$1C,$FE,$00,$00
Data.a $00,$00,$F0,$F0,$38,$38,$1E,$38,$38,$F0,$00,$00,$00,$00,$1E,$1E,$38,$38,$F0,$38,$38,$1E,$00,$00
petskii_colors:
Data.a $01,$01,$01,$FF,$FF,$FF,$88,$00,$00,$AA,$FF,$EE,$CC,$44,$CC,$00,$CC,$55,$00,$00,$AA,$EE,$EE,$77,$DD,$88,$55,$66,$44,$00,$FF,$77,$77,$33,$33,$33,$77,$77,$77,$AA,$FF,$66,$00,$88,$FF,$BB,$BB,$BB
Data.a $00,$00,$00
mcursor_type_0:
Data.a $F8,$FF,$00,$00,$F8,$FF,$F0,$7F,$FF,$7F,$F0,$1F,$FF,$1F,$FE,$07,$FF,$07,$CE,$01,$CF,$01,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
Data.a $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
EndDataSection
Last edited by miso on Fri Feb 07, 2025 1:15 pm, edited 1 time in total.
- Psychophanta
- Always Here
- Posts: 5153
- Joined: Wed Jun 11, 2003 9:33 pm
- Location: Anare
- Contact:
Re: Any trick to know distance to the surface of an entity?
Thank you miso.
I believed what the manual estates about PickX()/Y/Z , i.e. , those coordinates refer to the entity position in the world.
But you are right, it is not like that, is referred ( at least for RayCast() ) to the point coordinate in its "skin".
So, it is what I needed, and I think soon will share the mini-demo-game, or whatever can be called.
I believed what the manual estates about PickX()/Y/Z , i.e. , those coordinates refer to the entity position in the world.
But you are right, it is not like that, is referred ( at least for RayCast() ) to the point coordinate in its "skin".
So, it is what I needed, and I think soon will share the mini-demo-game, or whatever can be called.
Re: Any trick to know distance to the surface of an entity?

- Psychophanta
- Always Here
- Posts: 5153
- Joined: Wed Jun 11, 2003 9:33 pm
- Location: Anare
- Contact:
Re: Any trick to know distance to the surface of an entity?
@miso Don't be in a hurry, good things take time. If you have been good this year, I will put the source code, otherwise: coal (which means a link to video or to executeable) 

Re: Any trick to know distance to the surface of an entity?
@Psychophanta
Sure, just take your time. No need to hurry.
Sure, just take your time. No need to hurry.

- Psychophanta
- Always Here
- Posts: 5153
- Joined: Wed Jun 11, 2003 9:33 pm
- Location: Anare
- Contact: