Page 1 of 1

Totally lost at rotating an object

Posted: Fri Apr 05, 2024 2:49 pm
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.

Re: Totally lost at rotating an object

Posted: Fri Apr 05, 2024 3:58 pm
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

Re: Totally lost at rotating an object

Posted: Fri Apr 05, 2024 4:39 pm
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?

Re: Totally lost at rotating an object

Posted: Fri Apr 05, 2024 4:59 pm
by pjay
EntityPitch() & EntityYaw() I think - I initially tried with EntityDirectionX/Y() but it wasn't right.

Re: Totally lost at rotating an object

Posted: Fri Apr 05, 2024 5:02 pm
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!!!

Re: Totally lost at rotating an object

Posted: Fri Apr 05, 2024 6:18 pm
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


Re: Totally lost at rotating an object

Posted: Fri Apr 05, 2024 6:54 pm
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...