Merge pull request #1149 from AbigailBuccaneer/tighter-visibility-checking

Improve object visibility culling with tighter bounding spheres
1008-fix
krzys_h 2018-05-07 20:53:00 +02:00 committed by GitHub
commit f146d2885b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 16 additions and 11 deletions

View File

@ -765,7 +765,7 @@ void CEngine::AddBaseObjTriangles(int baseObjRank, const std::vector<VertexTex2>
p1.bboxMax.z = Math::Max(vertices[i].coord.z, p1.bboxMax.z);
}
p1.radius = Math::Max(p1.bboxMin.Length(), p1.bboxMax.Length());
p1.boundingSphere = Math::BoundingSphereForBox(p1.bboxMin, p1.bboxMax);
p1.totalTriangles += vertices.size() / 3;
}
@ -801,7 +801,7 @@ void CEngine::AddBaseObjQuick(int baseObjRank, const EngineBaseObjDataTier& buff
p1.bboxMax.z = Math::Max(p3.vertices[i].coord.z, p1.bboxMax.z);
}
p1.radius = Math::Max(p1.bboxMin.Length(), p1.bboxMax.Length());
p1.boundingSphere = Math::BoundingSphereForBox(p1.bboxMin, p1.bboxMax);
}
if (p3.type == ENG_TRIANGLE_TYPE_TRIANGLES)
@ -856,7 +856,7 @@ void CEngine::DebugObject(int objRank)
vecStr = p1.bboxMax.ToString();
l->Debug(" bboxMax: %s\n", vecStr.c_str());
l->Debug(" totalTriangles: %d\n", p1.totalTriangles);
l->Debug(" radius: %f\n", p1.radius);
l->Debug(" radius: %f\n", p1.boundingSphere.radius);
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
{
@ -1659,7 +1659,6 @@ void CEngine::UpdateGeometry()
p1.bboxMin.LoadZero();
p1.bboxMax.LoadZero();
p1.radius = 0;
for (int l2 = 0; l2 < static_cast<int>( p1.next.size() ); l2++)
{
@ -1678,10 +1677,10 @@ void CEngine::UpdateGeometry()
p1.bboxMax.y = Math::Max(p3.vertices[i].coord.y, p1.bboxMax.y);
p1.bboxMax.z = Math::Max(p3.vertices[i].coord.z, p1.bboxMax.z);
}
p1.radius = Math::Max(p1.bboxMin.Length(), p1.bboxMax.Length());
}
}
p1.boundingSphere = Math::BoundingSphereForBox(p1.bboxMin, p1.bboxMax);
}
m_updateGeometry = false;
@ -1925,9 +1924,8 @@ bool CEngine::IsVisible(int objRank)
assert(baseObjRank >= 0 && baseObjRank < static_cast<int>(m_baseObjects.size()));
float radius = m_baseObjects[baseObjRank].radius;
Math::Vector center(0.0f, 0.0f, 0.0f);
if (m_device->ComputeSphereVisibility(center, radius) == Gfx::FRUSTUM_PLANE_ALL)
const auto& sphere = m_baseObjects[baseObjRank].boundingSphere;
if (m_device->ComputeSphereVisibility(sphere.pos, sphere.radius) == Gfx::FRUSTUM_PLANE_ALL)
{
m_objects[objRank].visible = true;
return true;

View File

@ -246,8 +246,8 @@ struct EngineBaseObject
Math::Vector bboxMin;
//! bounding box max (origin 0,0,0 always included)
Math::Vector bboxMax;
//! Radius of the sphere at the origin
float radius = 0.0f;
//! A bounding sphere that contains all the vertices in this EngineBaseObject
Math::Sphere boundingSphere;
//! Next tier (Tex)
std::vector<EngineBaseObjTexTier> next;

View File

@ -44,4 +44,11 @@ inline float DistanceBetweenSpheres(const Sphere& sphere1, const Sphere& sphere2
return Math::Distance(sphere1.pos, sphere2.pos) - sphere1.radius - sphere2.radius;
}
inline Sphere BoundingSphereForBox(Vector mins, Vector maxs)
{
auto centroid = (maxs + mins) / 2.0f;
auto halfExtent = (maxs - centroid);
return Sphere{centroid, halfExtent.Length()};
}
} // namespace Math