Ticket #3712: ticket3712.patch
File ticket3712.patch, 13.2 KB (added by , 8 years ago) |
---|
-
source/graphics/Frustum.cpp
66 66 67 67 void CFrustum::Transform(CMatrix3D& m) 68 68 { 69 for (size_t i = 0; i < m_NumPlanes; i++)69 for (size_t i = 0; i < m_NumPlanes; ++i) 70 70 { 71 71 CVector3D n = m.Rotate(m_aPlanes[i].m_Norm); 72 72 CVector3D p = m.Transform(m_aPlanes[i].m_Norm * -m_aPlanes[i].m_Dist); … … 77 77 78 78 bool CFrustum::IsPointVisible (const CVector3D &point) const 79 79 { 80 PLANESIDE Side; 81 82 for (size_t i=0; i<m_NumPlanes; i++) 80 for (size_t i=0; i<m_NumPlanes; ++i) 83 81 { 84 Side = m_aPlanes[i].ClassifyPoint (point); 85 86 if (Side == PS_BACK) 82 if (m_aPlanes[i].IsPointOnBackSide(point)) 87 83 return false; 88 84 } 89 85 … … 90 86 return true; 91 87 } 92 88 93 bool CFrustum::DoesSegmentIntersect(const CVector3D& startRef, const CVector3D &endRef) 89 bool CFrustum::DoesSegmentIntersect(const CVector3D& startRef, const CVector3D &endRef) const 94 90 { 95 91 CVector3D start = startRef; 96 92 CVector3D end = endRef; … … 101 97 CVector3D intersect; 102 98 for ( size_t i = 0; i<m_NumPlanes; ++i ) 103 99 { 104 if ( m_aPlanes[i].FindLineSegIntersection(start, end, &intersect))100 if (m_aPlanes[i].FindLineSegIntersection(start, end, &intersect)) 105 101 { 106 if ( IsPointVisible( intersect ))102 if (IsPointVisible(intersect)) 107 103 return true; 108 104 } 109 105 } … … 110 106 return false; 111 107 } 112 108 113 bool CFrustum::IsSphereVisible 109 bool CFrustum::IsSphereVisible(const CVector3D ¢er, float radius) const 114 110 { 115 for (size_t i = 0; i < m_NumPlanes; i++)111 for (size_t i = 0; i < m_NumPlanes; ++i) 116 112 { 117 113 float Dist = m_aPlanes[i].DistanceToPlane(center); 118 114 // If none of the sphere is in front of the plane, then … … 124 120 return true; 125 121 } 126 122 127 bool CFrustum::IsBoxVisible (const CVector3D &position,const CBoundingBoxAligned &bounds) const123 bool CFrustum::IsBoxVisible(const CVector3D &position, const CBoundingBoxAligned &bounds) const 128 124 { 129 125 //basically for every plane we calculate the furthest point 130 126 //in the box to that plane. If that point is beyond the plane 131 127 //then the box is not visible 132 128 CVector3D FarPoint; 133 PLANESIDE Side;134 129 CVector3D Min = position+bounds[0]; 135 130 CVector3D Max = position+bounds[1]; 136 131 137 for (size_t i=0; i<m_NumPlanes; i++)132 for (size_t i=0; i<m_NumPlanes; ++i) 138 133 { 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; 189 137 190 Side = m_aPlanes[i].ClassifyPoint (FarPoint); 138 if (m_aPlanes[i].IsPointOnBackSide(FarPoint)) 139 return false; 140 } 191 141 192 if (Side == PS_BACK) 142 return true; 143 } 144 145 bool 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)) 193 157 return false; 194 158 } 195 159 -
source/graphics/Frustum.h
55 55 56 56 //The following methods return true if the shape is 57 57 //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 ¢er, 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 ¢er, float radius) const; 61 bool IsBoxVisible(const CVector3D &position, const CBoundingBoxAligned &bounds) const; 62 bool IsBoxVisible(const CBoundingBoxAligned &bounds) const; 62 63 63 64 CPlane& operator[](size_t idx) { return m_aPlanes[idx]; } 64 65 const CPlane& operator[](size_t idx) const { return m_aPlanes[idx]; } -
source/graphics/GameView.cpp
498 498 PROFILE3("submit terrain"); 499 499 500 500 CTerrain* pTerrain = m->Game->GetWorld()->GetTerrain(); 501 float waterHeight = g_Renderer.GetWaterManager()->m_WaterHeight + 0.001f; 501 502 const ssize_t patchesPerSide = pTerrain->GetPatchesPerSide(); 502 503 503 504 // 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 { 506 509 CPatch* patch=pTerrain->GetPatch(i,j); // can't fail 507 510 508 511 // If the patch is underwater, calculate a bounding box that also contains the water plane 509 512 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) 512 514 bounds[1].Y = waterHeight; 513 }514 515 515 if (!m->Culling || frustum.IsBoxVisible (CVector3D(0,0,0), bounds)) {516 if (!m->Culling || frustum.IsBoxVisible(bounds)) 516 517 c->Submit(patch); 517 }518 518 } 519 519 } 520 520 } -
source/maths/Plane.cpp
27 27 #include "Plane.h" 28 28 #include "MathUtil.h" 29 29 30 CPlane::CPlane () 30 const float CPlane::m_EPS = 0.001f; 31 32 CPlane::CPlane() 31 33 { 32 34 m_Dist = 0.0f; 33 35 } 34 36 35 37 //sets the plane equation from 3 points on that plane 36 void CPlane::Set 38 void CPlane::Set(const CVector3D &p1, const CVector3D &p2, const CVector3D &p3) 37 39 { 38 40 CVector3D D1, D2; 39 41 CVector3D Norm; … … 45 47 //cross multiply gives normal 46 48 Norm = D2.Cross(D1); 47 49 48 Set 50 Set(Norm, p1); 49 51 } 50 52 51 53 //sets the plane equation from a normal and a point on 52 54 //that plane 53 void CPlane::Set 55 void CPlane::Set(const CVector3D &norm, const CVector3D &point) 54 56 { 55 57 m_Norm = norm; 56 58 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); 60 60 61 61 // Normalize (); 62 62 } … … 76 76 77 77 //returns the side of the plane on which this point 78 78 //lies. 79 PLANESIDE CPlane::ClassifyPoint 79 PLANESIDE CPlane::ClassifyPoint(const CVector3D &point) const 80 80 { 81 float Dist ;81 float Dist = DistanceToPlane(point); 82 82 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) 91 84 return PS_FRONT; 92 else if (Dist < - EPS)85 else if (Dist < -m_EPS) 93 86 return PS_BACK; 94 87 95 88 return PS_ON; … … 97 90 98 91 //calculates the intersection point of a line with this 99 92 //plane. Returns false if there is no intersection 100 bool CPlane::FindLineSegIntersection (const CVector3D &start, const CVector3D &end, CVector3D *intsect)93 bool CPlane::FindLineSegIntersection(const CVector3D &start, const CVector3D &end, CVector3D *intsect) const 101 94 { 102 95 float dist1 = DistanceToPlane( start ); 103 96 float dist2 = DistanceToPlane( end ); … … 111 104 return true; 112 105 } 113 106 114 bool CPlane::FindRayIntersection (const CVector3D &start, const CVector3D &direction, CVector3D *intsect)107 bool CPlane::FindRayIntersection(const CVector3D &start, const CVector3D &direction, CVector3D *intsect) const 115 108 { 116 109 float dot = m_Norm.Dot (direction); 117 110 if (dot == 0.0f) 118 111 return false; 119 112 120 *intsect = start - (direction * (DistanceToPlane 113 *intsect = start - (direction * (DistanceToPlane(start)/dot)); 121 114 return true; 122 115 } -
source/maths/Plane.h
38 38 class CPlane 39 39 { 40 40 public: 41 CPlane 42 CPlane 41 CPlane(); 42 CPlane(const CVector4D& coeffs) : m_Norm(coeffs.X, coeffs.Y, coeffs.Z), m_Dist(coeffs.W) { } 43 43 44 44 //sets the plane equation from 3 points on that plane 45 void Set 45 void Set(const CVector3D &p1, const CVector3D &p2, const CVector3D &p3); 46 46 47 47 //sets the plane equation from a normal and a point on 48 48 //that plane 49 void Set 49 void Set(const CVector3D &norm, const CVector3D &point); 50 50 51 51 //normalizes the plane equation 52 52 void Normalize (); 53 53 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; 57 58 58 59 //solves the plane equation for a particular point 59 inline float DistanceToPlane 60 inline float DistanceToPlane(const CVector3D &point) const; 60 61 61 62 //calculates the intersection point of a line with this 62 63 //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; 65 66 66 67 public: 67 68 CVector3D m_Norm; //normal vector of the plane 68 69 float m_Dist; //Plane distance (ie D in the plane eq.) 70 static const float m_EPS; 69 71 }; 70 72 71 73 float CPlane::DistanceToPlane (const CVector3D &point) const 72 74 { 73 float Dist; 75 return m_Norm.X * point.X + m_Norm.Y * point.Y + m_Norm.Z * point.Z + m_Dist; 76 } 74 77 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; 78 bool CPlane::IsPointOnBackSide(const CVector3D &point) const 79 { 80 return DistanceToPlane(point) < -m_EPS; 81 81 } 82 82 83 83 #endif -
source/renderer/WaterManager.cpp
908 908 909 909 for (size_t a = 0; a < m_ShoreWaves.size(); ++a) 910 910 { 911 if (!frustrum.IsBoxVisible( CVector3D(0,0,0),m_ShoreWaves[a]->m_AABB))911 if (!frustrum.IsBoxVisible(m_ShoreWaves[a]->m_AABB)) 912 912 continue; 913 913 914 914 CVertexBuffer::VBChunk* VBchunk = m_ShoreWaves[a]->m_VBvertices; -
source/simulation2/components/CCmpProjectileManager.cpp
335 335 336 336 model.ValidatePosition(); 337 337 338 if (culling && !frustum.IsBoxVisible( CVector3D(0, 0, 0),model.GetWorldBoundsRec()))338 if (culling && !frustum.IsBoxVisible(model.GetWorldBoundsRec())) 339 339 continue; 340 340 341 341 // TODO: do something about LOS (copy from CCmpVisualActor) -
source/simulation2/components/CCmpUnitRenderer.cpp
430 430 unit.lastTransformFrame = m_FrameNumber; 431 431 } 432 432 433 if (culling && !frustum.IsBoxVisible( CVector3D(0, 0, 0),unitModel.GetWorldBoundsRec()))433 if (culling && !frustum.IsBoxVisible(unitModel.GetWorldBoundsRec())) 434 434 continue; 435 435 436 436 collector.SubmitRecursive(&unitModel);