Ticket #554: cameraConstraints.diff

File cameraConstraints.diff, 6.7 KB (added by Sergey, 14 years ago)

previous diff was broken

  • graphics/Terrain.cpp

     
    9494}
    9595
    9696///////////////////////////////////////////////////////////////////////////////
     97// GetEdgeNearestPoint: get the nearest edge point close to the passed
     98// returns true if the point was outside the map
     99bool CTerrain::GetEdgeNearestPoint(float *x, float *z) const
     100{
     101    debug_assert(x != NULL && z != NULL && "NULL parameters have been passed");
    97102
     103    // do nothing if the point is already on the map
     104    if(IsOnMap(*x, *z))
     105        return false;
     106
     107    float min_x = GetMinX();
     108    float max_x = GetMaxX() - 1.0f / CELL_SIZE;
     109    float min_z = GetMinZ();
     110    float max_z = GetMaxZ() - 1.0f / CELL_SIZE;
     111
     112    // x constraint
     113    if(*x < min_x)
     114        *x = min_x;
     115    else if(*x > max_x)
     116        *x = max_x;
     117
     118    // z constraint
     119    if(*z < min_z)
     120        *z = min_z;
     121    else if(*z > max_z)
     122        *z = max_z;
     123
     124    return true;
     125}
     126
     127///////////////////////////////////////////////////////////////////////////////
     128
    98129CStr8 CTerrain::GetMovementClass(ssize_t i, ssize_t j) const
    99130{
    100131    CMiniPatch* tile = GetTile(i, j);
  • graphics/Camera.h

     
    8282        // Get the point on the plane at height h corresponding to pixel (px,py)
    8383        CVector3D GetWorldCoordinates(int px, int py, float h) const;
    8484        // Get the point on the terrain the camera is pointing towards
    85         CVector3D GetFocus();
     85        CVector3D GetFocus(bool *is_on_map = NULL);
    8686
    8787        // Build an orientation matrix from camera position, camera focus point, and up-vector
    8888        void LookAt(const CVector3D& camera, const CVector3D& orientation, const CVector3D& up);
  • graphics/GameView.cpp

     
    6060const float CGameView::defaultNear = 4.f;
    6161const float CGameView::defaultFar = 4096.f;
    6262const float CGameView::defaultCullFOV = CGameView::defaultFOV + DEGTORAD(6.0f); //add 6 degrees to the default FOV for use with the culling frustum
     63const float CGameView::cameraPivotMargin = 20.0f;
    6364
    6465/**
    6566 * A value with exponential decay towards the target value.
     
    739740            m->PosY.AddSmoothly(limit - nearPoint.Y);
    740741    }
    741742    */
    742 
     743   
    743744    m->RotateY.Wrap(-(float)M_PI, (float)M_PI);
    744745
     746    // Ensure the ViewCamera focus is inside the map with the chosen margins
     747    // if not so - apply margins to the camera
     748    if (m->ConstrainCamera)
     749    {
     750        CCamera targetCam = m->ViewCamera;
     751        SetupCameraMatrix(m, &targetCam.m_Orientation);
     752        CVector3D pivot = targetCam.m_Orientation.GetTranslation() + targetCam.m_Orientation.GetIn() * m->ViewZoomDefault;
     753        ApplyCameraPivotMargins(pivot);
     754    }
     755
    745756    // Update the camera matrix
    746757    SetupCameraMatrix(m, &m->ViewCamera.m_Orientation);
    747758    m->ViewCamera.UpdateFrustum();
    748759}
    749760
     761// ApplyCameraPivotMargins: constraint camera pivot
     762// returns true if margins were applied to the pivot passed
     763bool CGameView::ApplyCameraPivotMargins(CVector3D &pivot)
     764{
     765    bool        margins_applied = false;
     766    CTerrain    *pter = m->Game->GetWorld()->GetTerrain();
     767    debug_assert(pter != NULL && "NULL terrain pointer");
     768    CVector3D   old_pivot(pivot);
     769
     770    float   min_x = pter->GetMinX() + cameraPivotMargin;
     771    float   max_x = pter->GetMaxX() - cameraPivotMargin;
     772    float   min_z = pter->GetMinZ() + cameraPivotMargin;
     773    float   max_z = pter->GetMaxZ() - cameraPivotMargin;
     774
     775         if(pivot.X < min_x) { pivot.X = min_x; margins_applied = true; }
     776    else if(pivot.X > max_x) { pivot.X = max_x; margins_applied = true; }
     777         if(pivot.Z < min_z) { pivot.Z = min_z; margins_applied = true; }
     778    else if(pivot.Z > max_z) { pivot.Z = max_z; margins_applied = true; }
     779
     780    if(margins_applied)
     781    {
     782        m->PosX.Add(pivot.X - old_pivot.X);
     783        m->PosZ.Add(pivot.Z - old_pivot.Z);
     784
     785        // doesn't need because of the fixed Y camera position
     786//      pivot.Y = pter->GetExactGroundLevel(pivot.X, pivot.Z);
     787//      m->PosY.Add(pivot.Y - old_pivot.Y);
     788    }
     789
     790    return margins_applied;
     791}
     792
    750793void CGameView::MoveCameraTarget(const CVector3D& target)
    751794{
    752795    // Maintain the same orientation and level of zoom, if we can
  • graphics/Terrain.h

     
    6666    // return number of patches along edge of the terrain
    6767    ssize_t GetPatchesPerSide() const { return m_MapSizePatches; }
    6868
     69    float GetMinX() const { return 0.0f; }
     70    float GetMinZ() const { return 0.0f; }
     71    float GetMaxX() const { return (float)((m_MapSize-1) * CELL_SIZE); }
     72    float GetMaxZ() const { return (float)((m_MapSize-1) * CELL_SIZE); }
     73
    6974    bool IsOnMap(float x, float z) const
    7075    {
    71         return ((x >= 0.0f) && (x < (float)((m_MapSize-1) * CELL_SIZE))
    72              && (z >= 0.0f) && (z < (float)((m_MapSize-1) * CELL_SIZE)));
     76        return ((x >= GetMinX()) && (x < GetMaxX())
     77             && (z >= GetMinZ()) && (z < GetMaxZ()));
    7378    }
     79   
     80    // GetEdgeNearestPoint: get the nearest edge point close to the passed
     81    // returns true if the point was outside the map
     82    bool GetEdgeNearestPoint(float *x, float *z) const;
    7483
    7584    CStr8 GetMovementClass(ssize_t i, ssize_t j) const;
    7685
  • graphics/GameView.h

     
    4444    static const float defaultFOV, defaultCullFOV, defaultNear, defaultFar;
    4545
    4646private:
     47    static const float cameraPivotMargin;
    4748    CGameViewImpl* m;
    4849
    4950    // Check whether lighting environment has changed and update vertex data if necessary
     
    7677    // *presentation*
    7778    void Update(float DeltaTime);
    7879
     80    // ApplyCameraPivotMargins: constraint pivot
     81    // returns true if margins were applied to the pivot passed
     82    bool ApplyCameraPivotMargins(CVector3D &pivot);
     83
    7984    // Render: Render the World
    8085    void Render();
    8186
  • graphics/Camera.cpp

     
    285285    return CVector3D(0.f, h, 0.f);
    286286}
    287287
    288 CVector3D CCamera::GetFocus()
     288CVector3D CCamera::GetFocus(bool *is_on_map)
    289289{
    290290    // Basically the same as GetWorldCoordinates
    291291
     
    298298    dir = m_Orientation.GetIn();
    299299
    300300    if (tracer.RayIntersect(origin, dir, x, z, currentTarget))
     301    {
     302        if(is_on_map != NULL) *is_on_map = true;
    301303        return (currentTarget);
     304    }
    302305
    303306    // Off the edge of the world?
    304307    // Work out where it /would/ hit, if the map were extended out to infinity with average height.
    305308
     309    if(is_on_map != NULL) *is_on_map = false;
    306310    return (origin + dir * ((50.0f - origin.Y) / dir.Y));
    307311}
    308312