Ticket #56: cameraFollowingMode.diff

File cameraFollowingMode.diff, 12.3 KB (added by markelov, 20 months ago)

camera following mode

  • source/ps/Hotkey.cpp

     
    7474    { HOTKEY_WIREFRAME, "wireframe", SDLK_w, 0 }, 
    7575    { HOTKEY_TOGGLEFULLSCREEN, "togglefullscreen", 0, 0 }, 
    7676    { HOTKEY_CAMERA_RESET, "camera.reset", 0, 0 }, 
     77    { HOTKEY_CAMERA_FOLLOW, "camera.follow", 0, 0 }, 
    7778    { HOTKEY_CAMERA_ZOOM_IN, "camera.zoom.in", SDLK_PLUS, SDLK_KP_PLUS }, 
    7879    { HOTKEY_CAMERA_ZOOM_OUT, "camera.zoom.out", SDLK_MINUS, SDLK_KP_MINUS }, 
    7980    { HOTKEY_CAMERA_ZOOM_WHEEL_IN, "camera.zoom.wheel.in", MOUSE_WHEELUP, 0 }, 
  • source/ps/Hotkey.h

     
    5555    HOTKEY_WIREFRAME, 
    5656    HOTKEY_TOGGLEFULLSCREEN, 
    5757    HOTKEY_CAMERA_RESET, 
     58    HOTKEY_CAMERA_FOLLOW, 
    5859    HOTKEY_CAMERA_ZOOM_IN, 
    5960    HOTKEY_CAMERA_ZOOM_OUT, 
    6061    HOTKEY_CAMERA_ZOOM_WHEEL_IN, 
  • source/gui/scripting/ScriptFunctions.cpp

     
    7272    g_GUI->PopPage(); 
    7373} 
    7474 
     75/** 
     76 * Start / stop camera following mode 
     77 * @param entityid unit id to follow for. If zero - stop following mode 
     78 */ 
     79void CameraFollow(void* UNUSED(cbdata), entity_id_t entityid) 
     80{ 
     81    if(g_Game && g_Game->GetView()) 
     82        g_Game->GetView()->CameraFollow(entityid); 
     83} 
     84 
    7585bool IsNewSimulation(void* UNUSED(cbdata)) 
    7686{ 
    7787    return true; // XXX: delete this function 
     
    313323    scriptInterface.RegisterFunction<void, std::wstring, CScriptVal, &PushGuiPage>("PushGuiPage"); 
    314324    scriptInterface.RegisterFunction<void, std::wstring, CScriptVal, &SwitchGuiPage>("SwitchGuiPage"); 
    315325    scriptInterface.RegisterFunction<void, &PopGuiPage>("PopGuiPage"); 
     326    scriptInterface.RegisterFunction<void, entity_id_t, &CameraFollow>("CameraFollow"); 
    316327 
    317328    // Simulation<->GUI interface functions: 
    318329    scriptInterface.RegisterFunction<bool, &IsNewSimulation>("IsNewSimulation"); 
  • source/graphics/GameView.cpp

     
    5252#include "scripting/ScriptableObject.h" 
    5353#include "simulation/LOSManager.h" 
    5454#include "simulation2/Simulation2.h" 
     55#include "simulation2/components/ICmpPosition.h" 
    5556 
    5657extern int g_xres, g_yres; 
    5758 
     
    273274} 
    274275 
    275276CGameView::CGameView(CGame *pGame): 
    276     m(new CGameViewImpl(pGame)) 
     277    m(new CGameViewImpl(pGame)), 
     278    m_cameraFollowingEntity(0) 
    277279{ 
    278280    SViewPort vp; 
    279281    vp.m_X=0; 
     
    529531    g_Renderer.GetWaterManager()->UnloadWaterTextures(); 
    530532} 
    531533 
    532  
    533534static void ClampDistance(CGameViewImpl* m, bool smooth) 
    534535{ 
    535536    if (!m->ConstrainCamera) 
     
    603604    if (hotkeys[HOTKEY_CAMERA_ROTATE_DOWN]) 
    604605        m->RotateX.AddSmoothly(m->ViewRotateXSpeed * DeltaTime); 
    605606 
    606     float moveRightward = 0.f; 
    607     float moveForward = 0.f; 
    608  
    609     if (hotkeys[HOTKEY_CAMERA_PAN]) 
     607    // Process camera movements only if it is not in following mode 
     608    if(m_cameraFollowingEntity == 0) 
    610609    { 
    611         moveRightward += m->ViewDragSpeed * mouse_dx; 
    612         moveForward += m->ViewDragSpeed * -mouse_dy; 
    613     } 
     610        float moveRightward = 0.f; 
     611        float moveForward = 0.f; 
    614612 
    615     if (g_mouse_active) 
    616     { 
    617         if (g_mouse_x >= g_xres - 2 && g_mouse_x < g_xres) 
    618             moveRightward += m->ViewScrollSpeed * DeltaTime; 
    619         else if (g_mouse_x <= 3 && g_mouse_x >= 0) 
    620             moveRightward -= m->ViewScrollSpeed * DeltaTime; 
     613        if (hotkeys[HOTKEY_CAMERA_PAN]) 
     614        { 
     615            moveRightward += m->ViewDragSpeed * mouse_dx; 
     616            moveForward += m->ViewDragSpeed * -mouse_dy; 
     617        } 
    621618 
    622         if (g_mouse_y >= g_yres - 2 && g_mouse_y < g_yres) 
    623             moveForward -= m->ViewScrollSpeed * DeltaTime; 
    624         else if (g_mouse_y <= 3 && g_mouse_y >= 0) 
    625             moveForward += m->ViewScrollSpeed * DeltaTime; 
    626     } 
     619        if (g_mouse_active) 
     620        { 
     621            if (g_mouse_x >= g_xres - 2 && g_mouse_x < g_xres) 
     622                moveRightward += m->ViewScrollSpeed * DeltaTime; 
     623            else if (g_mouse_x <= 3 && g_mouse_x >= 0) 
     624                moveRightward -= m->ViewScrollSpeed * DeltaTime; 
    627625 
    628     if (hotkeys[HOTKEY_CAMERA_PAN_KEYBOARD]) 
     626            if (g_mouse_y >= g_yres - 2 && g_mouse_y < g_yres) 
     627                moveForward -= m->ViewScrollSpeed * DeltaTime; 
     628            else if (g_mouse_y <= 3 && g_mouse_y >= 0) 
     629                moveForward += m->ViewScrollSpeed * DeltaTime; 
     630        } 
     631 
     632        if (hotkeys[HOTKEY_CAMERA_PAN_KEYBOARD]) 
     633        { 
     634            if (hotkeys[HOTKEY_CAMERA_RIGHT]) 
     635                moveRightward += m->ViewScrollSpeed * DeltaTime; 
     636            if (hotkeys[HOTKEY_CAMERA_LEFT]) 
     637                moveRightward -= m->ViewScrollSpeed * DeltaTime; 
     638            if (hotkeys[HOTKEY_CAMERA_UP]) 
     639                moveForward += m->ViewScrollSpeed * DeltaTime; 
     640            if (hotkeys[HOTKEY_CAMERA_DOWN]) 
     641                moveForward -= m->ViewScrollSpeed * DeltaTime; 
     642        } 
     643 
     644        if (moveRightward || moveForward) 
     645        { 
     646            float s = sin(m->RotateY.GetSmoothedValue()); 
     647            float c = cos(m->RotateY.GetSmoothedValue()); 
     648            m->PosX.AddSmoothly(c * moveRightward); 
     649            m->PosZ.AddSmoothly(-s * moveRightward); 
     650            m->PosX.AddSmoothly(s * moveForward); 
     651            m->PosZ.AddSmoothly(c * moveForward); 
     652        } 
     653    } // if(m_cameraFollowingEntity == 0) 
     654 
     655    /** 
     656     * if camera is in following mode (m_cameraFollowingEntity > 0) 
     657     * follow the unit, do not process camera movement actions 
     658     * see http://trac.wildfiregames.com/ticket/56 for more description 
     659     */ 
     660    else 
    629661    { 
    630         if (hotkeys[HOTKEY_CAMERA_RIGHT]) 
    631             moveRightward += m->ViewScrollSpeed * DeltaTime; 
    632         if (hotkeys[HOTKEY_CAMERA_LEFT]) 
    633             moveRightward -= m->ViewScrollSpeed * DeltaTime; 
    634         if (hotkeys[HOTKEY_CAMERA_UP]) 
    635             moveForward += m->ViewScrollSpeed * DeltaTime; 
    636         if (hotkeys[HOTKEY_CAMERA_DOWN]) 
    637             moveForward -= m->ViewScrollSpeed * DeltaTime; 
    638     } 
     662        debug_assert(m && m->Game && m->Game->GetSimulation2()); 
    639663 
    640     if (moveRightward || moveForward) 
    641     { 
    642         float s = sin(m->RotateY.GetSmoothedValue()); 
    643         float c = cos(m->RotateY.GetSmoothedValue()); 
    644         m->PosX.AddSmoothly(c * moveRightward); 
    645         m->PosZ.AddSmoothly(-s * moveRightward); 
    646         m->PosX.AddSmoothly(s * moveForward); 
    647         m->PosZ.AddSmoothly(c * moveForward); 
     664        CmpPtr<ICmpPosition> cmpPosition(*(m->Game->GetSimulation2()), m_cameraFollowingEntity); 
     665        if (!cmpPosition.null() && cmpPosition->IsInWorld()) 
     666        { 
     667            CVector3D pos = cmpPosition->GetInterpolatedTransform(m->Game->GetSimulation2()->GetLastFrameOffset(), false).GetTranslation(); 
     668            // move the camera after unit 
     669            // use smoothed values of rotation around X and Y, since we need to hold user's rotation done 
     670            // in this function above 
     671            CCamera targetCam = m->ViewCamera; 
     672            targetCam.m_Orientation.SetIdentity(); 
     673            targetCam.m_Orientation.RotateX(m->RotateX.GetSmoothedValue()); 
     674            targetCam.m_Orientation.RotateY(m->RotateY.GetSmoothedValue()); 
     675            targetCam.m_Orientation.Translate(m->PosX.GetValue(), m->PosY.GetValue(), m->PosZ.GetValue()); 
     676 
     677            CVector3D pivot = targetCam.GetFocus(); 
     678            CVector3D delta = pos - pivot; 
     679            m->PosX.AddSmoothly(delta.X); 
     680            m->PosY.AddSmoothly(delta.Y); 
     681            m->PosZ.AddSmoothly(delta.Z); 
     682        } 
     683        else 
     684            m_cameraFollowingEntity = 0; 
    648685    } 
    649686 
    650687    if (hotkeys[HOTKEY_CAMERA_ZOOM_IN]) 
     
    758795    } 
    759796    */ 
    760797 
     798 
    761799    m->RotateY.Wrap(-(float)M_PI, (float)M_PI); 
    762800 
    763801    // Update the camera matrix 
     
    824862    m->RotateY.SetValueSmoothly(DEGTORAD(m->ViewRotateYDefault)); 
    825863} 
    826864 
     865 
    827866InReaction game_view_handler(const SDL_Event_* ev) 
    828867{ 
    829868    // put any events that must be processed even if inactive here 
  • source/graphics/GameView.h

     
    2323extern float g_YMinOffset; 
    2424 
    2525#include "renderer/Scene.h" 
     26#include "simulation2/system/Entity.h" 
    2627 
    2728#include "lib/input.h" // InReaction - can't forward-declare enum 
    2829 
     
    4647private: 
    4748    static const float cameraPivotMargin; 
    4849    CGameViewImpl* m; 
     50    entity_id_t m_cameraFollowingEntity; 
    4951 
    5052    // Check whether lighting environment has changed and update vertex data if necessary 
    5153    void CheckLightEnv(); 
     
    8587    void MoveCameraTarget(const CVector3D& target); 
    8688    void ResetCameraTarget(const CVector3D& target); 
    8789    void ResetCameraAngleZoom(); 
     90    void CameraFollow(entity_id_t entityid) { m_cameraFollowingEntity = entityid; } 
    8891 
    8992    CCamera *GetCamera(); 
    9093    CCinemaManager* GetCinema(); 
  • source/simulation2/Simulation2.cpp

     
    277277//////////////////////////////////////////////////////////////// 
    278278 
    279279CSimulation2::CSimulation2(CUnitManager* unitManager, CTerrain* terrain) : 
    280     m(new CSimulation2Impl(unitManager, terrain)) 
     280    m(new CSimulation2Impl(unitManager, terrain)), 
     281    m_frameOffset(0.0f) 
    281282{ 
    282283} 
    283284 
     
    367368 
    368369void CSimulation2::Interpolate(float frameLength, float frameOffset) 
    369370{ 
     371    m_frameOffset = frameOffset; 
    370372    m->Interpolate(frameLength, frameOffset); 
    371373} 
    372374 
  • source/simulation2/Simulation2.h

     
    155155    std::string GenerateSchema(); 
    156156 
    157157private: 
     158    float m_frameOffset; 
    158159    CSimulation2Impl* m; 
    159160 
    160161    NONCOPYABLE(CSimulation2); 
     162 
     163public: 
     164    float GetLastFrameOffset() const { return m_frameOffset; } 
    161165}; 
    162166 
    163167#endif // INCLUDED_SIMULATION2 
  • binaries/data/mods/public/maps/scenarios/Combat_demo.xml

     
    372372        </Entity> 
    373373    </Entities> 
    374374    <Paths/> 
    375 </Scenario> 
    376  No newline at end of file 
     375</Scenario> 
  • binaries/data/mods/public/gui/session_new/session.xml

     
    6262        <object hotkey="killUnit"> 
    6363            <action on="Press">performCommand(g_Selection.toList()[0], "delete");</action> 
    6464        </object> 
     65 
     66        <!-- camera.follow mode - follow the first unit in the selection --> 
     67        <object hotkey="camera.follow"> 
     68            <action on="Press">performCommand(g_Selection.toList()[0], "camera.follow");</action> 
     69        </object> 
    6570         
    6671        <!-- ================================  ================================ --> 
    6772        <!-- Developer / Debug items --> 
  • binaries/data/mods/public/gui/session_new/input.js

     
    2424var placementPosition; 
    2525var placementEntity; 
    2626 
     27// the unit camera is following for 
     28var followingEntity = 0; 
     29 
    2730var mouseX = 0; 
    2831var mouseY = 0; 
    2932var mouseIsOverObject = false; 
     
    730733// Performs the specified command (delete, town bell, repair, etc.) 
    731734function performCommand(entity, commandName) 
    732735{ 
     736    // entity depending commands 
    733737    if (entity) 
    734738    { 
    735739        switch (commandName) 
     
    741745            break; 
    742746        } 
    743747    } 
     748 
     749    // common commands 
     750    if(commandName == "camera.follow") 
     751    { 
     752        var l_followingEntity = 0; 
     753 
     754        if(entity) 
     755        { 
     756            // stop following mode if it is performing for the same unit 
     757            var entState = GetEntityState(entity); 
     758            if (entState && isUnit(entState) && (followingEntity != entity)) 
     759                l_followingEntity = entity; 
     760        } 
     761 
     762        // calling that function with followingEntity = 0 will stop following mode 
     763        if(l_followingEntity != followingEntity) 
     764        { 
     765            followingEntity = l_followingEntity; 
     766            Engine.CameraFollow(followingEntity); 
     767        } 
     768    } 
    744769} 
  • binaries/data/config/default.cfg

     
    113113 
    114114; > CAMERA SETTINGS 
    115115hotkey.camera.reset = "H"                   ; Reset camera rotation to default. 
     116hotkey.camera.follow = "F"                          ; Follow the first unit in the selection 
    116117hotkey.camera.reset.origin = "Ctrl+H"               ; Reset camera to origin. 
    117118hotkey.camera.zoom.in = Plus, Equals, NumPlus           ; Zoom camera in. 
    118119hotkey.camera.zoom.out = Minus, NumMinus            ; Zoom camera out.