Added Entity hierarchy and hierarchical transforms

This commit is contained in:
Simon Lübeß
2021-08-28 22:28:40 +02:00
parent ce03f7c600
commit b376525d30
7 changed files with 127 additions and 53 deletions
+1 -1
View File
@@ -72,7 +72,7 @@ namespace GlitchyEngine.Renderer
var camera = world.GetComponent<CameraComponent>(cameraEntity);
var transform = world.GetComponent<TransformComponent>(cameraEntity);
var trans = transform.Transform;
var trans = transform.WorldTransform;
var view = trans.Invert();
var proj = camera.Projection;
+2 -1
View File
@@ -221,8 +221,9 @@ namespace GlitchyEngine.World
Entity entity = world.NewEntity();
TransformComponent* myComp = world.AssignComponent<TransformComponent>(entity);
myComp.Transform = Matrix.Identity;
myComp.LocalTransform = Matrix.Identity;
#unwarn
TransformComponent gotComp = *world.GetComponent<TransformComponent>(entity);
world.RemoveComponent<TransformComponent>(entity);
@@ -0,0 +1,10 @@
namespace GlitchyEngine.World
{
/**
* A Component that allows to specify a parent entity.
*/
public struct ParentComponent
{
public Entity Entity;
}
}
+14 -20
View File
@@ -8,17 +8,20 @@ namespace GlitchyEngine.World
Vector3 _rotation = .Zero;
Vector3 _scale = .One;
Matrix _transform;
bool _dirty;
Matrix _localTransform;
public bool IsDirty;
public Matrix Transform
public Matrix WorldTransform;
/// The frame when the transform was recalculated
public uint Frame;
public Matrix LocalTransform
{
get mut
{
return _transform;
}
set mut => _transform = value;
get => _localTransform;
set mut => _localTransform = value;
}
public Vector3 Position
{
get => _position;
@@ -28,7 +31,7 @@ namespace GlitchyEngine.World
return;
_position = value;
_dirty = true;
IsDirty = true;
}
}
@@ -41,7 +44,7 @@ namespace GlitchyEngine.World
return;
_rotation = value;
_dirty = true;
IsDirty = true;
}
}
@@ -54,17 +57,8 @@ namespace GlitchyEngine.World
return;
_scale = value;
_dirty = true;
IsDirty = true;
}
}
public void Update() mut
{
if(!_dirty)
return;
_transform = .Translation(_position) * .RotationX(_rotation.X) *
.RotationY(_rotation.Y) * .RotationZ(_rotation.Z) * .Scaling(_scale);
_dirty = false;
}
}
}
@@ -0,0 +1,57 @@
namespace GlitchyEngine.World
{
public static class TransformSystem
{
static uint _frame;
public static void Update(EcsWorld world)
{
_frame++;
for(var entity in world.Enumerate(typeof(TransformComponent)))
{
UpdateEntity(entity, world);
}
}
private static TransformComponent* UpdateEntity(Entity entity, EcsWorld world)
{
// Todo: this probably needs a rewrite as it may scale poorly with deep hierarchies!
var transform = world.GetComponent<TransformComponent>(entity);
// If tranform was updated this frame -> skip
if(transform.Frame == _frame)
return transform;
var parent = world.GetComponent<ParentComponent>(entity);
if(transform.IsDirty)
{
transform.LocalTransform = .Translation(transform.Position) * .RotationX(transform.Rotation.X) *
.RotationY(transform.Rotation.Y) * .RotationZ(transform.Rotation.Z) * .Scaling(transform.Scale);
transform.Frame = _frame;
transform.IsDirty = false;
if(parent == null)
{
transform.WorldTransform = transform.LocalTransform;
}
}
if(parent != null)
{
var parentTransform = UpdateEntity(parent.Entity, world);
// Parent transform is newer than our transform or was updated this frame
if(parentTransform.Frame >= transform.Frame)
{
transform.WorldTransform = parentTransform.WorldTransform * transform.LocalTransform;
transform.Frame = parentTransform.Frame;
}
}
return transform;
}
}
}
+41 -30
View File
@@ -270,23 +270,54 @@ namespace Sandbox
*/
}
Entity evenCrazierParent;
Entity crazyParent;
void InitEcs()
{
_world.Register<TransformComponent>();
_world.Register<ParentComponent>();
_world.Register<MeshComponent>();
_world.Register<CameraComponent>();
Entity[20][20] entities;
for(int x < 20)
for(int y < 20)
{
Entity entity = _world.NewEntity();
entities[x][y] = entity;
var transform = _world.AssignComponent<TransformComponent>(entity);
transform.Transform = Matrix.Translation(x * 0.2f, y * 0.2f, 0) * Matrix.Scaling(0.1f);
transform.LocalTransform = Matrix.Translation(x * 0.2f, y * 0.2f, 0) * Matrix.Scaling(0.1f);
var mesh = _world.AssignComponent<MeshComponent>(entity);
mesh.Mesh = _quadGeometryBinding;
}
crazyParent = _world.NewEntity();
evenCrazierParent = _world.NewEntity();
var crazyTransform = _world.AssignComponent<TransformComponent>(evenCrazierParent);
crazyTransform.Position = .Zero;
crazyTransform.Scale = .One;
crazyTransform.Rotation = .Zero;
var pp = _world.AssignComponent<ParentComponent>(crazyParent);
pp.Entity = evenCrazierParent;
crazyTransform = _world.AssignComponent<TransformComponent>(crazyParent);
crazyTransform.Position = .Zero;
crazyTransform.Scale = .(2.0f, 2.0f, 2.0f);
crazyTransform.Rotation = .Zero;
for(int x < 20)
for(int y < 20)
{
var parent = _world.AssignComponent<ParentComponent>(entities[x][y]);
parent.Entity = crazyParent;
}
}
float f = 0.0f;
@@ -387,39 +418,19 @@ namespace Sandbox
}
}
/*
// Draw bind pose
for(Joint joint in Skeleton.Joints)
{
Matrix bindPose = joint.InverseBindPose.Invert();
if(joint.ParentID != uint8.MaxValue)
{
Vector3 start = bindPose.Translation;
Matrix parentBindPose = Skeleton.Joints[joint.ParentID].InverseBindPose.Invert();
Vector3 end = parentBindPose.Translation;
Renderer.DrawLine(start, end, .White);
}
Renderer.DrawLine(.Zero, Vector3(0.1f, 0, 0), .Red, bindPose);
Renderer.DrawLine(.Zero, Vector3(0, 0.1f, 0), .Lime, bindPose);
Renderer.DrawLine(.Zero, Vector3(0, 0, 0.1f), .Blue, bindPose);
}
*/
testEffect.ReleaseRef();
}
_context.SetRasterizerState(_rasterizerState);
for(var entity in _world.Enumerate(typeof(TransformComponent)))
{
var transform = _world.GetComponent<TransformComponent>(entity);
transform.Update();
}
var crazyTransform = _world.GetComponent<TransformComponent>(evenCrazierParent);
crazyTransform.Rotation += .((float)gameTime.FrameTime.TotalSeconds / 2, 0, 0);
crazyTransform = _world.GetComponent<TransformComponent>(crazyParent);
crazyTransform.Rotation += .(0, (float)gameTime.FrameTime.TotalSeconds, 0);
TransformSystem.Update(_world);
int i = 0;
for(var entity in _world.Enumerate(typeof(TransformComponent), typeof(MeshComponent)))
{
@@ -433,7 +444,7 @@ namespace Sandbox
var transform = _world.GetComponent<TransformComponent>(entity);
var mesh = _world.GetComponent<MeshComponent>(entity);
Renderer.Submit(mesh.Mesh, basicEffect, transform.Transform);
Renderer.Submit(mesh.Mesh, basicEffect, transform.WorldTransform);
}
basicEffect.Variables["BaseColor"].SetData(_squareColor1);
+2 -1
View File
@@ -244,7 +244,8 @@ namespace Sandbox
movement *= (float)(gameTime.FrameTime.TotalSeconds);
cameraTransform.Position += .(movement, 0);
cameraTransform.Update();
Runtime.NotImplemented();
//cameraTransform.Update();
}
var camera = _world.GetComponent<CameraComponent>(_cameraEntity);