Add support for Large Worlds in more engine systems

This commit is contained in:
Wojtek Figat
2022-07-02 20:07:04 +02:00
parent 85fe22d7a7
commit 33513834df
18 changed files with 398 additions and 188 deletions

View File

@@ -341,6 +341,7 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=subresource/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=subresources/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=taskbar/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Teleport/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=texcoord/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=texcoords/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=texel/@EntryIndexedValue">True</s:Boolean>

View File

@@ -41,8 +41,7 @@ namespace FlaxEditor.Gizmo
_materialAxisZ == null ||
_materialAxisFocus == null ||
_materialWire == null ||
_materialWireFocus == null
)
_materialWireFocus == null)
{
// Error
Platform.Fatal("Failed to load transform gizmo resources.");
@@ -56,13 +55,12 @@ namespace FlaxEditor.Gizmo
return;
Matrix m1, m2, m3;
bool isXAxis = _activeAxis == Axis.X || _activeAxis == Axis.XY || _activeAxis == Axis.ZX;
bool isYAxis = _activeAxis == Axis.Y || _activeAxis == Axis.XY || _activeAxis == Axis.YZ;
bool isZAxis = _activeAxis == Axis.Z || _activeAxis == Axis.YZ || _activeAxis == Axis.ZX;
bool isCenter = _activeAxis == Axis.Center;
renderContext.View.GetWorldMatrix(ref _gizmoWorld, out Matrix world);
// Switch mode
const float gizmoModelsScale2RealGizmoSize = 0.075f;
switch (_activeMode)
{
@@ -71,7 +69,7 @@ namespace FlaxEditor.Gizmo
if (!_modelTranslateAxis || !_modelTranslateAxis.IsLoaded || !_modelBox || !_modelBox.IsLoaded)
break;
Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m3);
Matrix.Multiply(ref m3, ref _gizmoWorld, out m1);
Matrix.Multiply(ref m3, ref world, out m1);
var axisMesh = _modelTranslateAxis.LODs[0].Meshes[0];
var boxMesh = _modelBox.LODs[0].Meshes[0];
var boxSize = 10.0f;
@@ -114,7 +112,7 @@ namespace FlaxEditor.Gizmo
var circleMesh = _modelCircle.LODs[0].Meshes[0];
var boxMesh = _modelBox.LODs[0].Meshes[0];
Matrix.Scaling(8.0f, out m3);
Matrix.Multiply(ref m3, ref _gizmoWorld, out m1);
Matrix.Multiply(ref m3, ref world, out m1);
// X axis
Matrix.RotationZ(Mathf.PiOverTwo, out m2);
@@ -131,7 +129,7 @@ namespace FlaxEditor.Gizmo
// Center box
Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m3);
Matrix.Multiply(ref m3, ref _gizmoWorld, out m1);
Matrix.Multiply(ref m3, ref world, out m1);
Matrix.Scaling(1.0f, out m2);
Matrix.Multiply(ref m2, ref m1, out m3);
boxMesh.Draw(ref renderContext, isCenter ? _materialWireFocus : _materialWire, ref m3);
@@ -144,7 +142,7 @@ namespace FlaxEditor.Gizmo
if (!_modelScaleAxis || !_modelScaleAxis.IsLoaded || !_modelBox || !_modelBox.IsLoaded)
break;
Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m3);
Matrix.Multiply(ref m3, ref _gizmoWorld, out m1);
Matrix.Multiply(ref m3, ref world, out m1);
var axisMesh = _modelScaleAxis.LODs[0].Meshes[0];
var boxMesh = _modelBox.LODs[0].Meshes[0];

View File

@@ -52,9 +52,8 @@ namespace FlaxEditor.Gizmo
// Transform ray into local space of the gizmo
Ray localRay;
Matrix.Invert(ref _gizmoWorld, out Matrix invGizmoWorld);
Vector3.TransformNormal(ref ray.Direction, ref invGizmoWorld, out localRay.Direction);
Vector3.Transform(ref ray.Position, ref invGizmoWorld, out localRay.Position);
_gizmoWorld.WorldToLocalVector(ref ray.Direction, out localRay.Direction);
_gizmoWorld.WorldToLocal(ref ray.Position, out localRay.Position);
// Find gizmo collisions with mouse
Real closestIntersection = Real.MaxValue;

View File

@@ -36,9 +36,7 @@ namespace FlaxEditor.Gizmo
protected BoundingBox _startBounds = BoundingBox.Empty;
private Vector3 _accMoveDelta;
private Matrix _axisAlignedWorld = Matrix.Identity;
private Matrix _gizmoWorld = Matrix.Identity;
private Transform _gizmoWorld = Transform.Identity;
private Vector3 _intersectPosition;
private bool _isActive;
private bool _isDuplicating;
@@ -46,19 +44,11 @@ namespace FlaxEditor.Gizmo
private bool _isTransforming;
private Vector3 _lastIntersectionPosition;
private Vector3 _localForward = Vector3.Forward;
private Vector3 _localRight = Vector3.Right;
private Vector3 _localUp = Vector3.Up;
private Matrix _objectOrientedWorld = Matrix.Identity;
private Quaternion _rotationDelta = Quaternion.Identity;
private Matrix _rotationMatrix;
private float _rotationSnapDelta;
private Vector3 _scaleDelta;
private float _screenScale;
private Matrix _screenScaleMatrix;
private Vector3 _tDelta;
private Vector3 _translationDelta;
private Vector3 _translationScaleSnapDelta;
@@ -170,43 +160,17 @@ namespace FlaxEditor.Gizmo
UpdateGizmoPosition();
// Scale gizmo to fit on-screen
Vector3 vLength = Owner.ViewPosition - Position;
Vector3 position = Position;
Vector3 vLength = Owner.ViewPosition - position;
float gizmoSize = Editor.Instance.Options.Options.Visual.GizmoSize;
_screenScale = (float)(vLength.Length / GizmoScaleFactor * gizmoSize);
Matrix.Scaling(_screenScale, out _screenScaleMatrix);
// Setup world
Quaternion orientation = GetSelectedObject(0).Orientation;
Matrix.RotationQuaternion(ref orientation, out Matrix rotation);
_localForward = rotation.Forward;
_localUp = rotation.Up;
// Vector Rotation (Local/World)
_localForward.Normalize();
Vector3.Cross(ref _localForward, ref _localUp, out _localRight);
Vector3.Cross(ref _localRight, ref _localForward, out _localUp);
_localRight.Normalize();
_localUp.Normalize();
// Create both world matrices
_objectOrientedWorld = _screenScaleMatrix * Matrix.CreateWorld(Position, _localForward, _localUp);
_axisAlignedWorld = _screenScaleMatrix * Matrix.CreateWorld(Position, Vector3.Backward, Vector3.Up);
// Assign world
_gizmoWorld = new Transform(position, orientation, new Float3(_screenScale));
if (_activeTransformSpace == TransformSpace.World && _activeMode != Mode.Scale)
{
_gizmoWorld = _axisAlignedWorld;
// Align lines, boxes etc. with the grid-lines
_rotationMatrix = Matrix.Identity;
}
else
{
_gizmoWorld = _objectOrientedWorld;
// Align lines, boxes etc. with the selected object
_rotationMatrix.Forward = _localForward;
_rotationMatrix.Up = _localUp;
_rotationMatrix.Right = _localRight;
_gizmoWorld.Orientation = Quaternion.Identity;
}
}
@@ -216,7 +180,8 @@ namespace FlaxEditor.Gizmo
Vector3 delta = Vector3.Zero;
Ray ray = Owner.MouseRay;
Matrix.Invert(ref _rotationMatrix, out var invRotationMatrix);
Matrix.RotationQuaternion(ref _gizmoWorld.Orientation, out var rotationMatrix);
Matrix.Invert(ref rotationMatrix, out var invRotationMatrix);
ray.Position = Vector3.Transform(ray.Position, invRotationMatrix);
Vector3.TransformNormal(ref ray.Direction, ref invRotationMatrix, out ray.Direction);
@@ -334,7 +299,7 @@ namespace FlaxEditor.Gizmo
if (_activeMode == Mode.Translate)
{
// Transform (local or world)
delta = Vector3.Transform(delta, _rotationMatrix);
delta = Vector3.Transform(delta, rotationMatrix);
_translationDelta = delta;
}
else if (_activeMode == Mode.Scale)
@@ -369,11 +334,11 @@ namespace FlaxEditor.Gizmo
{
Float3 dir;
if (_activeAxis == Axis.X)
dir = _rotationMatrix.Right;
dir = Float3.Right * _gizmoWorld.Orientation;
else if (_activeAxis == Axis.Y)
dir = _rotationMatrix.Up;
dir = Float3.Up * _gizmoWorld.Orientation;
else
dir = _rotationMatrix.Forward;
dir = Float3.Forward * _gizmoWorld.Orientation;
Float3 viewDir = Owner.ViewPosition - Position;
Float3.Dot(ref viewDir, ref dir, out float dot);

View File

@@ -151,6 +151,16 @@ namespace FlaxEngine
corners.AddRange(GetCorners());
}
/// <summary>
/// Transforms this box using a transformation.
/// </summary>
/// <param name="transform">The transformation.</param>
/// <remarks>While any kind of transformation can be applied, it is recommended to apply scaling using scale method instead, which scales the Extents and keeps the Transformation for rotation only, and that preserves collision detection accuracy.</remarks>
public void Transform(ref Transform transform)
{
Transformation = transform.LocalToWorld(Transformation);
}
/// <summary>
/// Transforms this box using a transformation matrix.
/// </summary>
@@ -425,6 +435,20 @@ namespace FlaxEngine
return result;
}
/// <summary>
/// Transforms bounding box using the given transformation.
/// </summary>
/// <param name="box">The bounding box to transform.</param>
/// <param name="transform">The transformation.</param>
/// <returns>The result of the transformation.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static OrientedBoundingBox operator *(OrientedBoundingBox box, Transform transform)
{
OrientedBoundingBox result = box;
result.Transformation = transform.LocalToWorld(result.Transformation);
return result;
}
/// <summary>
/// Tests for equality between two objects.
/// </summary>

View File

@@ -7,6 +7,7 @@
#include "Quaternion.h"
#include "Matrix.h"
#include "Matrix3x3.h"
#include "Transform.h"
#include "../Types/String.h"
// Float
@@ -214,6 +215,14 @@ Float3 Float3::Transform(const Float3& vector, const Matrix& transform)
vector.X * transform.M13 + vector.Y * transform.M23 + vector.Z * transform.M33 + transform.M43);
}
template<>
Float3 Float3::Transform(const Float3& vector, const ::Transform& transform)
{
Vector3 result;
transform.LocalToWorld(vector, result);
return result;
}
template<>
void Float3::TransformCoordinate(const Float3& coordinate, const Matrix& transform, Float3& result)
{
@@ -508,6 +517,14 @@ Double3 Double3::Transform(const Double3& vector, const Matrix& transform)
vector.X * transform.M13 + vector.Y * transform.M23 + vector.Z * transform.M33 + transform.M43);
}
template<>
Double3 Double3::Transform(const Double3& vector, const ::Transform& transform)
{
Vector3 result;
transform.LocalToWorld(vector, result);
return result;
}
template<>
void Double3::TransformCoordinate(const Double3& coordinate, const Matrix& transform, Double3& result)
{
@@ -748,6 +765,12 @@ Int3 Int3::Transform(const Int3& vector, const Matrix& transform)
return vector;
}
template<>
Int3 Int3::Transform(const Int3& vector, const ::Transform& transform)
{
return vector;
}
template<>
void Int3::TransformCoordinate(const Int3& coordinate, const Matrix& transform, Int3& result)
{

View File

@@ -1432,6 +1432,17 @@ namespace FlaxEngine
vector.X * transform.M14 + vector.Y * transform.M24 + vector.Z * transform.M34 + transform.M44);
}
/// <summary>
/// Transforms a 3D vector by the given <see cref="FlaxEngine.Transform" />.
/// </summary>
/// <param name="vector">The source vector.</param>
/// <param name="transform">The transformation <see cref="FlaxEngine.Transform" />.</param>
/// <param name="result">When the method completes, contains the transformed <see cref="Vector3" />.</param>
public static void Transform(ref Vector3 vector, ref Transform transform, out Vector3 result)
{
transform.LocalToWorld(ref vector, out result);
}
/// <summary>
/// Transforms a 3D vector by the given <see cref="Matrix" />.
/// </summary>
@@ -1444,6 +1455,18 @@ namespace FlaxEngine
return result;
}
/// <summary>
/// Transforms a 3D vector by the given <see cref="FlaxEngine.Transform" />.
/// </summary>
/// <param name="vector">The source vector.</param>
/// <param name="transform">The transformation <see cref="FlaxEngine.Transform" />.</param>
/// <returns>The transformed <see cref="Vector4" />.</returns>
public static Vector3 Transform(Vector3 vector, Transform transform)
{
Transform(ref vector, ref transform, out Vector3 result);
return result;
}
/// <summary>
/// Performs a coordinate transformation using the given <see cref="Matrix" />.
/// </summary>

View File

@@ -712,12 +712,24 @@ public:
// @param result When the method completes, contains the transformed Vector3
static FLAXENGINE_API void Transform(const Vector3Base& vector, const Matrix3x3& transform, Vector3Base& result);
// Transforms a 3D vector by the given transformation
// @param vector The source vector
// @param transform The transformation
// @param result When the method completes, contains the transformed Vector3
static FLAXENGINE_API void Transform(const Vector3Base& vector, const ::Transform& transform, Vector3Base& result);
// Transforms a 3D vector by the given matrix
// @param vector The source vector
// @param transform The transformation matrix
// @returns Transformed Vector3
static FLAXENGINE_API Vector3Base Transform(const Vector3Base& vector, const Matrix& transform);
// Transforms a 3D vector by the given transformation
// @param vector The source vector
// @param transform The transformation
// @returns Transformed Vector3
static FLAXENGINE_API Vector3Base Transform(const Vector3Base& vector, const ::Transform& transform);
// Transforms a 3D vector by the given matrix
// @param vector The source vector
// @param transform The transformation matrix

View File

@@ -191,6 +191,41 @@ void UpdateList(float dt, Array<T>& list)
}
}
void TeleportList(const Float3& delta, Array<DebugLine>& list)
{
for (auto& l : list)
{
l.Start += delta;
l.End += delta;
}
}
void TeleportList(const Float3& delta, Array<Vertex>& list)
{
for (auto& v : list)
{
v.Position += delta;
}
}
void TeleportList(const Float3& delta, Array<DebugTriangle>& list)
{
for (auto& v : list)
{
v.V0 += delta;
v.V1 += delta;
v.V2 += delta;
}
}
void TeleportList(const Float3& delta, Array<DebugText3D>& list)
{
for (auto& v : list)
{
v.Transform.Translation += delta;
}
}
struct DebugDrawData
{
Array<DebugLine> DefaultLines;
@@ -255,6 +290,18 @@ struct DebugDrawData
OneFrameText3D.Clear();
}
void Teleport(const Float3& delta)
{
TeleportList(delta, DefaultLines);
TeleportList(delta, OneFrameLines);
TeleportList(delta, DefaultTriangles);
TeleportList(delta, OneFrameTriangles);
TeleportList(delta, DefaultWireTriangles);
TeleportList(delta, OneFrameWireTriangles);
TeleportList(delta, DefaultText3D);
TeleportList(delta, OneFrameText3D);
}
inline void Clear()
{
DefaultLines.Clear();
@@ -286,6 +333,7 @@ struct DebugDrawData
struct DebugDrawContext
{
Vector3 Origin = Vector3::Zero;
DebugDrawData DebugDrawDefault;
DebugDrawData DebugDrawDepthTest;
Float3 LastViewPos = Float3::Zero;
@@ -670,6 +718,14 @@ void DebugDraw::Draw(RenderContext& renderContext, GPUTextureView* target, GPUTe
if (renderContext.Buffers == nullptr || !DebugDrawVB)
return;
auto context = GPUDevice::Instance->GetMainContext();
if (Context->Origin != renderContext.View.Origin)
{
// Teleport existing debug shapes to maintain their location
Float3 delta = Context->Origin - renderContext.View.Origin;
Context->DebugDrawDefault.Teleport(delta);
Context->DebugDrawDepthTest.Teleport(delta);
Context->Origin = renderContext.View.Origin;
}
Context->LastViewPos = renderContext.View.Position;
Context->LastViewProj = renderContext.View.Projection;
@@ -858,17 +914,18 @@ void DebugDraw::DrawActors(Actor** selectedActors, int32 selectedActorsCount, bo
void DebugDraw::DrawLine(const Vector3& start, const Vector3& end, const Color& color, float duration, bool depthTest)
{
const Float3 startF = start - Context->Origin, endF = end - Context->Origin;
auto& debugDrawData = depthTest ? Context->DebugDrawDepthTest : Context->DebugDrawDefault;
if (duration > 0)
{
DebugLine l = { start, end, Color32(color), duration };
DebugLine l = { startF, endF, Color32(color), duration };
debugDrawData.DefaultLines.Add(l);
}
else
{
Vertex l = { start, Color32(color) };
Vertex l = { startF, Color32(color) };
debugDrawData.OneFrameLines.Add(l);
l.Position = end;
l.Position = endF;
debugDrawData.OneFrameLines.Add(l);
}
}
@@ -886,14 +943,15 @@ void DebugDraw::DrawLines(const Span<Float3>& lines, const Matrix& transform, co
// Draw lines
const Float3* p = lines.Get();
auto& debugDrawData = depthTest ? Context->DebugDrawDepthTest : Context->DebugDrawDefault;
const Matrix transformF = transform * Matrix::Translation(-Context->Origin);
if (duration > 0)
{
DebugLine l = { Float3::Zero, Float3::Zero, Color32(color), duration };
debugDrawData.DefaultLines.EnsureCapacity(debugDrawData.DefaultLines.Count() + lines.Length());
for (int32 i = 0; i < lines.Length(); i += 2)
{
Float3::Transform(*p++, transform, l.Start);
Float3::Transform(*p++, transform, l.End);
Float3::Transform(*p++, transformF, l.Start);
Float3::Transform(*p++, transformF, l.End);
debugDrawData.DefaultLines.Add(l);
}
}
@@ -903,9 +961,9 @@ void DebugDraw::DrawLines(const Span<Float3>& lines, const Matrix& transform, co
debugDrawData.OneFrameLines.EnsureCapacity(debugDrawData.OneFrameLines.Count() + lines.Length() * 2);
for (int32 i = 0; i < lines.Length(); i += 2)
{
Float3::Transform(*p++, transform, l.Position);
Float3::Transform(*p++, transformF, l.Position);
debugDrawData.OneFrameLines.Add(l);
Float3::Transform(*p++, transform, l.Position);
Float3::Transform(*p++, transformF, l.Position);
debugDrawData.OneFrameLines.Add(l);
}
}
@@ -929,14 +987,15 @@ void DebugDraw::DrawLines(const Span<Double3>& lines, const Matrix& transform, c
// Draw lines
const Double3* p = lines.Get();
auto& debugDrawData = depthTest ? Context->DebugDrawDepthTest : Context->DebugDrawDefault;
const Matrix transformF = transform * Matrix::Translation(-Context->Origin);
if (duration > 0)
{
DebugLine l = { Float3::Zero, Float3::Zero, Color32(color), duration };
debugDrawData.DefaultLines.EnsureCapacity(debugDrawData.DefaultLines.Count() + lines.Length());
for (int32 i = 0; i < lines.Length(); i += 2)
{
Float3::Transform(*p++, transform, l.Start);
Float3::Transform(*p++, transform, l.End);
Float3::Transform(*p++, transformF, l.Start);
Float3::Transform(*p++, transformF, l.End);
debugDrawData.DefaultLines.Add(l);
}
}
@@ -946,9 +1005,9 @@ void DebugDraw::DrawLines(const Span<Double3>& lines, const Matrix& transform, c
debugDrawData.OneFrameLines.EnsureCapacity(debugDrawData.OneFrameLines.Count() + lines.Length() * 2);
for (int32 i = 0; i < lines.Length(); i += 2)
{
Float3::Transform(*p++, transform, l.Position);
Float3::Transform(*p++, transformF, l.Position);
debugDrawData.OneFrameLines.Add(l);
Float3::Transform(*p++, transform, l.Position);
Float3::Transform(*p++, transformF, l.Position);
debugDrawData.OneFrameLines.Add(l);
}
}
@@ -961,25 +1020,27 @@ void DebugDraw::DrawLines(const Array<Double3, HeapAllocation>& lines, const Mat
void DebugDraw::DrawBezier(const Vector3& p1, const Vector3& p2, const Vector3& p3, const Vector3& p4, const Color& color, float duration, bool depthTest)
{
const Float3 p1F = p1 - Context->Origin, p2F = p2 - Context->Origin, p3F = p3 - Context->Origin, p4F = p4 - Context->Origin;
// Find amount of segments to use
const Vector3 d1 = p2 - p1;
const Vector3 d2 = p3 - p2;
const Vector3 d3 = p4 - p3;
const Real len = d1.Length() + d2.Length() + d3.Length();
const int32 segmentCount = Math::Clamp(Math::CeilToInt((float)len * 0.05f), 1, 100);
const Float3 d1 = p2F - p1F;
const Float3 d2 = p3F - p2F;
const Float3 d3 = p4F - p3F;
const float len = d1.Length() + d2.Length() + d3.Length();
const int32 segmentCount = Math::Clamp(Math::CeilToInt(len * 0.05f), 1, 100);
const float segmentCountInv = 1.0f / (float)segmentCount;
// Draw segmented curve from lines
auto& debugDrawData = depthTest ? Context->DebugDrawDepthTest : Context->DebugDrawDefault;
if (duration > 0)
{
DebugLine l = { p1, Float3::Zero, Color32(color), duration };
DebugLine l = { p1F, Float3::Zero, Color32(color), duration };
debugDrawData.DefaultLines.EnsureCapacity(debugDrawData.DefaultLines.Count() + segmentCount + 2);
for (int32 i = 0; i <= segmentCount; i++)
{
const float t = (float)i * segmentCountInv;
Vector3 end;
AnimationUtils::Bezier(p1, p2, p3, p4, t, end);
Float3 end;
AnimationUtils::Bezier(p1F, p2F, p3F, p4F, t, end);
l.End = end;
debugDrawData.DefaultLines.Add(l);
l.Start = l.End;
@@ -987,14 +1048,14 @@ void DebugDraw::DrawBezier(const Vector3& p1, const Vector3& p2, const Vector3&
}
else
{
Vertex l = { p1, Color32(color) };
Vertex l = { p1F, Color32(color) };
debugDrawData.OneFrameLines.EnsureCapacity(debugDrawData.OneFrameLines.Count() + segmentCount * 2 + 4);
for (int32 i = 0; i <= segmentCount; i++)
{
const float t = (float)i * segmentCountInv;
debugDrawData.OneFrameLines.Add(l);
Vector3 position;
AnimationUtils::Bezier(p1, p2, p3, p4, t, position);
Float3 position;
AnimationUtils::Bezier(p1F, p2F, p3F, p4F, t, position);
l.Position = position;
debugDrawData.OneFrameLines.Add(l);
}
@@ -1004,8 +1065,10 @@ void DebugDraw::DrawBezier(const Vector3& p1, const Vector3& p2, const Vector3&
void DebugDraw::DrawWireBox(const BoundingBox& box, const Color& color, float duration, bool depthTest)
{
// Get corners
Float3 corners[8];
Vector3 corners[8];
box.GetCorners(corners);
for (Vector3& c : corners)
c -= Context->Origin;
// Draw lines
auto& debugDrawData = depthTest ? Context->DebugDrawDepthTest : Context->DebugDrawDefault;
@@ -1036,8 +1099,10 @@ void DebugDraw::DrawWireBox(const BoundingBox& box, const Color& color, float du
void DebugDraw::DrawWireFrustum(const BoundingFrustum& frustum, const Color& color, float duration, bool depthTest)
{
// Get corners
Float3 corners[8];
Vector3 corners[8];
frustum.GetCorners(corners);
for (Vector3& c : corners)
c -= Context->Origin;
// Draw lines
auto& debugDrawData = depthTest ? Context->DebugDrawDepthTest : Context->DebugDrawDefault;
@@ -1068,8 +1133,10 @@ void DebugDraw::DrawWireFrustum(const BoundingFrustum& frustum, const Color& col
void DebugDraw::DrawWireBox(const OrientedBoundingBox& box, const Color& color, float duration, bool depthTest)
{
// Get corners
Float3 corners[8];
Vector3 corners[8];
box.GetCorners(corners);
for (Vector3& c : corners)
c -= Context->Origin;
// Draw lines
auto& debugDrawData = depthTest ? Context->DebugDrawDepthTest : Context->DebugDrawDefault;
@@ -1101,7 +1168,9 @@ void DebugDraw::DrawWireSphere(const BoundingSphere& sphere, const Color& color,
{
// Select LOD
int32 index;
const float screenRadiusSquared = RenderTools::ComputeBoundsScreenRadiusSquared(sphere.Center, (float)sphere.Radius, Context->LastViewPos, Context->LastViewProj);
const Float3 centerF = sphere.Center - Context->Origin;
const float radiusF = (float)sphere.Radius;
const float screenRadiusSquared = RenderTools::ComputeBoundsScreenRadiusSquared(centerF, radiusF, Context->LastViewPos, Context->LastViewProj);
if (screenRadiusSquared > DEBUG_DRAW_SPHERE_LOD0_SCREEN_SIZE * DEBUG_DRAW_SPHERE_LOD0_SCREEN_SIZE * 0.25f)
index = 0;
else if (screenRadiusSquared > DEBUG_DRAW_SPHERE_LOD1_SCREEN_SIZE * DEBUG_DRAW_SPHERE_LOD1_SCREEN_SIZE * 0.25f)
@@ -1117,8 +1186,8 @@ void DebugDraw::DrawWireSphere(const BoundingSphere& sphere, const Color& color,
DebugLine l = { Float3::Zero, Float3::Zero, Color32(color), duration };
for (int32 i = 0; i < cache.Vertices.Count();)
{
l.Start = sphere.Center + cache.Vertices.Get()[i++] * sphere.Radius;
l.End = sphere.Center + cache.Vertices.Get()[i++] * sphere.Radius;
l.Start = centerF + cache.Vertices.Get()[i++] * radiusF;
l.End = centerF + cache.Vertices.Get()[i++] * radiusF;
debugDrawData.DefaultLines.Add(l);
}
}
@@ -1127,9 +1196,9 @@ void DebugDraw::DrawWireSphere(const BoundingSphere& sphere, const Color& color,
Vertex l = { Float3::Zero, Color32(color) };
for (int32 i = 0; i < cache.Vertices.Count();)
{
l.Position = sphere.Center + cache.Vertices.Get()[i++] * sphere.Radius;
l.Position = centerF + cache.Vertices.Get()[i++] * radiusF;
debugDrawData.OneFrameLines.Add(l);
l.Position = sphere.Center + cache.Vertices.Get()[i++] * sphere.Radius;
l.Position = centerF + cache.Vertices.Get()[i++] * radiusF;
debugDrawData.OneFrameLines.Add(l);
}
}
@@ -1148,16 +1217,18 @@ void DebugDraw::DrawSphere(const BoundingSphere& sphere, const Color& color, flo
list = duration > 0 ? &Context->DebugDrawDefault.DefaultTriangles : &Context->DebugDrawDefault.OneFrameTriangles;
list->EnsureCapacity(list->Count() + SphereTriangleCache.Count());
const Float3 centerF = sphere.Center - Context->Origin;
const float radiusF = (float)sphere.Radius;
for (int32 i = 0; i < SphereTriangleCache.Count();)
{
t.V0 = sphere.Center + SphereTriangleCache[i++] * sphere.Radius;
t.V1 = sphere.Center + SphereTriangleCache[i++] * sphere.Radius;
t.V2 = sphere.Center + SphereTriangleCache[i++] * sphere.Radius;
t.V0 = centerF + SphereTriangleCache[i++] * radiusF;
t.V1 = centerF + SphereTriangleCache[i++] * radiusF;
t.V2 = centerF + SphereTriangleCache[i++] * radiusF;
list->Add(t);
}
}
void DebugDraw::DrawCircle(const Vector3& position, const Vector3& normal, float radius, const Color& color, float duration, bool depthTest)
void DebugDraw::DrawCircle(const Vector3& position, const Float3& normal, float radius, const Color& color, float duration, bool depthTest)
{
// Create matrix transform for unit circle points
Matrix world, scale, matrix;
@@ -1170,15 +1241,28 @@ void DebugDraw::DrawCircle(const Vector3& position, const Vector3& normal, float
Float3::Cross(normal, Float3::Up, right);
Float3::Cross(right, normal, up);
Matrix::Scaling(radius, scale);
Matrix::CreateWorld(position, normal, up, world);
const Float3 positionF = position - Context->Origin;
Matrix::CreateWorld(positionF, normal, up, world);
Matrix::Multiply(scale, world, matrix);
// Draw lines of the unit circle after linear transform
Float3 prev = Float3::Transform(CircleCache[0], matrix);
auto& debugDrawData = depthTest ? Context->DebugDrawDepthTest : Context->DebugDrawDefault;
for (int32 i = 1; i < DEBUG_DRAW_CIRCLE_VERTICES;)
{
Float3 cur = Float3::Transform(CircleCache[i++], matrix);
DrawLine(prev, cur, color, duration, depthTest);
if (duration > 0)
{
DebugLine l = { prev, cur, Color32(color), duration };
debugDrawData.DefaultLines.Add(l);
}
else
{
Vertex l = { prev, Color32(color) };
debugDrawData.OneFrameLines.Add(l);
l.Position = cur;
debugDrawData.OneFrameLines.Add(l);
}
prev = cur;
}
}
@@ -1195,18 +1279,13 @@ void DebugDraw::DrawTriangle(const Vector3& v0, const Vector3& v1, const Vector3
DebugTriangle t;
t.Color = Color32(color);
t.TimeLeft = duration;
t.V0 = v0;
t.V1 = v1;
t.V2 = v2;
t.V0 = v0 - Context->Origin;
t.V1 = v1 - Context->Origin;
t.V2 = v2 - Context->Origin;
if (depthTest)
{
Context->DebugDrawDepthTest.Add(t);
}
else
{
Context->DebugDrawDefault.Add(t);
}
}
void DebugDraw::DrawTriangles(const Span<Float3>& vertices, const Color& color, float duration, bool depthTest)
@@ -1216,11 +1295,12 @@ void DebugDraw::DrawTriangles(const Span<Float3>& vertices, const Color& color,
t.Color = Color32(color);
t.TimeLeft = duration;
auto dst = AppendTriangles(vertices.Length() / 3, duration, depthTest);
const Float3 origin = Context->Origin;
for (int32 i = 0; i < vertices.Length();)
{
t.V0 = vertices.Get()[i++];
t.V1 = vertices.Get()[i++];
t.V2 = vertices.Get()[i++];
t.V0 = vertices.Get()[i++] - origin;
t.V1 = vertices.Get()[i++] - origin;
t.V2 = vertices.Get()[i++] - origin;
*dst++ = t;
}
}
@@ -1232,11 +1312,12 @@ void DebugDraw::DrawTriangles(const Span<Float3>& vertices, const Matrix& transf
t.Color = Color32(color);
t.TimeLeft = duration;
auto dst = AppendTriangles(vertices.Length() / 3, duration, depthTest);
const Matrix transformF = transform * Matrix::Translation(-Context->Origin);
for (int32 i = 0; i < vertices.Length();)
{
Float3::Transform(vertices.Get()[i++], transform, t.V0);
Float3::Transform(vertices.Get()[i++], transform, t.V1);
Float3::Transform(vertices.Get()[i++], transform, t.V2);
Float3::Transform(vertices.Get()[i++], transformF, t.V0);
Float3::Transform(vertices.Get()[i++], transformF, t.V1);
Float3::Transform(vertices.Get()[i++], transformF, t.V2);
*dst++ = t;
}
}
@@ -1258,11 +1339,12 @@ void DebugDraw::DrawTriangles(const Span<Float3>& vertices, const Span<int32>& i
t.Color = Color32(color);
t.TimeLeft = duration;
auto dst = AppendTriangles(indices.Length() / 3, duration, depthTest);
const Float3 origin = Context->Origin;
for (int32 i = 0; i < indices.Length();)
{
t.V0 = vertices[indices.Get()[i++]];
t.V1 = vertices[indices.Get()[i++]];
t.V2 = vertices[indices.Get()[i++]];
t.V0 = vertices[indices.Get()[i++]] - origin;
t.V1 = vertices[indices.Get()[i++]] - origin;
t.V2 = vertices[indices.Get()[i++]] - origin;
*dst++ = t;
}
}
@@ -1274,11 +1356,12 @@ void DebugDraw::DrawTriangles(const Span<Float3>& vertices, const Span<int32>& i
t.Color = Color32(color);
t.TimeLeft = duration;
auto dst = AppendTriangles(indices.Length() / 3, duration, depthTest);
const Matrix transformF = transform * Matrix::Translation(-Context->Origin);
for (int32 i = 0; i < indices.Length();)
{
Float3::Transform(vertices[indices.Get()[i++]], transform, t.V0);
Float3::Transform(vertices[indices.Get()[i++]], transform, t.V1);
Float3::Transform(vertices[indices.Get()[i++]], transform, t.V2);
Float3::Transform(vertices[indices.Get()[i++]], transformF, t.V0);
Float3::Transform(vertices[indices.Get()[i++]], transformF, t.V1);
Float3::Transform(vertices[indices.Get()[i++]], transformF, t.V2);
*dst++ = t;
}
}
@@ -1300,11 +1383,12 @@ void DebugDraw::DrawTriangles(const Span<Double3>& vertices, const Color& color,
t.Color = Color32(color);
t.TimeLeft = duration;
auto dst = AppendTriangles(vertices.Length() / 3, duration, depthTest);
const Double3 origin = Context->Origin;
for (int32 i = 0; i < vertices.Length();)
{
t.V0 = vertices.Get()[i++];
t.V1 = vertices.Get()[i++];
t.V2 = vertices.Get()[i++];
t.V0 = vertices.Get()[i++] - origin;
t.V1 = vertices.Get()[i++] - origin;
t.V2 = vertices.Get()[i++] - origin;
*dst++ = t;
}
}
@@ -1316,11 +1400,12 @@ void DebugDraw::DrawTriangles(const Span<Double3>& vertices, const Matrix& trans
t.Color = Color32(color);
t.TimeLeft = duration;
auto dst = AppendTriangles(vertices.Length() / 3, duration, depthTest);
const Matrix transformF = transform * Matrix::Translation(-Context->Origin);
for (int32 i = 0; i < vertices.Length();)
{
Float3::Transform(vertices.Get()[i++], transform, t.V0);
Float3::Transform(vertices.Get()[i++], transform, t.V1);
Float3::Transform(vertices.Get()[i++], transform, t.V2);
Float3::Transform(vertices.Get()[i++], transformF, t.V0);
Float3::Transform(vertices.Get()[i++], transformF, t.V1);
Float3::Transform(vertices.Get()[i++], transformF, t.V2);
*dst++ = t;
}
}
@@ -1342,11 +1427,12 @@ void DebugDraw::DrawTriangles(const Span<Double3>& vertices, const Span<int32>&
t.Color = Color32(color);
t.TimeLeft = duration;
auto dst = AppendTriangles(indices.Length() / 3, duration, depthTest);
const Double3 origin = Context->Origin;
for (int32 i = 0; i < indices.Length();)
{
t.V0 = vertices[indices.Get()[i++]];
t.V1 = vertices[indices.Get()[i++]];
t.V2 = vertices[indices.Get()[i++]];
t.V0 = vertices[indices.Get()[i++]] - origin;
t.V1 = vertices[indices.Get()[i++]] - origin;
t.V2 = vertices[indices.Get()[i++]] - origin;
*dst++ = t;
}
}
@@ -1358,11 +1444,12 @@ void DebugDraw::DrawTriangles(const Span<Double3>& vertices, const Span<int32>&
t.Color = Color32(color);
t.TimeLeft = duration;
auto dst = AppendTriangles(indices.Length() / 3, duration, depthTest);
const Matrix transformF = transform * Matrix::Translation(-Context->Origin);
for (int32 i = 0; i < indices.Length();)
{
Float3::Transform(vertices[indices.Get()[i++]], transform, t.V0);
Float3::Transform(vertices[indices.Get()[i++]], transform, t.V1);
Float3::Transform(vertices[indices.Get()[i++]], transform, t.V2);
Float3::Transform(vertices[indices.Get()[i++]], transformF, t.V0);
Float3::Transform(vertices[indices.Get()[i++]], transformF, t.V1);
Float3::Transform(vertices[indices.Get()[i++]], transformF, t.V2);
*dst++ = t;
}
}
@@ -1384,11 +1471,12 @@ void DebugDraw::DrawWireTriangles(const Span<Float3>& vertices, const Color& col
t.Color = Color32(color);
t.TimeLeft = duration;
auto dst = AppendTriangles(vertices.Length() / 3, duration, depthTest);
const Float3 origin = Context->Origin;
for (int32 i = 0; i < vertices.Length();)
{
t.V0 = vertices.Get()[i++];
t.V1 = vertices.Get()[i++];
t.V2 = vertices.Get()[i++];
t.V0 = vertices.Get()[i++] - origin;
t.V1 = vertices.Get()[i++] - origin;
t.V2 = vertices.Get()[i++] - origin;
*dst++ = t;
}
}
@@ -1405,11 +1493,12 @@ void DebugDraw::DrawWireTriangles(const Span<Float3>& vertices, const Span<int32
t.Color = Color32(color);
t.TimeLeft = duration;
auto dst = AppendTriangles(indices.Length() / 3, duration, depthTest);
const Float3 origin = Context->Origin;
for (int32 i = 0; i < indices.Length();)
{
t.V0 = vertices[indices.Get()[i++]];
t.V1 = vertices[indices.Get()[i++]];
t.V2 = vertices[indices.Get()[i++]];
t.V0 = vertices[indices.Get()[i++]] - origin;
t.V1 = vertices[indices.Get()[i++]] - origin;
t.V2 = vertices[indices.Get()[i++]] - origin;
*dst++ = t;
}
}
@@ -1426,11 +1515,12 @@ void DebugDraw::DrawWireTriangles(const Span<Double3>& vertices, const Color& co
t.Color = Color32(color);
t.TimeLeft = duration;
auto dst = AppendTriangles(vertices.Length() / 3, duration, depthTest);
const Double3 origin = Context->Origin;
for (int32 i = 0; i < vertices.Length();)
{
t.V0 = vertices.Get()[i++];
t.V1 = vertices.Get()[i++];
t.V2 = vertices.Get()[i++];
t.V0 = vertices.Get()[i++] - origin;
t.V1 = vertices.Get()[i++] - origin;
t.V2 = vertices.Get()[i++] - origin;
*dst++ = t;
}
}
@@ -1447,11 +1537,12 @@ void DebugDraw::DrawWireTriangles(const Span<Double3>& vertices, const Span<int3
t.Color = Color32(color);
t.TimeLeft = duration;
auto dst = AppendTriangles(indices.Length() / 3, duration, depthTest);
const Double3 origin = Context->Origin;
for (int32 i = 0; i < indices.Length();)
{
t.V0 = vertices[indices.Get()[i++]];
t.V1 = vertices[indices.Get()[i++]];
t.V2 = vertices[indices.Get()[i++]];
t.V0 = vertices[indices.Get()[i++]] - origin;
t.V1 = vertices[indices.Get()[i++]] - origin;
t.V2 = vertices[indices.Get()[i++]] - origin;
*dst++ = t;
}
}
@@ -1497,50 +1588,97 @@ void DebugDraw::DrawWireTube(const Vector3& position, const Quaternion& orientat
const float halfLength = length / 2.0f;
Matrix rotation, translation, world;
Matrix::RotationQuaternion(orientation, rotation);
Matrix::Translation(position, translation);
const Float3 positionF = position - Context->Origin;
Matrix::Translation(positionF, translation);
Matrix::Multiply(rotation, translation, world);
// Write vertices
#define DRAW_WIRE_BOX_LINE(x1, y1, z1, x2, y2, z2) DrawLine(Float3::Transform(Float3(x1, y1, z1), world), Float3::Transform(Float3(x2, y2, z2), world), color, duration, depthTest)
for (float a = 0.0f; a < TWO_PI; a += step)
auto& debugDrawData = depthTest ? Context->DebugDrawDepthTest : Context->DebugDrawDefault;
Color32 color32(color);
if (duration > 0)
{
// Calculate sines and cosines
// TODO: optimize this stuff
float sinA = Math::Sin(a) * radius;
float cosA = Math::Cos(a) * radius;
float sinB = Math::Sin(a + step) * radius;
float cosB = Math::Cos(a + step) * radius;
// First XY loop
DRAW_WIRE_BOX_LINE(cosA, sinA, -halfLength, cosB, sinB, -halfLength);
// Second loop
DRAW_WIRE_BOX_LINE(cosA, sinA, halfLength, cosB, sinB, halfLength);
if (a >= PI)
#define DRAW_WIRE_BOX_LINE(x1, y1, z1, x2, y2, z2) debugDrawData.DefaultLines.Add({ Float3::Transform(Float3(x1, y1, z1), world), Float3::Transform(Float3(x2, y2, z2), world), color32, duration });
for (float a = 0.0f; a < TWO_PI; a += step)
{
// First XZ loop
DRAW_WIRE_BOX_LINE(cosA, 0, sinA - halfLength, cosB, 0, sinB - halfLength);
// Calculate sines and cosines
float sinA = Math::Sin(a) * radius;
float cosA = Math::Cos(a) * radius;
float sinB = Math::Sin(a + step) * radius;
float cosB = Math::Cos(a + step) * radius;
// First YZ loop
DRAW_WIRE_BOX_LINE(0, cosA, sinA - halfLength, 0, cosB, sinB - halfLength);
// First XY loop
DRAW_WIRE_BOX_LINE(cosA, sinA, -halfLength, cosB, sinB, -halfLength);
// Second loop
DRAW_WIRE_BOX_LINE(cosA, sinA, halfLength, cosB, sinB, halfLength);
if (a >= PI)
{
// First XZ loop
DRAW_WIRE_BOX_LINE(cosA, 0, sinA - halfLength, cosB, 0, sinB - halfLength);
// First YZ loop
DRAW_WIRE_BOX_LINE(0, cosA, sinA - halfLength, 0, cosB, sinB - halfLength);
}
else
{
// Second XZ loop
DRAW_WIRE_BOX_LINE(cosA, 0, sinA + halfLength, cosB, 0, sinB + halfLength);
// Second YZ loop
DRAW_WIRE_BOX_LINE(0, cosA, sinA + halfLength, 0, cosB, sinB + halfLength);
}
// Connection
if (Math::NearEqual(sinA, radius) || Math::NearEqual(cosA, radius) || Math::NearEqual(sinA, -radius) || Math::NearEqual(cosA, -radius))
{
DRAW_WIRE_BOX_LINE(cosA, sinA, -halfLength, cosA, sinA, halfLength);
}
}
else
#undef DRAW_WIRE_BOX_LINE
}
else
{
#define DRAW_WIRE_BOX_LINE(x1, y1, z1, x2, y2, z2) debugDrawData.OneFrameLines.Add({ Float3::Transform(Float3(x1, y1, z1), world), color32 }); debugDrawData.OneFrameLines.Add({ Float3::Transform(Float3(x2, y2, z2), world), color32 });
for (float a = 0.0f; a < TWO_PI; a += step)
{
// Second XZ loop
DRAW_WIRE_BOX_LINE(cosA, 0, sinA + halfLength, cosB, 0, sinB + halfLength);
// Calculate sines and cosines
float sinA = Math::Sin(a) * radius;
float cosA = Math::Cos(a) * radius;
float sinB = Math::Sin(a + step) * radius;
float cosB = Math::Cos(a + step) * radius;
// Second YZ loop
DRAW_WIRE_BOX_LINE(0, cosA, sinA + halfLength, 0, cosB, sinB + halfLength);
}
// First XY loop
DRAW_WIRE_BOX_LINE(cosA, sinA, -halfLength, cosB, sinB, -halfLength);
// Connection
if (Math::NearEqual(sinA, radius) || Math::NearEqual(cosA, radius) || Math::NearEqual(sinA, -radius) || Math::NearEqual(cosA, -radius))
{
DRAW_WIRE_BOX_LINE(cosA, sinA, -halfLength, cosA, sinA, halfLength);
// Second loop
DRAW_WIRE_BOX_LINE(cosA, sinA, halfLength, cosB, sinB, halfLength);
if (a >= PI)
{
// First XZ loop
DRAW_WIRE_BOX_LINE(cosA, 0, sinA - halfLength, cosB, 0, sinB - halfLength);
// First YZ loop
DRAW_WIRE_BOX_LINE(0, cosA, sinA - halfLength, 0, cosB, sinB - halfLength);
}
else
{
// Second XZ loop
DRAW_WIRE_BOX_LINE(cosA, 0, sinA + halfLength, cosB, 0, sinB + halfLength);
// Second YZ loop
DRAW_WIRE_BOX_LINE(0, cosA, sinA + halfLength, 0, cosB, sinB + halfLength);
}
// Connection
if (Math::NearEqual(sinA, radius) || Math::NearEqual(cosA, radius) || Math::NearEqual(sinA, -radius) || Math::NearEqual(cosA, -radius))
{
DRAW_WIRE_BOX_LINE(cosA, sinA, -halfLength, cosA, sinA, halfLength);
}
#undef DRAW_WIRE_BOX_LINE
}
}
#undef DRAW_WIRE_BOX_LINE
}
}
@@ -1575,7 +1713,8 @@ namespace
DebugTriangle t;
t.Color = Color32(color);
t.TimeLeft = duration;
const Matrix world = Matrix::RotationQuaternion(orientation) * Matrix::Translation(position);
const Float3 positionF = position - Context->Origin;
const Matrix world = Matrix::RotationQuaternion(orientation) * Matrix::Translation(positionF);
// Write triangles
for (uint32 i = 0; i < DEBUG_DRAW_CYLINDER_VERTICES; i += 4)
@@ -1631,7 +1770,8 @@ namespace
DebugTriangle t;
t.Color = Color32(color);
t.TimeLeft = duration;
const Matrix world = Matrix::RotationQuaternion(orientation) * Matrix::Translation(position);
const Float3 positionF = position - Context->Origin;
const Matrix world = Matrix::RotationQuaternion(orientation) * Matrix::Translation(positionF);
t.V0 = world.GetTranslation();
Float3 vertices[DEBUG_DRAW_CONE_RESOLUTION];
@@ -1716,7 +1856,8 @@ void DebugDraw::DrawArc(const Vector3& position, const Quaternion& orientation,
list = duration > 0 ? &Context->DebugDrawDefault.DefaultTriangles : &Context->DebugDrawDefault.OneFrameTriangles;
const int32 resolution = Math::CeilToInt((float)DEBUG_DRAW_CONE_RESOLUTION / TWO_PI * angle);
const float angleStep = angle / (float)resolution;
const Matrix world = Matrix::RotationQuaternion(orientation) * Matrix::Translation(position);
const Float3 positionF = position - Context->Origin;
const Matrix world = Matrix::RotationQuaternion(orientation) * Matrix::Translation(positionF);
float currentAngle = 0.0f;
DebugTriangle t;
t.Color = Color32(color);
@@ -1742,7 +1883,8 @@ void DebugDraw::DrawWireArc(const Vector3& position, const Quaternion& orientati
angle = TWO_PI;
const int32 resolution = Math::CeilToInt((float)DEBUG_DRAW_CONE_RESOLUTION / TWO_PI * angle);
const float angleStep = angle / (float)resolution;
const Matrix world = Matrix::RotationQuaternion(orientation) * Matrix::Translation(position);
const Float3 positionF = position - Context->Origin;
const Matrix world = Matrix::RotationQuaternion(orientation) * Matrix::Translation(positionF);
float currentAngle = 0.0f;
Float3 prevPos(world.GetTranslation());
if (angle >= TWO_PI)
@@ -1768,8 +1910,8 @@ void DebugDraw::DrawWireArrow(const Vector3& position, const Quaternion& orienta
Float3::Transform(Float3::Forward, orientation, direction);
Float3::Transform(Float3::Up, orientation, up);
Float3::Transform(Float3::Right, orientation, right);
const auto end = position + direction * (100.0f * scale);
const auto capEnd = position + direction * (70.0f * scale);
const Vector3 end = position + direction * (100.0f * scale);
const Vector3 capEnd = position + direction * (70.0f * scale);
const float arrowSidesRatio = scale * 30.0f;
DrawLine(position, end, color, duration, depthTest);
@@ -1782,8 +1924,10 @@ void DebugDraw::DrawWireArrow(const Vector3& position, const Quaternion& orienta
void DebugDraw::DrawBox(const BoundingBox& box, const Color& color, float duration, bool depthTest)
{
// Get corners
Float3 corners[8];
Vector3 corners[8];
box.GetCorners(corners);
for (Vector3& c : corners)
c -= Context->Origin;
// Draw triangles
DebugTriangle t;
@@ -1808,8 +1952,10 @@ void DebugDraw::DrawBox(const BoundingBox& box, const Color& color, float durati
void DebugDraw::DrawBox(const OrientedBoundingBox& box, const Color& color, float duration, bool depthTest)
{
// Get corners
Float3 corners[8];
Vector3 corners[8];
box.GetCorners(corners);
for (Vector3& c : corners)
c -= Context->Origin;
// Draw triangles
DebugTriangle t;
@@ -1855,7 +2001,7 @@ void DebugDraw::DrawText(const StringView& text, const Vector3& position, const
t.Text.Resize(text.Length() + 1);
Platform::MemoryCopy(t.Text.Get(), text.Get(), text.Length() * sizeof(Char));
t.Text[text.Length()] = 0;
t.Transform = position;
t.Transform = position - Context->Origin;
t.FaceCamera = true;
t.Size = size;
t.Color = color;
@@ -1872,6 +2018,7 @@ void DebugDraw::DrawText(const StringView& text, const Transform& transform, con
Platform::MemoryCopy(t.Text.Get(), text.Get(), text.Length() * sizeof(Char));
t.Text[text.Length()] = 0;
t.Transform = transform;
t.Transform.Translation -= Context->Origin;
t.FaceCamera = false;
t.Size = size;
t.Color = color;

View File

@@ -140,7 +140,7 @@ API_CLASS(Static) class FLAXENGINE_API DebugDraw
/// <param name="color">The color.</param>
/// <param name="duration">The duration (in seconds). Use 0 to draw it only once.</param>
/// <param name="depthTest">If set to <c>true</c> depth test will be performed, otherwise depth will be ignored.</param>
API_FUNCTION() static void DrawCircle(const Vector3& position, const Vector3& normal, float radius, const Color& color, float duration = 0.0f, bool depthTest = true);
API_FUNCTION() static void DrawCircle(const Vector3& position, const Float3& normal, float radius, const Color& color, float duration = 0.0f, bool depthTest = true);
/// <summary>
/// Draws the wireframe triangle.

View File

@@ -201,6 +201,6 @@ DrawPass RenderView::GetShadowsDrawPassMask(ShadowsCastingMode shadowsMode) cons
void RenderView::GetWorldMatrix(const Transform& transform, Matrix& world) const
{
const Vector3 translation = transform.Translation - Origin;
const Float3 translation = transform.Translation - Origin;
Matrix::Transformation(transform.Scale, transform.Orientation, translation, world);
}

View File

@@ -103,5 +103,16 @@ namespace FlaxEngine
UpdateCachedData();
}
/// <summary>
/// Calculates the world matrix for the given transformation instance rendering.
/// </summary>
/// <param name="transform">The object transformation.</param>
/// <param name="world">The output matrix.</param>
public void GetWorldMatrix(ref Transform transform, out Matrix world)
{
Float3 translation = transform.Translation - Origin;
Matrix.Transformation(ref transform.Scale, ref transform.Orientation, ref translation, out world);
}
}
}

View File

@@ -23,7 +23,8 @@ AnimatedModel::AnimatedModel(const SpawnParams& params)
, _lastUpdateFrame(0)
{
GraphInstance.Object = this;
UpdateBounds();
_box = _boxLocal = BoundingBox(Vector3::Zero);
_sphere = BoundingSphere(Vector3::Zero, 0.0f);
SkinnedModel.Changed.Bind<AnimatedModel, &AnimatedModel::OnSkinnedModelChanged>(this);
SkinnedModel.Loaded.Bind<AnimatedModel, &AnimatedModel::OnSkinnedModelLoaded>(this);
@@ -709,7 +710,7 @@ void AnimatedModel::Draw(RenderContext& renderContext)
const DrawPass drawModes = (DrawPass)(DrawModes & renderContext.View.Pass & (int32)renderContext.View.GetShadowsDrawPassMask(ShadowsMode));
if (SkinnedModel && SkinnedModel->IsLoaded() && drawModes != DrawPass::None)
{
_lastMinDstSqr = Math::Min(_lastMinDstSqr, Vector3::DistanceSquared(GetPosition(), renderContext.View.Position));
_lastMinDstSqr = Math::Min(_lastMinDstSqr, Vector3::DistanceSquared(_transform.Translation, renderContext.View.Position + renderContext.View.Origin));
if (_skinningData.IsReady())
{
@@ -729,6 +730,7 @@ void AnimatedModel::Draw(RenderContext& renderContext)
draw.DrawState = &_drawState;
draw.DrawModes = drawModes;
draw.Bounds = _sphere;
draw.Bounds.Center -= renderContext.View.Origin;
draw.PerInstanceRandom = GetPerInstanceRandom();
draw.LODBias = LODBias;
draw.ForcedLOD = ForcedLOD;

View File

@@ -27,7 +27,8 @@ void BoxCollider::SetSize(const Float3& value)
void BoxCollider::DrawPhysicsDebug(RenderView& view)
{
if (!view.CullingFrustum.Intersects(_sphere))
const BoundingSphere sphere(_sphere.Center - view.Origin, _sphere.Radius);
if (!view.CullingFrustum.Intersects(sphere))
return;
if (view.Mode == ViewMode::PhysicsColliders && !GetIsTrigger())
DebugDraw::DrawBox(_bounds, _staticActor ? Color::CornflowerBlue : Color::Orchid, 0, true);

View File

@@ -39,7 +39,8 @@ void CapsuleCollider::SetHeight(const float value)
void CapsuleCollider::DrawPhysicsDebug(RenderView& view)
{
if (!view.CullingFrustum.Intersects(_sphere))
const BoundingSphere sphere(_sphere.Center - view.Origin, _sphere.Radius);
if (!view.CullingFrustum.Intersects(sphere))
return;
Quaternion rot;
Quaternion::Multiply(_transform.Orientation, Quaternion::Euler(0, 90, 0), rot);

View File

@@ -69,7 +69,8 @@ void MeshCollider::DrawPhysicsDebug(RenderView& view)
{
if (CollisionData && CollisionData->IsLoaded())
{
if (!view.CullingFrustum.Intersects(_sphere))
const BoundingSphere sphere(_sphere.Center - view.Origin, _sphere.Radius);
if (!view.CullingFrustum.Intersects(sphere))
return;
if (view.Mode == ViewMode::PhysicsColliders && !GetIsTrigger())
{

View File

@@ -27,7 +27,8 @@ void SphereCollider::SetRadius(const float value)
void SphereCollider::DrawPhysicsDebug(RenderView& view)
{
if (!view.CullingFrustum.Intersects(_sphere))
const BoundingSphere sphere(_sphere.Center - view.Origin, _sphere.Radius);
if (!view.CullingFrustum.Intersects(sphere))
return;
if (view.Mode == ViewMode::PhysicsColliders && !GetIsTrigger())
DebugDraw::DrawSphere(_sphere, _staticActor ? Color::CornflowerBlue : Color::Orchid, 0, true);

View File

@@ -88,7 +88,8 @@ bool SplineCollider::CanBeTrigger() const
void SplineCollider::DrawPhysicsDebug(RenderView& view)
{
if (!view.CullingFrustum.Intersects(_sphere))
const BoundingSphere sphere(_sphere.Center - view.Origin, _sphere.Radius);
if (!view.CullingFrustum.Intersects(sphere))
return;
if (view.Mode == ViewMode::PhysicsColliders && !GetIsTrigger())
DebugDraw::DrawTriangles(_vertexBuffer, _indexBuffer, Color::CornflowerBlue, 0, true);