Hi, Currently I failed to reproduce the bug at the demo project. But I notice that there is a stack overflow at the tree, if a lot of objects are inserted at the same time.
Edit: Lowering the number of iterations from 50 to 25 at line 56 avoid the issue.
Code: Select all
using System.Numerics;
using BepuPhysics;
using BepuPhysics.Collidables;
using BepuUtilities;
using BepuUtilities.Collections;
using DemoContentLoader;
using DemoRenderer;
using Demos.Port;
using DemoUtilities;
using OpenTK.Input;
using Quaternion = BepuUtilities.Quaternion;
namespace Demos.Demos
{
public class BigConveyorDemo : Demo
{
private BodyDescription _boxDescription;
private BodyDescription _horizontalConveyorDescription;
private BodyDescription _verticalConveyorDescription;
private const float ConveyorSpeed = 2f;
private readonly Quaternion[] _orientations = new Quaternion[4];
private QuickList<int> _createdObjects;
private const float _conveyorHalfWidth = 1.5f;
private const float _horizontalHalfLenght = 80f;
private const float _verticalHalfLenght = 4f;
public override void Initialize(ContentArchive content, Camera camera)
{
camera.Position = new Vector3(-30, 8, -60);
camera.Yaw = MathHelper.Pi * 3f / 4;
camera.Pitch = 0;
Simulation = Simulation.Create(BufferPool, new DemoNarrowPhaseCallbacks(), new DemoPoseIntegratorCallbacks(new Vector3(0f,-9.81f,0f))
// , new CustomPositionLastTimestepper()
);
_createdObjects = new QuickList<int>(1000, BufferPool);
_boxDescription = CreateBoxDescription(1, 1, 1);
_horizontalConveyorDescription = CreateConveyorDescription(_horizontalHalfLenght);
_verticalConveyorDescription = CreateConveyorDescription(_verticalHalfLenght);
_orientations[0] = Quaternion.Identity;
Quaternion.CreateFromYawPitchRoll(-1.5708f, 0, 0, out _orientations[1]);
Quaternion.CreateFromYawPitchRoll(-3.1416f, 0, 0, out _orientations[2]);
Quaternion.CreateFromYawPitchRoll(-4.7124f, 0, 0, out _orientations[3]);
var startPosition = Vector3.Zero;
for (int i = 0; i < 50; i++)
{
CreateLevel(ref startPosition);
}
}
private BodyDescription CreateConveyorDescription(float halfLenght)
{
var description = CreateBoxDescription(halfLenght * 2, 1f, _conveyorHalfWidth * 2);
//description.ConveyorSettings.IsLinearConveyor = true;
//description.ConveyorSettings.ConveyorVelocity = new Vector3(ConveyorSpeed, 0,0);
description.LocalInertia = new BodyInertia();
description.Activity.SleepThreshold = -1;
return description;
}
private BodyDescription CreateBoxDescription(float width, float height, float lenght )
{
var boxShape = new Box(width, height, lenght);
var boxShapeIndex = Simulation.Shapes.Add(boxShape);
boxShape.ComputeInertia(1, out var boxInertia);
Symmetric3x3.Scale(boxInertia.InverseInertiaTensor, .5f, out boxInertia.InverseInertiaTensor);
var boxDescription = new BodyDescription()
{
LocalInertia = boxInertia,
Pose = new RigidPose
{
Position = Vector3.Zero,
Orientation = Quaternion.Identity
},
Activity = new BodyActivityDescription { MinimumTimestepCountUnderThreshold = 32, SleepThreshold = .01f },
Collidable = new CollidableDescription { Shape = boxShapeIndex, SpeculativeMargin = .1f },
};
return boxDescription;
}
private void CreateLevel(ref Vector3 position)
{
var boxPosition = position;
CreateHorizontalConveyor(ref position, ref _orientations[0]);
boxPosition.Y += 2;
for (var i = -(_horizontalHalfLenght-1); i <= (_horizontalHalfLenght - 1); i += 2)
{
boxPosition.X = i;
Instantiate(_boxDescription, ref boxPosition,ref _orientations[0]);
}
position += new Vector3(_horizontalHalfLenght + _conveyorHalfWidth, 0, _verticalHalfLenght - _conveyorHalfWidth);
CreateVerticalConveyor(ref position, ref _orientations[1]);
position += new Vector3(-_horizontalHalfLenght + _conveyorHalfWidth, 0, _verticalHalfLenght + _conveyorHalfWidth);
CreateHorizontalConveyor(ref position, ref _orientations[2]);
boxPosition = position;
boxPosition.Y += 2;
for (var i = -(_horizontalHalfLenght - 1); i <= (_horizontalHalfLenght - 1); i += 2)
{
boxPosition.X = i;
Instantiate(_boxDescription, ref boxPosition, ref _orientations[0]);
}
position += new Vector3(-_horizontalHalfLenght - _conveyorHalfWidth, 0, _verticalHalfLenght - _conveyorHalfWidth);
CreateVerticalConveyor(ref position, ref _orientations[1]);
position += new Vector3(_horizontalHalfLenght - _conveyorHalfWidth, 0, _verticalHalfLenght + _conveyorHalfWidth);
}
private void CreateHorizontalConveyor(ref Vector3 position, ref Quaternion orientation)
{
Instantiate(_horizontalConveyorDescription, ref position, ref orientation);
}
private void CreateVerticalConveyor(ref Vector3 position, ref Quaternion orientation)
{
Instantiate(_verticalConveyorDescription, ref position, ref orientation);
}
private void Instantiate(BodyDescription bodyReference, ref Vector3 position, ref Quaternion orientation)
{
bodyReference.Pose.Position = position;
bodyReference.Pose.Orientation = orientation;
_createdObjects.Add(Simulation.Bodies.Add(bodyReference), BufferPool);
}
private float _spawnCount = 0;
private float _spawnTime = 2f;
public override void Update(Window window, Camera camera, Input input, float dt)
{
base.Update(window, camera, input, dt);
#region KeyInput
if (input.WasPushed(Key.Z))
{
var boxPosition = new Vector3(-_horizontalHalfLenght + 1, 2,0);
var identity = Quaternion.Identity;
Instantiate(_boxDescription, ref boxPosition, ref identity);
}
_spawnCount += dt;
if (_spawnCount >= _spawnTime)
{
_spawnCount -= _spawnTime;
var boxPosition = new Vector3(-_horizontalHalfLenght + 1 , 2, 0);
var identity = Quaternion.Identity;
Instantiate(_boxDescription, ref boxPosition, ref identity);
}
//I know it is unoptimized but it is the easier way to delete the falling boxes.
for (var i = _createdObjects.Count - 1; i > 0; --i)
{
var bodiIndex = _createdObjects[i];
var reference = new BodyReference(bodiIndex, Simulation.Bodies);
if (reference.Pose.Position.Y < -10)
{
Simulation.Bodies.Remove(bodiIndex);
_createdObjects.RemoveAt(i);
}
}
#endregion
}
}
}