StarSim

StarSim.git
git clone git://git.lenczewski.org/StarSim.git
Log | Files | Refs | README | LICENSE

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:
MStarSim/StarSimLib/Constants.cs | 3+--
MStarSim/StarSimLib/Graphics/Drawer.cs | 64+++++++++++++++++++++++++++++++++++++++++++++++++++-------------
MStarSim/StarSimLib/Physics/Body.cs | 1+
MStarSim/StarSimLib/StarSimLib.xml | 26+++++++++++++++++++++++---
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.