static void CreateBallSocket(ref RigidPose a, ref RigidPose b, out BallSocket description) { var midpoint = 0.5f * (a.Position + b.Position); description.LocalOffsetA = QuaternionEx.Transform(midpoint - a.Position, QuaternionEx.Conjugate(a.Orientation)); description.LocalOffsetB = QuaternionEx.Transform(midpoint - b.Position, QuaternionEx.Conjugate(b.Orientation)); description.SpringSettings = new SpringSettings(15, 0.1f); }
static void CreateBallSocket(ref RigidPose a, ref RigidPose b, out BallSocket description) { var midpoint = 0.5f * (a.Position + b.Position); description.LocalOffsetA = Quaternion.Transform(midpoint - a.Position, Quaternion.Conjugate(a.Orientation)); description.LocalOffsetB = Quaternion.Transform(midpoint - b.Position, Quaternion.Conjugate(b.Orientation)); description.SpringSettings = new SpringSettings { NaturalFrequency = (float)(Math.PI * 0.5f * 60), DampingRatio = 0.1f }; }
public unsafe override void Initialize(ContentArchive content, Camera camera) { camera.Position = new Vector3(-30, 8, -60); camera.Yaw = MathHelper.Pi * 3f / 4; camera.Pitch = 0; //The PositionFirstTimestepper is the simplest timestepping mode, but since it integrates velocity into position at the start of the frame, directly modified velocities outside of the timestep //will be integrated before collision detection or the solver has a chance to intervene. That's fine in this demo. Other built-in options include the PositionLastTimestepper and the SubsteppingTimestepper. //Note that the timestepper also has callbacks that you can use for executing logic between processing stages, like BeforeCollisionDetection. Simulation = Simulation.Create(BufferPool, new DemoNarrowPhaseCallbacks(), new DemoPoseIntegratorCallbacks(new Vector3(0, -10, 0)), new PositionFirstTimestepper()); var boxShape = new Box(1, 1, 1); boxShape.ComputeInertia(1, out var boxInertia); var boxIndex = Simulation.Shapes.Add(boxShape); const int forkCount = 20; const int blocksPerChain = 20; BodyHandle[] blockHandles = new BodyHandle[blocksPerChain]; for (int forkIndex = 0; forkIndex < forkCount; ++forkIndex) { //Build the blocks. for (int blockIndex = 0; blockIndex < blocksPerChain; ++blockIndex) { var bodyDescription = BodyDescription.CreateDynamic( new Vector3(0, 5 + blockIndex * (boxShape.Height + 1), (forkIndex - forkCount * 0.5f) * (boxShape.Length + 4)), //Make the uppermost block kinematic to hold up the rest of the chain. blockIndex == blocksPerChain - 1 ? new BodyInertia() : boxInertia, new CollidableDescription(boxIndex, .1f), new BodyActivityDescription(.01f, 32)); blockHandles[blockIndex] = Simulation.Bodies.Add(bodyDescription); } //Build the chains. for (int i = 1; i < blocksPerChain; ++i) { var ballSocket = new BallSocket { LocalOffsetA = new Vector3(0, 1f, 0), LocalOffsetB = new Vector3(0, -1f, 0), SpringSettings = new SpringSettings(30, 5) }; Simulation.Solver.Add(blockHandles[i - 1], blockHandles[i], ref ballSocket); } } Simulation.Statics.Add(new StaticDescription(new Vector3(1, -0.5f, 1), new CollidableDescription(Simulation.Shapes.Add(new Box(200, 1, 200)), 0.1f))); //Build the coin description for the ponz-I mean ICO. var coinShape = new Cylinder(1.5f, 0.2f); coinShape.ComputeInertia(1, out var coinInertia); coinDescription = BodyDescription.CreateDynamic(RigidPose.Identity, coinInertia, new CollidableDescription(Simulation.Shapes.Add(coinShape), 0.1f), new BodyActivityDescription(0.01f)); }
void Start() { foreach (Transform tr in ballSocketParent) { BallSocket ballSocket = tr.GetChild(0).GetComponent <BallSocket>(); ballSocket.OnSocketActivated += SocketActivated; ballSockets.Add(ballSocket); } foreach (Transform tr in ballsParent) { Ball ball = tr.GetComponent <Ball>(); balls.Add(ball); } }
public unsafe override void Initialize(ContentArchive content, Camera camera) { camera.Position = new Vector3(-120, 30, -120); camera.Yaw = MathHelper.Pi * 3f / 4; camera.Pitch = 0.1f; Simulation = Simulation.Create(BufferPool, new DemoNarrowPhaseCallbacks(), new DemoPoseIntegratorCallbacks(new Vector3(0, -10, 0))); Simulation.Solver.IterationCount = 8; //Build a grid of shapes to be connected. var clothNodeShape = new Sphere(0.5f); clothNodeShape.ComputeInertia(1, out var clothNodeInertia); var clothNodeShapeIndex = Simulation.Shapes.Add(clothNodeShape); const int width = 128; const int length = 128; const float spacing = 1.75f; int[][] nodeHandles = new int[width][]; for (int i = 0; i < width; ++i) { nodeHandles[i] = new int[length]; for (int j = 0; j < length; ++j) { var location = new Vector3(0, 30, 0) + new Vector3(spacing, 0, spacing) * (new Vector3(i, 0, j) + new Vector3(-width * 0.5f, 0, -length * 0.5f)); var bodyDescription = new BodyDescription { Activity = new BodyActivityDescription { MinimumTimestepCountUnderThreshold = 32, SleepThreshold = 0.01f }, Pose = new RigidPose { Orientation = BepuUtilities.Quaternion.Identity, Position = location }, Collidable = new CollidableDescription { Shape = clothNodeShapeIndex, Continuity = new ContinuousDetectionSettings { Mode = ContinuousDetectionMode.Discrete }, SpeculativeMargin = 0.1f }, LocalInertia = clothNodeInertia }; nodeHandles[i][j] = Simulation.Bodies.Add(bodyDescription); } } //Construct some joints between the nodes. var left = new BallSocket { LocalOffsetA = new Vector3(-spacing * 0.5f, 0, 0), LocalOffsetB = new Vector3(spacing * 0.5f, 0, 0), SpringSettings = new SpringSettings(10, 1) }; var up = new BallSocket { LocalOffsetA = new Vector3(0, 0, -spacing * 0.5f), LocalOffsetB = new Vector3(0, 0, spacing * 0.5f), SpringSettings = new SpringSettings(10, 1) }; var leftUp = new BallSocket { LocalOffsetA = new Vector3(-spacing * 0.5f, 0, -spacing * 0.5f), LocalOffsetB = new Vector3(spacing * 0.5f, 0, spacing * 0.5f), SpringSettings = new SpringSettings(10, 1) }; var rightUp = new BallSocket { LocalOffsetA = new Vector3(spacing * 0.5f, 0, -spacing * 0.5f), LocalOffsetB = new Vector3(-spacing * 0.5f, 0, spacing * 0.5f), SpringSettings = new SpringSettings(10, 1) }; for (int i = 0; i < width; ++i) { for (int j = 0; j < length; ++j) { if (i >= 1) { Simulation.Solver.Add(nodeHandles[i][j], nodeHandles[i - 1][j], ref left); } if (j >= 1) { Simulation.Solver.Add(nodeHandles[i][j], nodeHandles[i][j - 1], ref up); } if (i >= 1 && j >= 1) { Simulation.Solver.Add(nodeHandles[i][j], nodeHandles[i - 1][j - 1], ref leftUp); } if (i < width - 1 && j >= 1) { Simulation.Solver.Add(nodeHandles[i][j], nodeHandles[i + 1][j - 1], ref rightUp); } } } var bigBallShape = new Sphere(45); var bigBallShapeIndex = Simulation.Shapes.Add(bigBallShape); var bigBallDescription = new BodyDescription { Collidable = new CollidableDescription { Continuity = new ContinuousDetectionSettings { Mode = ContinuousDetectionMode.Discrete }, Shape = bigBallShapeIndex, SpeculativeMargin = 0.1f }, Activity = new BodyActivityDescription(0), Pose = new RigidPose { Position = new Vector3(-10, -15, 0), Orientation = BepuUtilities.Quaternion.Identity } }; bigBallHandle = Simulation.Bodies.Add(bigBallDescription); var groundShape = new Box(200, 1, 200); var groundShapeIndex = Simulation.Shapes.Add(groundShape); var groundDescription = new BodyDescription { Collidable = new CollidableDescription { Continuity = new ContinuousDetectionSettings { Mode = ContinuousDetectionMode.Discrete }, Shape = groundShapeIndex, SpeculativeMargin = 0.1f }, Activity = new BodyActivityDescription(0), Pose = new RigidPose { Position = new Vector3(0, -10, 0), Orientation = BepuUtilities.Quaternion.Identity } }; Simulation.Bodies.Add(groundDescription); }
public unsafe 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(0, -10, 0))); var boxShape = new Box(1, 1, 1); boxShape.ComputeInertia(1, out var boxInertia); var boxIndex = Simulation.Shapes.Add(boxShape); const int forkCount = 20; const int blocksPerChain = 20; int[] blockHandles = new int[blocksPerChain]; for (int forkIndex = 0; forkIndex < forkCount; ++forkIndex) { //Build the blocks. for (int blockIndex = 0; blockIndex < blocksPerChain; ++blockIndex) { var bodyDescription = new BodyDescription { //Make the uppermost block kinematic to hold up the rest of the chain. LocalInertia = blockIndex == blocksPerChain - 1 ? new BodyInertia() : boxInertia, Pose = new RigidPose { Position = new Vector3(0, 5 + blockIndex * (boxShape.Height + 1), (forkIndex - forkCount * 0.5f) * (boxShape.Length + 4)), Orientation = Quaternion.Identity }, Activity = new BodyActivityDescription { MinimumTimestepCountUnderThreshold = 32, SleepThreshold = .01f }, Collidable = new CollidableDescription { Shape = boxIndex, SpeculativeMargin = .1f }, }; blockHandles[blockIndex] = Simulation.Bodies.Add(bodyDescription); } //Build the chains. for (int i = 1; i < blocksPerChain; ++i) { var ballSocket = new BallSocket { LocalOffsetA = new Vector3(0, 1f, 0), LocalOffsetB = new Vector3(0, -1f, 0), SpringSettings = new SpringSettings(30, 5) }; Simulation.Solver.AddRef(blockHandles[i - 1], blockHandles[i], ref ballSocket); } } var staticShape = new Box(200, 1, 200); var staticShapeIndex = Simulation.Shapes.Add(staticShape); var staticDescription = new StaticDescription { Collidable = new CollidableDescription { Continuity = new ContinuousDetectionSettings { Mode = ContinuousDetectionMode.Discrete }, Shape = staticShapeIndex, SpeculativeMargin = 0.1f }, Pose = new RigidPose { Position = new Vector3(1, -0.5f, 1), Orientation = Quaternion.Identity } }; Simulation.Statics.Add(staticDescription); //Build the coin description for the ponz-I mean ICO. var coinShape = new Cylinder(1.5f, 0.2f); coinShape.ComputeInertia(1, out var coinInertia); coinDescription = BodyDescription.CreateDynamic(RigidPose.Identity, coinInertia, new CollidableDescription(Simulation.Shapes.Add(coinShape), 0.1f), new BodyActivityDescription(0.01f)); }
public unsafe override void Initialize(ContentArchive content, Camera camera) { camera.Position = new Vector3(-20, 10, -20); //camera.Yaw = MathHelper.Pi ; camera.Yaw = MathHelper.Pi * 3f / 4; //camera.Pitch = MathHelper.PiOver2 * 0.999f; Simulation = Simulation.Create(BufferPool, new TestCallbacks()); Simulation.PoseIntegrator.Gravity = new Vector3(0, -10, 0); Simulation.Deterministic = false; var a = AddBody(new Box(3, 1, 1), 1, new RigidPose { Position = new Vector3(0, 10, 0), Orientation = BepuUtilities.Quaternion.Identity }, Simulation); var b = AddBody(new Box(3, 1, 1), 0, new RigidPose { Position = new Vector3(5, 10, 0), Orientation = BepuUtilities.Quaternion.Identity }, Simulation); a.Velocity.Angular = new Vector3(1f, 5f, 1f); //a.Pose.Orientation = BepuUtilities.Quaternion.CreateFromAxisAngle(Vector3.Normalize(new Vector3(1, 1, 1)), MathHelper.PiOver4); var springSettings = new SpringSettings(15, 1); var ballSocket = new BallSocket { LocalOffsetA = new Vector3(2.5f, 0, 0), LocalOffsetB = new Vector3(-2.5f, 0, 0), SpringSettings = springSettings }; Simulation.Solver.Add(a.Handle, b.Handle, ref ballSocket); //springSettings = new BepuPhysics.CollisionDetection.SpringSettings { DampingRatio = 0f, NaturalFrequency = MathHelper.Pi * 1 }; var angularHinge = new AngularHinge { HingeAxisLocalA = Vector3.Normalize(new Vector3(0, 1, 0)), HingeAxisLocalB = Vector3.Normalize(new Vector3(0, 1, 0)), SpringSettings = springSettings }; Simulation.Solver.Add(a.Handle, b.Handle, ref angularHinge); //var swivelHinge = new AngularSwivelHinge //{ // SwivelAxisLocalA = new Vector3(1, 0, 0), // HingeAxisLocalB = new Vector3(0, 1, 0), // SpringSettings = springSettings //}; //Simulation.Solver.Add(a.Handle, b.Handle, ref swivelHinge); var swingLimit = new SwingLimit { AxisLocalA = new Vector3(1, 0, 0), AxisLocalB = new Vector3(1, 0, 0), MinimumDot = -0.5f, SpringSettings = new SpringSettings(15, 1) }; Simulation.Solver.Add(a.Handle, b.Handle, ref swingLimit); var staticShape = new Box(100, 1, 100); var staticShapeIndex = Simulation.Shapes.Add(staticShape); var staticDescription = new StaticDescription { Collidable = new CollidableDescription { Continuity = new ContinuousDetectionSettings { Mode = ContinuousDetectionMode.Discrete }, Shape = staticShapeIndex, SpeculativeMargin = 0.1f }, Pose = new RigidPose { Position = new Vector3(1, -0.5f, 1), Orientation = BepuUtilities.Quaternion.Identity } }; Simulation.Statics.Add(staticDescription); }
public unsafe override void Initialize(ContentArchive content, Camera camera) { camera.Position = new Vector3(-120, 30, -120); camera.Yaw = MathHelper.Pi * 3f / 4; camera.Pitch = 0.1f; //The PositionFirstTimestepper is the simplest timestepping mode, but since it integrates velocity into position at the start of the frame, directly modified velocities outside of the timestep //will be integrated before collision detection or the solver has a chance to intervene. That's fine in this demo. Other built-in options include the PositionLastTimestepper and the SubsteppingTimestepper. //Note that the timestepper also has callbacks that you can use for executing logic between processing stages, like BeforeCollisionDetection. Simulation = Simulation.Create(BufferPool, new DemoNarrowPhaseCallbacks(), new DemoPoseIntegratorCallbacks(new Vector3(0, -10, 0)), new PositionFirstTimestepper()); //Build a grid of shapes to be connected. var clothNodeShape = new Sphere(0.5f); clothNodeShape.ComputeInertia(1, out var clothNodeInertia); var clothNodeShapeIndex = Simulation.Shapes.Add(clothNodeShape); const int width = 128; const int length = 128; const float spacing = 1.75f; BodyHandle[][] nodeHandles = new BodyHandle[width][]; for (int i = 0; i < width; ++i) { nodeHandles[i] = new BodyHandle[length]; for (int j = 0; j < length; ++j) { var location = new Vector3(0, 30, 0) + new Vector3(spacing, 0, spacing) * (new Vector3(i, 0, j) + new Vector3(-width * 0.5f, 0, -length * 0.5f)); var bodyDescription = new BodyDescription { Activity = new BodyActivityDescription { MinimumTimestepCountUnderThreshold = 32, SleepThreshold = 0.01f }, Pose = new RigidPose { Orientation = Quaternion.Identity, Position = location }, Collidable = new CollidableDescription { Shape = clothNodeShapeIndex, Continuity = new ContinuousDetectionSettings { Mode = ContinuousDetectionMode.Discrete }, SpeculativeMargin = 0.1f }, LocalInertia = clothNodeInertia }; nodeHandles[i][j] = Simulation.Bodies.Add(bodyDescription); } } //Construct some joints between the nodes. var left = new BallSocket { LocalOffsetA = new Vector3(-spacing * 0.5f, 0, 0), LocalOffsetB = new Vector3(spacing * 0.5f, 0, 0), SpringSettings = new SpringSettings(10, 1) }; var up = new BallSocket { LocalOffsetA = new Vector3(0, 0, -spacing * 0.5f), LocalOffsetB = new Vector3(0, 0, spacing * 0.5f), SpringSettings = new SpringSettings(10, 1) }; var leftUp = new BallSocket { LocalOffsetA = new Vector3(-spacing * 0.5f, 0, -spacing * 0.5f), LocalOffsetB = new Vector3(spacing * 0.5f, 0, spacing * 0.5f), SpringSettings = new SpringSettings(10, 1) }; var rightUp = new BallSocket { LocalOffsetA = new Vector3(spacing * 0.5f, 0, -spacing * 0.5f), LocalOffsetB = new Vector3(-spacing * 0.5f, 0, spacing * 0.5f), SpringSettings = new SpringSettings(10, 1) }; for (int i = 0; i < width; ++i) { for (int j = 0; j < length; ++j) { if (i >= 1) { Simulation.Solver.Add(nodeHandles[i][j], nodeHandles[i - 1][j], ref left); } if (j >= 1) { Simulation.Solver.Add(nodeHandles[i][j], nodeHandles[i][j - 1], ref up); } if (i >= 1 && j >= 1) { Simulation.Solver.Add(nodeHandles[i][j], nodeHandles[i - 1][j - 1], ref leftUp); } if (i < width - 1 && j >= 1) { Simulation.Solver.Add(nodeHandles[i][j], nodeHandles[i + 1][j - 1], ref rightUp); } } } var bigBallShape = new Sphere(25); var bigBallShapeIndex = Simulation.Shapes.Add(bigBallShape); var bigBallDescription = new StaticDescription { Collidable = new CollidableDescription { Continuity = new ContinuousDetectionSettings { Mode = ContinuousDetectionMode.Discrete }, Shape = bigBallShapeIndex, SpeculativeMargin = 0.1f }, Pose = new RigidPose { Position = new Vector3(-10, -15, 0), Orientation = Quaternion.Identity } }; Simulation.Statics.Add(bigBallDescription); var groundShape = new Box(200, 1, 200); var groundShapeIndex = Simulation.Shapes.Add(groundShape); var groundDescription = new StaticDescription { Collidable = new CollidableDescription { Continuity = new ContinuousDetectionSettings { Mode = ContinuousDetectionMode.Discrete }, Shape = groundShapeIndex, SpeculativeMargin = 0.1f }, Pose = new RigidPose { Position = new Vector3(0, -10, 0), Orientation = Quaternion.Identity } }; Simulation.Statics.Add(groundDescription); }