Seite 1 von 1

Probleme mit RayCast

Verfasst: 22.08.2013 01:35
von MightyMAC
Hallo Leute,

ich versuche mir gerade ein Pfadfindungssystem in 3D zu basteln. Dafür werde ich mir den Dijkstra-Algorithmus zu rate ziehen. Diesem zu Grunde liegen soll eine Liste von Wegpunkten (Waypoints). Ich habe mir gerade ein Testprogramm zusammen gezimmert welches mir Verbindungen zwischen einzelnen Wegpunkten zeigen soll. Ich verwende den Befehl RayCast() um die Sichtbarkeit zwischen den Wegpunkten festzustellen. Leider klappt das irgendwie überhaupt nicht! :(

Ich denke mal ich bin wieder zu doof dafür, darum bitte ich euch darum mal einen Blick auf folgendes Programm zu werfen:

Code: Alles auswählen

InitEngine3D()
InitSprite()

Structure Str_PathConnection
  *Waypoint
  Distance.d
EndStructure

Structure Str_PathWaypoint
  Entity.l
  List Connection.Str_PathConnection()
EndStructure

Global NewList Waypoint.Str_PathWaypoint()

OpenWindow(0,100,100,800,600,"Test")
OpenWindowedScreen(WindowID(0),0,0,800,600)

; Camera
CreateCamera(1,0,0,100,100)
MoveCamera(1,0,100,100,#PB_Relative)
RotateCamera(1,-50,0,0)

; Materials
CreateTexture(0,256,256)
StartDrawing(TextureOutput(0))
  Box(0,0,255,255,RGB(200,0,0))
StopDrawing()

CreateTexture(1,256,256)
StartDrawing(TextureOutput(1))
  Box(0,0,255,255,RGB(0,0,200))
StopDrawing()

CreateTexture(2,256,256)
StartDrawing(TextureOutput(2))
  Box(0,0,255,255,RGB(0,200,200))
StopDrawing()

CreateMaterial(0,TextureID(0))
CreateMaterial(1,TextureID(1))
CreateMaterial(2,TextureID(2))

; Floor
CreatePlane(2,100,100,10,10,1,1)
CreateEntity(3,MeshID(2),MaterialID(0))

; Walls
CreateCube(4,10)
CreateEntity(5,MeshID(4),MaterialID(1),0,0,0,1)
ScaleEntity(5,5,2,0.3)
CreateEntity(8,MeshID(4),MaterialID(1),20,0,0,1)
ScaleEntity(8,0.3,2,5)

; Light
CreateLight(6,RGB(255,255,255),0,100,0)
AmbientColor(RGB(25, 25, 25))

Global WaypointMesh=CreateCylinder(#PB_Any,0.2,15)

Hero=CreateEntity(#PB_Any,MeshID(WaypointMesh),MaterialID(2),10,0,20,0)
ScaleEntity(Hero,3,1,10)

Aim=CreateEntity(#PB_Any,MeshID(WaypointMesh),MaterialID(2),0,0,-20,0)

Procedure Pathfinding_Init(StartMesh,AimMesh)
  Protected *TempWaypoint.Str_PathWaypoint
  Protected LineCount=0
  
  ; Add Start and Aim to the waypoint graph
  AddElement(Waypoint())
  Waypoint()\Entity=StartMesh
  AddElement(Waypoint())
  Waypoint()\Entity=AimMesh
  
  ; Check all connections between waypoints
  ForEach Waypoint()
    ClearList(Waypoint()\Connection())
    *TempWaypoint=@Waypoint()
    PushListPosition(Waypoint())
    ForEach Waypoint()
      If @Waypoint()<>*TempWaypoint
        Res=RayCast(EntityX(*TempWaypoint\Entity),EntityY(*TempWaypoint\Entity)+4,EntityZ(*TempWaypoint\Entity),EntityX(Waypoint()\Entity),EntityY(Waypoint()\Entity)+4,EntityZ(Waypoint()\Entity),1)
        Debug "Cast ("+StrD(EntityX(*TempWaypoint\Entity))+", "+StrD(EntityY(*TempWaypoint\Entity))+", "+StrD(EntityZ(*TempWaypoint\Entity))+") - ("+StrD(EntityX(Waypoint()\Entity))+", "+StrD(EntityY(Waypoint()\Entity))+", "+StrD(EntityZ(Waypoint()\Entity))+")"
        If Res<0
          AddElement(*TempWaypoint\Connection())
          *TempWaypoint\Connection()\Waypoint=@Waypoint()
          *TempWaypoint\Connection()\Distance=Sqr(Pow(EntityX(*TempWaypoint\Entity)+EntityX(Waypoint()\Entity),2.0) + Pow(EntityY(*TempWaypoint\Entity)+EntityY(Waypoint()\Entity),2.0) + Pow(EntityZ(*TempWaypoint\Entity)+EntityZ(Waypoint()\Entity),2.0))
          CreateLine3D(100+LineCount,EntityX(*TempWaypoint\Entity),EntityY(*TempWaypoint\Entity)+4,EntityZ(*TempWaypoint\Entity),RGB(255,255,255),EntityX(Waypoint()\Entity),EntityY(Waypoint()\Entity)+4,EntityZ(Waypoint()\Entity),RGB(255,255,255))
          LineCount+1
          Debug "Connection!"
        Else
          Debug "No Connection - Wall: "+Str(Res)
        EndIf
      EndIf
    Next
    PopListPosition(Waypoint())
  Next
EndProcedure

Procedure Add_Waypoint(x.d,y.d,z.d)
  AddElement(Waypoint())
  Waypoint()\Entity=CreateEntity(#PB_Any,MeshID(WaypointMesh),MaterialID(1),x,y,z)
EndProcedure

; Add some waypoints
Add_Waypoint(30,0,10)
Add_Waypoint(-30,0,0)
Add_Waypoint(-30,0,-30)

; Render world has to be called once, otherwise RayCast does not work
RenderWorld()

Pathfinding_Init(Hero,Aim)

; Create overlay sprite for text output
Overlay=CreateSprite(#PB_Any,800,600)
StartDrawing(SpriteOutput(Overlay))
  DrawingMode(#PB_2DDrawing_Transparent)
  ForEach Waypoint()
    DrawText(CameraProjectionX(1,EntityX(Waypoint()\Entity),EntityY(Waypoint()\Entity),EntityZ(Waypoint()\Entity)),CameraProjectionY(1,EntityX(Waypoint()\Entity),EntityY(Waypoint()\Entity),EntityZ(Waypoint()\Entity)),"("+StrD(EntityX(Waypoint()\Entity))+", "+StrD(EntityY(Waypoint()\Entity))+", "+StrD(EntityZ(Waypoint()\Entity))+")")
  Next
StopDrawing()

; Main loop
Repeat
  RenderWorld()
  DisplayTransparentSprite(Overlay,0,0)
  FlipBuffers()
Until WindowEvent()=#PB_Event_CloseWindow
Zum einen sollte der RayCast-Befehl, meiner bescheidenen Einschätzung nach, die Wände (PickMode=1) erkennen und dann zurückgeben, daß keine Verbindung zwischen Wegpunkten, die sich nicht sehen können, vorhanden ist. Das macht er aber nicht. Zum anderen dürfte er doch als Ergebnisse, wenn er denn die Wände erkennt nur 5 oder 8 (die Wall-Entities) zurückgeben, er gibt aber auch 0 zurück, warum?

Kann mir da einer weiterhelfen?

Danke im voraus.

Gruß
MAC

Re: Probleme mit RayCast

Verfasst: 22.08.2013 06:37
von Makke
Die Pick- und Visibility Masken müssen wie folgt festgelegt werden.

Code: Alles auswählen

1<<1
bis
1<<31

Re: Probleme mit RayCast

Verfasst: 22.08.2013 23:11
von MightyMAC
Ja, danke für den Hinweis, aber das ändert nichts an dem Problem.

Re: Probleme mit RayCast

Verfasst: 28.08.2013 07:46
von Makke
Schau Dir mal das Beispiel zu RayCast im Examples Ordner für PB an, wenn ich das richtig sehe ist dort nur ein Richtungsvektor als zweite Angabe angegeben und trotzdem findet er alle weiter dahinter liegenden Entities. Evt. ist der Befehl geändert worden aber die Beschreibung noch nicht.

Re: Probleme mit RayCast

Verfasst: 28.08.2013 10:28
von MightyMAC
Ja, richtig. Die zweite Angabe ist ein Vektor. Im englischen Forum habe ich das mit Comtois rausgefunden. Die Anleitung wird dementsprechend geändert. Auch hat RayCast() wohl einen Bug, der mit dem nächsten Release behoben sein soll. Mal abwarten.
Das mit dem Vektor ist auch irgendwie doof, da jetzt keine Verbindung zwischen Wegpunkten angezeigt werden, obwohl sie sich sehen können, wenn Wände dahinterliegen. Mal sehen wie ich das mache.

Re: Probleme mit RayCast

Verfasst: 28.08.2013 20:15
von Makke
Bleibt Dir nur Ray-Collide, das funktioniert noch mit Start- und Endpunkt.