arcball transform system for camera
parent
df59c033ef
commit
a8e8402833
2
FNA
2
FNA
|
@ -1 +1 @@
|
||||||
Subproject commit 9a8a84c3d427f47759a92342aaa8f7f08e751a64
|
Subproject commit c665d2e08c25fb63e58e987b7c1af75af22aa010
|
2
Kav
2
Kav
|
@ -1 +1 @@
|
||||||
Subproject commit d156fbc39a771ac990cbb809b82ba771464785a5
|
Subproject commit 55b1555df2ded543e623c8b5eb60d3a3fff9e32c
|
|
@ -0,0 +1,14 @@
|
||||||
|
using Encompass;
|
||||||
|
|
||||||
|
namespace KavTest
|
||||||
|
{
|
||||||
|
public struct ArcballTransformComponent : IComponent
|
||||||
|
{
|
||||||
|
public ArcballTransform ArcballTransform { get; }
|
||||||
|
|
||||||
|
public ArcballTransformComponent(ArcballTransform arcballTransform)
|
||||||
|
{
|
||||||
|
ArcballTransform = arcballTransform;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,9 +4,9 @@ using KavTest.Messages;
|
||||||
|
|
||||||
namespace KavTest.Engines
|
namespace KavTest.Engines
|
||||||
{
|
{
|
||||||
[Reads(typeof(CameraComponent))]
|
[Reads(typeof(CameraComponent), typeof(ArcballTransformComponent))]
|
||||||
[Receives(typeof(MoveCameraMessage))]
|
[Receives(typeof(MoveCameraMessage), typeof(RotateCameraMessage))]
|
||||||
[Sends(typeof(LocalTranslationMessage))]
|
[Writes(typeof(ArcballTransformComponent))]
|
||||||
public class CameraEngine : Engine
|
public class CameraEngine : Engine
|
||||||
{
|
{
|
||||||
public override void Update(double dt)
|
public override void Update(double dt)
|
||||||
|
@ -14,11 +14,21 @@ namespace KavTest.Engines
|
||||||
if (SomeComponent<CameraComponent>())
|
if (SomeComponent<CameraComponent>())
|
||||||
{
|
{
|
||||||
var cameraEntity = ReadEntity<CameraComponent>();
|
var cameraEntity = ReadEntity<CameraComponent>();
|
||||||
|
var arcballTransformComponent = GetComponent<ArcballTransformComponent>(cameraEntity);
|
||||||
|
|
||||||
|
var transform = arcballTransformComponent.ArcballTransform;
|
||||||
|
|
||||||
foreach (var moveMessage in ReadMessages<MoveCameraMessage>())
|
foreach (var moveMessage in ReadMessages<MoveCameraMessage>())
|
||||||
{
|
{
|
||||||
SendMessage(new LocalTranslationMessage(cameraEntity, moveMessage.Translation * (float)dt));
|
transform = transform.TranslateLocal(moveMessage.Translation * (float)dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (var rotateMessage in ReadMessages<RotateCameraMessage>())
|
||||||
|
{
|
||||||
|
transform = transform.RotateLocal(-rotateMessage.Yaw * 0.25f * (float)dt, rotateMessage.Pitch * 0.25f * (float)dt);
|
||||||
|
}
|
||||||
|
|
||||||
|
SetComponent(cameraEntity, new ArcballTransformComponent(transform));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,35 @@
|
||||||
using Encompass;
|
using Encompass;
|
||||||
|
using KavTest.Components;
|
||||||
using KavTest.Messages;
|
using KavTest.Messages;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using Microsoft.Xna.Framework.Input;
|
using Microsoft.Xna.Framework.Input;
|
||||||
|
|
||||||
namespace KavTest.Engines
|
namespace KavTest.Engines
|
||||||
{
|
{
|
||||||
[Sends(typeof(MoveCameraMessage))]
|
[Reads(typeof(CameraComponent))]
|
||||||
|
[Sends(
|
||||||
|
typeof(MoveCameraMessage),
|
||||||
|
typeof(RotateCameraMessage)
|
||||||
|
)]
|
||||||
public class InputEngine : Engine
|
public class InputEngine : Engine
|
||||||
{
|
{
|
||||||
|
private int centerX;
|
||||||
|
private int centerY;
|
||||||
|
|
||||||
|
public InputEngine(int centerX, int centerY)
|
||||||
|
{
|
||||||
|
System.Console.WriteLine(centerX);
|
||||||
|
System.Console.WriteLine(centerY);
|
||||||
|
this.centerX = centerX;
|
||||||
|
this.centerY = centerY;
|
||||||
|
Mouse.SetPosition(centerX, centerY);
|
||||||
|
System.Console.WriteLine(Mouse.GetState().X);
|
||||||
|
}
|
||||||
|
|
||||||
public override void Update(double dt)
|
public override void Update(double dt)
|
||||||
{
|
{
|
||||||
var keyboardState = Keyboard.GetState();
|
var keyboardState = Keyboard.GetState();
|
||||||
|
var mouseState = Mouse.GetState();
|
||||||
|
|
||||||
if (keyboardState.IsKeyDown(Keys.W))
|
if (keyboardState.IsKeyDown(Keys.W))
|
||||||
{
|
{
|
||||||
|
@ -31,6 +50,15 @@ namespace KavTest.Engines
|
||||||
{
|
{
|
||||||
SendMessage(new MoveCameraMessage(new Vector3(5, 0, 0)));
|
SendMessage(new MoveCameraMessage(new Vector3(5, 0, 0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var mouseMovement = new Vector2(centerX - mouseState.X, centerY - mouseState.Y);
|
||||||
|
Mouse.SetPosition(centerX, centerY);
|
||||||
|
|
||||||
|
if (SomeComponent<CameraComponent>())
|
||||||
|
{
|
||||||
|
var cameraEntity = ReadEntity<CameraComponent>();
|
||||||
|
SendMessage(new RotateCameraMessage(cameraEntity, mouseMovement.X, mouseMovement.Y));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@ namespace KavTest
|
||||||
Smuggler.Importer.ImportGLB(GraphicsDevice, File.OpenRead("Content/rustysphere.glb"))
|
Smuggler.Importer.ImportGLB(GraphicsDevice, File.OpenRead("Content/rustysphere.glb"))
|
||||||
);
|
);
|
||||||
|
|
||||||
WorldBuilder.AddEngine(new InputEngine());
|
WorldBuilder.AddEngine(new InputEngine(GraphicsDevice.Viewport.Width / 2, GraphicsDevice.Viewport.Height / 2));
|
||||||
WorldBuilder.AddEngine(new AngularVelocityEngine());
|
WorldBuilder.AddEngine(new AngularVelocityEngine());
|
||||||
WorldBuilder.AddEngine(new MotionEngine());
|
WorldBuilder.AddEngine(new MotionEngine());
|
||||||
WorldBuilder.AddEngine(new CameraEngine());
|
WorldBuilder.AddEngine(new CameraEngine());
|
||||||
|
@ -65,15 +65,13 @@ namespace KavTest
|
||||||
300f
|
300f
|
||||||
));
|
));
|
||||||
|
|
||||||
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(
|
WorldBuilder.SetComponent(cameraEntity, new ArcballTransformComponent(
|
||||||
cameraTransform
|
new ArcballTransform(
|
||||||
|
new Vector3(0, 0, -10),
|
||||||
|
MathHelper.Pi,
|
||||||
|
0
|
||||||
|
)
|
||||||
));
|
));
|
||||||
WorldBuilder.SetComponent(cameraEntity, new CameraComponent(
|
WorldBuilder.SetComponent(cameraEntity, new CameraComponent(
|
||||||
Matrix.CreatePerspectiveFieldOfView(
|
Matrix.CreatePerspectiveFieldOfView(
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
using Encompass;
|
||||||
|
|
||||||
|
namespace KavTest
|
||||||
|
{
|
||||||
|
public struct RotateCameraMessage : IMessage, IHasEntity
|
||||||
|
{
|
||||||
|
public Entity Entity { get; }
|
||||||
|
public float Yaw { get; }
|
||||||
|
public float Pitch { get; }
|
||||||
|
|
||||||
|
public RotateCameraMessage(Entity entity, float yaw, float pitch)
|
||||||
|
{
|
||||||
|
Entity = entity;
|
||||||
|
Yaw = yaw;
|
||||||
|
Pitch = pitch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -54,11 +54,11 @@ namespace KavTest.Renderers
|
||||||
if (SomeComponent<CameraComponent>())
|
if (SomeComponent<CameraComponent>())
|
||||||
{
|
{
|
||||||
var cameraEntity = ReadEntity<CameraComponent>();
|
var cameraEntity = ReadEntity<CameraComponent>();
|
||||||
var transformComponent = GetComponent<Transform3DComponent>(cameraEntity);
|
var transformComponent = GetComponent<ArcballTransformComponent>(cameraEntity);
|
||||||
var cameraComponent = GetComponent<CameraComponent>(cameraEntity);
|
var cameraComponent = GetComponent<CameraComponent>(cameraEntity);
|
||||||
|
|
||||||
var camera = new Kav.Camera(
|
var camera = new Kav.Camera(
|
||||||
transformComponent.Transform.TransformMatrix,
|
transformComponent.ArcballTransform.TransformMatrix,
|
||||||
cameraComponent.Projection
|
cameraComponent.Projection
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
using Microsoft.Xna.Framework;
|
||||||
|
|
||||||
|
namespace KavTest
|
||||||
|
{
|
||||||
|
public struct ArcballTransform
|
||||||
|
{
|
||||||
|
public Vector3 Position { get; }
|
||||||
|
public float Yaw { get; }
|
||||||
|
public float Pitch { get; }
|
||||||
|
|
||||||
|
private Matrix RotationMatrix { get; }
|
||||||
|
public Matrix TransformMatrix { get; }
|
||||||
|
public Vector3 Forward { get { return TransformMatrix.Forward; } }
|
||||||
|
public Vector3 Right { get { return TransformMatrix.Right; } }
|
||||||
|
public Vector3 Up { get { return TransformMatrix.Up; } }
|
||||||
|
|
||||||
|
public ArcballTransform(Vector3 position, float yaw, float pitch)
|
||||||
|
{
|
||||||
|
Position = position;
|
||||||
|
Yaw = yaw;
|
||||||
|
Pitch = pitch;
|
||||||
|
RotationMatrix = CreateRotationMatrix(Yaw, Pitch);
|
||||||
|
TransformMatrix = CreateTransformMatrix(Position, RotationMatrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArcballTransform RotateLocal(float deltaYaw, float deltaPitch)
|
||||||
|
{
|
||||||
|
return new ArcballTransform(Position, Yaw + deltaYaw, Pitch + deltaPitch);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArcballTransform TranslateLocal(Vector3 localTranslation)
|
||||||
|
{
|
||||||
|
var worldTranslation = Vector3.Transform(localTranslation, RotationMatrix);
|
||||||
|
return new ArcballTransform(Position + worldTranslation, Yaw, Pitch);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Matrix CreateRotationMatrix(float yaw, float pitch)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
Matrix.CreateRotationX(pitch) *
|
||||||
|
Matrix.CreateRotationY(yaw);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Matrix CreateTransformMatrix(Vector3 position, Matrix rotation)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
rotation *
|
||||||
|
Matrix.CreateTranslation(position);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1 +1 @@
|
||||||
Subproject commit 0a30dab3c2a8ef4ce435af8123bcb64efe4926d8
|
Subproject commit bdd9f595493609444d8ebb31b9d07b7ef320eafb
|
Loading…
Reference in New Issue