Am Boden ausrichten (Winkel)
Am Boden ausrichten (Winkel)
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
)
Re: Am Boden ausrichten (Winkel)
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:

Habe das aber nur autodidaktisch erlernt, bin also nicht gerade der Profi...
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:
- Ein RayCast senkrecht nach unten
- einen Vektor aus NormalX(), NormalY() und NormalZ() bilden
- die Spieler-Entity so drehen, dass Y-Achse die gleiche Ausrichtung wie der Normalen-Vektor besitzt.
Habe das aber nur autodidaktisch erlernt, bin also nicht gerade der Profi...
PureBasic 5.73 LTE x86/x64 | Windows 7 (x64)
Re: Am Boden ausrichten (Winkel)
Oo
SetOrientation() führte zum Absturz, kurz darauf ein Bluescreen. So langsam bin ich etwas von der oberflächlichen Ogre Integration angepisst.
SetOrientation() führte zum Absturz, kurz darauf ein Bluescreen. So langsam bin ich etwas von der oberflächlichen Ogre Integration angepisst.
Re: Am Boden ausrichten (Winkel)
Bluescreen? 
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.
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...
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.
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)
Re: Am Boden ausrichten (Winkel)
War jetzt lediglich dieser Befehl, den letzten hatte ich vor etwa 1-2 Jahren.
Das möcht ich nicht reproduzieren.
Edit: aktuell 5.11
Wie genau rechnet sich dann der Aufprallwinkel aus?
Die NormalXYZ() Funktionen flattern auf platten Terrain wild umher (bspw. -0.1 zu -1.23 zu 0.2).
Edit: aktuell 5.11
Wie genau rechnet sich dann der Aufprallwinkel aus?
Code: Alles auswählen
RayCast(0, 0, 0, 0, 2, 0, -1)Re: Am Boden ausrichten (Winkel)
Ich nutze 5.20 Beta 15, evtl. ist's auch ein Bug der bereits gefixt wurde. (mal ohne Grundlage, rein aus dem Bauch raus...Alexi hat geschrieben:aktuell 5.11
Alexi hat geschrieben:Wie genau rechnet sich dann der Aufprallwinkel aus?
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.PureBasic-Hilfe (NormalizeMesh) hat geschrieben:Es wird automatisch der Normalen-Vektor für jeden Eckpunkt (Knoten) des angegebenen Meshs oder Sub-Meshs berechnet.
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!)
Ö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.Alexi hat geschrieben:Die NormalXYZ() Funktionen flattern auf platten Terrain wild umher (bspw. -0.1 zu -1.23 zu 0.2).Code: Alles auswählen
RayCast(0, 0, 0, 0, 2, 0, -1)
PS: Normalen-Vektor, normalisierter Vektor und Rundungsfehler bei Floats wegen der Normalisierung... und da soll man als Normalo nicht durcheinander kommen?!
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)
Re: Am Boden ausrichten (Winkel)
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. 
Re: Am Boden ausrichten (Winkel)
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))
EndProcedureRe: Am Boden ausrichten (Winkel)
Entweder hattest Du einen Fehler drin oder es wurde in der Beta 17 gefixt. Folgendes funktioniert bei mir einwandfrei:Alexi hat geschrieben:(...) dass CreateImage() nicht #PB_Image_Transparent in der Beta 16 annimmt (...)
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_CloseWindowComoitis (...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...Alexi hat geschrieben:(...) fällt mein Spieler mit RayCollide des öfteren durch den Boden.
Auf jeden Fall ist/war das kein PureBasic-Bug.
Dass ist ja mal echt (dezent formuliert) äußerst ungünstig...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
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!):
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-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).
PureBasic 5.73 LTE x86/x64 | Windows 7 (x64)
Re: Am Boden ausrichten (Winkel)
Hat sich erledigt. Der von dir bereits genannte Herr Comtois hat eine optimale Lösung mit Interpolation. 