mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 13:01:52 +00:00
Better Transform component and edit gui
This commit is contained in:
@@ -3,6 +3,7 @@ using GlitchyEngine.Events;
|
||||
using GlitchyEngine.ImGui;
|
||||
using GlitchyEngine.Renderer;
|
||||
using GlitchyEngine.Debug;
|
||||
using GlitchyEngine.Content;
|
||||
|
||||
namespace GlitchyEngine
|
||||
{
|
||||
@@ -24,12 +25,16 @@ namespace GlitchyEngine
|
||||
#endif
|
||||
|
||||
private GameTime _gameTime;
|
||||
|
||||
private IContentManager _contentManager;
|
||||
|
||||
public bool IsRunning => _running;
|
||||
public Window Window => _window;
|
||||
|
||||
public EffectLibrary EffectLibrary => _effectLibrary;
|
||||
|
||||
public IContentManager ContentManager => _contentManager;
|
||||
|
||||
public bool IsMinimized => _isMinimized;
|
||||
|
||||
[Inline]
|
||||
@@ -51,6 +56,8 @@ namespace GlitchyEngine
|
||||
_rendererApi = new RendererAPI();
|
||||
_rendererApi.Context = _window.Context;
|
||||
|
||||
_contentManager = new ContentManager("./content");
|
||||
|
||||
SamplerStateManager.Init();
|
||||
|
||||
RenderCommand.RendererAPI = _rendererApi;
|
||||
@@ -73,6 +80,9 @@ namespace GlitchyEngine
|
||||
Renderer.Deinit();
|
||||
|
||||
delete _effectLibrary;
|
||||
|
||||
delete _contentManager;
|
||||
|
||||
delete _rendererApi;
|
||||
delete _window;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using GlitchyEngine.Math;
|
||||
using GlitchyEngine.Renderer;
|
||||
using System;
|
||||
|
||||
namespace ImGui
|
||||
{
|
||||
@@ -21,6 +22,10 @@ namespace ImGui
|
||||
// Wouldn't be necesseary if RenderTarget2D was Texture2D
|
||||
public static extern void Image(RenderTarget2D texture, Vec2 size, Vec2 uv0 = Vec2.Zero, Vec2 uv1 = Vec2.Ones, Vec4 tint_col = Vec4.Ones, Vec4 border_col = Vec4.Zero);
|
||||
|
||||
public static void TextUnformatted(StringView text) => TextUnformattedImpl(text.Ptr, text.Ptr + text.Length);
|
||||
|
||||
public static void PushID(StringView id) => PushID(id.Ptr, id.Ptr + id.Length);
|
||||
|
||||
/// Releases references that accumulated calls like ImGui::Image
|
||||
protected internal static extern void CleanupFrame();
|
||||
|
||||
|
||||
@@ -18,10 +18,10 @@ namespace GlitchyEngine.Math
|
||||
public const float PiOverFour = 0.785398163f;
|
||||
|
||||
/// Converts radians to degrees
|
||||
const float RadToDeg = 180.0f / Pi;
|
||||
public const float RadToDeg = 180.0f / Pi;
|
||||
|
||||
/// Converts radians to degrees
|
||||
const float DegToRad = Pi / 180.0f;
|
||||
public const float DegToRad = Pi / 180.0f;
|
||||
|
||||
// Converts the given radians to degrees
|
||||
public static float ToDegrees(float radians)
|
||||
|
||||
@@ -314,35 +314,65 @@ namespace GlitchyEngine.Math
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Vector3 ToEulerAngles(Quaternion q1)
|
||||
public static Vector3 ToEulerAngles(Quaternion q)
|
||||
{
|
||||
// http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/
|
||||
|
||||
|
||||
Vector3 result;
|
||||
|
||||
float sqw = q1.W*q1.W;
|
||||
float sqx = q1.X*q1.X;
|
||||
float sqy = q1.Y*q1.Y;
|
||||
float sqz = q1.Z*q1.Z;
|
||||
float sqw = q.W*q.W;
|
||||
float sqx = q.X*q.X;
|
||||
float sqy = q.Y*q.Y;
|
||||
float sqz = q.Z*q.Z;
|
||||
float unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
|
||||
float test = q1.X*q1.Y + q1.Z*q1.W;
|
||||
if (test > 0.499f*unit) { // singularity at north pole
|
||||
result.Y = 2.0f * Math.Atan2(q1.X,q1.W);
|
||||
float test = q.X*q.Y + q.Z*q.W;
|
||||
if (test > 0.4999f*unit) { // singularity at north pole
|
||||
result.Y = 2.0f * Math.Atan2(q.X,q.W);
|
||||
result.Z = Math.PI_f / 2.0f;
|
||||
result.X = 0.0f;
|
||||
return result;
|
||||
}
|
||||
if (test < -0.499f*unit) { // singularity at south pole
|
||||
result.Y = -2.0f * Math.Atan2(q1.X,q1.W);
|
||||
if (test < -0.4999f*unit) { // singularity at south pole
|
||||
result.Y = -2.0f * Math.Atan2(q.X,q.W);
|
||||
result.Z = -Math.PI_f / 2.0f;
|
||||
result.X = 0.0f;
|
||||
return result;
|
||||
}
|
||||
result.Y = Math.Atan2(2*q1.Y*q1.W-2*q1.X*q1.Z , sqx - sqy - sqz + sqw);
|
||||
result.Y = Math.Atan2(2*q.Y*q.W-2*q.X*q.Z , sqx - sqy - sqz + sqw);
|
||||
result.Z = Math.Asin(2*test/unit);
|
||||
result.X = Math.Atan2(2*q1.X*q1.W-2*q1.Y*q1.Z , -sqx + sqy - sqz + sqw);
|
||||
result.X = Math.Atan2(2*q.X*q.W-2*q.Y*q.Z , -sqx + sqy - sqz + sqw);
|
||||
|
||||
return result;
|
||||
|
||||
//return .(q.Pitch(), q.Yaw(), q.Roll());
|
||||
}
|
||||
/*
|
||||
public float Pitch()
|
||||
{
|
||||
float y = 2.0f * (Y * Z + W * X);
|
||||
float x = W * W - X * X - Y * Y + Z * Z;
|
||||
|
||||
if (Vector2(x, y).Equals(.Zero)) //avoid atan2(0,0) - handle singularity - Matiis
|
||||
return 2.0f * Math.Atan2(X, W);
|
||||
|
||||
return Math.Atan2(y, x);
|
||||
}
|
||||
|
||||
public float Yaw()
|
||||
{
|
||||
return Math.Asin(Math.Clamp(-2.0f * (X * Z - W * Y), -1.0f, 1.0f));
|
||||
}
|
||||
|
||||
public float Roll()
|
||||
{
|
||||
float y = 2.0f * (X * Y + W * Z);
|
||||
float x = W * W + X * X - Y * Y - Z * Z;
|
||||
|
||||
if (Vector2(x, y).Equals(.Zero)) //avoid atan2(0,0) - handle singularity - Matiis
|
||||
return 0;
|
||||
|
||||
return Math.Atan2(y, x);
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -284,5 +284,10 @@ namespace GlitchyEngine.Math
|
||||
|
||||
[Inline]
|
||||
public static explicit operator Self(float value) => Self(value);
|
||||
|
||||
public bool Equals(Vector2 v, float epsilon = Math.[Friend]sMachineEpsilonFloat)
|
||||
{
|
||||
return (Math.Abs(v.X - X) < epsilon) && (Math.Abs(v.Y - Y) < epsilon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,36 +13,25 @@ namespace GlitchyEngine.World
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
struct SimpleTransformComponent
|
||||
{
|
||||
public EcsEntity Parent = .InvalidEntity;
|
||||
public Matrix Transform = Matrix.Identity;
|
||||
|
||||
public this()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public this(Matrix transform)
|
||||
{
|
||||
Transform = transform;
|
||||
}
|
||||
}
|
||||
|
||||
struct SpriterRendererComponent
|
||||
struct SpriterRendererComponent : IDisposableComponent
|
||||
{
|
||||
public Texture2D Sprite = null;
|
||||
public ColorRGBA Color = .White;
|
||||
|
||||
public this()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public this(ColorRGBA color)
|
||||
{
|
||||
Color = color;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Sprite?.ReleaseRef();
|
||||
}
|
||||
}
|
||||
|
||||
struct SceneCamera : Camera
|
||||
@@ -229,7 +218,7 @@ namespace GlitchyEngine.World
|
||||
|
||||
private void CalculateProjection() mut
|
||||
{
|
||||
if (_projectionType case .Orthographic)//(let nearPlane, let farPlane, let projectionHeight))
|
||||
if (_projectionType case .Orthographic)
|
||||
{
|
||||
float halfHeight = _orthographicHeight / 2.0f;
|
||||
float halfWidth = halfHeight * _aspectRatio;
|
||||
@@ -237,11 +226,11 @@ namespace GlitchyEngine.World
|
||||
_projection = Matrix.OrthographicProjectionOffCenter(-halfWidth, halfWidth, halfHeight, -halfHeight,
|
||||
_orthographicNearPlane, _orthographicFarPlane);
|
||||
}
|
||||
else if (_projectionType case .Perspective)//(let nearPlane, let farPlane, let fovY))
|
||||
else if (_projectionType case .Perspective)
|
||||
{
|
||||
_projection = Matrix.PerspectiveProjection(_perspectiveFovY, _aspectRatio, _perspectiveNearPlane, _perspectiveFarPlane);
|
||||
}
|
||||
else if (_projectionType case .InfinitePerspective)//(let nearPlane, let fovY))
|
||||
else if (_projectionType case .InfinitePerspective)
|
||||
{
|
||||
_projection = Matrix.InfinitePerspectiveProjection(_perspectiveFovY, _aspectRatio, _perspectiveNearPlane);
|
||||
}
|
||||
|
||||
@@ -16,7 +16,10 @@ namespace GlitchyEngine.World
|
||||
entity.AddComponent<SpriterRendererComponent>(.(ColorRGBA(0.2f, 0.9f, 0.15f)));
|
||||
|
||||
Entity entity2 = CreateEntity("Red Square");
|
||||
entity2.AddComponent<SpriterRendererComponent>(.(ColorRGBA(0.95f, 0.1f, 0.3f)));
|
||||
var v = entity2.AddComponent<SpriterRendererComponent>(.(ColorRGBA(0.95f, 0.1f, 0.3f)));
|
||||
v.Sprite = new Texture2D("Textures/rocket.png");
|
||||
v.Sprite.SamplerState = SamplerStateManager.PointClamp;
|
||||
|
||||
}
|
||||
|
||||
public ~this()
|
||||
@@ -25,7 +28,7 @@ namespace GlitchyEngine.World
|
||||
|
||||
public void Update(GameTime gameTime)
|
||||
{
|
||||
//TransformSystem.Update(_ecsWorld);
|
||||
TransformSystem.Update(_ecsWorld);
|
||||
|
||||
for (var (entity, script) in _ecsWorld.Enumerate<NativeScriptComponent>())
|
||||
{
|
||||
@@ -40,25 +43,25 @@ namespace GlitchyEngine.World
|
||||
}
|
||||
|
||||
Camera* primaryCamera = null;
|
||||
Matrix* primaryCameraTransform = null;
|
||||
Matrix primaryCameraTransform = default;
|
||||
|
||||
for (var (entity, transform, camera) in _ecsWorld.Enumerate<SimpleTransformComponent, CameraComponent>())
|
||||
for (var (entity, transform, camera) in _ecsWorld.Enumerate<TransformComponent, CameraComponent>())
|
||||
{
|
||||
if (camera.Primary)
|
||||
{
|
||||
primaryCamera = &camera.Camera;
|
||||
primaryCameraTransform = &transform.Transform;
|
||||
primaryCameraTransform = transform.WorldTransform;
|
||||
}
|
||||
}
|
||||
|
||||
// Sprite renderer
|
||||
if (primaryCamera != null)
|
||||
{
|
||||
Renderer2D.BeginScene(*primaryCamera, *primaryCameraTransform);
|
||||
Renderer2D.BeginScene(*primaryCamera, primaryCameraTransform);
|
||||
|
||||
for (var (entity, transform, sprite) in _ecsWorld.Enumerate<SimpleTransformComponent, SpriterRendererComponent>())
|
||||
for (var (entity, transform, sprite) in _ecsWorld.Enumerate<TransformComponent, SpriterRendererComponent>())
|
||||
{
|
||||
Renderer2D.DrawQuad(transform.Transform, sprite.Color);
|
||||
Renderer2D.DrawQuad(transform.WorldTransform, sprite.Sprite, sprite.Color);
|
||||
}
|
||||
|
||||
Renderer2D.EndScene();
|
||||
@@ -68,7 +71,7 @@ namespace GlitchyEngine.World
|
||||
public Entity CreateEntity(String name = "")
|
||||
{
|
||||
Entity entity = Entity(_ecsWorld.NewEntity(), this);
|
||||
entity.AddComponent<SimpleTransformComponent>(.(.Identity));
|
||||
entity.AddComponent<TransformComponent>();
|
||||
|
||||
let nameComponent = entity.AddComponent<DebugNameComponent>();
|
||||
nameComponent.SetName(name.IsEmpty ? "Entity" : name);
|
||||
|
||||
@@ -4,6 +4,8 @@ namespace GlitchyEngine.World
|
||||
{
|
||||
internal Entity _entity;
|
||||
|
||||
protected TransformComponent* transform => GetComponent<TransformComponent>();
|
||||
|
||||
public T* AddComponent<T>(T value = T()) where T: struct, new
|
||||
{
|
||||
return _entity.AddComponent<T>(value);
|
||||
|
||||
@@ -4,9 +4,13 @@ namespace GlitchyEngine.World
|
||||
{
|
||||
public struct TransformComponent
|
||||
{
|
||||
Vector3 _position = .Zero;
|
||||
Quaternion _rotation = .Identity;
|
||||
Vector3 _scale = .One;
|
||||
EcsEntity _parent = .InvalidEntity;
|
||||
|
||||
Vector3 _position = .(0, 0, 0);
|
||||
Quaternion _rotation = .(0, 0, 0, 1);
|
||||
Vector3 _scale = .(1, 1, 1);
|
||||
|
||||
Vector3 _editorRotationEuler = .Zero;
|
||||
|
||||
Matrix _localTransform = .Identity;
|
||||
public bool IsDirty = false;
|
||||
@@ -16,6 +20,19 @@ namespace GlitchyEngine.World
|
||||
/// The frame when the transform was recalculated
|
||||
public uint Frame;
|
||||
|
||||
public EcsEntity Parent
|
||||
{
|
||||
get => _parent;
|
||||
set mut
|
||||
{
|
||||
if (_parent == value)
|
||||
return;
|
||||
|
||||
_parent = value;
|
||||
IsDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
public Matrix LocalTransform
|
||||
{
|
||||
get => _localTransform;
|
||||
@@ -55,6 +72,24 @@ namespace GlitchyEngine.World
|
||||
|
||||
_rotation = value;
|
||||
IsDirty = true;
|
||||
|
||||
_editorRotationEuler = Quaternion.ToEulerAngles(_rotation);
|
||||
}
|
||||
}
|
||||
|
||||
/// Allows the user to edit the euler angles in the editor without rotations getting funky because of singularities or ambiguity of angles.
|
||||
internal Vector3 EditorRotationEuler
|
||||
{
|
||||
get => _editorRotationEuler;
|
||||
set mut
|
||||
{
|
||||
if (_editorRotationEuler == value)
|
||||
return;
|
||||
|
||||
_editorRotationEuler = value;
|
||||
|
||||
_rotation = Quaternion.FromEulerAngles(_editorRotationEuler.Y, _editorRotationEuler.X, _editorRotationEuler.Z);
|
||||
IsDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,16 +100,7 @@ namespace GlitchyEngine.World
|
||||
public Vector3 RotationEuler
|
||||
{
|
||||
get => Quaternion.ToEulerAngles(_rotation);
|
||||
set mut
|
||||
{
|
||||
Quaternion quat = Quaternion.FromEulerAngles(value.Y, value.X, value.Z);
|
||||
|
||||
if(_rotation == quat)
|
||||
return;
|
||||
|
||||
_rotation = quat;
|
||||
IsDirty = true;
|
||||
}
|
||||
set mut => Rotation = Quaternion.FromEulerAngles(value.Y, value.X, value.Z);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace GlitchyEngine.World
|
||||
|
||||
transform.Frame = _frame;
|
||||
|
||||
var parent = world.GetComponent<ParentComponent>(entity);
|
||||
//var parent = world.GetComponent<ParentComponent>(entity);
|
||||
|
||||
if(transform.IsDirty)
|
||||
{
|
||||
@@ -35,18 +35,16 @@ namespace GlitchyEngine.World
|
||||
|
||||
transform.IsDirty = false;
|
||||
|
||||
if(parent == null)
|
||||
if(transform.Parent == EcsEntity.InvalidEntity)
|
||||
{
|
||||
transform.WorldTransform = transform.LocalTransform;
|
||||
}
|
||||
}
|
||||
|
||||
if(parent != null)
|
||||
if(transform.Parent != EcsEntity.InvalidEntity)
|
||||
{
|
||||
var parentEntity = parent.Entity;
|
||||
|
||||
var parentTransform = world.GetComponent<TransformComponent>(parentEntity);
|
||||
UpdateEntity(parentEntity, parentTransform, world);
|
||||
var parentTransform = world.GetComponent<TransformComponent>(transform.Parent);
|
||||
UpdateEntity(transform.Parent, parentTransform, world);
|
||||
|
||||
// TODO: I think we unnecessarily recalculate world transform every frame
|
||||
// Parent transform is newer than our transform or was updated this frame
|
||||
|
||||
Reference in New Issue
Block a user