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!
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();
}
}
}