lots of 3d math stuff

pull/1/head
cosmonaut 2020-08-06 00:00:02 -07:00
parent 305b2d0911
commit e620cc479a
20 changed files with 278 additions and 66 deletions

2
Kav

@ -1 +1 @@
Subproject commit 2419a89d3245dc7d52f6b4301902f840ea10beaf Subproject commit 4c4150620456c6625cf660d7a81571e4b1f7f9d5

View File

@ -5,7 +5,7 @@ VisualStudioVersion = 15.0.26124.0
MinimumVisualStudioVersion = 15.0.26124.0 MinimumVisualStudioVersion = 15.0.26124.0
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KavTest.Core", "KavTest\KavTest.Core.csproj", "{4589302C-174A-4173-9654-CAA6CA1B5220}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KavTest.Core", "KavTest\KavTest.Core.csproj", "{4589302C-174A-4173-9654-CAA6CA1B5220}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "kav", "Kav\kav.csproj", "{08398000-DF30-465A-AE07-E11D108B8A74}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kav", "Kav\Kav.csproj", "{08398000-DF30-465A-AE07-E11D108B8A74}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution

View File

@ -5,7 +5,7 @@ VisualStudioVersion = 15.0.26124.0
MinimumVisualStudioVersion = 15.0.26124.0 MinimumVisualStudioVersion = 15.0.26124.0
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FNATemplate.Framework", "KavTest\KavTest.Framework.csproj", "{9ED076FA-32C3-4F1E-BB90-549B3A2FA46F}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FNATemplate.Framework", "KavTest\KavTest.Framework.csproj", "{9ED076FA-32C3-4F1E-BB90-549B3A2FA46F}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "kav", "Kav\kav.csproj", "{9B2EC2DE-7E2C-4768-B812-43AB4C7E31C5}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kav", "Kav\Kav.csproj", "{9B2EC2DE-7E2C-4768-B812-43AB4C7E31C5}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Smuggler", "Smuggler\Smuggler.csproj", "{06664804-2B01-46F5-B8EC-07E5E2C1EADC}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Smuggler", "Smuggler\Smuggler.csproj", "{06664804-2B01-46F5-B8EC-07E5E2C1EADC}"
EndProject EndProject

View File

@ -5,7 +5,7 @@ namespace KavTest.Components
{ {
public struct AngularVelocityComponent : IComponent public struct AngularVelocityComponent : IComponent
{ {
public Vector3 AngularVelocity { get; } public Vector3 AngularVelocity { get; } // should this be a quaternion?
public AngularVelocityComponent(Vector3 angularVelocity) public AngularVelocityComponent(Vector3 angularVelocity)
{ {

View File

@ -1,15 +1,15 @@
using Encompass; using Encompass;
using Kav; using Microsoft.Xna.Framework;
namespace KavTest.Components namespace KavTest.Components
{ {
public struct CameraComponent : IComponent public struct CameraComponent : IComponent
{ {
public Camera Camera { get; } public Matrix Projection { get; }
public CameraComponent(Camera camera) public CameraComponent(Matrix projection)
{ {
Camera = camera; Projection = projection;
} }
} }
} }

Binary file not shown.

View File

@ -0,0 +1,23 @@
using Encompass;
using KavTest.Components;
using KavTest.Messages;
using Microsoft.Xna.Framework;
namespace KavTest.Engines
{
[Reads(typeof(AngularVelocityComponent))]
[Sends(typeof(LocalRotationMessage))]
public class AngularVelocityEngine : Engine
{
public override void Update(double dt)
{
foreach (var entity in ReadEntities<AngularVelocityComponent>())
{
ref readonly var angularVelocityComponent = ref GetComponent<AngularVelocityComponent>(entity);
var angularVelocity = angularVelocityComponent.AngularVelocity * (float)dt;
SendMessage(new LocalRotationMessage(entity, Quaternion.CreateFromYawPitchRoll(angularVelocity.X, angularVelocity.Y, angularVelocity.Z)));
}
}
}
}

View File

@ -0,0 +1,25 @@
using Encompass;
using KavTest.Components;
using KavTest.Messages;
namespace KavTest.Engines
{
[Reads(typeof(CameraComponent))]
[Receives(typeof(MoveCameraMessage))]
[Sends(typeof(LocalTranslationMessage))]
public class CameraEngine : Engine
{
public override void Update(double dt)
{
if (SomeComponent<CameraComponent>())
{
var cameraEntity = ReadEntity<CameraComponent>();
foreach (var moveMessage in ReadMessages<MoveCameraMessage>())
{
SendMessage(new LocalTranslationMessage(cameraEntity, moveMessage.Translation * (float)dt));
}
}
}
}
}

View File

@ -0,0 +1,36 @@
using Encompass;
using KavTest.Messages;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
namespace KavTest.Engines
{
[Sends(typeof(MoveCameraMessage))]
public class InputEngine : Engine
{
public override void Update(double dt)
{
var keyboardState = Keyboard.GetState();
if (keyboardState.IsKeyDown(Keys.W))
{
SendMessage(new MoveCameraMessage(new Vector3(0, 0, -5)));
}
if (keyboardState.IsKeyDown(Keys.A))
{
SendMessage(new MoveCameraMessage(new Vector3(-5, 0, 0)));
}
if (keyboardState.IsKeyDown(Keys.S))
{
SendMessage(new MoveCameraMessage(new Vector3(0, 0, 5)));
}
if (keyboardState.IsKeyDown(Keys.D))
{
SendMessage(new MoveCameraMessage(new Vector3(5, 0, 0)));
}
}
}
}

View File

@ -0,0 +1,55 @@
using Encompass;
using KavTest.Components;
using KavTest.Messages;
using Microsoft.Xna.Framework;
namespace KavTest.Engines
{
[Reads(typeof(Transform3DComponent))]
[Receives(
typeof(TranslationMessage),
typeof(LocalTranslationMessage),
typeof(LocalRotationMessage)
)]
[Writes(typeof(Transform3DComponent))]
public class MotionEngine : Engine
{
public override void Update(double dt)
{
foreach (var entity in ReadEntities<Transform3DComponent>())
{
ref readonly var transformComponent = ref GetComponent<Transform3DComponent>(entity);
Vector3 translation = Vector3.Zero;
Vector3 localTranslation = Vector3.Zero;
Quaternion rotation = Quaternion.Identity;
Quaternion localRotation = Quaternion.Identity;
foreach (var message in ReadMessagesWithEntity<TranslationMessage>(entity))
{
translation += message.Translation;
}
foreach (var message in ReadMessagesWithEntity<LocalTranslationMessage>(entity))
{
localTranslation += message.Translation;
}
foreach (var message in ReadMessagesWithEntity<LocalRotationMessage>(entity))
{
localRotation *= message.Rotation;
}
var newTransform =
transformComponent.Transform.
TranslateLocal(localTranslation).
RotateLocal(localRotation).
Translate(translation);
SetComponent(entity, new Transform3DComponent(newTransform));
}
}
}
}

View File

@ -1,27 +0,0 @@
using Encompass;
using KavTest.Components;
using Microsoft.Xna.Framework;
namespace KavTest.Engines
{
[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<Transform3DComponent>(entity))
{
ref readonly var angularVelocityComponent = ref GetComponent<AngularVelocityComponent>(entity);
ref readonly var transformComponent = ref GetComponent<Transform3DComponent>(entity);
var angularVelocity = angularVelocityComponent.AngularVelocity * (float)dt;
SetComponent(entity, new Transform3DComponent(transformComponent.Transform.Rotate(angularVelocity)));
}
}
}
}
}

View File

@ -30,7 +30,6 @@
<ProjectReference Include="..\encompass-cs\encompass-cs\encompass-cs.csproj" /> <ProjectReference Include="..\encompass-cs\encompass-cs\encompass-cs.csproj" />
<ProjectReference Include="..\Kav\Kav.csproj" /> <ProjectReference Include="..\Kav\Kav.csproj" />
<ProjectReference Include="..\Smuggler\Smuggler.csproj" /> <ProjectReference Include="..\Smuggler\Smuggler.csproj" />
<ProjectReference Include="..\NoAlloq\NoAlloq\NoAlloq.csproj" />
</ItemGroup> </ItemGroup>
<Import Project="..\build\CopyFNALibs.targets"/> <Import Project="..\build\CopyFNALibs.targets"/>
<Import Sdk="Microsoft.NET.Sdk" Project="Sdk.targets" /> <Import Sdk="Microsoft.NET.Sdk" Project="Sdk.targets" />

View File

@ -33,10 +33,13 @@ namespace KavTest
{ {
var rustyBallModel = ModelLoader.Load( var rustyBallModel = ModelLoader.Load(
GraphicsDevice, GraphicsDevice,
Smuggler.Importer.ImportGLB(GraphicsDevice, File.OpenRead("Content/cube.glb")) Smuggler.Importer.ImportGLB(GraphicsDevice, File.OpenRead("Content/rustysphere.glb"))
); );
WorldBuilder.AddEngine(new RotationEngine()); WorldBuilder.AddEngine(new InputEngine());
WorldBuilder.AddEngine(new AngularVelocityEngine());
WorldBuilder.AddEngine(new MotionEngine());
WorldBuilder.AddEngine(new CameraEngine());
WorldBuilder.AddEngine(new RustyBallSpawner(rustyBallModel)); WorldBuilder.AddEngine(new RustyBallSpawner(rustyBallModel));
WorldBuilder.AddEngine(new LightBulbSpawner()); WorldBuilder.AddEngine(new LightBulbSpawner());
WorldBuilder.AddGeneralRenderer(new SceneRenderer(GraphicsDevice), 0); WorldBuilder.AddGeneralRenderer(new SceneRenderer(GraphicsDevice), 0);
@ -47,12 +50,12 @@ namespace KavTest
)); ));
WorldBuilder.SendMessage(new RustyBallSpawnMessage( WorldBuilder.SendMessage(new RustyBallSpawnMessage(
new Transform3D(new Vector3(-5, 0, 0)), new Transform3D(new Vector3(-3, 0, 0)),
new Vector3(-1, 1, -1) new Vector3(-1, 1, -1)
)); ));
WorldBuilder.SendMessage(new RustyBallSpawnMessage( WorldBuilder.SendMessage(new RustyBallSpawnMessage(
new Transform3D(new Vector3(5, 0, 0)), new Transform3D(new Vector3(3, 0, 0)),
new Vector3(-1, 1, 1) new Vector3(-1, 1, 1)
)); ));
@ -62,11 +65,22 @@ namespace KavTest
300f 300f
)); ));
var cameraMatrix = Matrix.CreateLookAt(new Vector3(10, 0, 0), Vector3.Zero, Vector3.Up); var cameraTransform = new Transform3D(
new Vector3(0, 0, -10),
Quaternion.CreateFromAxisAngle(Vector3.Up, MathHelper.Pi),
Vector3.One
);
var cameraEntity = WorldBuilder.CreateEntity(); var cameraEntity = WorldBuilder.CreateEntity();
WorldBuilder.SetComponent(cameraEntity, new Transform3DComponent(
cameraTransform
));
WorldBuilder.SetComponent(cameraEntity, new CameraComponent( WorldBuilder.SetComponent(cameraEntity, new CameraComponent(
new Kav.Camera( Matrix.CreatePerspectiveFieldOfView(
cameraMatrix MathHelper.PiOver4,
16f / 9f,
0.1f,
200f
) )
)); ));

View File

@ -0,0 +1,17 @@
using Encompass;
using Microsoft.Xna.Framework;
namespace KavTest.Messages
{
public struct LocalRotationMessage : IMessage, IHasEntity
{
public Entity Entity { get; }
public Quaternion Rotation { get; }
public LocalRotationMessage(Entity entity, Quaternion rotation)
{
Entity = entity;
Rotation = rotation;
}
}
}

View File

@ -0,0 +1,17 @@
using Encompass;
using Microsoft.Xna.Framework;
namespace KavTest.Messages
{
public struct LocalTranslationMessage : IMessage, IHasEntity
{
public Entity Entity { get; }
public Vector3 Translation { get; }
public LocalTranslationMessage(Entity entity, Vector3 translation)
{
Entity = entity;
Translation = translation;
}
}
}

View File

@ -0,0 +1,15 @@
using Encompass;
using Microsoft.Xna.Framework;
namespace KavTest.Messages
{
public struct MoveCameraMessage : IMessage
{
public Vector3 Translation { get; }
public MoveCameraMessage(Vector3 translation)
{
Translation = translation;
}
}
}

View File

@ -0,0 +1,17 @@
using Encompass;
using Microsoft.Xna.Framework;
namespace KavTest.Messages
{
public struct TranslationMessage : IMessage, IHasEntity
{
public Entity Entity { get; }
public Vector3 Translation { get; }
public TranslationMessage(Entity entity, Vector3 translation)
{
Entity = entity;
Translation = translation;
}
}
}

View File

@ -53,11 +53,18 @@ namespace KavTest.Renderers
{ {
if (SomeComponent<CameraComponent>()) if (SomeComponent<CameraComponent>())
{ {
var cameraComponent = ReadComponent<CameraComponent>(); var cameraEntity = ReadEntity<CameraComponent>();
var transformComponent = GetComponent<Transform3DComponent>(cameraEntity);
var cameraComponent = GetComponent<CameraComponent>(cameraEntity);
var camera = new Kav.Camera(
transformComponent.Transform.TransformMatrix,
cameraComponent.Projection
);
Kav.Renderer.Render( Kav.Renderer.Render(
GraphicsDevice, GraphicsDevice,
cameraComponent.Camera, camera,
Models, Models,
PointLights PointLights
); );

View File

@ -4,57 +4,73 @@ namespace KavTest
{ {
public struct Transform3D : System.IEquatable<Transform3D> public struct Transform3D : System.IEquatable<Transform3D>
{ {
public Matrix TransformMatrix { get; private set; } public static Transform3D Identity = new Transform3D(Vector3.Zero, Quaternion.Identity, Vector3.One);
public Vector3 Position { get; private set; } public Matrix TransformMatrix { get; }
public Vector3 Position { get; }
public Quaternion Orientation { get; }
public Vector3 Scale { get; }
public Vector3 Forward { get { return TransformMatrix.Forward; } } public Vector3 Forward { get { return TransformMatrix.Forward; } }
public Vector3 Right { get { return TransformMatrix.Right; } }
public Vector3 Up { get { return TransformMatrix.Up; } }
public Transform3D(Vector3 position, Quaternion orientation, Vector3 scale) public Transform3D(Vector3 position, Quaternion orientation, Vector3 scale)
{ {
Position = position; Position = position;
TransformMatrix = CreateTransformMatrix(position, orientation, scale); Orientation = orientation;
Scale = scale;
TransformMatrix = CreateTransformMatrix(Position, Orientation, Scale);
}
public Transform3D(Vector3 position, Quaternion orientation)
{
Position = position;
Orientation = orientation;
Scale = Vector3.One;
TransformMatrix = CreateTransformMatrix(Position, Orientation, Scale);
} }
public Transform3D(Vector3 position) public Transform3D(Vector3 position)
{ {
Position = position; Position = position;
TransformMatrix = CreateTransformMatrix(position, Quaternion.Identity, Vector3.One); Orientation = Quaternion.Identity;
} Scale = Vector3.One;
TransformMatrix = CreateTransformMatrix(Position, Orientation, Scale);
public Transform3D(Matrix matrix)
{
Position = matrix.Translation;
TransformMatrix = matrix;
} }
public Transform3D WithPosition(Vector3 position) public Transform3D WithPosition(Vector3 position)
{ {
return Translate(position - TransformMatrix.Translation); return Translate(position - Position);
} }
public Transform3D Translate(Vector3 translation) public Transform3D Translate(Vector3 translation)
{ {
return new Transform3D(Matrix.CreateTranslation(translation) * TransformMatrix); return new Transform3D(Position + translation, Orientation, Scale);
} }
public Transform3D Rotate(Quaternion other) public Transform3D TranslateLocal(Vector3 translation)
{ {
return new Transform3D(Matrix.CreateFromQuaternion(other) * TransformMatrix); return Translate(Vector3.Transform(translation, Orientation));
} }
public Transform3D Rotate(float yaw, float pitch, float roll) public Transform3D RotateLocal(Quaternion other)
{ {
return Rotate(Quaternion.CreateFromYawPitchRoll( return new Transform3D(Position, Orientation * other, Scale);
}
public Transform3D RotateLocal(float yaw, float pitch, float roll)
{
return RotateLocal(Quaternion.CreateFromYawPitchRoll(
yaw, yaw,
pitch, pitch,
roll roll
)); ));
} }
public Transform3D Rotate(Vector3 eulerAngles) public Transform3D RotateLocal(Vector3 eulerAngles)
{ {
return Rotate(Quaternion.CreateFromYawPitchRoll( return RotateLocal(Quaternion.CreateFromYawPitchRoll(
eulerAngles.X, eulerAngles.X,
eulerAngles.Y, eulerAngles.Y,
eulerAngles.Z eulerAngles.Z
@ -63,9 +79,7 @@ namespace KavTest
public Transform3D Compose(Transform3D other) public Transform3D Compose(Transform3D other)
{ {
return new Transform3D( return new Transform3D(Position + other.Position, Orientation * other.Orientation, Scale * other.Scale);
other.TransformMatrix * TransformMatrix
);
} }
private static Matrix CreateTransformMatrix(Vector3 position, Quaternion orientation, Vector3 scale) private static Matrix CreateTransformMatrix(Vector3 position, Quaternion orientation, Vector3 scale)