Camera movement - Walking on a plane

Everything related to 3D programming
OgreVorbis
User
User
Posts: 76
Joined: Thu Jan 16, 2020 10:47 pm

Camera movement - Walking on a plane

Post by OgreVorbis »

I posted this by accident in the 2D game sub forum initially.
I just need the camera to hover at a constant height (Y pos) and allow me to move it around without floating. Such as in an FPS game. But I don't need physics or anything complicated (no jumping). I tweaked some code for an hour and can't make it work. It either floats around or doesn't aim correctly. None of the examples do this from what I can tell.

Here's what I cobbled together from some examples. It's not fully working, but it has to be close.

Code: Select all

#MOVEMENT_SPEED = 1
Global MouseXRotation.f,MouseYRotation.f,KeyX.f,KeyZ.f

InitEngine3D() 
InitSprite()
InitMouse()
InitKeyboard()

OpenWindow(0, 0, 0, 640, 480, "Plane example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0), 0, 0, 640, 480, 0, 0, 0)

; Light
CreateLight(#PB_Any, RGB(25, 25, 180), -5, 10, 5, #PB_Light_Point)

; Camera
CreateCamera(0, 0, 0, 100, 100)
MoveCamera(0, 2, 1, 3, #PB_Absolute | #PB_Local)
CameraLookAt(0, 0, 0, 0)

; Create the plane and attach it to the scene
CreatePlane(0, 32, 32, 1, 1, 0, 0)
CreateEntity(0, MeshID(0), #PB_Material_None)

Repeat
	If ExamineMouse()
		MouseYRotation = -MouseDeltaX() / 10
		MouseXRotation = -MouseDeltaY() / 10
	EndIf
	RotateCamera(0, MouseXRotation, MouseYRotation, 0, #PB_Relative)
	;Update Key Presses and position the Camera accordingly
	If ExamineKeyboard()
		If KeyboardPushed(#PB_Key_Left) : KeyX = -#MOVEMENT_SPEED : EndIf
		If KeyboardPushed(#PB_Key_Right) : KeyX = #MOVEMENT_SPEED : EndIf
		If KeyboardPushed(#PB_Key_Up) : KeyZ = -#MOVEMENT_SPEED : EndIf
		If KeyboardPushed(#PB_Key_Down) : KeyZ = #MOVEMENT_SPEED : EndIf
		If KeyboardPushed(#PB_Key_Escape) : ReleaseMouse(#True) : EndIf
		MoveCamera(0, KeyX, 0, KeyZ)
		KeyX = 0
		KeyZ = 0
	EndIf
    RenderWorld()
    FlipBuffers()
Until WaitWindowEvent(1) = #PB_Event_CloseWindow
I know there has to be an example of this or someone must have code. It would be needed in many applications/games.
My blog/software site: http://dosaidsoft.com/
OgreVorbis
User
User
Posts: 76
Joined: Thu Jan 16, 2020 10:47 pm

Re: Camera movement - Walking on a plane

Post by OgreVorbis »

OK, well, I just pruned the FPS sample. Maybe it could be simpler than this, but it works perfectly. See below.
Now I wonder why there isn't a rectangle prefab. There really should be a CreateBox(#Mesh, Width, Height, Depth). CreateCube() can only be a size, but doesn't have dimensions. I want to create a wall, but it would be stupid to load a mesh for something that simple.
EDIT: I figured out how to make a wall:

Code: Select all

Procedure CreateBox(MeshNo.i, Width.i, Height.i, Depth.i)
	CreateCube(MeshNo, 1)
	TransformMesh(MeshNo, 0, 0, 0, Width, Height, Depth, 0, 0, 0)
	UpdateMeshBoundingBox(MeshNo)
EndProcedure

Code: Select all

Global ScreenWidth, ScreenHeight

IncludeFile #PB_Compiler_Home + "examples/3d/Screen3DRequester.pb"

#PlayerSpeed = 80
#CameraSpeed = 10

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

Structure s_Key
  Up.i
  Down.i
  Left.i
  Right.i
EndStructure

Structure s_Entity
  EntityBody.i
  BodyOffsetY.f 
  elapsedTime.f
  Fov.f
  Key.s_Key
  MainNode.i
  CameraNode.i
  ForwardNode.i
  StrafeNode.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 HandleEntity(*Entity.s_Entity)

Define Robot.s_Entity

If InitEngine3D()
  
  InitSprite()
  InitKeyboard()
  InitMouse()
  
  If Screen3DRequester()

    ;- Guy Body
    CreateCapsule(0, 2.0, 1.0)
    CreateEntity(0, MeshID(0), #PB_Material_None, 10, 4, 10)
    HideEntity(0, 1)
    
    ;- Ground
    CreatePlane(1, 300, 300, 1, 1, 0, 0)
    CreateEntity(1, MeshID(1), #PB_Material_None, 0, -50, 200)
    CreatePlane(2, 400, 400, 1, 1, 0, 0)
    CreateEntity(2, MeshID(2), #PB_Material_None)
    
    CreateCube(3, 20)
    CreateEntity(3, MeshID(3), #PB_Material_None, 15, 4, 15)

     ;Body
    CreateEntityBody(0, #PB_Entity_CapsuleBody, 0.45, 0, 0)
    CreateEntityBody(1, #PB_Entity_StaticBody)
    CreateEntityBody(2, #PB_Entity_StaticBody)
    CreateEntityBody(3, #PB_Entity_BoxBody, 3, 1, 3)
    
    With Robot
      \Fov = 50
      \EntityBody = 0
      \BodyOffsetY = 43 
      \Key\Down  = #PB_Key_S ;Down
      \Key\Left  = #PB_Key_A ;Left
      \Key\Right = #PB_Key_D;Right
      \Key\Up    = #PB_Key_W   ;Up
    
      \MainNode   = CreateNode(#PB_Any) ; Entity position
      \CameraNode = CreateNode(#PB_Any,  0, 80,  0) ; Camera position
      \ForwardNode= CreateNode(#PB_Any,  0,  0, -1) ; Direction normalized 
      \StrafeNode = CreateNode(#PB_Any, -1,  0,  0) ; Direction normalized
      
      AttachNodeObject(\MainNode  , NodeID(\CameraNode))
      AttachNodeObject(\MainNode  , NodeID(\ForwardNode))
      AttachNodeObject(\MainNode  , NodeID(\StrafeNode))
    EndWith
    
    ;- Camera
    CreateCamera(0, 0, 0, 100, 100)
    CameraRange(0, 0.08, 5000) 
    AttachNodeObject(Robot\CameraNode, CameraID(0))
    CameraLookAt(0, NodeX(Robot\ForwardNode) * 100, NodeY(Robot\CameraNode), NodeZ(Robot\ForwardNode) * 100) 
    
    ;- Light
    CreateLight(0, RGB(255, 255, 255), 200, 100, 200, #PB_Light_Point)
    
    ;- Fog
    Fog(RGB(127, 127, 127), 128, 10, 2000)
 
    ;- *** Main loop ***
    Repeat
      Screen3DEvents()
      
      If Engine3DStatus(#PB_Engine3D_CurrentFPS)
        Robot\elapsedTime = 40/Engine3DStatus(#PB_Engine3D_CurrentFPS)
      EndIf  
      
      HandleEntity(@Robot)
      
      RenderWorld(60)
      FlipBuffers()
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
  EndIf
  
Else
  MessageRequester("Error", "The 3D Engine can't be initialized",0)
EndIf

End

Procedure HandleEntity(*Entity.s_Entity)
  Protected.Vector3 Forward, Strafe, PosMain, PosDir, PosStrafe 
  Protected.f Speed, Speed2
  Protected.f MouseX, MouseY
  Static Rot.Vector3, Trans.Vector3
  
  
  With *Entity
    GetNodePosition(PosMain, \MainNode)
    GetNodePosition(PosDir, \ForwardNode)
    GetNodePosition(PosStrafe, \StrafeNode)
    SubVector3(Forward, PosDir, PosMain)
    SubVector3(Strafe, PosStrafe, PosMain)
    
    Speed = #PlayerSpeed * \elapsedTime
    Speed2 = Speed * 0.5
    
     
    If  ExamineMouse()
      
      MouseX = -(MouseDeltaX()/200) * \Fov * \elapsedTime
      MouseY = -(MouseDeltaY()/200) * \Fov * \elapsedTime
      Rot\z = 0
      Rot\y + MouseX
      If NodePitch(\CameraNode) < 80 And MouseY > 0
        Rot\x + MouseY
      ElseIf NodePitch(\CameraNode) > -80 And MouseY < 0 
        Rot\x + MouseY
      EndIf
         
      If MouseButton(#PB_MouseButton_Right)
        If \Fov > 20
          \Fov - 2 * \elapsedTime
        EndIf  
      Else
        If \Fov < 50
          \Fov + 2 * \elapsedTime
        EndIf  
      EndIf
      
    EndIf
    If ExamineKeyboard()
      
      Rot\x * 0.30
      Rot\y * 0.30
      Rot\z * 0.30
      Trans\x * 0.80
      Trans\y = -8
      Trans\z * 0.80
      
      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)
        Trans\x = Strafe\x * Speed
        Trans\z = Strafe\z * Speed
      ElseIf KeyboardPushed(\Key\Right)
        Trans\x = Strafe\x * -Speed
        Trans\z = Strafe\z * -Speed
      EndIf 
      
      MoveEntity(\EntityBody, Trans\x, Trans\y, Trans\z)
    EndIf
          
    
    CameraFOV(0, \Fov)  
       
    RotateEntity(\EntityBody,     0, Rot\y, 0, #PB_Relative)
    RotateNode(\CameraNode  , Rot\x,     0, 0, #PB_Relative)
    
    MoveNode(\MainNode, EntityX(\EntityBody), EntityY(\EntityBody) - \BodyOffsetY, EntityZ(\EntityBody), #PB_Absolute) 
    RotateNode(\MainNode, 0, EntityYaw(\EntityBody), 0) 
    
  EndWith   
EndProcedure
My blog/software site: http://dosaidsoft.com/
MrBean
User
User
Posts: 17
Joined: Sat Dec 22, 2012 7:27 am

Re: Camera movement - Walking on a plane

Post by MrBean »

i have found this example on my hard drive, don't know who create it originally.
here the camera follow the cube. you can hide the cube by the code:
HideEntity(Player, #True)
while the camera still follow the hidden cube
to let the camera higher a little change line 95
CameraFollow(...... EntityY(Player) + 1 to EntityY(Player) + 3
to let the cube (the Player) higher change line 49
Player = CreateEntity(..., 0, 0.5, 0) to Player = CreateEntity(..., 0, 2, 0)

Code: Select all

EnableExplicit  

Enumeration
  #Mainform
EndEnumeration

#Speed = 0.1

Global WWIdth, WHeight,  Window, Event
Global Camera, Texture, Material, Mesh, Entity
Global Ground, Player, PlayerSpeed.f

InitEngine3D()
InitKeyboard()
InitSprite()
InitMouse()

OpenWindow(#Mainform,0,0, 0, 0, "", #PB_Window_SystemMenu | #PB_Window_Maximize)
WWidth = WindowWidth(#Mainform, #PB_Window_InnerCoordinate)
WHeight = WindowHeight(#Mainform, #PB_Window_InnerCoordinate)
OpenWindowedScreen(WindowID(#Mainform),0,0,WWIdth,WHeight,0, 0, 0)

KeyboardMode(#PB_Keyboard_International)

;
;Light and shadow
AmbientColor(RGB(127, 127, 127))
CreateLight(#PB_Any,RGB(151, 251, 151), -1.8, 10, 5)
WorldShadows(#PB_Shadow_Additive)

; 
; Texture and materialt 
Texture = CreateTexture(#PB_Any,512,512)
StartDrawing(TextureOutput(Texture))
Box(0,0,512,512,RGB(0, 0, 0))
Box(1,1,510,510,RGB(255, 216, 0))
StopDrawing()

Material = CreateMaterial(#PB_Any,TextureID(texture))

;
; Ground
Mesh = CreatePlane(#PB_Any, 20, 20, 3, 6, 6, 6)
Ground = CreateEntity(#PB_Any, MeshID(Mesh), MaterialID(Material), 0, 0, 0)
;CreateEntityBody(Ground, #PB_Entity_StaticBody, 2, 0, 1)
; 
; Player (A cube=)
Mesh = CreateCube(#PB_Any, 1) 
Player = CreateEntity(#PB_Any, MeshID(Mesh), MaterialID(Material), 0, 0.5, 0)
;CreateEntityBody(Player, #PB_Entity_BoxBody, 10,2,2)

;
; Camera
Camera = CreateCamera(#PB_Any,0,0,100,100)
CameraBackColor(Camera, RGB(145, 182, 201))

;HideEntity(Player, #True)
Repeat
  Repeat
    Event  = WindowEvent()
    Select Event
      Case #PB_Event_CloseWindow
        End
        
    EndSelect
  Until Event = 0
  
  If ExamineKeyboard()
    If KeyboardPushed (#PB_Key_Escape)
      Break
    EndIf
  EndIf
  
  If KeyboardPushed (#PB_Key_Left)
    RotateEntity(Player, 0, 1.5, 0, #PB_Relative)
  ElseIf KeyboardPushed (#PB_Key_Right)
    RotateEntity(Player, 0, -1.5, 0, #PB_Relative)
  EndIf

  If KeyboardPushed (#PB_Key_Up)
    PlayerSpeed = #Speed
  ElseIf KeyboardPushed (#PB_Key_Down)
    PlayerSpeed = - #Speed
  Else
    PlayerSpeed = 0
  EndIf
  
  ;The bug 
  If PlayerSpeed <> 0
    ;DisableEntityBody(Player, #False)
    MoveEntity(Player, 0, 0, PlayerSpeed, #PB_Absolute|#PB_Local)
  EndIf 
    
  ;CamearaFollow (Since PB 5.20) 
  CameraFollow(Camera, EntityID(Player), 180, EntityY(Player) + 1, 5, 0.05, 0.05, #True)
  
  ; Rendering
  RenderWorld(80)
  FlipBuffers()  

ForEver
MrBean
User
User
Posts: 17
Joined: Sat Dec 22, 2012 7:27 am

Re: Camera movement - Walking on a plane

Post by MrBean »

this is a general roaming method using the keyboard and mouse as used in BillboardGrass.pb example .

Code: Select all

Define.f KeyX, KeyY, MouseX, MouseY
#CameraSpeed = 0.5

InitEngine3D()
InitSprite()
InitKeyboard()
InitMouse()

OpenWindow(0, 0, 0, 800, 600, " scene", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(0), 0, 0, 800, 600)

Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures", #PB_3DArchive_FileSystem)
Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Models", #PB_3DArchive_FileSystem)
Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Scripts", #PB_3DArchive_FileSystem)
Parse3DScripts()

CreateCamera(0, 0, 0, 100, 100)
MoveCamera(0, 0, 2, 20)
CameraLookAt(0, 0,2,0)
CameraBackColor(0, RGB(155,155,155))
GreenMaterial   = GetScriptMaterial(#PB_Any, "Color/Yellow")
RedMaterial   = GetScriptMaterial(#PB_Any, "Color/Green")
SetMaterialColor(RedMaterial, #PB_Material_SelfIlluminationColor, RGB(200,0,25))

CreateLight(1, RGB(220,220,220), 0,100,20)

CubeMesh = CreateCube(#PB_Any, 1)
SetMeshMaterial(CubeMesh, MaterialID(RedMaterial))

cube1 = CreateEntity(#PB_Any, MeshID(CubeMesh), #PB_Material_None, 0, 1, 0)

;create ground entity using the Cube mesh number 0 created above 
ground = CreateEntity(#PB_Any, MeshID(CubeMesh), #PB_Material_None, 0, 0, 0)
; and then we scale it to resemble a ground
ScaleEntity(ground, 30,0.5,30)


Repeat
    Repeat
    event = WindowEvent()
  Until event = 0
  If ExamineMouse()
        MouseX = -MouseDeltaX() * #CameraSpeed * 0.05
        MouseY = -MouseDeltaY() * #CameraSpeed * 0.05
      EndIf
      
      If ExamineKeyboard()
        
        If KeyboardPushed(#PB_Key_Left)
          KeyX = -#CameraSpeed 
        ElseIf KeyboardPushed(#PB_Key_Right)
          KeyX = #CameraSpeed 
        Else
          KeyX = 0
        EndIf
        
        If KeyboardPushed(#PB_Key_Up)
          KeyY = -#CameraSpeed 
        ElseIf KeyboardPushed(#PB_Key_Down)
          KeyY = #CameraSpeed 
        Else
          KeyY = 0
        EndIf
        
      EndIf
      
      RotateCamera(Camera, MouseY, MouseX, 0, #PB_Relative)
      MoveCamera  (Camera, KeyX, 0, KeyY)
      
      RenderWorld()
      FlipBuffers()
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
  

End
OgreVorbis
User
User
Posts: 76
Joined: Thu Jan 16, 2020 10:47 pm

Re: Camera movement - Walking on a plane

Post by OgreVorbis »

MrBean wrote: Tue Oct 26, 2021 3:50 pm this is a general roaming method using the keyboard and mouse as used in BillboardGrass.pb example .
Thanks. The first example you gave could be useful for me at some point, but it's more like a racing game type of camera. I altered it and it still seemed awkward for a first person camera. This second example floats around, just like I said I was avoiding.

But it's OK because I moved the code from my second post into a module and got it working pretty transparently with little code needed in the main source file. So I'm happy with it now.

The result I have now is like a Wolfenstein game. I made some level files in notepad with a grid and loaded cubes with textures. Eventually, I'll post the source in another thread. PB is really fun. I almost want to buy a second copy.
My blog/software site: http://dosaidsoft.com/
BarryG
Addict
Addict
Posts: 3268
Joined: Thu Apr 18, 2019 8:17 am

Re: Camera movement - Walking on a plane

Post by BarryG »

OgreVorbis wrote: Sun Oct 24, 2021 3:46 pm

Code: Select all

InitEngine3D() 
Tip: You can't use that command standalone like that; you need to actually check if it succeeded or not. Your code doesn't run on my PC because InitEngine3D() returns 0 for failure.
Post Reply