Improve object vis with tighter bounding spheres
This commit improves rendering performance by doing a better job of checking whether an object is visible via its bounding sphere or not. The engine maintains a bounding box for each EngineBaseObject that's exactly large enough to fit every vertex. From this, it computes a bounding sphere, and only draws objects if the sphere is within the view frustum. Previously, the bounding sphere was always centered on the EngineBaseObject's origin, even for models where the bounding box center is significantly offset from the origin. Now, the bounding sphere is always the tightest sphere which fits the bounding box.1008-fix
parent
fdf67b8217
commit
282a793a13
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue