Ticket #3712: ticket3712.patch

File ticket3712.patch, 13.2 KB (added by mimo, 8 years ago)
  • source/graphics/Frustum.cpp

     
    6666
    6767void CFrustum::Transform(CMatrix3D& m)
    6868{
    69     for (size_t i = 0; i < m_NumPlanes; i++)
     69    for (size_t i = 0; i < m_NumPlanes; ++i)
    7070    {
    7171        CVector3D n = m.Rotate(m_aPlanes[i].m_Norm);
    7272        CVector3D p = m.Transform(m_aPlanes[i].m_Norm * -m_aPlanes[i].m_Dist);
     
    7777
    7878bool CFrustum::IsPointVisible (const CVector3D &point) const
    7979{
    80     PLANESIDE Side;
    81 
    82     for (size_t i=0; i<m_NumPlanes; i++)
     80    for (size_t i=0; i<m_NumPlanes; ++i)
    8381    {
    84         Side = m_aPlanes[i].ClassifyPoint (point);
    85 
    86         if (Side == PS_BACK)
     82        if (m_aPlanes[i].IsPointOnBackSide(point))
    8783            return false;
    8884    }
    8985
     
    9086    return true;
    9187}
    9288
    93 bool CFrustum::DoesSegmentIntersect(const CVector3D& startRef, const CVector3D &endRef)
     89bool CFrustum::DoesSegmentIntersect(const CVector3D& startRef, const CVector3D &endRef) const
    9490{
    9591    CVector3D start = startRef;
    9692    CVector3D end = endRef;
     
    10197    CVector3D intersect;
    10298    for ( size_t i = 0; i<m_NumPlanes; ++i )
    10399    {
    104         if ( m_aPlanes[i].FindLineSegIntersection(start, end, &intersect) )
     100        if (m_aPlanes[i].FindLineSegIntersection(start, end, &intersect))
    105101        {
    106             if ( IsPointVisible( intersect ) )
     102            if (IsPointVisible(intersect))
    107103                return true;
    108104        }
    109105    }
     
    110106    return false;
    111107}
    112108
    113 bool CFrustum::IsSphereVisible (const CVector3D &center, float radius) const
     109bool CFrustum::IsSphereVisible(const CVector3D &center, float radius) const
    114110{
    115     for (size_t i = 0; i < m_NumPlanes; i++)
     111    for (size_t i = 0; i < m_NumPlanes; ++i)
    116112    {
    117113        float Dist = m_aPlanes[i].DistanceToPlane(center);
    118114        // If none of the sphere is in front of the plane, then
     
    124120    return true;
    125121}
    126122
    127 bool CFrustum::IsBoxVisible (const CVector3D &position,const CBoundingBoxAligned &bounds) const
     123bool CFrustum::IsBoxVisible(const CVector3D &position, const CBoundingBoxAligned &bounds) const
    128124{
    129125    //basically for every plane we calculate the furthest point
    130126    //in the box to that plane. If that point is beyond the plane
    131127    //then the box is not visible
    132128    CVector3D FarPoint;
    133     PLANESIDE Side;
    134129    CVector3D Min = position+bounds[0];
    135130    CVector3D Max = position+bounds[1];
    136131
    137     for (size_t i=0; i<m_NumPlanes; i++)
     132    for (size_t i=0; i<m_NumPlanes; ++i)
    138133    {
    139         if (m_aPlanes[i].m_Norm.X > 0.0f)
    140         {
    141             if (m_aPlanes[i].m_Norm.Y > 0.0f)
    142             {
    143                 if (m_aPlanes[i].m_Norm.Z > 0.0f)
    144                 {
    145                     FarPoint.X = Max.X; FarPoint.Y = Max.Y; FarPoint.Z = Max.Z;
    146                 }
    147                 else
    148                 {
    149                     FarPoint.X = Max.X; FarPoint.Y = Max.Y; FarPoint.Z = Min.Z;
    150                 }
    151             }
    152             else
    153             {
    154                 if (m_aPlanes[i].m_Norm.Z > 0.0f)
    155                 {
    156                     FarPoint.X = Max.X; FarPoint.Y = Min.Y; FarPoint.Z = Max.Z;
    157                 }
    158                 else
    159                 {
    160                     FarPoint.X = Max.X; FarPoint.Y = Min.Y; FarPoint.Z = Min.Z;
    161                 }
    162             }
    163         }
    164         else
    165         {
    166             if (m_aPlanes[i].m_Norm.Y > 0.0f)
    167             {
    168                 if (m_aPlanes[i].m_Norm.Z > 0.0f)
    169                 {
    170                     FarPoint.X = Min.X; FarPoint.Y = Max.Y; FarPoint.Z = Max.Z;
    171                 }
    172                 else
    173                 {
    174                     FarPoint.X = Min.X; FarPoint.Y = Max.Y; FarPoint.Z = Min.Z;
    175                 }
    176             }
    177             else
    178             {
    179                 if (m_aPlanes[i].m_Norm.Z > 0.0f)
    180                 {
    181                     FarPoint.X = Min.X; FarPoint.Y = Min.Y; FarPoint.Z = Max.Z;
    182                 }
    183                 else
    184                 {
    185                     FarPoint.X = Min.X; FarPoint.Y = Min.Y; FarPoint.Z = Min.Z;
    186                 }
    187             }
    188         }
     134        FarPoint.X = m_aPlanes[i].m_Norm.X > 0.0f ? Max.X : Min.X;
     135        FarPoint.Y = m_aPlanes[i].m_Norm.Y > 0.0f ? Max.Y : Min.Y;
     136        FarPoint.Z = m_aPlanes[i].m_Norm.Z > 0.0f ? Max.Z : Min.Z;
    189137       
    190         Side = m_aPlanes[i].ClassifyPoint (FarPoint);
     138        if (m_aPlanes[i].IsPointOnBackSide(FarPoint))
     139            return false;
     140    }
    191141
    192         if (Side == PS_BACK)
     142    return true;
     143}
     144
     145bool CFrustum::IsBoxVisible(const CBoundingBoxAligned &bounds) const
     146{
     147    //Same as the previous one, but with the position = (0, 0, 0)
     148    CVector3D FarPoint;
     149
     150    for (size_t i=0; i<m_NumPlanes; ++i)
     151    {
     152        FarPoint.X = m_aPlanes[i].m_Norm.X > 0.0f ? bounds[1].X : bounds[0].X;
     153        FarPoint.Y = m_aPlanes[i].m_Norm.Y > 0.0f ? bounds[1].Y : bounds[0].Y;
     154        FarPoint.Z = m_aPlanes[i].m_Norm.Z > 0.0f ? bounds[1].Z : bounds[0].Z;
     155       
     156        if (m_aPlanes[i].IsPointOnBackSide(FarPoint))
    193157            return false;
    194158    }
    195159
  • source/graphics/Frustum.h

     
    5555
    5656    //The following methods return true if the shape is
    5757    //partially or completely in front of the frustum planes
    58     bool IsPointVisible (const CVector3D &point) const;
    59     bool DoesSegmentIntersect(const CVector3D& start, const CVector3D &end);
    60     bool IsSphereVisible (const CVector3D &center, float radius) const;
    61     bool IsBoxVisible (const CVector3D &position,const CBoundingBoxAligned &bounds) const;
     58    bool IsPointVisible(const CVector3D &point) const;
     59    bool DoesSegmentIntersect(const CVector3D& start, const CVector3D &end) const;
     60    bool IsSphereVisible(const CVector3D &center, float radius) const;
     61    bool IsBoxVisible(const CVector3D &position, const CBoundingBoxAligned &bounds) const;
     62    bool IsBoxVisible(const CBoundingBoxAligned &bounds) const;
    6263
    6364    CPlane& operator[](size_t idx) { return m_aPlanes[idx]; }
    6465    const CPlane& operator[](size_t idx) const { return m_aPlanes[idx]; }
  • source/graphics/GameView.cpp

     
    498498    PROFILE3("submit terrain");
    499499
    500500    CTerrain* pTerrain = m->Game->GetWorld()->GetTerrain();
     501    float waterHeight = g_Renderer.GetWaterManager()->m_WaterHeight + 0.001f;
    501502    const ssize_t patchesPerSide = pTerrain->GetPatchesPerSide();
    502503
    503504    // find out which patches will be drawn
    504     for (ssize_t j=0; j<patchesPerSide; j++) {
    505         for (ssize_t i=0; i<patchesPerSide; i++) {
     505    for (ssize_t j=0; j<patchesPerSide; ++j)
     506    {
     507        for (ssize_t i=0; i<patchesPerSide; ++i)
     508        {
    506509            CPatch* patch=pTerrain->GetPatch(i,j);  // can't fail
    507510
    508511            // If the patch is underwater, calculate a bounding box that also contains the water plane
    509512            CBoundingBoxAligned bounds = patch->GetWorldBounds();
    510             float waterHeight = g_Renderer.GetWaterManager()->m_WaterHeight + 0.001f;
    511             if(bounds[1].Y < waterHeight) {
     513            if(bounds[1].Y < waterHeight)
    512514                bounds[1].Y = waterHeight;
    513             }
    514515
    515             if (!m->Culling || frustum.IsBoxVisible (CVector3D(0,0,0), bounds)) {
     516            if (!m->Culling || frustum.IsBoxVisible(bounds))
    516517                c->Submit(patch);
    517             }
    518518        }
    519519    }
    520520    }
  • source/maths/Plane.cpp

     
    2727#include "Plane.h"
    2828#include "MathUtil.h"
    2929
    30 CPlane::CPlane ()
     30const float CPlane::m_EPS = 0.001f;
     31
     32CPlane::CPlane()
    3133{
    3234    m_Dist = 0.0f;
    3335}
    3436
    3537//sets the plane equation from 3 points on that plane
    36 void CPlane::Set (const CVector3D &p1, const CVector3D &p2, const CVector3D &p3)
     38void CPlane::Set(const CVector3D &p1, const CVector3D &p2, const CVector3D &p3)
    3739{
    3840    CVector3D D1, D2;
    3941    CVector3D Norm;
     
    4547    //cross multiply gives normal
    4648    Norm = D2.Cross(D1);
    4749
    48     Set (Norm, p1);
     50    Set(Norm, p1);
    4951}
    5052
    5153//sets the plane equation from a normal and a point on
    5254//that plane
    53 void CPlane::Set (const CVector3D &norm, const CVector3D &point)
     55void CPlane::Set(const CVector3D &norm, const CVector3D &point)
    5456{
    5557    m_Norm = norm;
    5658
    57     m_Dist = - (norm.X * point.X +
    58                 norm.Y * point.Y +
    59                 norm.Z * point.Z);
     59    m_Dist = - (norm.X * point.X + norm.Y * point.Y + norm.Z * point.Z);
    6060
    6161//  Normalize ();
    6262}
     
    7676
    7777//returns the side of the plane on which this point
    7878//lies.
    79 PLANESIDE CPlane::ClassifyPoint (const CVector3D &point) const
     79PLANESIDE CPlane::ClassifyPoint(const CVector3D &point) const
    8080{
    81     float Dist;
     81    float Dist = DistanceToPlane(point);
    8282
    83     Dist = m_Norm.X * point.X +
    84            m_Norm.Y * point.Y +
    85            m_Norm.Z * point.Z +
    86            m_Dist;
    87 
    88     const float EPS = 0.001f;
    89 
    90     if (Dist > EPS)
     83    if (Dist > m_EPS)
    9184        return PS_FRONT;
    92     else if (Dist < -EPS)
     85    else if (Dist < -m_EPS)
    9386        return PS_BACK;
    9487
    9588    return PS_ON;
     
    9790
    9891//calculates the intersection point of a line with this
    9992//plane. Returns false if there is no intersection
    100 bool CPlane::FindLineSegIntersection (const CVector3D &start, const CVector3D &end, CVector3D *intsect)
     93bool CPlane::FindLineSegIntersection(const CVector3D &start, const CVector3D &end, CVector3D *intsect) const
    10194{
    10295    float dist1 = DistanceToPlane( start );
    10396    float dist2 = DistanceToPlane( end );
     
    111104    return true;
    112105}
    113106
    114 bool CPlane::FindRayIntersection (const CVector3D &start, const CVector3D &direction, CVector3D *intsect)
     107bool CPlane::FindRayIntersection(const CVector3D &start, const CVector3D &direction, CVector3D *intsect) const
    115108{
    116109    float dot = m_Norm.Dot (direction);
    117110    if (dot == 0.0f)
    118111        return false;
    119112
    120     *intsect = start - (direction * (DistanceToPlane (start)/dot));
     113    *intsect = start - (direction * (DistanceToPlane(start)/dot));
    121114    return true;
    122115}
  • source/maths/Plane.h

     
    3838class CPlane
    3939{
    4040    public:
    41         CPlane ();
    42         CPlane (const CVector4D& coeffs) : m_Norm(coeffs.X, coeffs.Y, coeffs.Z), m_Dist(coeffs.W) { }
     41        CPlane();
     42        CPlane(const CVector4D& coeffs) : m_Norm(coeffs.X, coeffs.Y, coeffs.Z), m_Dist(coeffs.W) { }
    4343
    4444        //sets the plane equation from 3 points on that plane
    45         void Set (const CVector3D &p1, const CVector3D &p2, const CVector3D &p3);
     45        void Set(const CVector3D &p1, const CVector3D &p2, const CVector3D &p3);
    4646
    4747        //sets the plane equation from a normal and a point on
    4848        //that plane
    49         void Set (const CVector3D &norm, const CVector3D &point);
     49        void Set(const CVector3D &norm, const CVector3D &point);
    5050
    5151        //normalizes the plane equation
    5252        void Normalize ();
    5353
    54         //returns the side of the plane on which this point
    55         //lies.
    56         PLANESIDE ClassifyPoint (const CVector3D &point) const;
     54        //returns the side of the plane on which this point lies
     55        PLANESIDE ClassifyPoint(const CVector3D &point) const;
     56        //returns true if this point is on the back side
     57        inline bool IsPointOnBackSide(const CVector3D &point) const;
    5758
    5859        //solves the plane equation for a particular point
    59         inline float DistanceToPlane (const CVector3D &point) const;
     60        inline float DistanceToPlane(const CVector3D &point) const;
    6061
    6162        //calculates the intersection point of a line with this
    6263        //plane. Returns false if there is no intersection
    63         bool FindLineSegIntersection (const CVector3D &start, const CVector3D &end, CVector3D *intsect);
    64         bool FindRayIntersection (const CVector3D &start, const CVector3D &direction, CVector3D *intsect);
     64        bool FindLineSegIntersection(const CVector3D &start, const CVector3D &end, CVector3D *intsect) const;
     65        bool FindRayIntersection(const CVector3D &start, const CVector3D &direction, CVector3D *intsect) const;
    6566
    6667    public:
    6768        CVector3D m_Norm;   //normal vector of the plane
    6869        float m_Dist;       //Plane distance (ie D in the plane eq.)
     70        static const float m_EPS;
    6971};
    7072
    7173float CPlane::DistanceToPlane (const CVector3D &point) const
    7274{
    73     float Dist;
     75    return m_Norm.X * point.X + m_Norm.Y * point.Y + m_Norm.Z * point.Z + m_Dist;
     76}
    7477
    75     Dist = m_Norm.X * point.X +
    76            m_Norm.Y * point.Y +
    77            m_Norm.Z * point.Z +
    78            m_Dist;
    79 
    80     return Dist;
     78bool CPlane::IsPointOnBackSide(const CVector3D &point) const
     79{
     80    return DistanceToPlane(point) < -m_EPS;
    8181}
    8282
    8383#endif
  • source/renderer/WaterManager.cpp

     
    908908
    909909    for (size_t a = 0; a < m_ShoreWaves.size(); ++a)
    910910    {
    911         if (!frustrum.IsBoxVisible(CVector3D(0,0,0), m_ShoreWaves[a]->m_AABB))
     911        if (!frustrum.IsBoxVisible(m_ShoreWaves[a]->m_AABB))
    912912            continue;
    913913       
    914914        CVertexBuffer::VBChunk* VBchunk = m_ShoreWaves[a]->m_VBvertices;
  • source/simulation2/components/CCmpProjectileManager.cpp

     
    335335
    336336        model.ValidatePosition();
    337337
    338         if (culling && !frustum.IsBoxVisible(CVector3D(0, 0, 0), model.GetWorldBoundsRec()))
     338        if (culling && !frustum.IsBoxVisible(model.GetWorldBoundsRec()))
    339339            continue;
    340340
    341341        // TODO: do something about LOS (copy from CCmpVisualActor)
  • source/simulation2/components/CCmpUnitRenderer.cpp

     
    430430            unit.lastTransformFrame = m_FrameNumber;
    431431        }
    432432
    433         if (culling && !frustum.IsBoxVisible(CVector3D(0, 0, 0), unitModel.GetWorldBoundsRec()))
     433        if (culling && !frustum.IsBoxVisible(unitModel.GetWorldBoundsRec()))
    434434            continue;
    435435
    436436        collector.SubmitRecursive(&unitModel);