diff --git a/src/Jitter2/Collision/Shapes/TransformedShape.cs b/src/Jitter2/Collision/Shapes/TransformedShape.cs index ba5f6cbc..38254bcc 100644 --- a/src/Jitter2/Collision/Shapes/TransformedShape.cs +++ b/src/Jitter2/Collision/Shapes/TransformedShape.cs @@ -126,7 +126,7 @@ public override void CalculateBoundingBox(in JMatrix orientation, in JVector pos else { OriginalShape.CalculateBoundingBox(orientation * this.transformation, - JVector.Transform(translation, transformation) + position, out box); + JVector.Transform(translation, orientation) + position, out box); } } diff --git a/src/Jitter2/SoftBodies/SoftBody.cs b/src/Jitter2/SoftBodies/SoftBody.cs index 297e577c..819cf3a5 100644 --- a/src/Jitter2/SoftBodies/SoftBody.cs +++ b/src/Jitter2/SoftBodies/SoftBody.cs @@ -30,13 +30,13 @@ namespace Jitter2.SoftBodies; public class SoftBody { - public List Points { get; } = new(); + public List Vertices { get; } = new(); public List Springs { get; } = new(); public List Shapes { get; } = new(); protected World world; - public bool IsActive => Points[0].IsActive; + public bool IsActive => Vertices[0].IsActive; public SoftBody(World world) { @@ -58,7 +58,7 @@ public void Destroy() world.Remove(spring); } - foreach (var point in Points) + foreach (var point in Vertices) { world.Remove(point); } diff --git a/src/Jitter2/SoftBodies/SoftBodyTetrahedron.cs b/src/Jitter2/SoftBodies/SoftBodyTetrahedron.cs index 1df9ad1a..1032b206 100644 --- a/src/Jitter2/SoftBodies/SoftBodyTetrahedron.cs +++ b/src/Jitter2/SoftBodies/SoftBodyTetrahedron.cs @@ -29,19 +29,19 @@ namespace Jitter2.SoftBodies; public class SoftBodyTetrahedron : Shape, ISoftBodyShape { - public SoftBodyTetrahedron(SoftBody body, RigidBody p1, RigidBody p2, RigidBody p3, RigidBody p4) + public SoftBodyTetrahedron(SoftBody body, RigidBody v1, RigidBody v2, RigidBody v3, RigidBody v4) { - Bodies[0] = p1; - Bodies[1] = p2; - Bodies[2] = p3; - Bodies[3] = p4; + Vertices[0] = v1; + Vertices[1] = v2; + Vertices[2] = v3; + Vertices[3] = v4; SoftBody = body; UpdateShape(); } - public RigidBody[] Bodies { get; } = new RigidBody[4]; + public RigidBody[] Vertices { get; } = new RigidBody[4]; public override JVector Velocity { @@ -51,7 +51,7 @@ public override JVector Velocity for (int i = 0; i < 4; i++) { - vel += Bodies[i].Velocity; + vel += Vertices[i].Velocity; } vel *= 0.25f; @@ -68,7 +68,7 @@ public override void CalculateMassInertia(out JMatrix inertia, out JVector com, for (int i = 0; i < 4; i++) { - com += Bodies[i].Position; + com += Vertices[i].Position; } com *= 0.25f; @@ -81,7 +81,7 @@ public RigidBody GetClosest(in JVector pos) for (int i = 0; i < 4; i++) { - float len = (pos - Bodies[i].Position).LengthSquared(); + float len = (pos - Vertices[i].Position).LengthSquared(); if (len < dist) { dist = len; @@ -89,7 +89,7 @@ public RigidBody GetClosest(in JVector pos) } } - return Bodies[closest]; + return Vertices[closest]; } public SoftBody SoftBody { get; } @@ -103,8 +103,8 @@ public override void UpdateWorldBoundingBox() for (int i = 0; i < 4; i++) { - box.AddPoint(Bodies[i].Position); - GeometricCenter += Bodies[i].Position; + box.AddPoint(Vertices[i].Position); + GeometricCenter += Vertices[i].Position; } GeometricCenter *= 0.25f; @@ -122,7 +122,7 @@ public override void SupportMap(in JVector direction, out JVector result) for (int i = 0; i < 4; i++) { - float dot = JVector.Dot(direction, Bodies[i].Position); + float dot = JVector.Dot(direction, Vertices[i].Position); if (dot > maxDot) { maxDot = dot; @@ -130,6 +130,6 @@ public override void SupportMap(in JVector direction, out JVector result) } } - result = Bodies[furthest].Position; + result = Vertices[furthest].Position; } } \ No newline at end of file diff --git a/src/Jitter2/SoftBodies/SoftBodyTriangle.cs b/src/Jitter2/SoftBodies/SoftBodyTriangle.cs index 08bb07cc..f035f643 100644 --- a/src/Jitter2/SoftBodies/SoftBodyTriangle.cs +++ b/src/Jitter2/SoftBodies/SoftBodyTriangle.cs @@ -30,78 +30,84 @@ namespace Jitter2.SoftBodies; public class SoftBodyTriangle : Shape, ISoftBodyShape { - private readonly RigidBody p2; - private readonly RigidBody p3; - private readonly RigidBody p1; + private readonly RigidBody v2; + private readonly RigidBody v3; + private readonly RigidBody v1; - public RigidBody Body1 => p1; - public RigidBody Body2 => p2; - public RigidBody Body3 => p3; + public RigidBody Vertex1 => v1; + public RigidBody Vertex2 => v2; + public RigidBody Vertex3 => v3; - public float Thickness { get; set; } = 0.05f; + private float halfThickness = 0.05f; - public SoftBodyTriangle(SoftBody body, RigidBody p1, RigidBody p2, RigidBody p3) + public float Thickness { - this.p1 = p1; - this.p2 = p2; - this.p3 = p3; + get => halfThickness * 2.0f; + set => halfThickness = value * 0.5f; + } + + public SoftBodyTriangle(SoftBody body, RigidBody v1, RigidBody v2, RigidBody v3) + { + this.v1 = v1; + this.v2 = v2; + this.v3 = v3; SoftBody = body; UpdateShape(); } - public override JVector Velocity => 1.0f / 3.0f * (p1.Data.Velocity + p2.Data.Velocity + p3.Data.Velocity); + public override JVector Velocity => 1.0f / 3.0f * (v1.Data.Velocity + v2.Data.Velocity + v3.Data.Velocity); public override void CalculateMassInertia(out JMatrix inertia, out JVector com, out float mass) { inertia = JMatrix.Identity; mass = 1; - com = 1.0f / 3.0f * (p1.Position + p2.Position + p3.Position); + com = 1.0f / 3.0f * (v1.Position + v2.Position + v3.Position); } public RigidBody GetClosest(in JVector pos) { - float len1 = (pos - p1.Position).LengthSquared(); - float len2 = (pos - p2.Position).LengthSquared(); - float len3 = (pos - p3.Position).LengthSquared(); + float len1 = (pos - v1.Position).LengthSquared(); + float len2 = (pos - v2.Position).LengthSquared(); + float len3 = (pos - v3.Position).LengthSquared(); if (len1 < len2 && len1 < len3) { - return p1; + return v1; } if (len2 < len3 && len2 <= len1) { - return p2; + return v2; } - return p3; + return v3; } public SoftBody SoftBody { get; } public override void UpdateWorldBoundingBox() { - float extraMargin = MathF.Max(Thickness, 0.01f); + float extraMargin = MathF.Max(halfThickness, 0.01f); var box = JBBox.SmallBox; - box.AddPoint(p1.Position); - box.AddPoint(p2.Position); - box.AddPoint(p3.Position); + box.AddPoint(v1.Position); + box.AddPoint(v2.Position); + box.AddPoint(v3.Position); box.Min -= JVector.One * extraMargin; box.Max += JVector.One * extraMargin; WorldBoundingBox = box; - GeometricCenter = 1.0f / 3.0f * (p1.Position + p2.Position + p3.Position); + GeometricCenter = 1.0f / 3.0f * (v1.Position + v2.Position + v3.Position); } public override void SupportMap(in JVector direction, out JVector result) { - JVector a = p1.Position; - JVector b = p2.Position; - JVector c = p3.Position; + JVector a = v1.Position; + JVector b = v2.Position; + JVector c = v3.Position; float min = JVector.Dot(a, direction); float dot = JVector.Dot(b, direction); @@ -121,6 +127,6 @@ public override void SupportMap(in JVector direction, out JVector result) result = c; } - result += JVector.Normalize(direction) * Thickness; + result += JVector.Normalize(direction) * halfThickness; } } \ No newline at end of file diff --git a/src/Jitter2/UnmanagedMemory/MemoryHelper.cs b/src/Jitter2/UnmanagedMemory/MemoryHelper.cs index e7e9de40..43832985 100644 --- a/src/Jitter2/UnmanagedMemory/MemoryHelper.cs +++ b/src/Jitter2/UnmanagedMemory/MemoryHelper.cs @@ -27,6 +27,22 @@ namespace Jitter2.UnmanagedMemory; public static unsafe class MemoryHelper { + /// + /// A block of 32 bytes of memory. + /// + [StructLayout(LayoutKind.Sequential, Size = 16)] + public struct MemBlock16 + { + } + + /// + /// A block of 32 bytes of memory. + /// + [StructLayout(LayoutKind.Sequential, Size = 32)] + public struct MemBlock32 + { + } + /// /// A block of 48 bytes of memory. /// @@ -45,13 +61,16 @@ public struct MemBlock64 public static T* AllocateHeap(int num) where T : unmanaged { - return (T*)Marshal.AllocHGlobal(num * sizeof(T)); + return (T*)AllocateHeap(num * sizeof(T)); } public static void Free(T* ptr) where T : unmanaged { - Marshal.FreeHGlobal((nint)ptr); + Free((void*)ptr); } + + public static void* AllocateHeap(int len) => NativeMemory.Alloc((nuint)len); + public static void Free(void* ptr) => NativeMemory.Free(ptr); /// /// Zeros out unmanaged memory. diff --git a/src/Jitter2/UnmanagedMemory/UnmanagedActiveList.cs b/src/Jitter2/UnmanagedMemory/UnmanagedActiveList.cs index 8e991508..6187e687 100644 --- a/src/Jitter2/UnmanagedMemory/UnmanagedActiveList.cs +++ b/src/Jitter2/UnmanagedMemory/UnmanagedActiveList.cs @@ -85,8 +85,8 @@ public UnmanagedActiveList(int maximumSize, int initialSize = 1024) size = initialSize; this.maximumSize = maximumSize; - memory = (T*)Marshal.AllocHGlobal(size * sizeof(T)); - handles = (T**)Marshal.AllocHGlobal(maximumSize * sizeof(IntPtr)); + memory = (T*)MemoryHelper.AllocateHeap(size * sizeof(T)); + handles = (T**)MemoryHelper.AllocateHeap(maximumSize * sizeof(IntPtr)); for (int i = 0; i < size; i++) { @@ -209,7 +209,7 @@ public JHandle Allocate(bool active = false, bool clear = false) $"Resizing to {size}x{typeof(T)} ({size}x{sizeof(T)} Bytes)."); var oldmemory = memory; - memory = (T*)Marshal.AllocHGlobal(size * sizeof(T)); + memory = (T*)MemoryHelper.AllocateHeap(size * sizeof(T)); for (int i = 0; i < osize; i++) { @@ -222,7 +222,7 @@ public JHandle Allocate(bool active = false, bool clear = false) Unsafe.AsRef(&memory[i]) = i; } - Marshal.FreeHGlobal((IntPtr)oldmemory); + MemoryHelper.Free(oldmemory); ResizeLock.ExitWriteLock(); } @@ -248,10 +248,10 @@ private void FreeResources() { if (!disposed) { - Marshal.FreeHGlobal((IntPtr)handles); + MemoryHelper.Free(handles); handles = (T**)0; - Marshal.FreeHGlobal((IntPtr)memory); + MemoryHelper.Free(memory); memory = (T*)0; disposed = true; diff --git a/src/Jitter2/World.cs b/src/Jitter2/World.cs index 1dd2782b..35a05d19 100644 --- a/src/Jitter2/World.cs +++ b/src/Jitter2/World.cs @@ -95,7 +95,7 @@ public SpanData(World world) private readonly ActiveList bodies = new(); private readonly ActiveList shapes = new(); - public static ulong IdCounter; + internal static ulong IdCounter; /// /// Defines the two available thread models. The model keeps the worker @@ -209,7 +209,7 @@ public JVector Gravity public World(int numBodies = 32768, int numContacts = 65536, int numConstraints = 32768) { // int numBodies = 32768, int numContacts = 65536, int numConstraints = 32768 - // with this choice 1024 KB are directly allocated on the heap. + // with this choice (32768 + 65536 + 2 x 32768) x 8 Bytes = 1280 KB are allocated on the heap. memRigidBodies = new UnmanagedActiveList(numBodies); memContacts = new UnmanagedActiveList(numContacts); memConstraints = new UnmanagedActiveList(numConstraints); diff --git a/src/JitterDemo/Demos/Demo16.cs b/src/JitterDemo/Demos/Demo16.cs index 33123232..789ca420 100644 --- a/src/JitterDemo/Demos/Demo16.cs +++ b/src/JitterDemo/Demos/Demo16.cs @@ -73,8 +73,8 @@ public void Draw() { foreach (var spring in SoftBodyCube.Edges) { - dr.PushLine(DebugRenderer.Color.Green, Conversion.FromJitter(cube.Points[spring.Item1].Position), - Conversion.FromJitter(cube.Points[spring.Item2].Position)); + dr.PushLine(DebugRenderer.Color.Green, Conversion.FromJitter(cube.Vertices[spring.Item1].Position), + Conversion.FromJitter(cube.Vertices[spring.Item2].Position)); dr.PushPoint(DebugRenderer.Color.White, Conversion.FromJitter(cube.Center.Position), 0.2f); } diff --git a/src/JitterDemo/Demos/Demo17.cs b/src/JitterDemo/Demos/Demo17.cs index 45103ec9..e73deb81 100644 --- a/src/JitterDemo/Demos/Demo17.cs +++ b/src/JitterDemo/Demos/Demo17.cs @@ -65,19 +65,19 @@ public void Build() world.DynamicTree.Filter = DynamicTreeCollisionFilter.Filter; world.BroadPhaseFilter = new BroadPhaseCollisionFilter(world); - RigidBody fb0 = cloth.Points.OrderByDescending(item => +item.Position.X + item.Position.Z).First(); + RigidBody fb0 = cloth.Vertices.OrderByDescending(item => +item.Position.X + item.Position.Z).First(); var c0 = world.CreateConstraint(fb0, world.NullBody); c0.Initialize(fb0.Position); - RigidBody fb1 = cloth.Points.OrderByDescending(item => +item.Position.X - item.Position.Z).First(); + RigidBody fb1 = cloth.Vertices.OrderByDescending(item => +item.Position.X - item.Position.Z).First(); var c1 = world.CreateConstraint(fb1, world.NullBody); c1.Initialize(fb1.Position); - RigidBody fb2 = cloth.Points.OrderByDescending(item => -item.Position.X + item.Position.Z).First(); + RigidBody fb2 = cloth.Vertices.OrderByDescending(item => -item.Position.X + item.Position.Z).First(); var c2 = world.CreateConstraint(fb2, world.NullBody); c2.Initialize(fb2.Position); - RigidBody fb3 = cloth.Points.OrderByDescending(item => -item.Position.X - item.Position.Z).First(); + RigidBody fb3 = cloth.Vertices.OrderByDescending(item => -item.Position.X - item.Position.Z).First(); var c3 = world.CreateConstraint(fb3, world.NullBody); c3.Initialize(fb3.Position); diff --git a/src/JitterDemo/Demos/SoftBody/PressurizedSphere.cs b/src/JitterDemo/Demos/SoftBody/PressurizedSphere.cs index eb6ce335..68cb2b6b 100644 --- a/src/JitterDemo/Demos/SoftBody/PressurizedSphere.cs +++ b/src/JitterDemo/Demos/SoftBody/PressurizedSphere.cs @@ -46,10 +46,10 @@ private static IEnumerable GenSphereTrianglesFromMesh(JVector offset, public SoftBodySphere(World world, JVector offset) : base(world, GenSphereTriangles(offset)) { - foreach (var point in Points) + foreach (var rb in Vertices) { - point.SetMassInertia(JMatrix.Identity * 1000, 0.01f); - point.Damping = (1, 0.99f); + rb.SetMassInertia(JMatrix.Identity * 1000, 0.01f); + rb.Damping = (1, 0.99f); } foreach (var spring in Springs) @@ -68,9 +68,9 @@ protected override void WorldOnPostStep(float dt) foreach (SoftBodyTriangle sbt in Shapes) { - JVector v1 = sbt.Body1.Position; - JVector v2 = sbt.Body2.Position; - JVector v3 = sbt.Body3.Position; + JVector v1 = sbt.Vertex1.Position; + JVector v2 = sbt.Vertex2.Position; + JVector v3 = sbt.Vertex3.Position; volume += ((v2.Y - v1.Y) * (v3.Z - v1.Z) - (v2.Z - v1.Z) * (v3.Y - v1.Y)) * (v1.X + v2.X + v3.X); @@ -80,16 +80,16 @@ protected override void WorldOnPostStep(float dt) foreach (SoftBodyTriangle sbt in Shapes) { - JVector p0 = sbt.Body1.Position; - JVector p1 = sbt.Body2.Position; - JVector p2 = sbt.Body3.Position; + JVector p0 = sbt.Vertex1.Position; + JVector p1 = sbt.Vertex2.Position; + JVector p2 = sbt.Vertex3.Position; JVector normal = (p1 - p0) % (p2 - p0); JVector force = normal * Pressure * invVol; - sbt.Body1.AddForce(force); - sbt.Body2.AddForce(force); - sbt.Body3.AddForce(force); + sbt.Vertex1.AddForce(force); + sbt.Vertex2.AddForce(force); + sbt.Vertex3.AddForce(force); } } } \ No newline at end of file diff --git a/src/JitterDemo/Demos/SoftBody/SoftBodyCloth.cs b/src/JitterDemo/Demos/SoftBody/SoftBodyCloth.cs index 51747630..cc43c504 100644 --- a/src/JitterDemo/Demos/SoftBody/SoftBodyCloth.cs +++ b/src/JitterDemo/Demos/SoftBody/SoftBodyCloth.cs @@ -102,20 +102,20 @@ private void Build() RigidBody body = world.CreateRigidBody(); body.SetMassInertia(JMatrix.Identity * 1000, 0.1f); body.Position = vertex; - Points.Add(body); + Vertices.Add(body); } foreach (var edge in edges) { - var constraint = world.CreateConstraint(Points[edge.IndexA], Points[edge.IndexB]); - constraint.Initialize(Points[edge.IndexA].Position, Points[edge.IndexB].Position); + var constraint = world.CreateConstraint(Vertices[edge.IndexA], Vertices[edge.IndexB]); + constraint.Initialize(Vertices[edge.IndexA].Position, Vertices[edge.IndexB].Position); constraint.Softness = 0.1f; Springs.Add(constraint); } foreach (var triangle in triangles) { - var tri = new SoftBodyTriangle(this, Points[triangle.IndexA], Points[triangle.IndexB], Points[triangle.IndexC]); + var tri = new SoftBodyTriangle(this, Vertices[triangle.IndexA], Vertices[triangle.IndexB], Vertices[triangle.IndexC]); tri.UpdateWorldBoundingBox(); world.AddShape(tri); Shapes.Add(tri); diff --git a/src/JitterDemo/Demos/SoftBody/SoftBodyCube.cs b/src/JitterDemo/Demos/SoftBody/SoftBodyCube.cs index 9894a37b..2946961a 100644 --- a/src/JitterDemo/Demos/SoftBody/SoftBodyCube.cs +++ b/src/JitterDemo/Demos/SoftBody/SoftBodyCube.cs @@ -35,15 +35,15 @@ public SoftBodyCube(World world, JVector offset) : base(world) var rb = world.CreateRigidBody(); rb.SetMassInertia(JMatrix.Identity * 100000, 0.2f); rb.Position = vertices[i] + offset; - Points.Add(rb); + Vertices.Add(rb); } SoftBodyTetrahedron[] tetrahedra = new SoftBodyTetrahedron[5]; - tetrahedra[0] = new SoftBodyTetrahedron(this, Points[0], Points[1], Points[5], Points[2]); - tetrahedra[1] = new SoftBodyTetrahedron(this, Points[2], Points[5], Points[6], Points[7]); - tetrahedra[2] = new SoftBodyTetrahedron(this, Points[3], Points[0], Points[2], Points[7]); - tetrahedra[3] = new SoftBodyTetrahedron(this, Points[0], Points[4], Points[5], Points[7]); - tetrahedra[4] = new SoftBodyTetrahedron(this, Points[0], Points[2], Points[5], Points[7]); + tetrahedra[0] = new SoftBodyTetrahedron(this, Vertices[0], Vertices[1], Vertices[5], Vertices[2]); + tetrahedra[1] = new SoftBodyTetrahedron(this, Vertices[2], Vertices[5], Vertices[6], Vertices[7]); + tetrahedra[2] = new SoftBodyTetrahedron(this, Vertices[3], Vertices[0], Vertices[2], Vertices[7]); + tetrahedra[3] = new SoftBodyTetrahedron(this, Vertices[0], Vertices[4], Vertices[5], Vertices[7]); + tetrahedra[4] = new SoftBodyTetrahedron(this, Vertices[0], Vertices[2], Vertices[5], Vertices[7]); for (int i = 0; i < 5; i++) { @@ -58,8 +58,8 @@ public SoftBodyCube(World world, JVector offset) : base(world) for (int i = 0; i < 8; i++) { - var constraint = world.CreateConstraint(Center, Points[i]); - constraint.Initialize(Points[i].Position); + var constraint = world.CreateConstraint(Center, Vertices[i]); + constraint.Initialize(Vertices[i].Position); constraint.Softness = 1; } } diff --git a/src/JitterDemo/Renderer/DearImGui/ImGui.cs b/src/JitterDemo/Renderer/DearImGui/ImGui.cs index ce372eae..90c51d58 100644 --- a/src/JitterDemo/Renderer/DearImGui/ImGui.cs +++ b/src/JitterDemo/Renderer/DearImGui/ImGui.cs @@ -14,11 +14,11 @@ public static unsafe class ImGui static ImGui() { - strPtr = (byte**)Marshal.AllocHGlobal(sizeof(IntPtr) * 3); + strPtr = (byte**)NativeMemory.Alloc((nuint)(sizeof(IntPtr) * 3)); for (int i = 0; i < 3; i++) { - strPtr[i] = (byte*)Marshal.AllocHGlobal(strPtrSize); + strPtr[i] = (byte*)NativeMemory.Alloc((nuint)(strPtrSize)); } }