Am Boden ausrichten (Winkel)

Für allgemeine Fragen zur Programmierung mit PureBasic.
Lambda
Beiträge: 526
Registriert: 16.06.2011 14:38

Am Boden ausrichten (Winkel)

Beitrag von Lambda »

Wie könnte man es anstellen den Spieler auf Terrain und Objekten auszurichten? Habe aktuell 4 RayCast's die den Boden abtasten, allerdings wüsste ich gerade nicht wie daraus der Spieler optimal gedreht wird. (vorallem flüssig, nicht ruckartig :D )
Benutzeravatar
Regenduft
Beiträge: 574
Registriert: 25.03.2008 15:07
Wohnort: THE LÄÄÄND!

Re: Am Boden ausrichten (Winkel)

Beitrag von Regenduft »

Da reicht ein RayCast() und dann NormalX(), NormalY() und NormalZ(). Sieht man schön im RayCast.pb-Demo!

Die Spielerausrichtung geht dann mit RotateEntity() und #PB_Absolute vermutlich am einfachsten. Evtl. wäre SetOrientation() sogar einfacher zu berechnen (und auf jeden Fall effizienter)...

Ich bin da leider auch nicht so bewandert um aus dem Stegreif heraus einen Code aus dem Ärmel zu schütteln, aber vom Prinzip her geht es so:
  1. Ein RayCast senkrecht nach unten
  2. einen Vektor aus NormalX(), NormalY() und NormalZ() bilden
  3. die Spieler-Entity so drehen, dass Y-Achse die gleiche Ausrichtung wie der Normalen-Vektor besitzt.
PS: Wenn Du 'nen Code postest schau ich's mir gerne mal an! :wink:
Habe das aber nur autodidaktisch erlernt, bin also nicht gerade der Profi...
PureBasic 5.73 LTE x86/x64 | Windows 7 (x64)
Lambda
Beiträge: 526
Registriert: 16.06.2011 14:38

Re: Am Boden ausrichten (Winkel)

Beitrag von Lambda »

Oo

SetOrientation() führte zum Absturz, kurz darauf ein Bluescreen. So langsam bin ich etwas von der oberflächlichen Ogre Integration angepisst.
Benutzeravatar
Regenduft
Beiträge: 574
Registriert: 25.03.2008 15:07
Wohnort: THE LÄÄÄND!

Re: Am Boden ausrichten (Winkel)

Beitrag von Regenduft »

Bluescreen? :shock:
Klingt mir eher nach einem Treiberproblem... Bei mir gibt's keine Probleme mit SetOrientation(). In was für einem Zusammenhang ist's abgestürzt? Eigener Code? Demo-Codes? Mir ist nämlich gestern meine Glaskugel abgestürzt. :wink:

Aber ohne Witz: Benutzt Du PureBasic 5.20 Beta 15 oder 5.11? Wenn's reproduzieren kannst wäre ein Bugreport sinnvoll. Gerade im 3D-Bereich hat sich bei PureBasic so extrem viel getan, dass es mich nicht wundert, wenn da einiges noch Zicken macht...
PureBasic 5.73 LTE x86/x64 | Windows 7 (x64)
Lambda
Beiträge: 526
Registriert: 16.06.2011 14:38

Re: Am Boden ausrichten (Winkel)

Beitrag von Lambda »

War jetzt lediglich dieser Befehl, den letzten hatte ich vor etwa 1-2 Jahren. :wink: Das möcht ich nicht reproduzieren. :D
Edit: aktuell 5.11

Wie genau rechnet sich dann der Aufprallwinkel aus?

Code: Alles auswählen

RayCast(0, 0, 0, 0, 2, 0, -1)
Die NormalXYZ() Funktionen flattern auf platten Terrain wild umher (bspw. -0.1 zu -1.23 zu 0.2).
Benutzeravatar
Regenduft
Beiträge: 574
Registriert: 25.03.2008 15:07
Wohnort: THE LÄÄÄND!

Re: Am Boden ausrichten (Winkel)

Beitrag von Regenduft »

Alexi hat geschrieben:aktuell 5.11
Ich nutze 5.20 Beta 15, evtl. ist's auch ein Bug der bereits gefixt wurde. (mal ohne Grundlage, rein aus dem Bauch raus... :wink:)
Alexi hat geschrieben:Wie genau rechnet sich dann der Aufprallwinkel aus?
PureBasic-Hilfe (NormalizeMesh) hat geschrieben:Es wird automatisch der Normalen-Vektor für jeden Eckpunkt (Knoten) des angegebenen Meshs oder Sub-Meshs berechnet.
Sind also im Mesh (oder Terrain) gespeicherte Werte. Das hat natürlich zur Folge, dass beim Wechsel von ein Poligon auf's nächste der Winkel ziemlich "rumspringen" kann. Auch das kann man schön in der RayCast.pb-Demo sehen: Schau mal genau hin, wenn der Strahl über die Kugel fährt. Kurz bevor er Sie verlässt hüpft der Normalenvektor wild herum, da (vermutlich) bei jedem Frame der Strahl auf einem anderen Polygon auftrifft.

Ich schätze mal, dass sich das nur durch Interpolation lösen lässt, sonst wird Dir dein Spieler immer beim Polygonwechsel "umklappen".

Ich habe auch irgendwie im Hinterkopf (kann also auch falsch sein), dass die Werte als Floats (nicht Double) gespeichert sind, was bei einem normalisierten Vektor (-> x,y,z = -1...+1) schon zu spürbaren Rundungsfehlern führen kann, da Floats zwischen -1 und +1 in der Genauigkeit abnehmen. (Ich drücke mich so vorsichtig aus, weil das echt alles nur Halbwissen ist!)
Alexi hat geschrieben:

Code: Alles auswählen

RayCast(0, 0, 0, 0, 2, 0, -1)
Die NormalXYZ() Funktionen flattern auf platten Terrain wild umher (bspw. -0.1 zu -1.23 zu 0.2).
Öhm... müsste das beim RayCast nicht "minus 2" lauten? Sonst strahlst Du doch nach oben, oder? Hast Du die Rückgabe von RayCast() überprüft? Wenn der Null ist und Du trotzdem danach NormalXYZ() aufrufst, dann ist's klar, dass er die wildesten Sachen macht. Hast Du's statt einem platten Terrain mal mit einem platten Mesh probiert? Nochmal ganz dezent: Wenn da ein Code wäre müsste ich nicht fragen. :wink:

PS: Normalen-Vektor, normalisierter Vektor und Rundungsfehler bei Floats wegen der Normalisierung... und da soll man als Normalo nicht durcheinander kommen?! :lol:

EDIT: Musst wohl 5.20 beta 16 ziehen oder auf die Final warten! Zwei interessante Postings zum Thema:
http://www.purebasic.fr/german/viewtopi ... 05#p315605
http://www.purebasic.fr/english/viewtop ... 04#p423704
PureBasic 5.73 LTE x86/x64 | Windows 7 (x64)
Lambda
Beiträge: 526
Registriert: 16.06.2011 14:38

Re: Am Boden ausrichten (Winkel)

Beitrag von Lambda »

Super, abgesehen davon, dass CreateImage() nicht #PB_Image_Transparent in der Beta 16 annimmt, fällt mein Spieler mit RayCollide des öfteren durch den Boden. :roll:
Lambda
Beiträge: 526
Registriert: 16.06.2011 14:38

Re: Am Boden ausrichten (Winkel)

Beitrag von Lambda »

Hier mal das Terrain Beispiel modifiziert. Es sind eben nur paar Zeilen, allerdings bin ich mir unsicher, wie die NormalXYZ() Werte anzuwenden sind. Zudem, wie zuverlässig gescannt wird und der Spieler davon ausgeschlossen wird. Dem Terrain lässt sich eben keine Maske zuweisen, einfacher wäre eine umgekehrte Maske.

Code: Alles auswählen

;
; ------------------------------------------------------------
;
;   PureBasic - Terrain : Physic
;
;    (c) 2012 - Fantaisie Software
;
; ------------------------------------------------------------
;

IncludeFile "Screen3DRequester.pb"

#TerrainMiniX = 0
#TerrainMiniY = 0
#TerrainMaxiX = 0
#TerrainMaxiY = 0
#PlayerSpeed = 60
#CameraSpeed = 10

Define.f KeyX, KeyY, MouseX, MouseY, TimeSinceLastFrame
Declare InitBlendMaps()

Structure Vector3
  x.f
  y.f
  z.f
EndStructure

Structure s_Key
  Up.i
  Down.i
  Left.i
  Right.i
  StrafeLeft.i
  StrafeRight.i
  Jump.i
EndStructure

Structure s_Entity
  Entity.i
  EntityBody.i
  BodyOffsetY.f 
  elapsedTime.f
  Key.s_Key
  MainNode.i  
  SightNode.i
  CameraNode.i  
  ForwardNode.i
  StrafeNode.i
EndStructure

Structure s_Camera
  Camera.i
  Tightness.f
  CameraNode.i 
  TargetNode.i
EndStructure    

Macro GetNodePosition(Position, Node)
  Position\x = NodeX(Node)  
  Position\y = NodeY(Node)  
  Position\z = NodeZ(Node)  
EndMacro

Macro SubVector3(V, V1, V2)
  V\x = V1\x - V2\x
  V\y = V1\y - V2\y
  V\z = V1\z - V2\z
EndMacro

;-Declare
Declare HandleEntity(*Entity.s_Entity)
Declare CameraTrack(*Camera.s_Camera, *Entity.s_Entity)
Declare OnGround(*Entity.s_Entity)


Define Robot.s_Entity
Define Camera.s_Camera

; OpenGL needs to have CG enabled to work (Linux and OS X have OpenGL by default)
;
CompilerIf #PB_Compiler_OS <> #PB_OS_Windows Or Subsystem("OpenGL")
  Flags = #PB_Engine3D_EnableCG
CompilerEndIf

If InitEngine3D(Flags)
  
  InitSprite()
  InitKeyboard()
  InitMouse()
  
  If Screen3DRequester()
    Add3DArchive("Data/Textures/"       , #PB_3DArchive_FileSystem)
    Add3DArchive("Data/Models"          , #PB_3DArchive_FileSystem)
    Add3DArchive("Data/Scripts"         , #PB_3DArchive_FileSystem)
    Add3DArchive("Data/Textures/nvidia" , #PB_3DArchive_FileSystem)
    Add3DArchive("Data/Packs/desert.zip", #PB_3DArchive_Zip)
    Parse3DScripts()
    
    WorldShadows(#PB_Shadow_Modulative, 200, RGB(120, 120, 120))
    
    MaterialFilteringMode(#PB_Default, #PB_Material_Anisotropic, 8)
    
    ;- Light 
    ;
    light = CreateLight(#PB_Any ,RGB(185, 185, 185), 4000, 1200, 1000, #PB_Light_Directional)
    SetLightColor(light, #PB_Light_SpecularColor, RGB(255*0.4, 255*0.4,255*0.4)) 
    LightDirection(light ,0.55, -0.3, -0.75) 
    AmbientColor(RGB(5, 5,5))
    
    ;- Camera 
    ;
    CreateCamera(0, 0, 0, 100, 100)
    CameraBackColor(0, RGB(5, 5, 10))
    
    ;----------------------------------
    ;-terrain definition
    SetupTerrains(LightID(Light), 3000, #PB_Terrain_NormalMapping)
    ;-initialize terrain 
    CreateTerrain(0, 513, 12000, 600, 3, "TerrainPhysic", "dat")
    ;-set all texture will be use when terrrain will be constructed 
    AddTerrainTexture(0,  0, 100, "dirt_grayrocky_diffusespecular.jpg",  "dirt_grayrocky_normalheight.jpg")
    AddTerrainTexture(0,  1,  30, "grass_green-01_diffusespecular.jpg", "grass_green-01_normalheight.jpg")
    AddTerrainTexture(0,  2, 200, "growth_weirdfungus-03_diffusespecular.jpg", "growth_weirdfungus-03_normalheight.jpg")
    
    ;-Construct terrains
    For ty = #TerrainMiniY To #TerrainMaxiY
      For tx = #TerrainMiniX To #TerrainMaxiX
        Imported = DefineTerrainTile(0, tx, ty, "terrain513.png", ty % 2, tx % 2)    
      Next
    Next  
    BuildTerrain(0)  
    
    If Imported = #True
      InitBlendMaps()
      UpdateTerrain(0)
      
      ; If enabled, it will save the terrain as a (big) cache for a faster load next time the program is executed
      ; SaveTerrain(0, #False)
    EndIf 
    
    ; enable shadow terrain
    TerrainRenderMode(0, 0)
    
    ;Add Physic
    TerrainPhysicBody(0, 0.1, 1)
    ;Texture
    CreateTexture(1, 256, 256)
    StartDrawing(TextureOutput(1))
    Box(0, 0, 256, 256, $002255)
    DrawingMode(#PB_2DDrawing_Outlined)
    Box(0, 0, 256, 256, $FFFFFF)
    Box(10, 10, 236, 236, $FFFF)
    StopDrawing()
    
    ;Material
    CreateMaterial(0, LoadTexture(0, "r2skin.jpg"))
    CreateMaterial(1, TextureID(1))
    CreateMaterial(2, LoadTexture(2, "Dirt.jpg"))
    CreateMaterial(3, LoadTexture(3, "Wood.jpg"))
    GetScriptMaterial(4, "Scene/GroundBlend")
    
    ;Robot
    LoadMesh   (0, "robot.mesh")
    CreateEntity (0, MeshID(0), #PB_Material_None);
    StartEntityAnimation(0, "Walk")
    
    ;Robot Body
    CreateEntity(1, MeshID(0), #PB_Material_None, 0, 426, 0)
    HideEntity(1, 1)
    
    ;Body
    EntityPhysicBody(1, #PB_Entity_CapsuleBody, 1, 0, 0) 
    
    ; Skybox
    SkyBox("desert07.jpg")
    
    ;
    With Robot
      \Entity = 0
      \EntityBody = 1
      \BodyOffsetY = 43 
      
      \Key\Down        = #PB_Key_Down
      \Key\Left        = #PB_Key_Left
      \Key\Right       = #PB_Key_Right
      \Key\Up          = #PB_Key_Up
      \Key\StrafeLeft  = #PB_Key_X
      \Key\StrafeRight = #PB_Key_C
      \Key\Jump        = #PB_Key_Space
      
      \MainNode    = CreateNode(#PB_Any) ; Entity position
      \SightNode   = CreateNode(#PB_Any,  120,  20,  0) ; For cameraLookAt 
      \CameraNode  = CreateNode(#PB_Any, -140, 100,  0) ; Camera position
      \ForwardNode = CreateNode(#PB_Any,    1,   0,  0) ; Direction normalized 
      \StrafeNode  = CreateNode(#PB_Any,    0,   0, -1) ; Direction normalized 
      
      AttachNodeObject(\MainNode, NodeID(\SightNode))
      AttachNodeObject(\MainNode, NodeID(\CameraNode))   
      AttachNodeObject(\MainNode, NodeID(\ForwardNode))     
      AttachNodeObject(\MainNode, NodeID(\StrafeNode))    
      AttachNodeObject(\MainNode, EntityID(\Entity))
    EndWith
    
    ;-Camera
    With Camera  
      \Camera = 0
      \Tightness = 0.035
      ; Camera use 2 nodes
      \CameraNode = CreateNode(#PB_Any, -3000, 700, 0) ; Camera position
      \TargetNode = CreateNode(#PB_Any) ; For cameraLookAt 
      AttachNodeObject(\CameraNode, CameraID(\Camera))
    EndWith  
    
    ;==================================
    ; create material
    Red = GetScriptMaterial(#PB_Any, "Color/Red")
    Blue = GetScriptMaterial(#PB_Any, "Color/Blue")
    Yellow = GetScriptMaterial(#PB_Any, "Color/Yellow")
    Green = GetScriptMaterial(#PB_Any, "Color/Green")
    
    ;==================================
    ; create Sphere
    MeshSphere = CreateSphere(#PB_Any, 10.0)
    For i = 0 To 5
      Entity=CreateEntity(#PB_Any, MeshID(MeshSphere), MaterialID(Green))
      MoveEntity(Entity, Random(2000)-1000, 800, Random(4000)-2000, #PB_Absolute)
      ; create bodies
      EntityPhysicBody(Entity, #PB_Entity_SphereBody, 5.0)
    Next
    
    ;==================================
    ; create Cylinder
    MeshCylinder = CreateCylinder(#PB_Any, 10.0, 60)
    For i = 0 To 5
      Entity=CreateEntity(#PB_Any, MeshID(MeshCylinder), MaterialID(Red))
      MoveEntity(Entity, Random(2000)-1000, 800, Random(4000)-2000, #PB_Absolute)
      ; create bodies
      EntityPhysicBody(Entity, #PB_Entity_CylinderBody, 10.0, 0, 1)
    Next
    
    ;==================================
    ; create Cube
    MeshCube = CreateCube(#PB_Any, 25.0)
    For i = 0 To 5
      Entity=CreateEntity(#PB_Any, MeshID(MeshCube), MaterialID(Yellow))
      MoveEntity(Entity, Random(2000)-1000, 800, Random(4000)-2000, #PB_Absolute)
      ; create bodies
      EntityPhysicBody(Entity, #PB_Entity_BoxBody, 5.0)
    Next
    
    Repeat
      
      Screen3DEvents()   
      
      Robot\elapsedTime = TimeSinceLastFrame 
      
      HandleEntity(@Robot)
      
      CameraTrack(@Camera, @Robot)
      
      TimeSinceLastFrame = RenderWorld(60) * 40 / 1000
      FlipBuffers()
      
    Until KeyboardPushed(#PB_Key_Escape)   
    
    End 
    
  EndIf 
Else
  CompilerIf #PB_Compiler_OS <> #PB_OS_Windows Or Subsystem("OpenGL")
    ;
    ; Terrain on Linux/OSX and Windows with OpenGL needs CG toolkit from nvidia
    ; It can be freely downloaded and installed from this site: https://developer.nvidia.com/cg-toolkit-download
    ;
    MessageRequester("Error","Can't initialize engine3D (Please ensures than CG Toolkit from nvidia is correcly installed)")
  CompilerElse
    MessageRequester("Error","Can't initialize engine3D")
  CompilerEndIf
EndIf 

Procedure Clamp(*var.float, min.f, max.f)
  If *var\f < min
    *var\f = min
  ElseIf *var\f > max
    *var\f = max
  EndIf
EndProcedure

Procedure InitBlendMaps()
  minHeight1.f = 70
  fadeDist1.f = 40
  minHeight2.f = 70
  fadeDist2.f = 15    
  For ty = #TerrainMiniY To #TerrainMaxiY
    For tx = #TerrainMiniX To #TerrainMaxiX
      Size = TerrainTileLayerMapSize(0, tx, ty)
      For y = 0 To Size-1
        For x = 0 To Size-1
          Height.f = TerrainTileHeightAtPosition(0, tx, ty, 1, x, y)
          
          val.f = (Height - minHeight1) / fadeDist1
          Clamp(@val, 0, 1)
          SetTerrainTileLayerBlend(0, tx, ty, 1, x, y, val)
          
          val.f = (Height - minHeight2) / fadeDist2
          Clamp(@val, 0, 1)
          SetTerrainTileLayerBlend(0, tx, ty, 2, x, y, val)
        Next
      Next
      UpdateTerrainTileLayerBlend(0, tx, ty, 1)
      UpdateTerrainTileLayerBlend(0, tx, ty, 2)
    Next
  Next  
EndProcedure  

Procedure OnGround(*Entity.s_Entity)
  With *Entity
    Result = RayCollide(EntityX(\EntityBody), EntityY(\EntityBody), EntityZ(\EntityBody), EntityX(\EntityBody), EntityY(\EntityBody)-70,  EntityZ(\EntityBody)) 
    ;CreateLine3D(20,EntityX(\EntityBody), EntityY(\EntityBody), EntityZ(\EntityBody), $FFFF, EntityX(\EntityBody), EntityY(\EntityBody)-70,  EntityZ(\EntityBody), $FFFF)  
    Delta.f = EntityY(\EntityBody) - PickY() - 43

    If Result=-1 Or (Result>-1 And (delta >= 1))
      ProcedureReturn 0
    Else
      ProcedureReturn 1
    EndIf  
  EndWith  
EndProcedure

Procedure HandleEntity(*Entity.s_Entity)
  Protected.Vector3 Forward, Strafe, PosMain, PosDir, PosStrafe
  Protected.f Speed, Speed2, x, y, MouseX, MouseY
  Static Jump.f, MemJump.i, Rot.Vector3, Trans.Vector3, Clic
  
  With *Entity
    GetNodePosition(PosMain, \MainNode)
    GetNodePosition(PosDir, \ForwardNode)
    GetNodePosition(PosStrafe, \StrafeNode)
    SubVector3(Forward, PosDir, PosMain)
    SubVector3(Strafe, PosStrafe, PosMain)
    
    Speed = #PlayerSpeed * \elapsedTime 
    Speed2 = Speed / 2
    
    If ExamineKeyboard()
      
      If KeyboardReleased(#PB_Key_F5)
        WorldDebug(#PB_World_DebugBody)
      ElseIf KeyboardReleased(#PB_Key_F6)
        WorldDebug(#PB_World_DebugEntity)
      ElseIf KeyboardReleased(#PB_Key_F7)
        WorldDebug(#PB_World_DebugNone)
      EndIf
      
      If KeyboardPushed(\Key\Jump) And OnGround(*Entity) 
        Jump = 18
        MemJump = 1
      EndIf  
      
      Rot\x * 0.30
      Rot\y * 0.30
      Rot\z * 0.30
      Trans\x * 0.20
      Trans\y = Jump
      Trans\z * 0.20
      
      If KeyboardPushed(\Key\Up)
        Trans\x + Forward\x * Speed 
        Trans\z + Forward\z * Speed
      ElseIf KeyboardPushed(\Key\Down)
        Trans\x + Forward\x * -Speed2
        Trans\z + Forward\z * -Speed2
      EndIf
      
      If KeyboardPushed(\Key\Left)
        Rot\y + 2 * \elapsedTime
      ElseIf KeyboardPushed(\Key\Right)
        Rot\y - 2 * \elapsedTime
      EndIf 
      
      If KeyboardPushed(\Key\StrafeLeft)
        Trans\x + Strafe\x * Speed2
        Trans\z + Strafe\z * Speed2
      ElseIf KeyboardPushed(\Key\StrafeRight)
        Trans\x + Strafe\x * -Speed2
        Trans\z + Strafe\z * -Speed2
      EndIf 
      
      If OnGround(*Entity) 
        Jump = 0 
      ElseIf MemJump  
        Jump + 20 * \elapsedTime 
        If Jump > 100 
          MemJump = 0
        EndIf  
      Else  
        Jump - 9 
      EndIf  
      
    EndIf
    
    MoveEntity  (\EntityBody, Trans\x, Trans\y, Trans\z)
    RotateEntity(\EntityBody, 0, Rot\y, 0, #PB_Relative)   
    
    
    Protected E = RayCast(EntityX(\EntityBody), EntityY(\EntityBody), EntityZ(\EntityBody)+4, EntityX(\EntityBody), EntityY(\EntityBody)-40, EntityZ(\EntityBody), -1)
    If E
      RotateNode(\MainNode, NormalZ()*45, EntityYaw(\EntityBody), -NormalX()*45)
    EndIf
    MoveNode(\MainNode, EntityX(\EntityBody), EntityY(\EntityBody)-\BodyOffsetY, EntityZ(\EntityBody), #PB_Absolute) 
    ;RotateNode(\MainNode, 0, , 0) 
    
  EndWith   
EndProcedure

Procedure CameraTrack(*Camera.s_Camera, *Entity.s_Entity)
  Protected.Vector3 CameraPosition, TargetPosition 
  Protected.f x, y, z
  
  GetNodePosition(CameraPosition, *Entity\CameraNode)
  GetNodePosition(TargetPosition, *Entity\SightNode)
  x = NodeX(*Camera\CameraNode)
  y = NodeY(*Camera\CameraNode)
  z = NodeZ(*Camera\CameraNode)
  x = (CameraPosition\x - x) *  *Camera\Tightness
  y = (CameraPosition\y - y) *  *Camera\Tightness
  z = (CameraPosition\z - z) *  *Camera\Tightness
  MoveNode(*Camera\CameraNode, x, y, z)
  
  x = NodeX(*Camera\TargetNode)
  y = NodeY(*Camera\TargetNode)
  z = NodeZ(*Camera\TargetNode)
  x = (TargetPosition\x - x) *  *Camera\Tightness
  y = (TargetPosition\y - y) *  *Camera\Tightness
  z = (TargetPosition\z - z) *  *Camera\Tightness
  MoveNode(*Camera\TargetNode, x, y, z)
  
  CameraLookAt(*Camera\Camera, NodeX(*Camera\TargetNode), NodeY(*Camera\TargetNode), NodeZ(*Camera\TargetNode))
  
EndProcedure
Benutzeravatar
Regenduft
Beiträge: 574
Registriert: 25.03.2008 15:07
Wohnort: THE LÄÄÄND!

Re: Am Boden ausrichten (Winkel)

Beitrag von Regenduft »

Alexi hat geschrieben:(...) dass CreateImage() nicht #PB_Image_Transparent in der Beta 16 annimmt (...)
Entweder hattest Du einen Fehler drin oder es wurde in der Beta 17 gefixt. Folgendes funktioniert bei mir einwandfrei:

Code: Alles auswählen

Debug CreateImage(0,64,32,32,#PB_Image_Transparent)
Debug CreateImage(1,32,32,32)
Debug OpenWindow(0,0,0,32,32,"")
Debug ImageGadget(0,0,0,32,32,ImageID(0))
Debug ImageGadget(1,32,0,32,32,ImageID(1))
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
Alexi hat geschrieben:(...) fällt mein Spieler mit RayCollide des öfteren durch den Boden. :roll:
Comoitis (...oder wie er genau heißt...) hat irgendwo geschrieben, dass da ein Fehler im Demo-Code drin war... Habe den Thread jetzt leider nicht auf Anhieb gefunden. Anscheinend gibt's im Beta 17 Code einen neuen Fehler... da schwebt die Entity nun über dem Boden... :|
Auf jeden Fall ist/war das kein PureBasic-Bug.
Alexi hat geschrieben:Zudem [bin ich mir unsicher], wie zuverlässig gescannt wird und der Spieler davon ausgeschlossen wird. Dem Terrain lässt sich eben keine Maske zuweisen
Dass ist ja mal echt (dezent formuliert) äußerst ungünstig... :wink:
Ich bin heute wohl wieder zu dumm für die Foren-SuFu und Google. Ich finde nicht mehr wo ich gelesen hatte, dass RayCast und Co jetzt auch für Terrains funktionieren.
Generell könnte man mal schauen, bei welchen PickMask-Bits das Terrain noch reagiert.
Wenn es nur bei -1 reagiert -> ganz doof...
Wenn es bei 0 oder jedem beliebigen Bit reagiert -> bissl besser...

Ansonsten: Dein Code liefert doch schon fast das von Dir erwartete! Sieht aus, als ob Du irgenwo die Achsen vertausch hast o.ä.. Leider ist jetzt Regenduft-Bettchenzeit, aber ich schau mir das mal noch genauer an!

Im Notfall kannst Du ja doch auf deine 4-Punkte-Methode zurück umschwenken, wobei 3 Punkte und TerrainHeight() statt RayCast() dann aber deutlich einfacher wären! Der einzige Vorteil von RayCast() besteht ja darin, dass man mit NormalXYZ() arbeiten kann.

EDIT: Mir ist gerade aufgefallen, dass es "ExamineWorldCollisions()" ja wieder gibt (und sogar besser als früher!):
PureBasic-Hilfe (ExamineWorldCollisions) hat geschrieben:Wenn auf #True gesetzt, werden Kontakt-Informationen über die kollidierenden Objekte gesammelt und können mittels WorldCollisionContact(), WorldCollisionNormal() und WorldCollisionAppliedImpulse() abgerufen werden. Wenn auf #False gesetzt, werden keine Kontakt-Informationen gesammelt (was schneller ist).
Allerdings bin ich mir unsicher ob das mit Terrains funktioniert... Anscheinend haben Terrains immer eine Sonderstellung oder wurden einfach noch nicht ordentlich eigepflegt (Terrain-Physik ist ja recht neu). /:->
PureBasic 5.73 LTE x86/x64 | Windows 7 (x64)
Lambda
Beiträge: 526
Registriert: 16.06.2011 14:38

Re: Am Boden ausrichten (Winkel)

Beitrag von Lambda »

Hat sich erledigt. Der von dir bereits genannte Herr Comtois hat eine optimale Lösung mit Interpolation. :wink:
Antworten