Any trick to know distance to the surface of an entity?

Everything related to 3D programming
User avatar
Psychophanta
Always Here
Always Here
Posts: 5153
Joined: Wed Jun 11, 2003 9:33 pm
Location: Anare
Contact:

Any trick to know distance to the surface of an entity?

Post by Psychophanta »

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.
http://www.zeitgeistmovie.com

while (world==business) world+=mafia;
miso
Enthusiast
Enthusiast
Posts: 466
Joined: Sat Oct 21, 2023 4:06 pm
Location: Hungary

Re: Any trick to know distance to the surface of an entity?

Post by miso »

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.

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.
User avatar
Psychophanta
Always Here
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?

Post by Psychophanta »

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.
http://www.zeitgeistmovie.com

while (world==business) world+=mafia;
miso
Enthusiast
Enthusiast
Posts: 466
Joined: Sat Oct 21, 2023 4:06 pm
Location: Hungary

Re: Any trick to know distance to the surface of an entity?

Post by miso »

;) I'm waiting for it.
User avatar
Psychophanta
Always Here
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?

Post by Psychophanta »

@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) :twisted:
http://www.zeitgeistmovie.com

while (world==business) world+=mafia;
miso
Enthusiast
Enthusiast
Posts: 466
Joined: Sat Oct 21, 2023 4:06 pm
Location: Hungary

Re: Any trick to know distance to the surface of an entity?

Post by miso »

@Psychophanta

Sure, just take your time. No need to hurry. ;)
User avatar
Psychophanta
Always Here
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?

Post by Psychophanta »

miso wrote: Tue Dec 03, 2024 8:45 am ;) I'm waiting for it.
viewtopic.php?t=86016
http://www.zeitgeistmovie.com

while (world==business) world+=mafia;
Post Reply