Add support for Large Worlds in more engine systems
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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];
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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())
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user