Updated transform Gizmos #340

This commit is contained in:
W2.Wizard
2023-02-16 15:23:18 +01:00
committed by Wojtek Figat
parent 969053a240
commit f8aa1cd5f8
14 changed files with 224 additions and 142 deletions

BIN
Content/Editor/Gizmo/Axis.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Editor/Gizmo/MaterialSphere.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Gizmo/RotationAxis.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Gizmo/ScaleAxis.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Editor/Gizmo/TranslateAxis.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Editor/Gizmo/TranslationAxis.flax (Stored with Git LFS) Normal file

Binary file not shown.

BIN
Content/Editor/Gizmo/WireCircle.flax (Stored with Git LFS)

Binary file not shown.

View File

@@ -3,7 +3,7 @@
"Version": { "Version": {
"Major": 1, "Major": 1,
"Minor": 5, "Minor": 5,
"Build": 6336 "Build": 6337
}, },
"Company": "Flax", "Company": "Flax",
"Copyright": "Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.", "Copyright": "Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.",

View File

@@ -6,44 +6,48 @@ namespace FlaxEditor.Gizmo
{ {
public partial class TransformGizmoBase public partial class TransformGizmoBase
{ {
private Model _modelTranslateAxis; // Models
private Model _modelTranslationAxis;
private Model _modelScaleAxis; private Model _modelScaleAxis;
private Model _modelBox; private Model _modelRotationAxis;
private Model _modelCircle; private Model _modelSphere;
private Model _modelCube;
// Materials
private MaterialInstance _materialAxisX; private MaterialInstance _materialAxisX;
private MaterialInstance _materialAxisY; private MaterialInstance _materialAxisY;
private MaterialInstance _materialAxisZ; private MaterialInstance _materialAxisZ;
private MaterialInstance _materialAxisFocus; private MaterialInstance _materialAxisFocus;
private MaterialBase _materialWire; private MaterialBase _materialSphere;
private MaterialBase _materialWireFocus;
private void InitDrawing() private void InitDrawing()
{ {
// Load content (but async - don't wait and don't block execution) // Axis Models
_modelTranslateAxis = FlaxEngine.Content.LoadAsyncInternal<Model>("Editor/Gizmo/TranslateAxis"); _modelTranslationAxis = FlaxEngine.Content.LoadAsyncInternal<Model>("Editor/Gizmo/TranslationAxis");
_modelScaleAxis = FlaxEngine.Content.LoadAsyncInternal<Model>("Editor/Gizmo/ScaleAxis"); _modelScaleAxis = FlaxEngine.Content.LoadAsyncInternal<Model>("Editor/Gizmo/ScaleAxis");
_modelBox = FlaxEngine.Content.LoadAsyncInternal<Model>("Editor/Gizmo/WireBox"); _modelRotationAxis = FlaxEngine.Content.LoadAsyncInternal<Model>("Editor/Gizmo/RotationAxis");
_modelCircle = FlaxEngine.Content.LoadAsyncInternal<Model>("Editor/Gizmo/WireCircle"); _modelSphere = FlaxEngine.Content.LoadAsyncInternal<Model>("Editor/Primitives/Sphere");
_modelCube = FlaxEngine.Content.LoadAsyncInternal<Model>("Editor/Primitives/Cube");
// Axis Materials
_materialAxisX = FlaxEngine.Content.LoadAsyncInternal<MaterialInstance>("Editor/Gizmo/MaterialAxisX"); _materialAxisX = FlaxEngine.Content.LoadAsyncInternal<MaterialInstance>("Editor/Gizmo/MaterialAxisX");
_materialAxisY = FlaxEngine.Content.LoadAsyncInternal<MaterialInstance>("Editor/Gizmo/MaterialAxisY"); _materialAxisY = FlaxEngine.Content.LoadAsyncInternal<MaterialInstance>("Editor/Gizmo/MaterialAxisY");
_materialAxisZ = FlaxEngine.Content.LoadAsyncInternal<MaterialInstance>("Editor/Gizmo/MaterialAxisZ"); _materialAxisZ = FlaxEngine.Content.LoadAsyncInternal<MaterialInstance>("Editor/Gizmo/MaterialAxisZ");
_materialAxisFocus = FlaxEngine.Content.LoadAsyncInternal<MaterialInstance>("Editor/Gizmo/MaterialAxisFocus"); _materialAxisFocus = FlaxEngine.Content.LoadAsyncInternal<MaterialInstance>("Editor/Gizmo/MaterialAxisFocus");
_materialWire = FlaxEngine.Content.LoadAsyncInternal<MaterialBase>("Editor/Gizmo/MaterialWire"); _materialSphere = FlaxEngine.Content.LoadAsyncInternal<MaterialInstance>("Editor/Gizmo/MaterialSphere");
_materialWireFocus = FlaxEngine.Content.LoadAsyncInternal<MaterialBase>("Editor/Gizmo/MaterialWireFocus");
// Ensure that every asset was loaded // Ensure that every asset was loaded
if (_modelTranslateAxis == null || if (_modelTranslationAxis == null ||
_modelScaleAxis == null || _modelScaleAxis == null ||
_modelBox == null || _modelRotationAxis == null ||
_modelCircle == null || _modelSphere == null ||
_modelCube == null ||
_materialAxisX == null || _materialAxisX == null ||
_materialAxisY == null || _materialAxisY == null ||
_materialAxisZ == null || _materialAxisZ == null ||
_materialAxisFocus == null || _materialAxisFocus == null ||
_materialWire == null || _materialSphere == null)
_materialWireFocus == null)
{ {
// Error
Platform.Fatal("Failed to load transform gizmo resources."); Platform.Fatal("Failed to load transform gizmo resources.");
} }
} }
@@ -58,6 +62,8 @@ namespace FlaxEditor.Gizmo
// https://github.com/FlaxEngine/FlaxEngine/issues/680 // https://github.com/FlaxEngine/FlaxEngine/issues/680
Matrix m1, m2, m3, mx1; Matrix m1, m2, m3, mx1;
float boxScale = 300f;
float boxSize = 0.085f;
bool isXAxis = _activeAxis == Axis.X || _activeAxis == Axis.XY || _activeAxis == Axis.ZX; bool isXAxis = _activeAxis == Axis.X || _activeAxis == Axis.XY || _activeAxis == Axis.ZX;
bool isYAxis = _activeAxis == Axis.Y || _activeAxis == Axis.XY || _activeAxis == Axis.YZ; bool isYAxis = _activeAxis == Axis.Y || _activeAxis == Axis.XY || _activeAxis == Axis.YZ;
bool isZAxis = _activeAxis == Axis.Z || _activeAxis == Axis.YZ || _activeAxis == Axis.ZX; bool isZAxis = _activeAxis == Axis.Z || _activeAxis == Axis.YZ || _activeAxis == Axis.ZX;
@@ -65,114 +71,137 @@ namespace FlaxEditor.Gizmo
renderContext.View.GetWorldMatrix(ref _gizmoWorld, out Matrix world); renderContext.View.GetWorldMatrix(ref _gizmoWorld, out Matrix world);
const float gizmoModelsScale2RealGizmoSize = 0.075f; const float gizmoModelsScale2RealGizmoSize = 0.075f;
Mesh sphereMesh, cubeMesh;
switch (_activeMode) switch (_activeMode)
{ {
case Mode.Translate: case Mode.Translate:
{ {
if (!_modelTranslateAxis || !_modelTranslateAxis.IsLoaded || !_modelBox || !_modelBox.IsLoaded) if (!_modelTranslationAxis || !_modelTranslationAxis.IsLoaded || !_modelCube || !_modelCube.IsLoaded || !_modelSphere || !_modelSphere.IsLoaded)
break; break;
var transAxisMesh = _modelTranslationAxis.LODs[0].Meshes[0];
cubeMesh = _modelCube.LODs[0].Meshes[0];
sphereMesh = _modelSphere.LODs[0].Meshes[0];
Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m3); Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m3);
Matrix.Multiply(ref m3, ref world, out m1); Matrix.Multiply(ref m3, ref world, out m1);
mx1 = m1; mx1 = m1;
mx1.M41 += 0.05f; mx1.M41 += 0.05f;
var axisMesh = _modelTranslateAxis.LODs[0].Meshes[0];
var boxMesh = _modelBox.LODs[0].Meshes[0];
var boxSize = 10.0f;
// XY plane
m2 = Matrix.Transformation(new Vector3(boxSize, 1.0f, boxSize), Quaternion.RotationX(Mathf.PiOverTwo), new Vector3(boxSize * 0.5f, boxSize * 0.5f, 0.0f));
Matrix.Multiply(ref m2, ref m1, out m3);
boxMesh.Draw(ref renderContext, _activeAxis == Axis.XY ? _materialWireFocus : _materialWire, ref m3);
// ZX plane
m2 = Matrix.Transformation(new Vector3(boxSize, 1.0f, boxSize), Quaternion.Identity, new Vector3(boxSize * 0.5f, 0.0f, boxSize * 0.5f));
Matrix.Multiply(ref m2, ref m1, out m3);
boxMesh.Draw(ref renderContext, _activeAxis == Axis.ZX ? _materialWireFocus : _materialWire, ref m3);
// YZ plane
m2 = Matrix.Transformation(new Vector3(boxSize, 1.0f, boxSize), Quaternion.RotationZ(Mathf.PiOverTwo), new Vector3(0.0f, boxSize * 0.5f, boxSize * 0.5f));
Matrix.Multiply(ref m2, ref m1, out m3);
boxMesh.Draw(ref renderContext, _activeAxis == Axis.YZ ? _materialWireFocus : _materialWire, ref m3);
// X axis // X axis
axisMesh.Draw(ref renderContext, isXAxis ? _materialAxisFocus : _materialAxisX, ref mx1);
// Y axis
Matrix.RotationZ(Mathf.PiOverTwo, out m2);
Matrix.Multiply(ref m2, ref m1, out m3);
axisMesh.Draw(ref renderContext, isYAxis ? _materialAxisFocus : _materialAxisY, ref m3);
// Z axis
Matrix.RotationY(-Mathf.PiOverTwo, out m2); Matrix.RotationY(-Mathf.PiOverTwo, out m2);
Matrix.Multiply(ref m2, ref m1, out m3); Matrix.Multiply(ref m2, ref m1, out m3);
axisMesh.Draw(ref renderContext, isZAxis ? _materialAxisFocus : _materialAxisZ, ref m3); transAxisMesh.Draw(ref renderContext, isXAxis ? _materialAxisFocus : _materialAxisX, ref m3);
// Y axis
Matrix.RotationX(Mathf.PiOverTwo, out m2);
Matrix.Multiply(ref m2, ref m1, out m3);
transAxisMesh.Draw(ref renderContext, isYAxis ? _materialAxisFocus : _materialAxisY, ref m3);
// Z axis
Matrix.RotationX(Mathf.Pi, out m2);
Matrix.Multiply(ref m2, ref m1, out m3);
transAxisMesh.Draw(ref renderContext, isZAxis ? _materialAxisFocus : _materialAxisZ, ref m3);
// XY plane
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationX(Mathf.PiOverTwo), new Vector3(boxSize * boxScale, boxSize * boxScale, 0.0f));
Matrix.Multiply(ref m2, ref m1, out m3);
cubeMesh.Draw(ref renderContext, _activeAxis == Axis.XY ? _materialAxisFocus : _materialAxisX, ref m3);
// ZX plane
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.Identity, new Vector3(boxSize * boxScale, 0.0f, boxSize * boxScale));
Matrix.Multiply(ref m2, ref m1, out m3);
cubeMesh.Draw(ref renderContext, _activeAxis == Axis.ZX ? _materialAxisFocus : _materialAxisZ, ref m3);
// YZ plane
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationZ(Mathf.PiOverTwo), new Vector3(0.0f, boxSize * boxScale, boxSize * boxScale));
Matrix.Multiply(ref m2, ref m1, out m3);
cubeMesh.Draw(ref renderContext, _activeAxis == Axis.YZ ? _materialAxisFocus : _materialAxisY, ref m3);
// Center sphere
Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m2);
Matrix.Multiply(ref m2, ref m1, out m3);
sphereMesh.Draw(ref renderContext, isCenter ? _materialAxisFocus : _materialSphere, ref m3);
break; break;
} }
case Mode.Rotate: case Mode.Rotate:
{ {
if (!_modelCircle || !_modelCircle.IsLoaded || !_modelBox || !_modelBox.IsLoaded) if (!_modelRotationAxis || !_modelRotationAxis.IsLoaded || !_modelSphere || !_modelSphere.IsLoaded)
break; break;
var circleMesh = _modelCircle.LODs[0].Meshes[0]; var rotationAxisMesh = _modelRotationAxis.LODs[0].Meshes[0];
var boxMesh = _modelBox.LODs[0].Meshes[0]; sphereMesh = _modelSphere.LODs[0].Meshes[0];
Matrix.Scaling(8.0f, out m3); Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m3);
Matrix.Multiply(ref m3, ref world, out m1); Matrix.Multiply(ref m3, ref world, out m1);
mx1 = m1;
mx1.M41 += 0.05f;
// X axis // X axis
Matrix.RotationZ(Mathf.PiOverTwo, out m2); Matrix.RotationZ(Mathf.PiOverTwo, out m2);
Matrix.Multiply(ref m2, ref m1, out m3); Matrix.Multiply(ref m2, ref m1, out m3);
circleMesh.Draw(ref renderContext, isXAxis ? _materialAxisFocus : _materialAxisX, ref m3); rotationAxisMesh.Draw(ref renderContext, isXAxis ? _materialAxisFocus : _materialAxisX, ref m3);
// Y axis // Y axis
circleMesh.Draw(ref renderContext, isYAxis ? _materialAxisFocus : _materialAxisY, ref m1); rotationAxisMesh.Draw(ref renderContext, isYAxis ? _materialAxisFocus : _materialAxisY, ref m1);
// Z axis // Z axis
Matrix.RotationX(-Mathf.PiOverTwo, out m2); Matrix.RotationX(-Mathf.PiOverTwo, out m2);
Matrix.Multiply(ref m2, ref m1, out m3); Matrix.Multiply(ref m2, ref m1, out m3);
circleMesh.Draw(ref renderContext, isZAxis ? _materialAxisFocus : _materialAxisZ, ref m3); rotationAxisMesh.Draw(ref renderContext, isZAxis ? _materialAxisFocus : _materialAxisZ, ref m3);
// Center box // Center box
Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m3); Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m2);
Matrix.Multiply(ref m3, ref world, out m1);
Matrix.Scaling(1.0f, out m2);
Matrix.Multiply(ref m2, ref m1, out m3); Matrix.Multiply(ref m2, ref m1, out m3);
boxMesh.Draw(ref renderContext, isCenter ? _materialWireFocus : _materialWire, ref m3); sphereMesh.Draw(ref renderContext, isCenter ? _materialAxisFocus : _materialSphere, ref m3);
break; break;
} }
case Mode.Scale: case Mode.Scale:
{ {
if (!_modelScaleAxis || !_modelScaleAxis.IsLoaded || !_modelBox || !_modelBox.IsLoaded) if (!_modelScaleAxis || !_modelScaleAxis.IsLoaded || !_modelCube || !_modelCube.IsLoaded || !_modelSphere || !_modelSphere.IsLoaded)
break; break;
var scaleAxisMesh = _modelScaleAxis.LODs[0].Meshes[0];
cubeMesh = _modelCube.LODs[0].Meshes[0];
sphereMesh = _modelSphere.LODs[0].Meshes[0];
Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m3); Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m3);
Matrix.Multiply(ref m3, ref world, out m1); Matrix.Multiply(ref m3, ref world, out m1);
mx1 = m1; mx1 = m1;
mx1.M41 -= 0.05f; mx1.M41 -= 0.05f;
var axisMesh = _modelScaleAxis.LODs[0].Meshes[0];
var boxMesh = _modelBox.LODs[0].Meshes[0];
// X axis // X axis
Matrix.RotationY(-Mathf.PiOverTwo, out m2); Matrix.RotationY(-Mathf.PiOverTwo, out m2);
Matrix.Multiply(ref m2, ref mx1, out m3); Matrix.Multiply(ref m2, ref mx1, out m3);
axisMesh.Draw(ref renderContext, isXAxis ? _materialAxisFocus : _materialAxisX, ref m3); scaleAxisMesh.Draw(ref renderContext, isXAxis ? _materialAxisFocus : _materialAxisX, ref m3);
// Y axis // Y axis
Matrix.RotationX(Mathf.PiOverTwo, out m2); Matrix.RotationX(Mathf.PiOverTwo, out m2);
Matrix.Multiply(ref m2, ref m1, out m3); Matrix.Multiply(ref m2, ref m1, out m3);
axisMesh.Draw(ref renderContext, isYAxis ? _materialAxisFocus : _materialAxisY, ref m3); scaleAxisMesh.Draw(ref renderContext, isYAxis ? _materialAxisFocus : _materialAxisY, ref m3);
// Z axis // Z axis
Matrix.RotationX(Mathf.Pi, out m2); Matrix.RotationX(Mathf.Pi, out m2);
Matrix.Multiply(ref m2, ref m1, out m3); Matrix.Multiply(ref m2, ref m1, out m3);
axisMesh.Draw(ref renderContext, isZAxis ? _materialAxisFocus : _materialAxisZ, ref m3); scaleAxisMesh.Draw(ref renderContext, isZAxis ? _materialAxisFocus : _materialAxisZ, ref m3);
// XY plane
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationX(Mathf.PiOverTwo), new Vector3(boxSize * boxScale, boxSize * boxScale, 0.0f));
Matrix.Multiply(ref m2, ref m1, out m3);
cubeMesh.Draw(ref renderContext, _activeAxis == Axis.XY ? _materialAxisFocus : _materialAxisX, ref m3);
// ZX plane
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.Identity, new Vector3(boxSize * boxScale, 0.0f, boxSize * boxScale));
Matrix.Multiply(ref m2, ref m1, out m3);
cubeMesh.Draw(ref renderContext, _activeAxis == Axis.ZX ? _materialAxisFocus : _materialAxisZ, ref m3);
// YZ plane
m2 = Matrix.Transformation(new Vector3(boxSize, boxSize * 0.1f, boxSize), Quaternion.RotationZ(Mathf.PiOverTwo), new Vector3(0.0f, boxSize * boxScale, boxSize * boxScale));
Matrix.Multiply(ref m2, ref m1, out m3);
cubeMesh.Draw(ref renderContext, _activeAxis == Axis.YZ ? _materialAxisFocus : _materialAxisY, ref m3);
// Center box // Center box
Matrix.Scaling(10.0f, out m2); Matrix.Scaling(gizmoModelsScale2RealGizmoSize, out m2);
Matrix.Multiply(ref m2, ref m1, out m3); Matrix.Multiply(ref m2, ref m1, out m3);
boxMesh.Draw(ref renderContext, isCenter ? _materialWireFocus : _materialWire, ref m3); sphereMesh.Draw(ref renderContext, isCenter ? _materialAxisFocus : _materialSphere, ref m3);
break; break;
} }

View File

@@ -102,9 +102,15 @@ namespace FlaxEditor.Gizmo
closestIntersection = intersection; closestIntersection = intersection;
} }
/*// Center
if (CenterBoxRaw.Intersects(ref localRay, out intersection) && intersection > closestIntersection)
{
_activeAxis = Axis.Center;
closestIntersection = intersection;
}*/
break; break;
} }
case Mode.Rotate: case Mode.Rotate:
{ {
// Circles // Circles
@@ -124,41 +130,53 @@ namespace FlaxEditor.Gizmo
closestIntersection = intersection; closestIntersection = intersection;
} }
// Center
/*if (CenterSphere.Intersects(ref ray, out intersection) && intersection < closestintersection)
{
_activeAxis = Axis.Center;
closestintersection = intersection;
}*/
break; break;
} }
case Mode.Scale: case Mode.Scale:
{ {
// Spheres collision // Boxes collision
if (ScaleXSphere.Intersects(ref ray, out intersection) && intersection < closestIntersection) if (XAxisBox.Intersects(ref localRay, out intersection) && intersection < closestIntersection)
{ {
_activeAxis = Axis.X; _activeAxis = Axis.X;
closestIntersection = intersection; closestIntersection = intersection;
} }
if (ScaleYSphere.Intersects(ref ray, out intersection) && intersection < closestIntersection) if (YAxisBox.Intersects(ref localRay, out intersection) && intersection < closestIntersection)
{ {
_activeAxis = Axis.Y; _activeAxis = Axis.Y;
closestIntersection = intersection; closestIntersection = intersection;
} }
if (ScaleZSphere.Intersects(ref ray, out intersection) && intersection < closestIntersection) if (ZAxisBox.Intersects(ref localRay, out intersection) && intersection < closestIntersection)
{ {
_activeAxis = Axis.Z; _activeAxis = Axis.Z;
closestIntersection = intersection; closestIntersection = intersection;
} }
// Center // Quad planes collision
if (CenterBox.Intersects(ref ray, out intersection) && intersection < closestIntersection) if (closestIntersection >= float.MaxValue)
closestIntersection = float.MinValue;
if (XYBox.Intersects(ref localRay, out intersection) && intersection > closestIntersection)
{
_activeAxis = Axis.XY;
closestIntersection = intersection;
}
if (XZBox.Intersects(ref localRay, out intersection) && intersection > closestIntersection)
{
_activeAxis = Axis.ZX;
closestIntersection = intersection;
}
if (YZBox.Intersects(ref localRay, out intersection) && intersection > closestIntersection)
{
_activeAxis = Axis.YZ;
closestIntersection = intersection;
}
/*// Center
if (CenterBoxRaw.Intersects(ref localRay, out intersection) && intersection < closestIntersection)
{ {
_activeAxis = Axis.Center; _activeAxis = Axis.Center;
closestIntersection = intersection; closestIntersection = intersection;
} }*/
break; break;
} }

View File

@@ -7,56 +7,53 @@ namespace FlaxEditor.Gizmo
{ {
public partial class TransformGizmoBase public partial class TransformGizmoBase
{ {
private const float GizmoScaleFactor = 18; /// <summary>
private const float LineLength = 3.0f; /// Scale of the gizmo itself
private const float LineOffset = 1.0f; /// </summary>
private const float MultiAxisThickness = 0.05f; private const float GizmoScaleFactor = 24;
private const float SingleAxisThickness = 0.3f;
private const float ScaleSpheresRadius = 0.7f;
private const float CenterBoxSize = 0.8f;
private const float CenterSphereRadius = 0.1f;
private const float HalfLineOffset = LineOffset / 2;
private readonly Vector3[] _translationLineVertices = /// <summary>
{ /// The length of each axis (outwards)
// -- X Axis -- // index 0 - 5 /// </summary>
new Vector3(HalfLineOffset, 0, 0), private const float AxisLength = 3.5f;
new Vector3(LineLength, 0, 0),
new Vector3(LineOffset, 0, 0),
new Vector3(LineOffset, LineOffset, 0),
new Vector3(LineOffset, 0, 0),
new Vector3(LineOffset, 0, LineOffset),
// -- Y Axis -- // index 6 - 11 /// <summary>
new Vector3(0, HalfLineOffset, 0), /// Offset to move axis away from center
new Vector3(0, LineLength, 0), /// </summary>
new Vector3(0, LineOffset, 0), private const float AxisOffset = 0.8f;
new Vector3(LineOffset, LineOffset, 0),
new Vector3(0, LineOffset, 0),
new Vector3(0, LineOffset, LineOffset),
// -- Z Axis -- // index 12 - 17 /// <summary>
new Vector3(0, 0, HalfLineOffset), /// How thick the axis should be
new Vector3(0, 0, LineLength), /// </summary>
new Vector3(0, 0, LineOffset), private const float AxisThickness = 0.3f;
new Vector3(LineOffset, 0, LineOffset),
new Vector3(0, 0, LineOffset),
new Vector3(0, LineOffset, LineOffset)
};
private BoundingBox XAxisBox = new BoundingBox(new Vector3(LineOffset, -SingleAxisThickness, -SingleAxisThickness), new Vector3(LineOffset + LineLength, SingleAxisThickness, SingleAxisThickness)); /// <summary>
private BoundingBox YAxisBox = new BoundingBox(new Vector3(-SingleAxisThickness, LineOffset, -SingleAxisThickness), new Vector3(SingleAxisThickness, LineOffset + LineLength, SingleAxisThickness)); /// Center box scale
private BoundingBox ZAxisBox = new BoundingBox(new Vector3(-SingleAxisThickness, -SingleAxisThickness, LineOffset), new Vector3(SingleAxisThickness, SingleAxisThickness, LineOffset + LineLength)); /// </summary>
private BoundingBox XZBox = new BoundingBox(Vector3.Zero, new Vector3(LineOffset, MultiAxisThickness, LineOffset)); private const float CenterBoxScale = 0.8f;
private BoundingBox XYBox = new BoundingBox(Vector3.Zero, new Vector3(LineOffset, LineOffset, MultiAxisThickness));
private BoundingBox YZBox = new BoundingBox(Vector3.Zero, new Vector3(MultiAxisThickness, LineOffset, LineOffset));
private BoundingBox CenterBoxRaw = new BoundingBox(new Vector3(-0.5f * CenterBoxSize), new Vector3(0.5f * CenterBoxSize));
private float RotateRadiusRaw = 4.0f;
private BoundingSphere ScaleXSphere => new BoundingSphere(Vector3.Transform(_translationLineVertices[1], _gizmoWorld), ScaleSpheresRadius * _screenScale); /// <summary>
private BoundingSphere ScaleYSphere => new BoundingSphere(Vector3.Transform(_translationLineVertices[7], _gizmoWorld), ScaleSpheresRadius * _screenScale); /// The inner minimum of the multiscale
private BoundingSphere ScaleZSphere => new BoundingSphere(Vector3.Transform(_translationLineVertices[13], _gizmoWorld), ScaleSpheresRadius * _screenScale); /// </summary>
private const float InnerExtend = AxisOffset + 0.5f;
/// <summary>
/// The outer maximum of the multiscale
/// </summary>
private const float OuterExtend = AxisOffset * 3.5f;
// Cube with the size AxisThickness, then moves it along the axis (AxisThickness) and finally makes it really long (AxisLength)
private BoundingBox XAxisBox = new BoundingBox(new Vector3(-AxisThickness), new Vector3(AxisThickness)).MakeOffsetted(AxisOffset * Vector3.UnitX).Merge(AxisLength * Vector3.UnitX);
private BoundingBox YAxisBox = new BoundingBox(new Vector3(-AxisThickness), new Vector3(AxisThickness)).MakeOffsetted(AxisOffset * Vector3.UnitY).Merge(AxisLength * Vector3.UnitY);
private BoundingBox ZAxisBox = new BoundingBox(new Vector3(-AxisThickness), new Vector3(AxisThickness)).MakeOffsetted(AxisOffset * Vector3.UnitZ).Merge(AxisLength * Vector3.UnitZ);
private BoundingBox XZBox = new BoundingBox(new Vector3(InnerExtend, 0, InnerExtend), new Vector3(OuterExtend, 0, OuterExtend));
private BoundingBox XYBox = new BoundingBox(new Vector3(InnerExtend, InnerExtend, 0), new Vector3(OuterExtend, OuterExtend, 0));
private BoundingBox YZBox = new BoundingBox(new Vector3(0, InnerExtend, InnerExtend), new Vector3(0, OuterExtend, OuterExtend));
private BoundingBox CenterBoxRaw = new BoundingBox(new Vector3(-0.5f * CenterBoxScale), new Vector3(0.5f * CenterBoxScale));
private OrientedBoundingBox CenterBox => new OrientedBoundingBox(CenterBoxRaw) * _gizmoWorld; private OrientedBoundingBox CenterBox => new OrientedBoundingBox(CenterBoxRaw) * _gizmoWorld;
private const float RotateRadiusRaw = 4.0f;
private Mode _activeMode = Mode.Translate; private Mode _activeMode = Mode.Translate;
private Axis _activeAxis = Axis.None; private Axis _activeAxis = Axis.None;

View File

@@ -419,6 +419,31 @@ namespace FlaxEngine
return box; return box;
} }
/// <summary>
/// Constructs a <see cref="BoundingBox" /> that is as large as the box and point.
/// </summary>
/// <param name="value1">The box to merge.</param>
/// <param name="value2">The point to merge.</param>
/// <param name="result">When the method completes, contains the newly constructed bounding box.</param>
public static void Merge(ref BoundingBox value1, ref Vector3 value2, out BoundingBox result)
{
Vector3.Min(ref value1.Minimum, ref value2, out result.Minimum);
Vector3.Max(ref value1.Maximum, ref value2, out result.Maximum);
}
/// <summary>
/// Constructs a <see cref="BoundingBox" /> that is as large as the box and point.
/// </summary>
/// <param name="value2">The point to merge.</param>
/// <returns>The newly constructed bounding box.</returns>
public BoundingBox Merge(Vector3 value2)
{
BoundingBox result;
Vector3.Min(ref Minimum, ref value2, out result.Minimum);
Vector3.Max(ref Maximum, ref value2, out result.Maximum);
return result;
}
/// <summary> /// <summary>
/// Transforms bounding box using the given transformation matrix. /// Transforms bounding box using the given transformation matrix.
/// </summary> /// </summary>
@@ -498,6 +523,19 @@ namespace FlaxEngine
result = new BoundingBox(min, max); result = new BoundingBox(min, max);
} }
/// <summary>
/// Creates the bounding box that is offseted by the given vector. Adds the offset value to minimum and maximum points.
/// </summary>
/// <param name="offset">The bounds offset.</param>
/// <returns>The offsetted bounds.</returns>
public BoundingBox MakeOffsetted(Vector3 offset)
{
BoundingBox result;
Vector3.Add(ref Minimum, ref offset, out result.Minimum);
Vector3.Add(ref Maximum, ref offset, out result.Maximum);
return result;
}
/// <summary> /// <summary>
/// Creates the bounding box that is offseted by the given vector. Adds the offset value to minimum and maximum points. /// Creates the bounding box that is offseted by the given vector. Adds the offset value to minimum and maximum points.
/// </summary> /// </summary>

View File

@@ -13,5 +13,5 @@ using System.Runtime.InteropServices;
[assembly: AssemblyCulture("")] [assembly: AssemblyCulture("")]
[assembly: ComVisible(false)] [assembly: ComVisible(false)]
[assembly: Guid("b8442186-4a70-7c85-704a-857c68060f38")] [assembly: Guid("b8442186-4a70-7c85-704a-857c68060f38")]
[assembly: AssemblyVersion("1.5.6336")] [assembly: AssemblyVersion("1.5.6337")]
[assembly: AssemblyFileVersion("1.5.6336")] [assembly: AssemblyFileVersion("1.5.6337")]

View File

@@ -3,11 +3,11 @@
#pragma once #pragma once
#define FLAXENGINE_NAME "FlaxEngine" #define FLAXENGINE_NAME "FlaxEngine"
#define FLAXENGINE_VERSION Version(1, 5, 6336) #define FLAXENGINE_VERSION Version(1, 5, 6337)
#define FLAXENGINE_VERSION_TEXT "1.5.6336" #define FLAXENGINE_VERSION_TEXT "1.5.6337"
#define FLAXENGINE_VERSION_MAJOR 1 #define FLAXENGINE_VERSION_MAJOR 1
#define FLAXENGINE_VERSION_MINOR 5 #define FLAXENGINE_VERSION_MINOR 5
#define FLAXENGINE_VERSION_BUILD 6336 #define FLAXENGINE_VERSION_BUILD 6337
#define FLAXENGINE_COMPANY "Flax" #define FLAXENGINE_COMPANY "Flax"
#define FLAXENGINE_COPYRIGHT "Copyright (c) 2012-2023 Wojciech Figat. All rights reserved." #define FLAXENGINE_COPYRIGHT "Copyright (c) 2012-2023 Wojciech Figat. All rights reserved."