aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbonmas14 <bonmas14@gmail.com>2023-10-24 20:59:19 +0300
committerbonmas14 <bonmas14@gmail.com>2023-10-24 20:59:19 +0300
commitbb22f05857bf5358343de294e98a655370e327aa (patch)
tree482f7f193105619006fb552616224ec1712908b3
parentaad3d0382c498f6a39e5dbf5c9682e18127df353 (diff)
downloadRayRoom-bb22f05857bf5358343de294e98a655370e327aa.tar.gz
RayRoom-bb22f05857bf5358343de294e98a655370e327aa.zip
- raycasting
- System.Drawing visualization - some tests
-rw-r--r--AudioTester/AudioTester.csproj25
-rw-r--r--AudioTester/Core/Extensions/Matrix2x2Extensions.cs14
-rw-r--r--AudioTester/Core/RenderStreamer.cs44
-rw-r--r--AudioTester/Program.cs56
-rw-r--r--AudioTester/RayRoomSettings.cs17
-rw-r--r--AudioTester/Resources/test.wavbin0 -> 672214 bytes
-rw-r--r--RayRoom.Tests/GlobalUsings.cs1
-rw-r--r--RayRoom.Tests/MathTest.cs41
-rw-r--r--RayRoom.Tests/RayRoom.Tests.csproj23
-rw-r--r--RayRoom.sln14
-rw-r--r--RayRoom/Core/AudioSimulator.cs54
-rw-r--r--RayRoom/Core/CastInfo.cs26
-rw-r--r--RayRoom/Core/CollisionHelpers.cs146
-rw-r--r--RayRoom/Core/IStructure.cs7
-rw-r--r--RayRoom/Core/Line.cs21
-rw-r--r--RayRoom/Core/Matrix2x2.cs39
-rw-r--r--RayRoom/Core/Ray.cs15
-rw-r--r--RayRoom/Core/Settings.cs7
-rw-r--r--RayRoom/Core/Sphere.cs21
19 files changed, 563 insertions, 8 deletions
diff --git a/AudioTester/AudioTester.csproj b/AudioTester/AudioTester.csproj
new file mode 100644
index 0000000..fc07b92
--- /dev/null
+++ b/AudioTester/AudioTester.csproj
@@ -0,0 +1,25 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <OutputType>Exe</OutputType>
+ <TargetFramework>net6.0</TargetFramework>
+ <ImplicitUsings>enable</ImplicitUsings>
+ <Nullable>enable</Nullable>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <PackageReference Include="NAudio" Version="2.2.1" />
+ <PackageReference Include="System.Drawing.Common" Version="7.0.0" />
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="Resources\*">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ </ItemGroup>
+ <ItemGroup>
+ <None Remove="Resources\test.wav" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\RayRoom\RayRoom.csproj" />
+ </ItemGroup>
+</Project>
diff --git a/AudioTester/Core/Extensions/Matrix2x2Extensions.cs b/AudioTester/Core/Extensions/Matrix2x2Extensions.cs
new file mode 100644
index 0000000..0e0b405
--- /dev/null
+++ b/AudioTester/Core/Extensions/Matrix2x2Extensions.cs
@@ -0,0 +1,14 @@
+using System.Drawing;
+using System.Numerics;
+
+namespace AudioTester.Core.Extensions
+{
+ internal static class PointExtensions
+ {
+ public static Point GetPoint(this Vector2 vector)
+ {
+ return new Point((int)MathF.Round(vector.X), (int)MathF.Round(vector.Y));
+ }
+ }
+
+}
diff --git a/AudioTester/Core/RenderStreamer.cs b/AudioTester/Core/RenderStreamer.cs
new file mode 100644
index 0000000..85f76a5
--- /dev/null
+++ b/AudioTester/Core/RenderStreamer.cs
@@ -0,0 +1,44 @@
+using NAudio.Codecs;
+using NAudio.Wave;
+using NAudio.Wave.SampleProviders;
+
+namespace AudioTester.Core
+{
+ internal class RenderStreamer : ISampleProvider
+ {
+ public WaveFormat WaveFormat { get; }
+
+ private const int ReadBufferSize = 1024;
+ private int sample;
+ private Random rand;
+
+ private AudioFileReader streamReader;
+ private ISampleProvider provider;
+
+ public RenderStreamer()
+ {
+ rand = new Random();
+ WaveFormat = WaveFormat.CreateIeeeFloatWaveFormat(44100, 2);
+ sample = 0;
+
+ streamReader = new AudioFileReader(@"Resources\test.wav");
+
+ provider = streamReader.ToSampleProvider();
+ }
+
+ public int Read(float[] buffer, int offset, int count)
+ {
+ int length = provider.Read(buffer, offset, count);
+
+ Console.WriteLine("i: {0}; o:{1}", count, length);
+
+ if (length < count)
+ {
+ streamReader.Position = 0;
+ length += provider.Read(buffer, length, count - length);
+ }
+
+ return length;
+ }
+ }
+}
diff --git a/AudioTester/Program.cs b/AudioTester/Program.cs
new file mode 100644
index 0000000..7557142
--- /dev/null
+++ b/AudioTester/Program.cs
@@ -0,0 +1,56 @@
+using AudioTester.Core;
+using AudioTester.Core.Extensions;
+using NAudio.Wave;
+using RayRoom.Core;
+using System.Drawing;
+using System.Numerics;
+
+namespace AudioTester
+{
+ internal class Program
+ {
+#pragma warning disable CA1416 // Проверка совместимости платформы
+ static void Main(string[] args)
+ {
+ AudioSimulator a = new AudioSimulator();
+
+ var array = a.Simulate(Vector2.Zero, 360);
+ var bitmap = new Bitmap(2000, 2000);
+
+ Matrix2x2 mat = new Matrix2x2(Vector2.UnitX * 100f, Vector2.UnitY * -100f);
+
+ Pen background = new Pen(Color.FromArgb(5, Color.White), 4);
+ Pen foreground = new Pen(Color.FromArgb(25, Color.White), 1);
+
+ using (Graphics g = Graphics.FromImage(bitmap))
+ {
+ g.Clear(Color.Black);
+
+ for (int i = 0; i < array.Length; i++)
+ {
+ g.DrawLine(background, (mat * array[i].a + new Vector2(1000, 1000)).GetPoint(), (mat * array[i].b + new Vector2(1000, 1000)).GetPoint());
+ g.DrawLine(foreground, (mat * array[i].a + new Vector2(1000, 1000)).GetPoint(), (mat * array[i].b + new Vector2(1000, 1000)).GetPoint());
+ }
+ }
+
+ bitmap.Save("bitmap.bmp");
+#pragma warning restore CA1416 // Проверка совместимости платформы
+ return;
+ var device = new RenderStreamer();
+
+ using (var wo = new WasapiOut(NAudio.CoreAudioApi.AudioClientShareMode.Shared, 150))
+ {
+ wo.Init(device);
+ wo.Play();
+
+ while (wo.PlaybackState == PlaybackState.Playing)
+ {
+ Thread.Sleep(100);
+
+ if (Console.KeyAvailable)
+ wo.Stop();
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/AudioTester/RayRoomSettings.cs b/AudioTester/RayRoomSettings.cs
new file mode 100644
index 0000000..c469279
--- /dev/null
+++ b/AudioTester/RayRoomSettings.cs
@@ -0,0 +1,17 @@
+using NAudio.Wave;
+using RayRoom.Core;
+
+namespace AudioTester
+{
+ internal static class RayRoomSettings
+ {
+ public static Settings GetSettingsFromWaveFromat(WaveFormat format, Settings baseSettings)
+ {
+ return new Settings(format.SampleRate,
+ baseSettings.maxRayReflections,
+ baseSettings.maxDiffusionRays,
+ baseSettings.fadeFactorPerMeter,
+ baseSettings.speedOfSoundMetersPerSec);
+ }
+ }
+}
diff --git a/AudioTester/Resources/test.wav b/AudioTester/Resources/test.wav
new file mode 100644
index 0000000..8ca09a1
--- /dev/null
+++ b/AudioTester/Resources/test.wav
Binary files differ
diff --git a/RayRoom.Tests/GlobalUsings.cs b/RayRoom.Tests/GlobalUsings.cs
new file mode 100644
index 0000000..ab67c7e
--- /dev/null
+++ b/RayRoom.Tests/GlobalUsings.cs
@@ -0,0 +1 @@
+global using Microsoft.VisualStudio.TestTools.UnitTesting; \ No newline at end of file
diff --git a/RayRoom.Tests/MathTest.cs b/RayRoom.Tests/MathTest.cs
new file mode 100644
index 0000000..804f32c
--- /dev/null
+++ b/RayRoom.Tests/MathTest.cs
@@ -0,0 +1,41 @@
+using RayRoom.Core;
+using System.Numerics;
+
+namespace RayRoom.Tests
+{
+ [TestClass]
+ public class MathTest
+ {
+ [TestMethod]
+ public void TestRayCollision()
+ {
+ Ray a = new Ray(Vector2.Zero, Vector2.UnitY);
+ Ray b = new Ray(new Vector2(4, 5), -Vector2.UnitX);
+ Ray c = new Ray(Vector2.One, -Vector2.UnitX);
+ Ray d = new Ray(Vector2.One, Vector2.UnitX);
+
+ Assert.IsTrue(CollisionHelpers.RaycastRayToRay(a, b, out CastInfo info));
+ Console.WriteLine(info.ToString());
+ Assert.IsTrue(CollisionHelpers.RaycastRayToRay(a, c, out info));
+ Console.WriteLine(info.ToString());
+ Assert.IsFalse(CollisionHelpers.RaycastRayToRay(a, d, out info));
+ Console.WriteLine(info.ToString());
+ }
+
+ [TestMethod]
+ public void TestRayToLineCollision()
+ {
+ Line a = new Line(Vector2.Zero, new Vector2(0, 4));
+ Ray b = new Ray(new Vector2(4, 5), -Vector2.UnitX);
+ Ray c = new Ray(Vector2.One, -Vector2.UnitX);
+ Ray d = new Ray(Vector2.One, Vector2.UnitX);
+
+ Assert.IsFalse(CollisionHelpers.RaycastRayToLine(a, b, out CastInfo info));
+ Console.WriteLine(info.ToString());
+ Assert.IsTrue(CollisionHelpers.RaycastRayToLine(a, c, out info));
+ Console.WriteLine(info.ToString());
+ Assert.IsFalse(CollisionHelpers.RaycastRayToLine(a, d, out info));
+ Console.WriteLine(info.ToString());
+ }
+ }
+} \ No newline at end of file
diff --git a/RayRoom.Tests/RayRoom.Tests.csproj b/RayRoom.Tests/RayRoom.Tests.csproj
new file mode 100644
index 0000000..ab4b2fe
--- /dev/null
+++ b/RayRoom.Tests/RayRoom.Tests.csproj
@@ -0,0 +1,23 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <TargetFramework>net6.0</TargetFramework>
+ <ImplicitUsings>enable</ImplicitUsings>
+ <Nullable>enable</Nullable>
+
+ <IsPackable>false</IsPackable>
+ <IsTestProject>true</IsTestProject>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
+ <PackageReference Include="MSTest.TestAdapter" Version="2.2.10" />
+ <PackageReference Include="MSTest.TestFramework" Version="2.2.10" />
+ <PackageReference Include="coverlet.collector" Version="3.2.0" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\RayRoom\RayRoom.csproj" />
+ </ItemGroup>
+
+</Project>
diff --git a/RayRoom.sln b/RayRoom.sln
index 5dd8ab3..3c6a15a 100644
--- a/RayRoom.sln
+++ b/RayRoom.sln
@@ -3,7 +3,11 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.7.34031.279
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RayRoom", "RayRoom\RayRoom.csproj", "{230DBE77-7C79-48AB-80F9-7ACBA8654F9E}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RayRoom", "RayRoom\RayRoom.csproj", "{230DBE77-7C79-48AB-80F9-7ACBA8654F9E}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AudioTester", "AudioTester\AudioTester.csproj", "{BDA8477C-5901-4849-98D7-134871412EF5}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RayRoom.Tests", "RayRoom.Tests\RayRoom.Tests.csproj", "{B077A864-8279-4237-858B-37AA5A66C10D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -15,6 +19,14 @@ Global
{230DBE77-7C79-48AB-80F9-7ACBA8654F9E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{230DBE77-7C79-48AB-80F9-7ACBA8654F9E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{230DBE77-7C79-48AB-80F9-7ACBA8654F9E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {BDA8477C-5901-4849-98D7-134871412EF5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BDA8477C-5901-4849-98D7-134871412EF5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BDA8477C-5901-4849-98D7-134871412EF5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BDA8477C-5901-4849-98D7-134871412EF5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B077A864-8279-4237-858B-37AA5A66C10D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B077A864-8279-4237-858B-37AA5A66C10D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B077A864-8279-4237-858B-37AA5A66C10D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B077A864-8279-4237-858B-37AA5A66C10D}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/RayRoom/Core/AudioSimulator.cs b/RayRoom/Core/AudioSimulator.cs
index 0451c0e..78cb356 100644
--- a/RayRoom/Core/AudioSimulator.cs
+++ b/RayRoom/Core/AudioSimulator.cs
@@ -1,4 +1,6 @@
using System;
+using System.Numerics;
+using System.Xml;
namespace RayRoom.Core
{
@@ -6,5 +8,57 @@ namespace RayRoom.Core
{
private Settings simulationSettings;
+ public Line[] Simulate(Vector2 position, int count)
+ {
+ Ray[] startupRays = new Ray[count];
+ for (int i = 0; i < count; i++)
+ {
+ float angle = i / (float)count * MathF.PI * 2f;
+ startupRays[i] = new Ray(position, UnitVectorFromAngle(angle));
+ }
+
+ List<IStructure> structures = new List<IStructure>
+ {
+ new Sphere(new Vector2(0, -3), 2f),
+ new Sphere(new Vector2(5, 3), 2f),
+ new Sphere(new Vector2(-0.5f, 0.5f), 0.5f),
+ new Line(new Vector2(-10, -10), new Vector2(0, 10)),
+ };
+
+ List<Ray> rays = new List<Ray>(startupRays);
+
+ List<Line> output = new List<Line>(count);
+
+ int castCount = count * 10;
+
+ while (rays.Count > 0 && castCount-- > 0)
+ {
+ var ray = rays[0];
+ rays.Remove(ray);
+ {
+ CastInfo closest = CastInfo.Default;
+
+ foreach (var structure in structures)
+ {
+ if (structure.CastRay(ray, out CastInfo info))
+ if (closest.distance > info.distance)
+ closest = info;
+ }
+
+ if (closest.collided)
+ {
+ output.Add(new Line(ray.position, closest.point));
+ rays.Add(new Ray(closest.point, ray.direction - 2 * Vector2.Dot(ray.direction, closest.normal) * closest.normal));
+ }
+ }
+ }
+
+ return output.ToArray();
+ }
+
+ private Vector2 UnitVectorFromAngle(float angle)
+ {
+ return new Vector2(MathF.Cos(angle), MathF.Sin(angle));
+ }
}
}
diff --git a/RayRoom/Core/CastInfo.cs b/RayRoom/Core/CastInfo.cs
new file mode 100644
index 0000000..6c6d9a0
--- /dev/null
+++ b/RayRoom/Core/CastInfo.cs
@@ -0,0 +1,26 @@
+using System.Numerics;
+
+namespace RayRoom.Core
+{
+ public struct CastInfo
+ {
+ public readonly Vector2 point;
+ public readonly Vector2 normal;
+ public readonly float distance;
+ public readonly bool collided;
+ public static CastInfo Default => new CastInfo(Vector2.Zero, Vector2.Zero, float.MaxValue, false);
+
+ public CastInfo(Vector2 point, Vector2 normal, float distance, bool collided)
+ {
+ this.point = point;
+ this.normal = normal;
+ this.distance = distance;
+ this.collided = collided;
+ }
+
+ public override string ToString()
+ {
+ return string.Format("p:{0} n:{1} d:{2} c:{3}", point.ToString(), normal.ToString(), distance.ToString(), collided.ToString());
+ }
+ }
+} \ No newline at end of file
diff --git a/RayRoom/Core/CollisionHelpers.cs b/RayRoom/Core/CollisionHelpers.cs
new file mode 100644
index 0000000..b0d0d40
--- /dev/null
+++ b/RayRoom/Core/CollisionHelpers.cs
@@ -0,0 +1,146 @@
+using System.Numerics;
+
+namespace RayRoom.Core
+{
+ public static class CollisionHelpers
+ {
+ private static float minimalThreshold = 0.001f;
+
+ public struct Distances
+ {
+ public readonly float a;
+ public readonly float b;
+
+ public Distances(float a, float b)
+ {
+ this.a = a;
+ this.b = b;
+ }
+ }
+
+ /// <summary>
+ /// Calculates ray collision
+ /// </summary>
+ /// <param name="a">static base ray</param>
+ /// <param name="b">raycaster</param>
+ /// <param name="info">collision info for b ray</param>
+ /// <returns>Distance modifiers for ray elements</returns>
+ public static Distances TestRays(Ray a, Ray b, out CastInfo info)
+ {
+ a = new Ray(a.position, Vector2.Normalize(a.direction));
+ b = new Ray(b.position, Vector2.Normalize(b.direction));
+
+ float dx = b.position.X - a.position.X;
+ float dy = b.position.Y - a.position.Y;
+
+ float det = b.direction.X * a.direction.Y - b.direction.Y * a.direction.X;
+
+ float u = (dy * b.direction.X - dx * b.direction.Y) / det;
+ float v = (dy * a.direction.X - dx * a.direction.Y) / det;
+
+ Vector2 normal = GetClosestNormal(a.direction, b.direction);
+
+ info = new CastInfo(b.position + b.direction * v, normal, (v * b.direction).Length(), true);
+
+ return new Distances(u, v);
+ }
+
+ public static Distances TestSphereToRay(Sphere a, Ray b, out CastInfo info)
+ {
+ Vector2 position = b.position - a.center;
+
+ float vb = 2 * b.direction.X * position.X + 2 * b.direction.Y * position.Y;
+ float va = MathF.Pow(b.direction.X, 2) + MathF.Pow(b.direction.Y, 2);
+ float vc = MathF.Pow(position.X, 2) + MathF.Pow(position.Y, 2) - MathF.Pow(a.radius, 2);
+
+ float discr = MathF.Pow(vb, 2) - 4 * va * vc;
+
+ Distances result;
+
+ if (discr >= 0)
+ {
+ float t0 = (-vb - MathF.Sqrt(discr)) / (va * 2);
+ float t1 = (-vb + MathF.Sqrt(discr)) / (va * 2);
+
+ float distance;
+
+ if (MathF.Abs(t0) < MathF.Abs(t1))
+ distance = t0;
+ else
+ distance = t1;
+
+ Vector2 normal = (b.position + b.direction * distance - a.center) / a.radius * -1f;
+
+ info = new CastInfo(b.position + b.direction * distance, normal, (b.direction * distance).Length(), true);
+ result = new Distances(t0, t1);
+ }
+ else
+ {
+ info = CastInfo.Default;
+ result = new Distances(0, 0);
+ }
+
+ return result;
+ }
+
+ private static Vector2 GetClosestNormal(Vector2 collision, Vector2 direction)
+ {
+ Vector2 n0 = new Vector2(collision.Y, -collision.X);
+ Vector2 n1 = new Vector2(-collision.Y, collision.X);
+
+ float t0 = Vector2.Dot(n0, direction);
+ float t1 = Vector2.Dot(n1, direction);
+
+ if (t0 < t1)
+ return n0;
+ else
+ return n1;
+ }
+
+ public static bool RaycastRayToSphere(Sphere sphere, Ray b, out CastInfo info)
+ {
+ var distances = TestSphereToRay(sphere, b, out info);
+
+ if (distances.a < minimalThreshold || distances.b < minimalThreshold)
+ {
+ info = CastInfo.Default;
+ return false;
+ }
+
+ return info.collided;
+ }
+
+ public static bool RaycastRayToLine(Line aLine, Ray b, out CastInfo info)
+ {
+ Ray a = new Ray(aLine.a, aLine.b - aLine.a);
+
+ var result = TestRays(a, b, out info);
+
+ bool output = result.b >= 0 && result.a >= 0 && result.a <= (aLine.b - aLine.a).Length();
+
+ if (result.a < minimalThreshold || result.b < minimalThreshold)
+ output = false;
+
+ if (!output)
+ info = CastInfo.Default;
+
+ return output;
+ }
+
+ public static bool RaycastRayToRay(Ray a, Ray b, out CastInfo info)
+ {
+ var result = TestRays(a, b, out info);
+
+ bool output = result.b >= 0 && result.a >= 0;
+
+ if (result.a < minimalThreshold || result.b < minimalThreshold)
+ output = false;
+
+ if (!output)
+ info = CastInfo.Default;
+
+ return output;
+
+ }
+ }
+} \ No newline at end of file
diff --git a/RayRoom/Core/IStructure.cs b/RayRoom/Core/IStructure.cs
new file mode 100644
index 0000000..9b42c92
--- /dev/null
+++ b/RayRoom/Core/IStructure.cs
@@ -0,0 +1,7 @@
+namespace RayRoom.Core
+{
+ public interface IStructure
+ {
+ bool CastRay(Ray ray, out CastInfo info);
+ }
+} \ No newline at end of file
diff --git a/RayRoom/Core/Line.cs b/RayRoom/Core/Line.cs
new file mode 100644
index 0000000..84d82fe
--- /dev/null
+++ b/RayRoom/Core/Line.cs
@@ -0,0 +1,21 @@
+using System.Numerics;
+
+namespace RayRoom.Core
+{
+ public class Line : IStructure
+ {
+ public readonly Vector2 a;
+ public readonly Vector2 b;
+
+ public Line(Vector2 a, Vector2 b)
+ {
+ this.a = a;
+ this.b = b;
+ }
+
+ public bool CastRay(Ray ray, out CastInfo info)
+ {
+ return CollisionHelpers.RaycastRayToLine(this, ray, out info);
+ }
+ }
+}
diff --git a/RayRoom/Core/Matrix2x2.cs b/RayRoom/Core/Matrix2x2.cs
new file mode 100644
index 0000000..be4047e
--- /dev/null
+++ b/RayRoom/Core/Matrix2x2.cs
@@ -0,0 +1,39 @@
+using System.Numerics;
+
+namespace AudioTester
+{
+ public struct Matrix2x2
+ {
+ float a, b, c, d;
+
+ public static Matrix2x2 Identity => new Matrix2x2(Vector2.UnitX, Vector2.UnitY);
+
+ public Matrix2x2(float a, float b, float c, float d)
+ {
+ this.a = a;
+ this.b = b;
+ this.c = c;
+ this.d = d;
+ }
+
+ public Matrix2x2(Vector2 a, Vector2 b)
+ {
+ this.a = a.X;
+ this.b = b.X;
+ this.c = a.Y;
+ this.d = b.Y;
+ }
+
+ public readonly float Determinant => (a*d) - (b*c);
+
+ public static Vector2 operator*(Matrix2x2 matrix, Vector2 vector)
+ {
+ return new Vector2(matrix.a, matrix.c) * vector.X + new Vector2(matrix.b, matrix.d) * vector.Y;
+ }
+
+ public static Matrix2x2 operator*(Matrix2x2 a, Matrix2x2 b)
+ {
+ return new Matrix2x2(a * new Vector2(b.a, b.c), a * new Vector2(b.b, b.d));
+ }
+ }
+} \ No newline at end of file
diff --git a/RayRoom/Core/Ray.cs b/RayRoom/Core/Ray.cs
index 0c2edcc..9cc8a6e 100644
--- a/RayRoom/Core/Ray.cs
+++ b/RayRoom/Core/Ray.cs
@@ -1,4 +1,5 @@
-using System.Numerics;
+using System.ComponentModel;
+using System.Numerics;
namespace RayRoom.Core
{
@@ -6,6 +7,16 @@ namespace RayRoom.Core
{
public readonly Vector2 position;
public readonly Vector2 direction;
- public readonly float length;
+
+ public Ray(Vector2 position, Vector2 direction)
+ {
+ this.position = position;
+ this.direction = direction;
+ }
+
+ public override string? ToString()
+ {
+ return string.Format("p:{0} d:{1}", position.ToString(), direction.ToString());
+ }
}
} \ No newline at end of file
diff --git a/RayRoom/Core/Settings.cs b/RayRoom/Core/Settings.cs
index 7ca0b45..f6064b8 100644
--- a/RayRoom/Core/Settings.cs
+++ b/RayRoom/Core/Settings.cs
@@ -8,13 +8,10 @@ namespace RayRoom.Core
public readonly int maxRayReflections;
public readonly int maxDiffusionRays;
- public readonly float fadeFactorPerMeter; //qurve
+ public readonly float fadeFactorPerMeter; //curve
public readonly float speedOfSoundMetersPerSec;
- public static Settings GetDefault()
- {
- return new Settings(441000, 10, 15, 0.001f, 330);
- }
+ public static Settings Default => new Settings(44100, 10, 15, 0.001f, 330f);
public Settings(int frequency, int maxRayReflections, int maxDiffusionRays, float fadeFactorPerMeter, float speedOfSoundMetersPerSec)
{
diff --git a/RayRoom/Core/Sphere.cs b/RayRoom/Core/Sphere.cs
new file mode 100644
index 0000000..892e46e
--- /dev/null
+++ b/RayRoom/Core/Sphere.cs
@@ -0,0 +1,21 @@
+using System.Numerics;
+
+namespace RayRoom.Core
+{
+ public class Sphere : IStructure
+ {
+ public readonly Vector2 center;
+ public readonly float radius;
+
+ public Sphere(Vector2 center, float radius)
+ {
+ this.center = center;
+ this.radius = radius;
+ }
+
+ public bool CastRay(Ray ray, out CastInfo info)
+ {
+ return CollisionHelpers.RaycastRayToSphere(this, ray, out info);
+ }
+ }
+} \ No newline at end of file