Fix foliage instance bounds calculations regression from 486781661e
Using matrix transformation doesn't work properly on some foliage. Add `BoundingSphere.Transform` with `Transform` instead of `Matrix`
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
#include "BoundingBox.h"
|
||||
#include "Matrix.h"
|
||||
#include "Ray.h"
|
||||
#include "Transform.h"
|
||||
#include "../Types/String.h"
|
||||
|
||||
const BoundingSphere BoundingSphere::Empty(Vector3(0, 0, 0), 0);
|
||||
@@ -220,3 +221,9 @@ void BoundingSphere::Transform(const BoundingSphere& sphere, const Matrix& matri
|
||||
Vector3::Transform(sphere.Center, matrix, result.Center);
|
||||
result.Radius = sphere.Radius * matrix.GetScaleVector().GetAbsolute().MaxValue();
|
||||
}
|
||||
|
||||
void BoundingSphere::Transform(const BoundingSphere& sphere, const ::Transform& transform, BoundingSphere& result)
|
||||
{
|
||||
Vector3::Transform(sphere.Center, transform, result.Center);
|
||||
result.Radius = sphere.Radius * transform.Scale.GetAbsolute().MaxValue();
|
||||
}
|
||||
|
||||
@@ -393,6 +393,30 @@ namespace FlaxEngine
|
||||
result.Radius = sphere.Radius * matrix.ScaleVector.Absolute.MaxValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transforms the bounding sphere using the specified transformation.
|
||||
/// </summary>
|
||||
/// <param name="sphere">The sphere.</param>
|
||||
/// <param name="transform">The transform.</param>
|
||||
/// <remarks>The result transformed sphere.</remarks>
|
||||
public static BoundingSphere Transform(BoundingSphere sphere, Transform transform)
|
||||
{
|
||||
Transform(ref sphere, ref transform, out var result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transforms the bounding sphere using the specified transformation.
|
||||
/// </summary>
|
||||
/// <param name="sphere">The sphere.</param>
|
||||
/// <param name="transform">The transform.</param>
|
||||
/// <param name="result">The result transformed sphere.</param>
|
||||
public static void Transform(ref BoundingSphere sphere, ref Transform transform, out BoundingSphere result)
|
||||
{
|
||||
Vector3.Transform(ref sphere.Center, ref transform, out result.Center);
|
||||
result.Radius = sphere.Radius * transform.Scale.Absolute.MaxValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests for equality between two objects.
|
||||
/// </summary>
|
||||
|
||||
@@ -224,6 +224,14 @@ public:
|
||||
/// <param name="matrix">The matrix.</param>
|
||||
/// <param name="result">The result transformed sphere.</param>
|
||||
static void Transform(const BoundingSphere& sphere, const Matrix& matrix, BoundingSphere& result);
|
||||
|
||||
/// <summary>
|
||||
/// Transforms the bounding sphere using the specified transformation.
|
||||
/// </summary>
|
||||
/// <param name="sphere">The sphere.</param>
|
||||
/// <param name="transform">The transform.</param>
|
||||
/// <param name="result">The result transformed sphere.</param>
|
||||
static void Transform(const BoundingSphere& sphere, const ::Transform& transform, BoundingSphere& result);
|
||||
};
|
||||
|
||||
template<>
|
||||
|
||||
@@ -653,7 +653,7 @@ void Foliage::UpdateBounds()
|
||||
typeBounds.Resize(FoliageTypes.Count());
|
||||
for (int32 i = 0; i < typeBounds.Count(); i++)
|
||||
{
|
||||
auto& type = FoliageTypes[i];
|
||||
const auto& type = FoliageTypes[i];
|
||||
bool ready = type.IsReady();
|
||||
typeReady.Set(i, ready);
|
||||
if (ready)
|
||||
@@ -661,16 +661,14 @@ void Foliage::UpdateBounds()
|
||||
}
|
||||
|
||||
// Update bounds for all instances
|
||||
Matrix foliageWorld, instanceLocal, instanceWorld;
|
||||
GetLocalToWorldMatrix(foliageWorld);
|
||||
Transform globalTransform = _transform, transform;
|
||||
for (auto i = Instances.Begin(); i.IsNotEnd(); ++i)
|
||||
{
|
||||
auto& instance = *i;
|
||||
if (typeReady.Get(instance.Type))
|
||||
{
|
||||
instance.Transform.GetWorld(instanceLocal);
|
||||
Matrix::Multiply(foliageWorld, instanceLocal, instanceWorld);
|
||||
BoundingSphere::Transform(typeBounds[instance.Type], instanceWorld, instance.Bounds);
|
||||
globalTransform.LocalToWorld(instance.Transform, transform);
|
||||
BoundingSphere::Transform(typeBounds[instance.Type], transform, instance.Bounds);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -837,11 +835,8 @@ void Foliage::SetInstanceTransform(int32 index, const Transform& value)
|
||||
{
|
||||
BoundingSphere typeBounds;
|
||||
BoundingSphere::FromBox(type.Model->GetBox(), typeBounds);
|
||||
Matrix foliageWorld, instanceLocal, instanceWorld;
|
||||
GetLocalToWorldMatrix(foliageWorld);
|
||||
instance.Transform.GetWorld(instanceLocal);
|
||||
Matrix::Multiply(foliageWorld, instanceLocal, instanceWorld);
|
||||
BoundingSphere::Transform(typeBounds, instanceWorld, instance.Bounds);
|
||||
const Transform transform = _transform.LocalToWorld(instance.Transform);
|
||||
BoundingSphere::Transform(typeBounds, transform, instance.Bounds);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -868,8 +863,7 @@ void Foliage::OnFoliageTypeModelLoaded(int32 index)
|
||||
|
||||
BoundingSphere typeBounds;
|
||||
BoundingSphere::FromBox(type.Model->GetBox(), typeBounds);
|
||||
Matrix foliageWorld, instanceLocal, instanceWorld;
|
||||
GetLocalToWorldMatrix(foliageWorld);
|
||||
Transform globalTransform = _transform, transform;
|
||||
|
||||
for (auto i = Instances.Begin(); i.IsNotEnd(); ++i)
|
||||
{
|
||||
@@ -877,9 +871,8 @@ void Foliage::OnFoliageTypeModelLoaded(int32 index)
|
||||
if (instance.Type != index)
|
||||
continue;
|
||||
|
||||
instance.Transform.GetWorld(instanceLocal);
|
||||
Matrix::Multiply(foliageWorld, instanceLocal, instanceWorld);
|
||||
BoundingSphere::Transform(typeBounds, instanceWorld, instance.Bounds);
|
||||
globalTransform.LocalToWorld(instance.Transform, transform);
|
||||
BoundingSphere::Transform(typeBounds, transform, instance.Bounds);
|
||||
|
||||
#if !FOLIAGE_USE_SINGLE_QUAD_TREE
|
||||
BoundingBox::FromSphere(instance.Bounds, box);
|
||||
|
||||
Reference in New Issue
Block a user