You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
BoxCast results are all correct, but performance is unbelievable low
400 BoxCast
Unity cost 2 ms
Bepu cost 6494 ms, and GC Alloc is 53.2 MB
bepuphysics2 source code here
GJKDistanceTester.Edge() cost 1753.64 ms, and 3.2MB GC Alloc
This looks like SIMD things.
I am not familiar with SIMD so I don't know how to modify these code to improve performance in Unity.
You looks pretty cool at these.
Can you give me some advice?
Thanks in advance!
Here's Bench MonoBehaviour, put it on PhysicsSystem gameobject and click Benchmark, it will start a Benchmark
using UnityEngine;
using System.Collections.Generic;
using BepuPhysics;
using BepuPhysics.Collidables;
using BepuPhysicsUnity;
public class Bench : MonoBehaviour
{
public bool benchmark;
PhysicSimulation _physicSimulation;
List<UnityEngine.Vector3> unityRayStartPositions;
int unityRayStartPositionsCount;
RaycastHit unityRaycastHit;
UnityEngine.Vector3 unityHalfExtents = new UnityEngine.Vector3(1, 1, 1);
List<System.Numerics.Vector3> bepuRayStartPositions;
int bepuRayStartPositionsCount;
System.Numerics.Vector3 Vector3Down = new System.Numerics.Vector3(0, -1, 0);
System.Numerics.Vector3 bepuHalfExtents = new System.Numerics.Vector3(1, 1, 1);
int boxCastCount = 400;
float detectDistance = 30;
void Start()
{
_physicSimulation = GetComponent<PhysicSimulation>();
unityRayStartPositions = new List<UnityEngine.Vector3>(boxCastCount);
bepuRayStartPositions = new List<System.Numerics.Vector3>(boxCastCount);
int loopCount = (int)Mathf.Sqrt(boxCastCount);
for (int i = 0; i < loopCount; i++)
{
for (int j = 0; j < loopCount; j++)
{
unityRayStartPositions.Add(new UnityEngine.Vector3(i * 0.1f, 5, j * 0.1f));
bepuRayStartPositions.Add(new System.Numerics.Vector3(i * 0.1f, 5, j * 0.1f));
}
}
unityRayStartPositionsCount = unityRayStartPositions.Count;
bepuRayStartPositionsCount = bepuRayStartPositions.Count;
//Add BoxCollider so Unity Physics.BoxCast can hit it
BoxDetection[] boxDetections = FindObjectsOfType<BoxDetection>();
for (int i = 0; i < boxDetections.Length; i++)
{
BoxDetection boxDetection = boxDetections[i];
if (boxDetection.GetComponent<BoxCollider>() == null)
{
boxDetection.gameObject.AddComponent<BoxCollider>();
//BoxDetection size does not match cube mesh, correct it
boxDetection.SetSize(boxDetection.transform.localScale);
}
}
}
void Benchmark()
{
System.Diagnostics.Stopwatch st = new System.Diagnostics.Stopwatch();
st.Start();
BenchmarkUnityBoxCast();
st.Stop();
UnityEngine.Debug.LogFormat("BenchmarkUnityBoxCast: {0} ms", st.ElapsedMilliseconds);
st.Reset();
st.Start();
BenchmarkBepuBoxCast();
st.Stop();
UnityEngine.Debug.LogFormat("BenchmarkBepuBoxCast: {0} ms", st.ElapsedMilliseconds);
st.Reset();
}
void BenchmarkUnityBoxCast()
{
for (int i = 0; i < unityRayStartPositionsCount; i++)
{
if (Physics.BoxCast(unityRayStartPositions[i], unityHalfExtents, UnityEngine.Vector3.down, out unityRaycastHit, UnityEngine.Quaternion.identity, detectDistance))
{
//UnityEngine.Debug.DrawLine(unityRayStartPositions[i], unityRaycastHit.point, Color.green);
}
}
}
void BenchmarkBepuBoxCast()
{
for (int i = 0; i < bepuRayStartPositionsCount; i++)
{
if (BepuBoxCast(bepuRayStartPositions[i], bepuHalfExtents, Vector3Down, BepuUtilities.Quaternion.Identity, detectDistance))
{
/*
UnityEngine.Vector3 start = new Vector3(bepuRayStartPositions[i].X, bepuRayStartPositions[i].Y, bepuRayStartPositions[i].Z);
UnityEngine.Vector3 end = new Vector3(_boxCastHitHandler.HitLocation.X, _boxCastHitHandler.HitLocation.Y, _boxCastHitHandler.HitLocation.Z);
UnityEngine.Debug.DrawLine(start, end, Color.red);
*/
}
}
}
struct SceneSweepHitHandler : ISweepHitHandler
{
public System.Numerics.Vector3 HitLocation;
public System.Numerics.Vector3 HitNormal;
public float T;
public bool AllowTest(CollidableReference collidable)
{
return true;
}
public bool AllowTest(CollidableReference collidable, int child)
{
return true;
}
public void OnHit(ref float maximumT, float t, in System.Numerics.Vector3 hitLocation, in System.Numerics.Vector3 hitNormal, CollidableReference collidable)
{
//Changing the maximum T value prevents the traversal from visiting any leaf nodes more distant than that later in the traversal.
//It is effectively an optimization that you can use if you only care about the time of first impact.
if (t < maximumT)
maximumT = t;
if (t < T)
{
T = t;
HitLocation = hitLocation;
HitNormal = hitNormal;
}
}
public void OnHitAtZeroT(ref float maximumT, CollidableReference collidable)
{
maximumT = 0;
T = 0;
HitLocation = new System.Numerics.Vector3();
HitNormal = new System.Numerics.Vector3();
}
}
SceneSweepHitHandler _boxCastHitHandler = new SceneSweepHitHandler();
Box _boxShape = new Box(1, 1, 1);
RigidPose _boxRigidPose = new RigidPose();
BodyVelocity _boxBodyVelocity = new BodyVelocity();
unsafe bool BepuBoxCast(System.Numerics.Vector3 origin, System.Numerics.Vector3 halfExtents, System.Numerics.Vector3 direction, BepuUtilities.Quaternion orientation, float maxDistance)
{
_boxCastHitHandler.T = float.MaxValue;
_boxShape.HalfWidth = halfExtents.X;
_boxShape.HalfHeight = halfExtents.Y;
_boxShape.HalfLength = halfExtents.Z;
_boxRigidPose.Position = origin;
_boxRigidPose.Orientation = orientation;
_boxBodyVelocity.Linear = direction;
_physicSimulation.Simulation.Sweep(_boxShape, _boxRigidPose, _boxBodyVelocity, maxDistance, _physicSimulation.BufferPool, ref _boxCastHitHandler);
if (_boxCastHitHandler.T < float.MaxValue && _boxCastHitHandler.T > 0)
{
return true;
}
else
{
return false;
}
}
void Update()
{
if (benchmark)
{
Benchmark();
benchmark = false;
//UnityEngine.Debug.Break();
}
}
}
The text was updated successfully, but these errors were encountered:
It's in deed an issue with SIMD that's disabled in Unity. I don't have a magical solution for this right now but I have a couple of leads to improve the speed. Utilizing SIMD/SSE in Unity3D (.NET 2.0).
BoxCast results are all correct, but performance is unbelievable low
400 BoxCast
Unity cost 2 ms
Bepu cost 6494 ms, and GC Alloc is 53.2 MB
bepuphysics2 source code here
GJKDistanceTester.Edge() cost 1753.64 ms, and 3.2MB GC Alloc
This looks like SIMD things.
I am not familiar with SIMD so I don't know how to modify these code to improve performance in Unity.
You looks pretty cool at these.
Can you give me some advice?
Thanks in advance!
Here's Bench MonoBehaviour, put it on PhysicsSystem gameobject and click Benchmark, it will start a Benchmark
The text was updated successfully, but these errors were encountered: