add transform abstraction

pull/1/head
Evan Hemsley 2020-08-05 15:10:04 -07:00
parent 7556ebd84c
commit 305b2d0911
10 changed files with 144 additions and 25 deletions

2
Kav

@ -1 +1 @@
Subproject commit f0f09115f5dfbe34179bab33f60d07230aed9dd7
Subproject commit 2419a89d3245dc7d52f6b4301902f840ea10beaf

View File

@ -1,13 +1,12 @@
using Encompass;
using Microsoft.Xna.Framework;
namespace KavTest.Components
{
public struct TransformComponent : IComponent
public struct Transform3DComponent : IComponent
{
public Matrix Transform { get; }
public Transform3D Transform { get; }
public TransformComponent(Matrix transform)
public Transform3DComponent(Transform3D transform)
{
Transform = transform;
}

View File

@ -4,24 +4,22 @@ using Microsoft.Xna.Framework;
namespace KavTest.Engines
{
[Reads(typeof(TransformComponent), typeof(AngularVelocityComponent))]
[Writes(typeof(TransformComponent))]
[Reads(typeof(Transform3DComponent), typeof(AngularVelocityComponent))]
[Writes(typeof(Transform3DComponent))]
public class RotationEngine : Engine
{
public override void Update(double dt)
{
foreach (var entity in ReadEntities<AngularVelocityComponent>())
{
if (HasComponent<TransformComponent>(entity))
if (HasComponent<Transform3DComponent>(entity))
{
ref readonly var angularVelocityComponent = ref GetComponent<AngularVelocityComponent>(entity);
ref readonly var transformComponent = ref GetComponent<TransformComponent>(entity);
ref readonly var transformComponent = ref GetComponent<Transform3DComponent>(entity);
var angularVelocity = angularVelocityComponent.AngularVelocity * (float)dt;
var transform = transformComponent.Transform;
var newTransform = Matrix.Transform(transform, Quaternion.CreateFromYawPitchRoll(angularVelocity.X, angularVelocity.Y, angularVelocity.Z));
SetComponent(entity, new TransformComponent(newTransform));
SetComponent(entity, new Transform3DComponent(transformComponent.Transform.Rotate(angularVelocity)));
}
}
}

View File

@ -10,7 +10,7 @@ namespace KavTest.Spawners
{
var entity = CreateEntity();
AddComponent(entity, new TransformComponent(message.Transform));
AddComponent(entity, new Transform3DComponent(message.Transform));
AddComponent(entity, new PointLightComponent(message.Color, message.Intensity));
}
}

View File

@ -18,9 +18,9 @@ namespace KavTest.Spawners
{
var entity = CreateEntity();
AddComponent(entity, new TransformComponent(message.Transform));
AddComponent(entity, new Transform3DComponent(message.Transform));
AddComponent(entity, new ModelComponent(RustyBallModel));
AddComponent(entity, new AngularVelocityComponent(new Microsoft.Xna.Framework.Vector3(5, -2, 1)));
AddComponent(entity, new AngularVelocityComponent(message.AngularVelocity));
}
}
}

View File

@ -42,10 +42,22 @@ namespace KavTest
WorldBuilder.AddGeneralRenderer(new SceneRenderer(GraphicsDevice), 0);
WorldBuilder.SendMessage(new RustyBallSpawnMessage(
Matrix.CreateTranslation(0, 0, 0)
new Transform3D(new Vector3(0, 0, 0)),
new Vector3(1, 1, -1)
));
WorldBuilder.SendMessage(new RustyBallSpawnMessage(
new Transform3D(new Vector3(-5, 0, 0)),
new Vector3(-1, 1, -1)
));
WorldBuilder.SendMessage(new RustyBallSpawnMessage(
new Transform3D(new Vector3(5, 0, 0)),
new Vector3(-1, 1, 1)
));
WorldBuilder.SendMessage(new LightBulbSpawnMessage(
Matrix.CreateTranslation(10, 0, -5),
new Transform3D(new Vector3(0, 2, -5)),
Color.White,
300f
));

View File

@ -5,11 +5,11 @@ namespace KavTest.Messages
{
public struct LightBulbSpawnMessage : IMessage
{
public Matrix Transform { get; }
public Transform3D Transform { get; }
public Color Color { get; }
public float Intensity { get; }
public LightBulbSpawnMessage(Matrix transform, Color color, float intensity)
public LightBulbSpawnMessage(Transform3D transform, Color color, float intensity)
{
Transform = transform;
Color = color;

View File

@ -6,11 +6,13 @@ namespace KavTest.Messages
{
public struct RustyBallSpawnMessage : IMessage
{
public Matrix Transform { get; }
public Transform3D Transform { get; }
public Vector3 AngularVelocity { get; }
public RustyBallSpawnMessage(Matrix transform)
public RustyBallSpawnMessage(Transform3D transform, Vector3 angularVelocity)
{
Transform = transform;
AngularVelocity = angularVelocity;
}
}
}

View File

@ -17,10 +17,10 @@ namespace KavTest.Renderers
{
foreach (var entity in ReadEntitiesAsEnumerable<ModelComponent>())
{
var transformComponent = GetComponent<TransformComponent>(entity);
var transformComponent = GetComponent<Transform3DComponent>(entity);
var modelComponent = GetComponent<ModelComponent>(entity);
modelComponent.Model.ApplyTransform(transformComponent.Transform);
modelComponent.Model.ApplyTransform(transformComponent.Transform.TransformMatrix);
yield return modelComponent.Model;
}
}
@ -32,11 +32,11 @@ namespace KavTest.Renderers
{
foreach (var entity in ReadEntitiesAsEnumerable<PointLightComponent>())
{
var transformComponent = GetComponent<TransformComponent>(entity);
var transformComponent = GetComponent<Transform3DComponent>(entity);
var pointLightComponent = GetComponent<PointLightComponent>(entity);
yield return new PointLight(
transformComponent.Transform.Translation,
transformComponent.Transform.TransformMatrix.Translation,
pointLightComponent.Color,
pointLightComponent.Intensity
);

View File

@ -0,0 +1,108 @@
using Microsoft.Xna.Framework;
namespace KavTest
{
public struct Transform3D : System.IEquatable<Transform3D>
{
public Matrix TransformMatrix { get; private set; }
public Vector3 Position { get; private set; }
public Vector3 Forward { get { return TransformMatrix.Forward; } }
public Transform3D(Vector3 position, Quaternion orientation, Vector3 scale)
{
Position = position;
TransformMatrix = CreateTransformMatrix(position, orientation, scale);
}
public Transform3D(Vector3 position)
{
Position = position;
TransformMatrix = CreateTransformMatrix(position, Quaternion.Identity, Vector3.One);
}
public Transform3D(Matrix matrix)
{
Position = matrix.Translation;
TransformMatrix = matrix;
}
public Transform3D WithPosition(Vector3 position)
{
return Translate(position - TransformMatrix.Translation);
}
public Transform3D Translate(Vector3 translation)
{
return new Transform3D(Matrix.CreateTranslation(translation) * TransformMatrix);
}
public Transform3D Rotate(Quaternion other)
{
return new Transform3D(Matrix.CreateFromQuaternion(other) * TransformMatrix);
}
public Transform3D Rotate(float yaw, float pitch, float roll)
{
return Rotate(Quaternion.CreateFromYawPitchRoll(
yaw,
pitch,
roll
));
}
public Transform3D Rotate(Vector3 eulerAngles)
{
return Rotate(Quaternion.CreateFromYawPitchRoll(
eulerAngles.X,
eulerAngles.Y,
eulerAngles.Z
));
}
public Transform3D Compose(Transform3D other)
{
return new Transform3D(
other.TransformMatrix * TransformMatrix
);
}
private static Matrix CreateTransformMatrix(Vector3 position, Quaternion orientation, Vector3 scale)
{
return Matrix.CreateScale(scale) *
Matrix.CreateFromQuaternion(orientation) *
Matrix.CreateTranslation(position);
}
public override bool Equals(object other)
{
if (other is Transform3D otherTransform)
{
return Equals(otherTransform);
}
return false;
}
public bool Equals(Transform3D other)
{
return TransformMatrix == other.TransformMatrix;
}
public override int GetHashCode()
{
return TransformMatrix.GetHashCode();
}
public static bool operator ==(Transform3D a, Transform3D b)
{
return a.Equals(b);
}
public static bool operator !=(Transform3D a, Transform3D b)
{
return !(a == b);
}
}
}