Totally lost at rotating an object

Everything related to 3D programming
User avatar
jacdelad
Addict
Addict
Posts: 2010
Joined: Wed Feb 03, 2021 12:46 pm
Location: Riesa

Totally lost at rotating an object

Post by jacdelad »

Hi,
I have a problem which I simply cannot solve (tried for two days now). I have a virtual pcb, which is shown from one side, so no rotation. Now the user can rotate the pcb with the mouse. I want to turn the pcb back into the starting rotation, when a key is released. This works without problems when setting the rotation via RotateEntity(ID,0,0,0,#PB_Absolute). So far so good. Now I want to make it more pleasing for the eye and rotate the pcb into position. Therefor I thought I just need to read the angles, divide them by 30 (for 30 steps) and substract the resulting values 30 times. But no, this does not work. I tried with EntityDirectionX/Y/Z(), EntityPitch/Roll/Yaw() and FetchOrientation(). This only resulted in the cognition that I have no idea what I'm doing. I googled too and found some info in the forum, but I simply don't understand it. So here's my question:
1. When do I need EntityDirectionX/Y/Z(), EntityPitch/Roll/Yaw(), FetchOrientation()?
2. How do I rotate my board smoothly into position?

Code: Select all

ExamineDesktops()
InitEngine3D(#PB_Engine3D_NoLog)
InitKeyboard()
InitMouse()
InitSprite()

OpenWindow(0,0,0,800,600,"Test",#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(MainWindow),0,0,WindowWidth(0),WindowHeight(0),0,0,0)

CreateCube(0,10)
CreateEntity(0,MeshID(0),#PB_Material_None)
ScaleEntity(0,1,1,0.05,#PB_Relative)
CreateLight(0, RGB(255, 0, 255), 0, 0, 200, #PB_Light_Point)
CreateCamera(0, 0, 0, 100, 100)
MoveCamera(0, 0, 0, 40, #PB_Absolute | #PB_Local)
CameraLookAt(0, 0, 0, 0)
CameraBackColor(0,#Gray)

Repeat
  Repeat:Until WindowEvent()=0
  
  KeyX = 0
  KeyY = 0
  MouseX = 0
  MouseY = 0
  ;{ Maussteuerung
  If ExamineMouse()
    If MouseButton(#PB_MouseButton_Middle)
      MouseX = -MouseDeltaX() * 0.2
      MouseY = -MouseDeltaY() * 0.2
    EndIf
  EndIf
  ;}
  
  If ExamineKeyboard()
    
    ;         If KeyboardReleased(#PB_Key_End)
    ;           RotateEntity(0,0,0,0,#PB_Absolute)
    ;         EndIf
    
    ;{ Ausrichtung        
    If KeyboardReleased(#PB_Key_End)
      Normalize=30
      ;Direction:
      RotX=-1*EntityDirectionX(0)/30
      RotY=-1*EntityDirectionY(0)/30
      RotZ=-1*EntityDirectionZ(0)/30
      ;Pitch/Roll/Yaw:
      ;RotX=-1*EntityPitch(0,#PB_Engine3D_Adjusted)/30
      ;RotY=-1*EntityYaw(0,#PB_Engine3D_Adjusted)/30
      ;RotZ=-1*EntityRoll(0,#PB_Engine3D_Adjusted)/30
      ;Instantly:
      ;RotateEntity(0,0,0,0,#PB_Absolute)
    EndIf
    
    If Normalize
      Normalize-1
      If Normalize=0
        RotateEntity(0,0,0,0,#PB_Absolute)
      Else
        RotateEntity(0,RotX,RotY,RotZ,#PB_Relative)
        ;RotateEntity(0,EntityDirectionX(0)-RotX,EntityDirectionY(0)-RotY,EntityDirectionZ(0)-RotZ,#PB_Absolute)
        ;RotateEntity(0,EntityPitch(0,#PB_Engine3D_Adjusted)-RotX,EntityYaw(0,#PB_Engine3D_Adjusted)-RotY,EntityRoll(0,#PB_Engine3D_Adjusted)-RotZ,#PB_Absolute)
      EndIf
    EndIf
    ;}
    
  EndIf
  
  RotateEntity(0, -MouseY, -MouseX, 0, #PB_Relative)
  MoveCamera  (0, KeyX, KeyY, 0)
  
  RenderWorld()
  FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape)

ReleaseMouse(#True)
CloseScreen()
The interesting part of the code is within the lines 41 to 66. I removed everything which is not necessary for this demonstration (including checks for successful initialization) to keep it short. Use the middle mouse key plus mouse movement to rotate the object and the end-key to reset orientation.
Good morning, that's a nice tnetennba!

PureBasic 6.21/Windows 11 x64/Ryzen 7900X/32GB RAM/3TB SSD
Synology DS1821+/DX517, 130.9TB+50.8TB+2TB SSD
pjay
Enthusiast
Enthusiast
Posts: 252
Joined: Thu Mar 30, 2006 11:14 am

Re: Totally lost at rotating an object

Post by pjay »

I'd do it this way:

Code: Select all

EnableExplicit
Define.f entity_rotationx.f, entity_rotationy.f, reset.f, resetspeed.f = 0.005

If InitEngine3D(#PB_Engine3D_NoLog)
  If InitKeyboard() And InitMouse() And InitSprite()
    
    OpenWindow(0,0,0,800,600,"Test",#PB_Window_ScreenCentered)
    OpenWindowedScreen(WindowID(0),0,0,WindowWidth(0) * DesktopResolutionX(),WindowHeight(0)* DesktopResolutionY(),0,0,0)
    
    CreateCube(0,10)
    CreateEntity(0,MeshID(0),#PB_Material_None)
    ScaleEntity(0,1,1,0.05,#PB_Relative)
    CreateLight(0, RGB(255, 0, 255), 0, 0, 200, #PB_Light_Point)
    CreateCamera(0, 0, 0, 100, 100)
    MoveCamera(0, 0, 0, 40, #PB_Absolute | #PB_Local)
    CameraLookAt(0, 0, 0, 0)
    CameraBackColor(0,#Gray)
    
    Macro LerpM(t, a, b) : ( a + t * ((b) - a) ) : EndMacro
    
    Repeat
      Repeat : Until WindowEvent() = 0
      ExamineKeyboard()
      
      ;{ Maussteuerung
      If ExamineMouse()
        If MouseButton(#PB_MouseButton_Middle)
          entity_rotationx = Mod(entity_rotationx + (MouseDeltaY() * 0.2), 360)
          entity_rotationy = Mod(entity_rotationy + (MouseDeltaX() * 0.2), 360)
          reset = 1
          RotateEntity(0, entity_rotationx,entity_rotationy , 0, #PB_Absolute)
        Else ;/ move back to 0...
          If reset > 0
            reset - resetspeed
            entity_rotationx = LerpM(reset,0.0,entity_rotationx)
            entity_rotationy = LerpM(reset,0.0,entity_rotationy) 
            RotateEntity(0, entity_rotationx, entity_rotationy, 0, #PB_Absolute)
            SetWindowTitle(0,"Rotation - X: "+StrF(EntityDirectionX(0),3) + "- Y: "+StrF(EntityDirectionY(0),3))
          EndIf
        EndIf
      EndIf
      ;}
      
      SetWindowTitle(0,"Rotation - X: "+StrF(entity_rotationx,3) + "- Y: "+StrF(entity_rotationy,3))
      RenderWorld() : FlipBuffers()
    Until KeyboardPushed(#PB_Key_Escape)
    
    ReleaseMouse(#True) : CloseScreen()
  EndIf
EndIf
User avatar
jacdelad
Addict
Addict
Posts: 2010
Joined: Wed Feb 03, 2021 12:46 pm
Location: Riesa

Re: Totally lost at rotating an object

Post by jacdelad »

WOW, this is smooth!!! Thanks very much, this is enough for me to to get this going!
Only one question: I'm not saving the rotation in entity_rotationx and entity_rotationy, which are the correct commands to get the rotation?
Good morning, that's a nice tnetennba!

PureBasic 6.21/Windows 11 x64/Ryzen 7900X/32GB RAM/3TB SSD
Synology DS1821+/DX517, 130.9TB+50.8TB+2TB SSD
pjay
Enthusiast
Enthusiast
Posts: 252
Joined: Thu Mar 30, 2006 11:14 am

Re: Totally lost at rotating an object

Post by pjay »

EntityPitch() & EntityYaw() I think - I initially tried with EntityDirectionX/Y() but it wasn't right.
User avatar
jacdelad
Addict
Addict
Posts: 2010
Joined: Wed Feb 03, 2021 12:46 pm
Location: Riesa

Re: Totally lost at rotating an object

Post by jacdelad »

Yeah, I'm also trying all combinations of Pitch/Roll/Yaw, but none of them worked yet. Pitch/Yaw does a jump before moving into position.
Edit: Ok, so I cache the x and y value now, no need to read it from the entity.

Also, how to modify this if I want to face the backside? I tried adding 180 to the y-value, but this obviously isn't right.
Edit: I found it, the second parameter for LerpM() must be 180 for the y-axis. Perfect!!!
Good morning, that's a nice tnetennba!

PureBasic 6.21/Windows 11 x64/Ryzen 7900X/32GB RAM/3TB SSD
Synology DS1821+/DX517, 130.9TB+50.8TB+2TB SSD
pjay
Enthusiast
Enthusiast
Posts: 252
Joined: Thu Mar 30, 2006 11:14 am

Re: Totally lost at rotating an object

Post by pjay »

If you wanted to do this without caching the xy rotations then you probably need to use the entity pitch(), roll() and yaw() commands seperately, along with 3 seperate RotateEntity() commands (much like in legacy OpenGL).

I see you've already figured out the 180 deg thing, but if you wanted to snap to nearest large face (front or back) then code is below.

Code: Select all

EnableExplicit
Define.f entity_rotationx.f, entity_rotationy.f, reset.f, resetspeed.f = 0.005, TargetX.f, TargetY.f

If InitEngine3D(#PB_Engine3D_NoLog)
  If InitKeyboard() And InitMouse() And InitSprite()
    
    OpenWindow(0,0,0,800,600,"Test",#PB_Window_ScreenCentered)
    OpenWindowedScreen(WindowID(0),0,0,WindowWidth(0) * DesktopResolutionX(),WindowHeight(0)* DesktopResolutionY(),0,0,0)
    
    CreateCube(0,10)
    CreateEntity(0,MeshID(0),#PB_Material_None)
    ScaleEntity(0,1,1,0.05,#PB_Relative)
    CreateLight(0, RGB(255, 0, 255), 0, 0, 200, #PB_Light_Point)
    CreateCamera(0, 0, 0, 100, 100)
    MoveCamera(0, 0, 0, 40, #PB_Absolute | #PB_Local)
    CameraLookAt(0, 0, 0, 0)
    CameraBackColor(0,#Gray)
    
    Macro LerpM(t, a, b) : ( a + t * ((b) - a) ) : EndMacro
    
    Repeat
      Repeat : Until WindowEvent() = 0
      ExamineKeyboard()
      
      ;{ Maussteuerung
      If ExamineMouse()
        If MouseButton(#PB_MouseButton_Middle)
          entity_rotationx = Mod(entity_rotationx + (MouseDeltaY() * 0.2), 360) : If entity_rotationx < 0 : entity_rotationx + 360 : EndIf
          entity_rotationy = Mod(entity_rotationy + (MouseDeltaX() * 0.2), 360) : If entity_rotationy < 0 : entity_rotationy + 360 : EndIf
          If entity_rotationy <= 90 : targety = 0 : EndIf
          If entity_rotationy > 90 And entity_rotationy < 270: targety = 180 : EndIf
          If entity_rotationy => 270 : targety = 360 : EndIf
          If entity_rotationx <= 90 : targetx = 0 : EndIf
          If entity_rotationx > 90 And entity_rotationx < 270: targetx = 180 : EndIf
          If entity_rotationx => 270 : targetx = 360 : EndIf
          reset = 1
          RotateEntity(0, entity_rotationx,entity_rotationy , 0, #PB_Absolute)
        Else ;/ move back to 0...
          If reset > 0
            reset - resetspeed
            entity_rotationx = LerpM(reset,TargetX,entity_rotationx)
            entity_rotationy = LerpM(reset,TargetY,entity_rotationy) 
            RotateEntity(0, entity_rotationx , entity_rotationy, 0, #PB_Absolute)
          EndIf
        EndIf
      EndIf
      ;}
      
      SetWindowTitle(0,"Rotation - X: "+StrF(entity_rotationx,3) + "- Y: "+StrF(entity_rotationy,3))
      RenderWorld() : FlipBuffers()
    Until KeyboardPushed(#PB_Key_Escape)
    
    ReleaseMouse(#True) : CloseScreen()
  EndIf
EndIf

User avatar
jacdelad
Addict
Addict
Posts: 2010
Joined: Wed Feb 03, 2021 12:46 pm
Location: Riesa

Re: Totally lost at rotating an object

Post by jacdelad »

Thanks very much again, I already figured this out. 8) My PCB now rotates exactly as I wanted it to.
It still feels a bit like witchcraft...
Good morning, that's a nice tnetennba!

PureBasic 6.21/Windows 11 x64/Ryzen 7900X/32GB RAM/3TB SSD
Synology DS1821+/DX517, 130.9TB+50.8TB+2TB SSD
Post Reply