Rotate camera around an object?

Everything related to 3D programming
Mythros
Enthusiast
Enthusiast
Posts: 306
Joined: Mon Aug 19, 2013 3:28 pm

Re: Rotate camera around an object?

Post by Mythros »

That's a BIT better, but it's still stuck in gimbal lock a bit, and shakes when looking up or down on the X-Axis of the node.

I have added a link to a small zip file which has a thread-safe executable along with the source itself & the needed Engine3D.dll, just incase you don't already have Engine3D.dll stored in your Windows folder. (It's just easier that way.)

http://download1351.mediafire.com/8ywji ... aOrbit.zip
User avatar
DK_PETER
Addict
Addict
Posts: 904
Joined: Sat Feb 19, 2011 10:06 am
Location: Denmark
Contact:

Re: Rotate camera around an object?

Post by DK_PETER »

Mythros wrote:That's a BIT better, but it's still stuck in gimbal lock a bit, and shakes when looking up or down on the X-Axis of the node.

I have added a link to a small zip file which has a thread-safe executable along with the source itself & the needed Engine3D.dll, just incase you don't already have Engine3D.dll stored in your Windows folder. (It's just easier that way.)

http://download1351.mediafire.com/8ywji ... aOrbit.zip
Hey Mythros.

Sorry...Houseguests suddently came by...
yeah.. I see what you mean.
I've made a quick update to the example. Try it out. Hope you'll get PB 5.20 soon.

Best regards
Peter
Current configurations:
Ubuntu 20.04/64 bit - Window 10 64 bit
Intel 6800K, GeForce Gtx 1060, 32 gb ram.
Amd Ryzen 9 5950X, GeForce 3070, 128 gb ram.
Mythros
Enthusiast
Enthusiast
Posts: 306
Joined: Mon Aug 19, 2013 3:28 pm

Re: Rotate camera around an object?

Post by Mythros »

Ok, I tried. We're back to where we started, minus gimbal lock. I need to get it from going beyond 90 & -90 on the X-axis. for some reason, its still tilting a bit on the Z-Axis.

Edit:

Here's a video showing EXACTLY how the cam should work.

http://www.youtube.com/watch?v=bdlSTtqXMn4
Mythros
Enthusiast
Enthusiast
Posts: 306
Joined: Mon Aug 19, 2013 3:28 pm

Re: Rotate camera around an object?

Post by Mythros »

I fixed it MOSTLY.

Now we just need to stop rotation at X=-90, positive 90 WITHOUT gimbal lock, and it's PERFECT!

Code: Select all

;PRESS Escape to exit

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

If InitEngine3D()
  
  InitSprite()
  InitKeyboard()
  InitMouse()
  
ExamineDesktops()
Width=DesktopWidth(0)
Height=DesktopHeight(0)

    OpenWindow(0, 0, 0, Width, Height, "Camera")
    OpenWindowedScreen(WindowID(0), 0, 0, Width, Height, 0, 0, 0)
    
    BoxTexture=CreateTexture(#PB_Any,256,256)
    StartDrawing(TextureOutput(BoxTexture))
      Box(0,0,256,256,RGB(255,255,0))
    StopDrawing()
    
    BoxMaterial=CreateMaterial(#PB_Any, TextureID(BoxTexture))
    SetMaterialColor(BoxMaterial, #PB_Material_SpecularColor, RGB(255,255,255))
    MaterialShininess(BoxMaterial,32)
    
    PlaneTexture=CreateTexture(#PB_Any,256,256)
    StartDrawing(TextureOutput(PlaneTexture))
      Box(0,0,256,256,RGB(0,255,255))
    StopDrawing()
    
    PlaneMaterial=CreateMaterial(#PB_Any, TextureID(PlaneTexture))
    SetMaterialColor(PlaneMaterial, #PB_Material_SpecularColor, RGB(255,255,255))
    MaterialShininess(PlaneMaterial,32)
    
    Box=CreateCube(#PB_Any,0.5)
    BoxEntity=CreateEntity(#PB_Any,MeshID(Box),MaterialID(BoxMaterial))
    
    Plane=CreatePlane(#PB_Any,10,10,10,10,10,10)
    PlaneEntity=CreateEntity(#PB_Any,MeshID(Plane),MaterialID(PlaneMaterial),0,-1,0)
    
    Light=CreateLight(#PB_Any, RGB(130,130,130), 1, 4, 4)
    SetLightColor(Light, #PB_Light_DiffuseColor, RGB(200,200,200))
    SetLightColor(Light, #PB_Light_SpecularColor, RGB(255,255,255))
    
    Camera=CreateCamera(#PB_Any, 0, 0, 100, 100)
    MoveCamera(Camera, 0, 0, 5, #PB_Absolute)
    CameraBackColor(Camera,RGB(50,50,50))
    CameraFixedYawAxis(Camera, #True, 0, 1, 0)
    
    Node=CreateNode(#PB_Any,0,0,0)
    AttachNodeObject(Node,CameraID(Camera))
    
    XLine=CreateLine3D(#PB_Any,0,0,0,RGB(255,0,0),5,0,0,RGB(255,0,0))
    YLine=CreateLine3D(#PB_Any,0,0,0,RGB(0,255,0),0,5,0,RGB(0,255,0))
    ZLine=CreateLine3D(#PB_Any,0,0,0,RGB(0,0,255),0,0,5,RGB(0,0,255))
    
    Repeat

      If ExamineMouse()
        MouseX = -MouseDeltaX() * #CameraSpeed * 0.05
        MouseY = -MouseDeltaY() * #CameraSpeed * 0.05
      EndIf  
      
      If ExamineKeyboard()
      EndIf
      
      RotateNode(Node,MouseY, MouseX, 0,#PB_Relative)
      RotateEntity(Boxentity, 0, MouseX, 0, #PB_Relative)
      CameraLookAt(Camera, EntityX(BoxEntity), EntityY(BoxEntity), EntityZ(BoxEntity))
      
      RenderWorld()
      FlipBuffers()
    Until KeyboardPushed(#PB_Key_Escape)

Else
  MessageRequester("Error", "The 3D Engine can't be initialized", 0)
EndIf
  
End
Mythros
Enthusiast
Enthusiast
Posts: 306
Joined: Mon Aug 19, 2013 3:28 pm

Re: Rotate camera around an object?

Post by Mythros »

i spoke too soon... -.- If you take another look at it, for some reason, when rotated above the players head or below the player and you turn on the Y axis, it does the z rotation thing. -.-
Mythros
Enthusiast
Enthusiast
Posts: 306
Joined: Mon Aug 19, 2013 3:28 pm

Re: Rotate camera around an object?

Post by Mythros »

Aha! The problem is with CameraRoll().. I don't know how to fix it, but maybe you do.

For some reason, the CameraRoll() is changing from 0 to another number, it should ALWAYS be at 0.. Idk why it is doing this.

Here's the somewhat fix:

Code: Select all

;PRESS Escape to exit

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

If InitEngine3D()
  
  InitSprite()
  InitKeyboard()
  InitMouse()
  
ExamineDesktops()
Width=DesktopWidth(0)
Height=DesktopHeight(0)

    OpenWindow(0, 0, 0, Width, Height, "Camera")
    OpenWindowedScreen(WindowID(0), 0, 0, Width, Height, 0, 0, 0)
    
    BoxTexture=CreateTexture(#PB_Any,256,256)
    StartDrawing(TextureOutput(BoxTexture))
      Box(0,0,256,256,RGB(255,255,0))
    StopDrawing()
    
    BoxMaterial=CreateMaterial(#PB_Any, TextureID(BoxTexture))
    SetMaterialColor(BoxMaterial, #PB_Material_SpecularColor, RGB(255,255,255))
    MaterialShininess(BoxMaterial,32)
    
    PlaneTexture=CreateTexture(#PB_Any,256,256)
    StartDrawing(TextureOutput(PlaneTexture))
      Box(0,0,256,256,RGB(0,255,255))
    StopDrawing()
    
    PlaneMaterial=CreateMaterial(#PB_Any, TextureID(PlaneTexture))
    SetMaterialColor(PlaneMaterial, #PB_Material_SpecularColor, RGB(255,255,255))
    MaterialShininess(PlaneMaterial,32)
    
    Box=CreateCube(#PB_Any,0.5)
    BoxEntity=CreateEntity(#PB_Any,MeshID(Box),MaterialID(BoxMaterial))
    
    Plane=CreatePlane(#PB_Any,10,10,10,10,10,10)
    PlaneEntity=CreateEntity(#PB_Any,MeshID(Plane),MaterialID(PlaneMaterial),0,-1,0)
    
    Light=CreateLight(#PB_Any, RGB(130,130,130), 1, 4, 4)
    SetLightColor(Light, #PB_Light_DiffuseColor, RGB(200,200,200))
    SetLightColor(Light, #PB_Light_SpecularColor, RGB(255,255,255))
    
    Camera=CreateCamera(#PB_Any, 0, 0, 100, 100)
    MoveCamera(Camera, 0, 0, 5, #PB_Absolute)
    CameraBackColor(Camera,RGB(50,50,50))
    
    Node=CreateNode(#PB_Any,0,0,0)
    AttachNodeObject(Node,CameraID(Camera))
    NodeFixedYawAxis(Node, #True, 0, 1, 0)
    
    XLine=CreateLine3D(#PB_Any,0,0,0,RGB(255,0,0),5,0,0,RGB(255,0,0))
    YLine=CreateLine3D(#PB_Any,0,0,0,RGB(0,255,0),0,5,0,RGB(0,255,0))
    ZLine=CreateLine3D(#PB_Any,0,0,0,RGB(0,0,255),0,0,5,RGB(0,0,255))
    
    TextObj1 = TextGadget(#PB_Any, 10, 10, WindowWidth(wnd), 25, "")
    TextObj2 = TextGadget(#PB_Any, 10, 30, WindowWidth(wnd), 25, "")
    TextObj3 = TextGadget(#PB_Any, 10, 50, WindowWidth(wnd), 25, "")
    TextObj4 = TextGadget(#PB_Any, 10, 70, WindowWidth(wnd), 25, "")
    TextObj5 = TextGadget(#PB_Any, 10, 90, WindowWidth(wnd), 25, "")
    TextObj6 = TextGadget(#PB_Any, 10, 110, WindowWidth(wnd), 25, "")
    
    Repeat
      
      Event = WaitWindowEvent()
      
      If Event = #PB_Event_CloseWindow
        Quit = 1
      EndIf

      If ExamineMouse()
        MouseX = -MouseDeltaX() * #CameraSpeed * 0.05
        MouseY = -MouseDeltaY() * #CameraSpeed * 0.05
      EndIf
      
      If ExamineKeyboard()
      EndIf
      
      npitch = NodePitch(Node, 1)
      nyaw = NodeYaw(Node, 1)
      nroll = NodeRoll(Node, 1)
      
      If npitch < 90: npitch = 90: EndIf
      If npitch > -90: npitch = -90: EndIf
            
      RotateNode(Node, MouseY, MouseX, 0, #PB_Relative)
      
      RotateEntity(Boxentity, 0, MouseX, 0, #PB_Relative)
      CameraLookAt(Camera, EntityX(BoxEntity), EntityY(BoxEntity), EntityZ(BoxEntity))
      NodeLookAt(Node, CameraX(Camera), CameraY(Camera), CameraZ(Camera), 0, 0, 0)
      
      RenderWorld()
      SetGadgetText(TextObj1, "MouseX: "+MouseX)
      SetGadgetText(TextObj2, "MouseY: "+MouseY)
      SetGadgetText(TextObj3, "----------------")
      SetGadgetText(TextObj4, "Node Pitch/Yaw/Roll: "+npitch+", "+nyaw+", "+nroll)
      SetGadgetText(TextObj5, "----------------")
      SetGadgetText(TextObj6, "Cam Pitch/Yaw/Roll: "+CameraPitch(Camera, 1)+", "+CameraYaw(Camera, 1)+", "+CameraRoll(Camera, 1))
      FlipBuffers()
    Until KeyboardPushed(#PB_Key_Escape)

Else
  MessageRequester("Error", "The 3D Engine can't be initialized", 0)
EndIf
  
End
User avatar
DK_PETER
Addict
Addict
Posts: 904
Joined: Sat Feb 19, 2011 10:06 am
Location: Denmark
Contact:

Re: Rotate camera around an object?

Post by DK_PETER »

Actually...After I watched your example via youtube.. I must admit, that I've totally misunderstood your question:
"Rotate camera around an object?". You want a stationary entity, which has the illusion of moving.
In reality - it's the plane - that's doing the moving. Something like this: (not finished, but you'll get the point and
you will still need to use two nodes).

Code: Select all

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

#CameraSpeed = 1

Structure Mesh_Data
	ID.i
	mesh.i
	mat.i
	tex.i
EndStructure

Global FixedPerson.Mesh_Data
Global ground.Mesh_Data

Global Win.i, node1.i, node2.i, Cam.i, KeyX, KeyZ

Procedure SetupScreen(x.i, y.i, width.i, height.i, Title.s)
	Win = OpenWindow(#PB_Any, x, y, width, height, Title,#PB_Window_SystemMenu | #PB_Window_ScreenCentered)
	OpenWindowedScreen(WindowID(Win),0,0,width, height-5,0,0,0,#PB_Screen_SmartSynchronization)
	cam = CreateCamera(#PB_Any, 0, 0, 100, 100)
	MoveCamera(Cam, 0, 15, 50)
	CameraLookAt(Cam, 0, 0, 0)
EndProcedure

Procedure CreateObjects()
	With FixedPerson
	\tex = CreateTexture(#PB_Any, 64, 64)
	StartDrawing(TextureOutput(\tex))
	Box(0, 0, 64, 64, $7B49FC)
	StopDrawing()
	\mat = CreateMaterial(#PB_Any,TextureID(\tex))	
	\mesh = CreateCube(#PB_Any,3)
	\ID   = CreateEntity(#PB_Any, MeshID(\mesh),MaterialID(\mat)) 
	MoveEntity(\ID, 0, 3, 0,#PB_Absolute)
	EndWith

	With ground
		\tex = CreateTexture(#PB_Any, 64, 64)
		StartDrawing(TextureOutput(\tex))
		Box(0, 0, 64, 64, $7B4943)
		LineXY(0, 0, 64, 64, $7BCC43)
		LineXY(0, 64, 64, 0, $7BCC43)
		StopDrawing()
		\mat = CreateMaterial(#PB_Any, TextureID(\tex))
		\mesh = CreatePlane(#PB_Any, 64, 64, 128, 128, 100, 100)
		\ID   = CreateEntity(#PB_Any, MeshID(\mesh), MaterialID(\mat))
		ScaleEntity(\ID, 250,1,250)
		MoveEntity(\ID, 0, 0, 0)
	EndWith
	
	node1 = CreateNode(#PB_Any, 0, 0, 0)
	node2 = CreateNode(#PB_Any, 0, 0, 0)
	AttachNodeObject(node1, EntityID(ground\ID))
	AttachNodeObject(node2, NodeID(Node1))
EndProcedure

SetupScreen(0,0,800,600,"Test")
CreateObjects()


Repeat
	ev = WindowEvent()	
	
	ExamineMouse()
	mouseX = -MouseDeltaX() * #CameraSpeed * 0.02
	MouseY = -MouseDeltaY() * #CameraSpeed * 0.02
	RotateNode(node1, 0, mouseX, 0, #PB_Relative)

	ExamineKeyboard()
	
	If KeyboardPushed(#PB_Key_W)
		KeyX + #CameraSpeed
	EndIf
	If KeyboardPushed(#PB_Key_S)
		KeyX - #CameraSpeed
	EndIf
	If KeyboardPushed(#PB_Key_A)
		KeyY + #CameraSpeed
	EndIf
	If KeyboardPushed(#PB_Key_D)
		KeyY - #CameraSpeed
	EndIf
	If KeyboardReleased(#PB_Key_All)
		KeyX = 0
		KeyY = 0
	EndIf
	
  MoveNode(Node2, keyY, 0, KeyX, #PB_Relative)
   
	RenderWorld()
	FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)
Last edited by DK_PETER on Tue Aug 27, 2013 4:38 pm, edited 1 time in total.
Current configurations:
Ubuntu 20.04/64 bit - Window 10 64 bit
Intel 6800K, GeForce Gtx 1060, 32 gb ram.
Amd Ryzen 9 5950X, GeForce 3070, 128 gb ram.
Mythros
Enthusiast
Enthusiast
Posts: 306
Joined: Mon Aug 19, 2013 3:28 pm

Re: Rotate camera around an object?

Post by Mythros »

That's close, but i still need to be able to look down AT the player with the camera (node), and have it slowly move the camera towards or away from me when colliding with the ground.

i hope i explained this right.. if not, please forgive me, and ask for more information.

:oops:
Mythros
Enthusiast
Enthusiast
Posts: 306
Joined: Mon Aug 19, 2013 3:28 pm

Re: Rotate camera around an object?

Post by Mythros »

Something more like this except with a capped value that doesnt gimbal lock the camera on the x-axis. :)

EDIT: For some reason, it's still messing around with the Z-rotation. it shouldn't use z-rotation at all ><

Code: Select all

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

#CameraSpeed = 1

Structure Mesh_Data
   ID.i
   mesh.i
   mat.i
   tex.i
EndStructure

Global FixedPerson.Mesh_Data
Global ground.Mesh_Data

Global Win.i, node1.i, node2.i, Cam.i, KeyX, KeyZ

Procedure SetupScreen(x.i, y.i, width.i, height.i, Title.s)
   Win = OpenWindow(#PB_Any, x, y, width, height, Title,#PB_Window_SystemMenu | #PB_Window_ScreenCentered)
   OpenWindowedScreen(WindowID(Win),0,0,width, height-5,0,0,0,#PB_Screen_SmartSynchronization)
   cam = CreateCamera(#PB_Any, 0, 0, 100, 100)
   MoveCamera(Cam, 0, 15, 50)
   CameraLookAt(Cam, 0, 0, 0)
EndProcedure

Procedure CreateObjects()
   With FixedPerson
   \tex = CreateTexture(#PB_Any, 64, 64)
   StartDrawing(TextureOutput(\tex))
   Box(0, 0, 64, 64, $7B49FC)
   StopDrawing()
   \mat = CreateMaterial(#PB_Any,TextureID(\tex))   
   \mesh = CreateCube(#PB_Any,3)
   \ID   = CreateEntity(#PB_Any, MeshID(\mesh),MaterialID(\mat)) 
   MoveEntity(\ID, 0, 3, 0,#PB_Absolute)
   EndWith

   With ground
      \tex = CreateTexture(#PB_Any, 64, 64)
      StartDrawing(TextureOutput(\tex))
      Box(0, 0, 64, 64, $7B4943)
      LineXY(0, 0, 64, 64, $7BCC43)
      LineXY(0, 64, 64, 0, $7BCC43)
      StopDrawing()
      \mat = CreateMaterial(#PB_Any, TextureID(\tex))
      \mesh = CreatePlane(#PB_Any, 64, 64, 128, 128, 100, 100)
      \ID   = CreateEntity(#PB_Any, MeshID(\mesh), MaterialID(\mat))
      ScaleEntity(\ID, 250,1,250)
      MoveEntity(\ID, 0, 0, 0)
   EndWith
   
   node1 = CreateNode(#PB_Any, 0, 0, 0)
   node2 = CreateNode(#PB_Any, 0, 0, 0)
   AttachNodeObject(node1, EntityID(ground\ID))
   AttachNodeObject(node2, NodeID(Node1))
EndProcedure

SetupScreen(0,0,800,600,"Test")
CreateObjects()


Repeat
   ev = WindowEvent()   
   
   ExamineMouse()
   mouseX = -MouseDeltaX() * #CameraSpeed * 0.02
   mouseY = -MouseDeltaY() * #CameraSpeed * 0.02
   RotateNode(node1, mouseY, mouseX, 0, #PB_Relative)

   ExamineKeyboard()
   
   If KeyboardPushed(#PB_Key_W)
      KeyX + #CameraSpeed
   EndIf
   If KeyboardPushed(#PB_Key_S)
      KeyX - #CameraSpeed
   EndIf
   If KeyboardPushed(#PB_Key_A)
      KeyY + #CameraSpeed
   EndIf
   If KeyboardPushed(#PB_Key_D)
      KeyY - #CameraSpeed
   EndIf
   If KeyboardReleased(#PB_Key_All)
      KeyX = 0
      KeyY = 0
   EndIf
   
   MoveNode(Node2, keyY, 0, KeyX, #PB_Relative)
   
   RenderWorld()
   FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)
User avatar
DK_PETER
Addict
Addict
Posts: 904
Joined: Sat Feb 19, 2011 10:06 am
Location: Denmark
Contact:

Re: Rotate camera around an object?

Post by DK_PETER »

Mythros wrote:That's close, but i still need to be able to look down AT the player with the camera (node), and have it slowly move the camera towards or away from me when colliding with the ground.

i hope i explained this right.. if not, please forgive me, and ask for more information.

:oops:
Hehe.. It's quite allright. :wink:
Give me some time...I'm getting pretty tired. I'll refine the example further and get back to you.
(If not Comtois beats me to it) :lol:

Best regards
Peter.
Current configurations:
Ubuntu 20.04/64 bit - Window 10 64 bit
Intel 6800K, GeForce Gtx 1060, 32 gb ram.
Amd Ryzen 9 5950X, GeForce 3070, 128 gb ram.
Mythros
Enthusiast
Enthusiast
Posts: 306
Joined: Mon Aug 19, 2013 3:28 pm

Re: Rotate camera around an object?

Post by Mythros »

Hehe.. It's quite allright. :wink:
Give me some time...I'm getting pretty tired. I'll refine the example further and get back to you.
(If not Comtois beats me to it) :lol:

Best regards
Peter.
Hehe, thanks alot for doing this for me, Peter! You do NOT know HOW much of a saving grace you have been / are being to me :)
User avatar
DK_PETER
Addict
Addict
Posts: 904
Joined: Sat Feb 19, 2011 10:06 am
Location: Denmark
Contact:

Re: Rotate camera around an object?

Post by DK_PETER »

Mythros wrote:
Hehe.. It's quite allright. :wink:
Give me some time...I'm getting pretty tired. I'll refine the example further and get back to you.
(If not Comtois beats me to it) :lol:

Best regards
Peter.
Hehe, thanks alot for doing this for me, Peter! You do NOT know HOW much of a saving grace you have been / are being to me :)
Anytime..I'm here to help like sooo many other good folks :-)

Anyway...I think this is close to what you want.
Note: Save the example in the PB's 3D examples folder

Code: Select all

;
; ------------------------------------------------------------
;
;   Built on Comtois's old example - PB 5.11 Compatible
;   FollowCamera is part of PB 5.20 and makes life at lot easier
;   Damn, I'm glad, that the 3D part of PB are getting a lot more attention!!
;   (c) 2013 - Fantaisie Software
;   Put this example in the PB 5.11's 3D examples folder
;   Keys: W, S, A, D, Q, Z, +, -
; ------------------------------------------------------------


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

#CameraSpeed = 1

#Mesh = 1
#Entity = 1
#Camera = 0

IncludeFile "Screen3DRequester.pb"

Define.f KeyX, KeyY, MouseX, MouseY, Speed1, Speed2, TimeSinceLastFrame, Dist.f = 7.0 , Angle = 180, CamAngle.f = 5

Declare CameraFollow(Camera.i, Entity.i, AngleD.f, Height.f, Distance.f, percent.f)

If InitEngine3D()
 
  Add3DArchive("Data/Textures", #PB_3DArchive_FileSystem)
  Add3DArchive("Data/Packs/skybox.zip", #PB_3DArchive_Zip)
  Parse3DScripts()
 
  InitSprite()
  InitKeyboard()
  InitMouse()
 
  If Screen3DRequester()
   
    ;-Ground
    ;
    CreateMaterial(0, LoadTexture(0, "Dirt.jpg"))
    CreatePlane(0, 500, 500, 1, 1, 25, 25)
    CreateEntity(0,MeshID(0),MaterialID(0))
    EntityRenderMode(0, 0)
   
    CreateCube(#Mesh, 1)
   
    CreateMaterial(1, LoadTexture(1, "DosCarte.png"))
   
    CreateEntity(#Entity, MeshID(#Mesh), MaterialID(1), 0, 1.5, 0)
    ScaleEntity(#Entity, 1, 3, 1.5)
   
    SkyBox("stevecube.jpg")
   
    CreateCamera(#Camera, 0, 0, 100, 100)
    CameraFollow(#Camera, #Entity, Angle, CamAngle, Dist, 0.5)
   
    Repeat
      Screen3DEvents()
     
      If ExamineMouse()
        MouseX = -MouseDeltaX() * #CameraSpeed * 0.5
        MouseY = -MouseDeltaY() * #CameraSpeed * 0.5
      EndIf
      
      
      Speed1 * 0.9
      Speed2 * 0.9
      
      If ExamineKeyboard()
       
        If KeyboardPushed(#PB_Key_A)
          Speed2 = 0.01 * TimeSinceLastFrame
        ElseIf KeyboardPushed(#PB_Key_D)
          Speed2 = -0.01 * TimeSinceLastFrame
        EndIf
       
        If KeyboardPushed(#PB_Key_W)
          Speed1 = 0.017 * TimeSinceLastFrame
        ElseIf KeyboardPushed(#PB_Key_S)
          Speed1 = -0.017 * TimeSinceLastFrame
        EndIf   
        
        If KeyboardPushed(#PB_Key_Add) And Dist < 15
        	Dist + 0.2
        EndIf
        If KeyboardPushed(#PB_Key_Subtract) And Dist > 7
        	Dist - 0.2 
        EndIf
        
        If KeyboardPushed(#PB_Key_Z) And CamAngle < 10
        	CamAngle + 0.2
        EndIf
        If KeyboardPushed(#PB_Key_Q) And CamAngle > 5
        	CamAngle - 0.2 
        EndIf
        	
      EndIf
     
     
      RotateEntity(#Entity, 0, MouseX * TimeSinceLastFrame/100, 0, #PB_Relative)
      MoveEntity(#Entity, Speed2, 0, Speed1, #PB_Local)
     
      CameraFollow(#Camera, #Entity, Angle, CamAngle, Dist, 0.5)
     
      TimeSinceLastFrame = RenderWorld()
      
      Screen3DStats()
      FlipBuffers()
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
  EndIf
 
Else
  MessageRequester("Error", "The 3D Engine can't be initialized",0)
EndIf

End

Procedure Normalize(*V.Vector3)
  Define.f magSq, oneOverMag
 
  magSq = *V\x * *V\x + *V\y * *V\y + *V\z * *V\z
  If magsq > 0
    oneOverMag = 1.0 / Sqr(magSq)
    *V\x * oneOverMag
    *V\y * oneOverMag
    *V\z * oneOverMag
  EndIf
 
EndProcedure

Procedure Lerp(*R.Vector3, *V1.Vector3, *V2.Vector3, percent.f)
  ;percent = 0 --> R = V1
  ;percent = 1 --> R = V2
 
  If percent<0
    percent=0
  EndIf
  If percent>1
    percent=1
  EndIf
  *R\x = *V1\x + percent * (*V2\x - *V1\x)
  *R\y = *V1\y + percent * (*V2\y - *V1\y)
  *R\z = *V1\z + percent * (*V2\z - *V1\z)
EndProcedure

Procedure CameraFollow(Camera.i, Entity.i, AngleD.f, Height.f, Distance.f, percent.f)
  Protected.Vector3 P, P1, P2, Angle2
  Static Angle.Vector3
 
  Angle2\x = Sin(Radian(EntityYaw(Entity)+AngleD))
  Angle2\y = 0
  Angle2\z = 0
  lerp(@Angle, @Angle, @Angle2, percent)
  Normalize(Angle)
 
  P1\x = CameraX(Camera)
  P1\y = 0
  P1\z = CameraZ(Camera)
  P2\x = EntityX(Entity) + Angle\x * Distance
  P2\y = 0
  P2\z = EntityZ(Entity) + Angle\z * Distance
  Lerp(@P, @P1, @P2, percent)
 
  MoveCamera(Camera, P\x, Height, P\z, #PB_Absolute)
  CameraLookAt(Camera, EntityX(Entity), EntityY(Entity), EntityZ(Entity))   
EndProcedure  
Best regards
Peter
Current configurations:
Ubuntu 20.04/64 bit - Window 10 64 bit
Intel 6800K, GeForce Gtx 1060, 32 gb ram.
Amd Ryzen 9 5950X, GeForce 3070, 128 gb ram.
Mythros
Enthusiast
Enthusiast
Posts: 306
Joined: Mon Aug 19, 2013 3:28 pm

Re: Rotate camera around an object?

Post by Mythros »

Thanks Peter, this is great! =)

EDIT: I have fixed MOST of it. The only thing left now is to make the zoom in / out work with mouse wheel & when holding down the left mouse button, if you move the mouse, instead of snapping onto the NEW mousey() value, i want it to remain at the OLD mousey() value (ONLY when CLICKING, NOT when holding the left mouse button & moving the mouse up or down)

(You'll see what I mean when you try the demo =)

Code: Select all

;
; ------------------------------------------------------------
;
;   Built on Comtois's old example - PB 5.11 Compatible
;   FollowCamera is part of PB 5.20 and makes life at lot easier
;   Damn, I'm glad, that the 3D part of PB are getting a lot more attention!!
;   (c) 2013 - Fantaisie Software
;   Put this example in the PB 5.11's 3D examples folder
;   Keys: W, S, A, D, Q, Z, +, -
; ------------------------------------------------------------


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

#CameraSpeed = 1

#Mesh = 1
#Entity = 1
#Camera = 0

IncludeFile "Screen3DRequester.pb"

Define.f KeyX, KeyY, MouseX, MouseY, Speed1, Speed2, TimeSinceLastFrame, Dist.f = 7.0 , Angle = 180, CamAngle.f = 5

Declare CameraFollow(Camera.i, Entity.i, AngleD.f, Height.f, Distance.f, percent.f)

If InitEngine3D()
 
  Add3DArchive("Data/Textures", #PB_3DArchive_FileSystem)
  Add3DArchive("Data/Packs/skybox.zip", #PB_3DArchive_Zip)
  Parse3DScripts()
 
  InitSprite()
  InitKeyboard()
  InitMouse()
 
  If Screen3DRequester()
   
    ;-Ground
    ;
    CreateMaterial(0, LoadTexture(0, "Dirt.jpg"))
    CreatePlane(0, 500, 500, 1, 1, 25, 25)
    CreateEntity(0,MeshID(0),MaterialID(0))
    EntityRenderMode(0, 0)
   
    CreateCube(#Mesh, 1)
   
    CreateMaterial(1, LoadTexture(1, "DosCarte.png"))
   
    CreateEntity(#Entity, MeshID(#Mesh), MaterialID(1), 0, 1.5, 0)
    ScaleEntity(#Entity, 1, 3, 1.5)
   
    SkyBox("stevecube.jpg")
   
    CreateCamera(#Camera, 0, 0, 100, 100)
    CameraFollow(#Camera, #Entity, Angle, CamAngle, Dist, 0.5)
   
    Repeat
      Screen3DEvents()
     
      If ExamineMouse()
        MouseX = -MouseDeltaX() * #CameraSpeed * 0.5
        MouseY = -MouseDeltaY() * #CameraSpeed * 0.5
      EndIf
      
      
      Speed1 * 0.9
      Speed2 * 0.9
      
      If ExamineKeyboard()
       
        If KeyboardPushed(#PB_Key_A)
          Speed1 = 0.01 * TimeSinceLastFrame
        ElseIf KeyboardPushed(#PB_Key_D)
          Speed1 = -0.01 * TimeSinceLastFrame
        EndIf
       
        If KeyboardPushed(#PB_Key_W)
          Speed2 = -0.017 * TimeSinceLastFrame
        ElseIf KeyboardPushed(#PB_Key_S)
          Speed2 = 0.017 * TimeSinceLastFrame
        EndIf
        
        If MouseButton(#PB_MouseButton_Left) And MouseDeltaY()
          If CamAngle <= 2
            If KeyboardPushed(#PB_Key_Add) And Dist < 15
              Dist + 0.2
            EndIf
            If KeyboardPushed(#PB_Key_Subtract) And Dist > 7
              Dist - 0.2 
            EndIf
          EndIf
              
          If CamAngle < 50
            CamAngle + 0.2
          EndIf
          If CamAngle > 2
            CamAngle - 0.2
          EndIf
        EndIf
      EndIf
     
      RotateEntity(#Entity, 0, MouseX * TimeSinceLastFrame/100, 0, #PB_Relative)
      MoveEntity(#Entity, Speed2, 0, Speed1, #PB_Local)
      
      If MouseButton(#PB_MouseButton_Left)
        Old_Final_Cam_Angle = Final_Cam_Angle
        Final_Cam_Angle = MouseY()/10+CamAngle
      Else
        Final_Cam_angle = Old_Final_Cam_Angle
      EndIf
      
      CameraFollow(#Camera, #Entity, Angle, Final_Cam_Angle, Dist, 0.5)
        
      TimeSinceLastFrame = RenderWorld()
      
      Screen3DStats()
      FlipBuffers()
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
  EndIf
 
Else
  MessageRequester("Error", "The 3D Engine can't be initialized",0)
EndIf

End

Procedure Normalize(*V.Vector3)
  Define.f magSq, oneOverMag
 
  magSq = *V\x * *V\x + *V\y * *V\y + *V\z * *V\z
  If magsq > 0
    oneOverMag = 1.0 / Sqr(magSq)
    *V\x * oneOverMag
    *V\y * oneOverMag
    *V\z * oneOverMag
  EndIf
 
EndProcedure

Procedure Lerp(*R.Vector3, *V1.Vector3, *V2.Vector3, percent.f)
  ;percent = 0 --> R = V1
  ;percent = 1 --> R = V2
 
  If percent<0
    percent=0
  EndIf
  If percent>1
    percent=1
  EndIf
  *R\x = *V1\x + percent * (*V2\x - *V1\x)
  *R\y = *V1\y + percent * (*V2\y - *V1\y)
  *R\z = *V1\z + percent * (*V2\z - *V1\z)
EndProcedure

Procedure CameraFollow(Camera.i, Entity.i, AngleD.f, Height.f, Distance.f, percent.f)
  Protected.Vector3 P, P1, P2, Angle2
  Static Angle.Vector3
 
  Angle2\x = Sin(Radian(EntityYaw(Entity)+AngleD))
  Angle2\y = 0
  Angle2\z = 0
  lerp(@Angle, @Angle, @Angle2, percent)
  Normalize(Angle)
 
  P1\x = CameraX(Camera)
  P1\y = 0
  P1\z = CameraZ(Camera)
  P2\x = EntityX(Entity) + Angle\x * Distance
  P2\y = 0
  P2\z = EntityZ(Entity) + Angle\z * Distance
  Lerp(@P, @P1, @P2, percent)
 
  MoveCamera(Camera, P\x, Height, P\z, #PB_Absolute)
  CameraLookAt(Camera, EntityX(Entity), EntityY(Entity), EntityZ(Entity))   
EndProcedure 
Thanks again, Peter! =)
Mythros
Enthusiast
Enthusiast
Posts: 306
Joined: Mon Aug 19, 2013 3:28 pm

Re: Rotate camera around an object?

Post by Mythros »

Any luck?
Mythros
Enthusiast
Enthusiast
Posts: 306
Joined: Mon Aug 19, 2013 3:28 pm

Re: Rotate camera around an object?

Post by Mythros »

Ugh, darn it. I'm SO close. Is there a way to make the camera look at the player while zooming but make it so it doesn't end up zooming into his head?

Like when I zoom, I wanna move the camera a certain distance on the Z-Axis, so I can zoom up close to the player, but not go past the player.

Anyway, rotate the camera by holding down the left click and moving your mouse up, then zoom in by scrolling with your mouse wheel & you will see the problem.

Here's a SORTA working example:

Code: Select all

;
; ------------------------------------------------------------
;
;   Built on Comtois's old example - PB 5.11 Compatible
;   FollowCamera is part of PB 5.20 and makes life at lot easier
;   Damn, I'm glad, that the 3D part of PB are getting a lot more attention!!
;   (c) 2013 - Fantaisie Software
;   Put this example in the PB 5.11's 3D examples folder
;   Keys: W, S, A, D, Q, Z, +, -
; ------------------------------------------------------------


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

#CameraSpeed = 1

#Mesh = 1
#Entity = 1
#Camera = 0

Global in_zoom_mode = 0

IncludeFile "Screen3DRequester.pb"

Define.f KeyX, KeyY, MouseX, MouseY, Speed1, Speed2, TimeSinceLastFrame, Dist.f = 7.0 , Angle = 180, CamAngle.f = 25

Declare CameraFollow(Camera.i, Entity.i, AngleD.f, Height.f, Distance.f, percent.f)

Global music

Procedure.w MouseWheelDelta() 
  x.w = ((EventwParam()>>16)&$FFFF) 
  ProcedureReturn -(x / 120) 
EndProcedure 

Global WM_MOUSEWHEEL = $20A
Global zoomspeed = 1
Global Wheel = 0

Global Cam_Dist = 10

If InitEngine3D()
 
  Add3DArchive("Data/Textures", #PB_3DArchive_FileSystem)
  Add3DArchive("Data/Packs/skybox.zip", #PB_3DArchive_Zip)
  Parse3DScripts()
 
  InitSprite()
  InitKeyboard()
  InitMouse()
  InitSound()
   
  If Screen3DRequester()
   
    ;-Ground
    ;
    CreateMaterial(0, LoadTexture(0, "Dirt.jpg"))
    CreatePlane(0, 500, 500, 1, 1, 25, 25)
    CreateEntity(0,MeshID(0),MaterialID(0))
    EntityRenderMode(0, 0)
   
    CreateCube(#Mesh, 1)
   
    CreateMaterial(1, LoadTexture(1, "DosCarte.png"))
   
    CreateEntity(#Entity, MeshID(#Mesh), MaterialID(1), 0, 1.5, 0)
    ScaleEntity(#Entity, 1, 3, 1.5)
   
    SkyBox("stevecube.jpg")
   
    CreateCamera(#Camera, 0, 0, 100, 100)
    CameraFollow(#Camera, #Entity, Angle, CamAngle, Dist, 0.0)
    
    ;UseOGGSoundDecoder()
    ;music = LoadSound(#PB_Any, "media\music\Anonymous - Illuminati (Expect Us REMIX) + Download.ogg")
    ;PlaySound(music, #PB_Sound_Loop, 35)
    
    CamAngle = 2
    
    Angle = 21.0
    
    Dist = 10
    
    Repeat
      
      Screen3DEvents()
      
      event = WaitWindowEvent()
      
      Select event
          
        Case #PB_Event_CloseWindow
          Quit=1
          
        Case WM_MOUSEWHEEL
          
          If zoomspeed >= 0
            Wheel + MouseWheelDelta() * zoomspeed
          ElseIf zoomspeed < 0
            Wheel - MouseWheelDelta() * zoomspeed
          EndIf
          
          If MouseWheelDelta()
            Dist = Wheel
          EndIf
        
          If Dist < -25: Dist=-25: EndIf
        
          If Dist > 25: Dist=25: EndIf
        
          If Wheel<-Dist: Wheel=-Dist: EndIf
        
          If Wheel>Dist: Wheel=Dist: EndIf
  
      EndSelect
      
      If ExamineMouse()
        MouseX = -MouseDeltaX() * #CameraSpeed * 0.5
        MouseY = -MouseDeltaY() * #CameraSpeed * 0.5
      EndIf
      
      Speed1 * 0.9
      Speed2 * 0.9
      
      If ExamineKeyboard()
       
        If KeyboardPushed(#PB_Key_A)
          Speed1 = -0.01 * TimeSinceLastFrame
          RotateEntity(#Entity, 0, -90, 0, #PB_Absolute)
        ElseIf KeyboardPushed(#PB_Key_D)
          Speed1 = 0.01 * TimeSinceLastFrame
        EndIf
       
        If KeyboardPushed(#PB_Key_W)
          Speed2 = 0.017 * TimeSinceLastFrame
        ElseIf KeyboardPushed(#PB_Key_S)
          Speed2 = -0.017 * TimeSinceLastFrame
        EndIf
        
       EndIf
        
        If MouseButton(#PB_MouseButton_Left)
          If CamAngle <= 2
            If CamAngle < 50
              CamAngle + 0.2
            EndIf
            If CamAngle > 2
              CamAngle - 0.2
            EndIf
          EndIf
        EndIf
                
        If KeyboardPushed(#PB_Key_Space)
          MessageRequester("Test", "Dist: "+Dist)
        EndIf
          
      RotateEntity(#Entity, 0, MouseX * TimeSinceLastFrame/100, 0, #PB_Relative)
      MoveEntity(#Entity, Speed2, 0, Speed1, #PB_Local)
      
      If MouseButton(#PB_MouseButton_Left)
        Old_Final_Cam_Angle = Final_Cam_Angle
        Final_Cam_Angle = MouseY()/15+CamAngle
      Else
        Final_Cam_angle = Old_Final_Cam_Angle
      EndIf
      
      CameraFollow(#Camera, #Entity, Angle, Final_Cam_Angle, Cam_Dist+Dist, 0.5)
        
      TimeSinceLastFrame = RenderWorld()
      
      Screen3DStats()
      FlipBuffers()
    Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
  EndIf
 
Else
  MessageRequester("Error", "The 3D Engine can't be initialized",0)
EndIf

End

Procedure Normalize(*V.Vector3)
  Define.f magSq, oneOverMag
 
  magSq = *V\x * *V\x + *V\y * *V\y + *V\z * *V\z
  If magsq > 0
    oneOverMag = 1.0 / Sqr(magSq)
    *V\x * oneOverMag
    *V\y * oneOverMag
    *V\z * oneOverMag
  EndIf
 
EndProcedure

Procedure Lerp(*R.Vector3, *V1.Vector3, *V2.Vector3, percent.f)
  ;percent = 0 --> R = V1
  ;percent = 1 --> R = V2
 
  If percent<0
    percent=0
  EndIf
  If percent>1
    percent=1
  EndIf
  *R\x = *V1\x + percent * (*V2\x - *V1\x)
  *R\y = *V1\y + percent * (*V2\y - *V1\y)
  *R\z = *V1\z + percent * (*V2\z - *V1\z)
EndProcedure

Procedure CameraFollow(Camera.i, Entity.i, AngleD.f, Height.f, Distance.f, percent.f)
  Protected.Vector3 P, P1, P2, Angle2
  Static Angle.Vector3
 
  Angle2\x = Sin(Radian(EntityYaw(Entity)+AngleD))
  Angle2\y = 0
  Angle2\z = 0
  lerp(@Angle, @Angle, @Angle2, percent)
  Normalize(Angle)
 
  P1\x = CameraX(Camera)
  P1\y = 0
  P1\z = CameraZ(Camera)
  P2\x = EntityX(Entity) + Angle\x * Distance
  P2\y = 0
  P2\z = EntityZ(Entity) + Angle\z * Distance
  Lerp(@P, @P1, @P2, percent)
  
  If Dist <> 0
    in_zoom_mode = 1
  Else
    in_zoom_mode = 0
  EndIf
 
  If Not in_zoom_mode
    MoveCamera(Camera, P\x, Height, P\z, #PB_Absolute)
    CameraLookAt(Camera, EntityX(Entity), EntityY(Entity), EntityZ(Entity))   
  Else
    MoveCamera(Camera, 0, 0, Dist, #PB_Absolute)
    CameraLookAt(Camera, EntityX(Entity), EntityY(Entity), EntityZ(Entity))   
  EndIf
EndProcedure
Post Reply