diff --git a/GlitchyEngine/src/World/TransformComponent.bf b/GlitchyEngine/src/World/TransformComponent.bf index 78dae5e..031db80 100644 --- a/GlitchyEngine/src/World/TransformComponent.bf +++ b/GlitchyEngine/src/World/TransformComponent.bf @@ -5,13 +5,13 @@ namespace GlitchyEngine.World public struct TransformComponent { Vector3 _position = .Zero; - Vector3 _rotation = .Zero; + Quaternion _rotation = .Identity; Vector3 _scale = .One; - Matrix _localTransform; - public bool IsDirty; + Matrix _localTransform = .Identity; + public bool IsDirty = false;; - public Matrix WorldTransform; + public Matrix WorldTransform = .Identity; /// The frame when the transform was recalculated public uint Frame; @@ -35,7 +35,8 @@ namespace GlitchyEngine.World } } - public Vector3 Rotation + /// Gets or sets the rotation. + public Quaternion Rotation { get => _rotation; set mut @@ -47,6 +48,44 @@ namespace GlitchyEngine.World IsDirty = true; } } + + /** + * Gets or sets the rotation using euler angles. + * @Note The rotations will be applied in the following order: YZX (the order in the vector is still XYZ!) + */ + 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; + } + } + + /** + * Gets or sets the rotation using axis angle, where Axis is the axis around which will be rotated and angle is the angle + * that was rotated around the axis in radians. + */ + public (Vector3 Axis, float Angle) RotationAxisAngle + { + get => _rotation.ToAxisAngle(); + set mut + { + Quaternion quat = Quaternion.FromAxisAngle(value.Axis, value.Angle); + + if(_rotation == quat) + return; + + _rotation = quat; + IsDirty = true; + } + } public Vector3 Scale { diff --git a/GlitchyEngine/src/World/TransformSystem.bf b/GlitchyEngine/src/World/TransformSystem.bf index 0f848ff..57415ec 100644 --- a/GlitchyEngine/src/World/TransformSystem.bf +++ b/GlitchyEngine/src/World/TransformSystem.bf @@ -16,7 +16,7 @@ namespace GlitchyEngine.World private static void UpdateEntity(Entity entity, TransformComponent* transform, EcsWorld world) { - // Todo: this probably needs a rewrite as it may scale poorly with deep hierarchies! + // Todo: test scaling with deep hierarchies! // transform was updated this frame -> skip if(transform.Frame == _frame) @@ -28,8 +28,7 @@ namespace GlitchyEngine.World if(transform.IsDirty) { - transform.LocalTransform = .Translation(transform.Position) * .RotationX(transform.Rotation.X) * - .RotationY(transform.Rotation.Y) * .RotationZ(transform.Rotation.Z) * .Scaling(transform.Scale); + transform.LocalTransform = .Translation(transform.Position) * .RotationQuaternion(transform.Rotation) * .Scaling(transform.Scale); transform.IsDirty = false; diff --git a/Sandbox/src/SandboxApp.bf b/Sandbox/src/SandboxApp.bf index 7d26bff..ceb032a 100644 --- a/Sandbox/src/SandboxApp.bf +++ b/Sandbox/src/SandboxApp.bf @@ -305,6 +305,7 @@ namespace Sandbox entities[x][y] = entity; var transform = _world.AssignComponent(entity); + *transform = TransformComponent(); transform.LocalTransform = Matrix.Translation(x * 0.2f, y * 0.2f, 0) * Matrix.Scaling(0.1f); var mesh = _world.AssignComponent(entity); @@ -326,7 +327,7 @@ namespace Sandbox var crazyTransform = _world.AssignComponent(evenCrazierParent); crazyTransform.Position = .Zero; crazyTransform.Scale = .One; - crazyTransform.Rotation = .Zero; + crazyTransform.Rotation = .Identity; var pp = _world.AssignComponent(crazyParent); pp.Entity = evenCrazierParent; @@ -334,7 +335,7 @@ namespace Sandbox crazyTransform = _world.AssignComponent(crazyParent); crazyTransform.Position = .Zero; crazyTransform.Scale = .(2.0f, 2.0f, 2.0f); - crazyTransform.Rotation = .Zero; + crazyTransform.Rotation = .Identity; for(int x < 20) for(int y < 20) @@ -447,15 +448,30 @@ namespace Sandbox _context.SetRasterizerState(_rasterizerState); - var crazyTransform = _world.GetComponent(evenCrazierParent); - crazyTransform.Rotation += .((float)gameTime.FrameTime.TotalSeconds / 2, 0, 0); - - crazyTransform = _world.GetComponent(crazyParent); + //var crazyTransform = _world.GetComponent(evenCrazierParent); //crazyTransform.Rotation += .((float)gameTime.FrameTime.TotalSeconds / 2, 0, 0); - - crazyTransform = _world.GetComponent(crazyParent); - crazyTransform.Rotation += .(0, (float)gameTime.FrameTime.TotalSeconds, 0); - + + + var crazyTransform = _world.GetComponent(crazyParent); + if(Input.IsKeyPressed(Key.Six)) + { + crazyTransform.RotationEuler += .((float)gameTime.FrameTime.TotalSeconds, 0, 0); + } + if(Input.IsKeyPressed(Key.Seven)) + { + crazyTransform.RotationEuler += .(0, (float)gameTime.FrameTime.TotalSeconds, 0); + } + if(Input.IsKeyPressed(Key.Eight)) + { + Vector3 vec = crazyTransform.RotationEuler; + vec += .(0, 0, (float)gameTime.FrameTime.TotalSeconds); + crazyTransform.RotationEuler = vec; + } + if(Input.IsKeyPressed(Key.Nine)) + { + crazyTransform.RotationEuler = .(0, 0, 0); + } + TransformSystem.Update(_world); for(var (entity, transform, mesh, meshRenderer) in _world.Enumerate())