commit 4e0d6b84aa2be5c803f8d4ee04561c9a55088bd0
parent 846f38d20589459cc09a38f93fbc5f54feb0195d
Author: Mikolaj Lenczewski <33129490+EnderRifter@users.noreply.github.com>
Date: Sat, 29 Jun 2019 21:27:04 +0100
Started work on proper projection and translation of bodies. Bugged at the moment.
Diffstat:
4 files changed, 76 insertions(+), 18 deletions(-)
diff --git a/StarSim/StarSimLib/Constants.cs b/StarSim/StarSimLib/Constants.cs
@@ -1,5 +1,4 @@
-using SFML.Graphics;
-using StarSimLib.Physics;
+using StarSimLib.Physics;
namespace StarSimLib
{
diff --git a/StarSim/StarSimLib/Graphics/Drawer.cs b/StarSim/StarSimLib/Graphics/Drawer.cs
@@ -12,15 +12,30 @@ namespace StarSimLib.Graphics
public class Drawer
{
/// <summary>
- /// The aspect ratio of the render target. Allows for normalisation of the <see cref="RenderTarget"/> space
- /// into a normal plane ([-1, -1] = top left, [1, 1] = bottom right).
+ /// The furthest distance that can be seen on the <see cref="RenderTarget"/>.
/// </summary>
- private readonly float aspectRatio;
+ private const double farDistance = 1000 * Constants.UniverseSize;
/// <summary>
/// The field of view for the drawer.
/// </summary>
- private readonly float fieldOfView;
+ private const double fieldOfView = 90f;
+
+ /// <summary>
+ /// The closest distance that can be seen on the <see cref="RenderTarget"/>.
+ /// </summary>
+ private const double nearDistance = 0.1;
+
+ /// <summary>
+ /// Inverse scale factor used in the projection matrix.
+ /// </summary>
+ private static readonly double inverseScaleFactor = 1 / Math.Tan(fieldOfView * 0.5 / 180 * Math.PI);
+
+ /// <summary>
+ /// The aspect ratio of the render target. Allows for normalisation of the <see cref="RenderTarget"/> space
+ /// into a normal plane ([-1, -1] = top left, [1, 1] = bottom right).
+ /// </summary>
+ private readonly double aspectRatio;
/// <summary>
/// Holds all the <see cref="Body"/> instances that should be simulated.
@@ -40,6 +55,11 @@ namespace StarSimLib.Graphics
private readonly Vector2u originOffset;
/// <summary>
+ /// Projection matrix used for mapping from 3D to 2D.
+ /// </summary>
+ private readonly Matrix4x4 projectionMatrix;
+
+ /// <summary>
/// The target to which the managed bodies will be drawn.
/// </summary>
private readonly RenderTarget renderTarget;
@@ -56,17 +76,20 @@ namespace StarSimLib.Graphics
public Drawer(RenderTarget target, ref Body[] bodies, ref Dictionary<Body, CircleShape> bodyShapeMap)
{
renderTarget = target;
- aspectRatio = renderTarget.Size.Y / (float)renderTarget.Size.X;
originOffset = target.Size / 2;
- managedBodies = bodies;
+ aspectRatio = renderTarget.Size.Y / (double)renderTarget.Size.X;
- managedBodyShapeMap = bodyShapeMap;
- }
+ projectionMatrix = new Matrix4x4(new[]
+ {
+ new [] { aspectRatio * inverseScaleFactor, 0, 0, 0 },
+ new [] { 0, inverseScaleFactor, 0, 0 },
+ new [] { 0, 0, farDistance / (farDistance - nearDistance), 1 },
+ new [] { 0, 0, -farDistance * nearDistance / (farDistance - nearDistance), 0 }
+ });
- private double InverseScaleFactor
- {
- get { return 1 / Math.Tan(fieldOfView / 2); }
+ managedBodies = bodies;
+ managedBodyShapeMap = bodyShapeMap;
}
/// <summary>
@@ -81,9 +104,24 @@ namespace StarSimLib.Graphics
// which is used as the new position of the shape.
CircleShape shape = managedBodyShapeMap[body];
+ Vector4d worldSpace = body.Position;
+
+ // project the body position
+ Vector4d projectedPosition = (worldSpace * projectionMatrix);
+
+ if (!projectedPosition.W.Equals(0))
+ {
+ projectedPosition.X /= projectedPosition.W;
+ projectedPosition.Y /= projectedPosition.W;
+ projectedPosition.Z /= projectedPosition.W;
+ }
+
+ Vector4d screenPosition = projectedPosition;
+
+ // final position
shape.Position = new Vector2f(
- (float)(body.Position.X * Constants.UniverseScalingFactor + originOffset.X),
- (float)(body.Position.Y * Constants.UniverseScalingFactor + originOffset.Y)
+ (float)(screenPosition.X * 100 + originOffset.X),
+ (float)(screenPosition.Y * 100 + originOffset.Y)
);
/*
diff --git a/StarSim/StarSimLib/Physics/Body.cs b/StarSim/StarSimLib/Physics/Body.cs
@@ -57,6 +57,7 @@ namespace StarSimLib.Physics
Id = id;
this.position = position;
+ this.position.W = 1;
this.velocity = velocity;
this.mass = mass;
diff --git a/StarSim/StarSimLib/StarSimLib.xml b/StarSim/StarSimLib/StarSimLib.xml
@@ -113,10 +113,9 @@
Represents a drawer capable of rendering bodies to a <see cref="T:SFML.Graphics.RenderTarget"/>.
</summary>
</member>
- <member name="F:StarSimLib.Graphics.Drawer.aspectRatio">
+ <member name="F:StarSimLib.Graphics.Drawer.farDistance">
<summary>
- The aspect ratio of the render target. Allows for normalisation of the <see cref="T:SFML.Graphics.RenderTarget"/> space
- into a normal plane ([-1, -1] = top left, [1, 1] = bottom right).
+ The furthest distance that can be seen on the <see cref="T:SFML.Graphics.RenderTarget"/>.
</summary>
</member>
<member name="F:StarSimLib.Graphics.Drawer.fieldOfView">
@@ -124,6 +123,22 @@
The field of view for the drawer.
</summary>
</member>
+ <member name="F:StarSimLib.Graphics.Drawer.nearDistance">
+ <summary>
+ The closest distance that can be seen on the <see cref="T:SFML.Graphics.RenderTarget"/>.
+ </summary>
+ </member>
+ <member name="F:StarSimLib.Graphics.Drawer.inverseScaleFactor">
+ <summary>
+ Inverse scale factor used in the projection matrix.
+ </summary>
+ </member>
+ <member name="F:StarSimLib.Graphics.Drawer.aspectRatio">
+ <summary>
+ The aspect ratio of the render target. Allows for normalisation of the <see cref="T:SFML.Graphics.RenderTarget"/> space
+ into a normal plane ([-1, -1] = top left, [1, 1] = bottom right).
+ </summary>
+ </member>
<member name="F:StarSimLib.Graphics.Drawer.managedBodies">
<summary>
Holds all the <see cref="T:StarSimLib.Physics.Body"/> instances that should be simulated.
@@ -141,6 +156,11 @@
to be in the centre of the render target and not the top left corner.
</summary>
</member>
+ <member name="F:StarSimLib.Graphics.Drawer.projectionMatrix">
+ <summary>
+ Projection matrix used for mapping from 3D to 2D.
+ </summary>
+ </member>
<member name="F:StarSimLib.Graphics.Drawer.renderTarget">
<summary>
The target to which the managed bodies will be drawn.