예제 #1
0
        void TryAddProjectileImpact(BodyHandle projectileHandle, CollidableReference impactedCollidable)
        {
            bool lockTaken = false;

            ProjectileLock.Enter(ref lockTaken);
            try
            {
                //Note that we have to protect against redundant adds- a projectile might hit multiple things in the same frame. Wouldn't want it to explode multiple times.
                for (int i = 0; i < ProjectileImpacts.Count; ++i)
                {
                    ref var impact = ref ProjectileImpacts[i];
                    //If the projectile has already been handled, ignore it.
                    if (impact.ProjectileHandle.Value == projectileHandle.Value)
                    {
                        return;
                    }
                }
                //The exploding projectiles list should have been sized ahead of time to hold all projectiles, so no dynamic allocations should be required.
                ref var newImpact = ref ProjectileImpacts.AllocateUnsafely();
                newImpact.ProjectileHandle = projectileHandle;
                if (impactedCollidable.Mobility != CollidableMobility.Static)
                {
                    //The filter's group id is the tank's main body handle. We use that to find the tank (if this body is related to a tank at all).
                    ref var properties = ref Properties[impactedCollidable.BodyHandle];
                    newImpact.ImpactedTankBodyHandle = new BodyHandle(properties.TankPart ? properties.Filter.GroupId : -1);
                }
예제 #2
0
 public MovingPlatform(CollidableDescription collidable, double timeOffset, float goalSatisfactionTime, Simulation simulation, Func <double, RigidPose> poseCreator)
 {
     PoseCreator = poseCreator;
     BodyHandle  = simulation.Bodies.Add(BodyDescription.CreateKinematic(poseCreator(timeOffset), collidable, new BodyActivityDescription(-1)));
     InverseGoalSatisfactionTime = 1f / goalSatisfactionTime;
     TimeOffset = timeOffset;
 }
예제 #3
0
        public override void Load(BodyHandle bodyHandle, ConnectionState connectionState, Simulator simulator, ObjectState state)
        {
            base.Load(bodyHandle, connectionState, simulator, state);
            PhyInterval worker = new PhyInterval(1, simulator);

            worker.Completed += Tick;


            material = new SimpleMaterial
            {
                FrictionCoefficient     = .97f,
                MaximumRecoveryVelocity = float.MaxValue,
                SpringSettings          = new SpringSettings(1f, 1.5f)
            };
            simulator.collidableMaterials.Allocate(bodyHandle) = material;

            reference = simulator.Simulation.Bodies.GetBodyReference(bodyHandle);
            simulator.OnContactListeners.Add(this.bodyHandle, this);


            SetPositionToStartPoint();
            CreateBall();
            CreateUser();
            CreateGauntlet();


            jumpState       = new JumpState(this);
            snappedState    = new SnappedState(this);
            notSnappedState = new Not_SnappedState(this);
            shotState       = new ShootState(this);
        }
예제 #4
0
 public ConstraintContacts(BufferPool pool, BodyHandle a, BodyHandle b)
 {
     //Nonconvex manifolds will never have less than the convex count, so we'll preallocate enough space for a nonconvex manifold.
     Contacts = new QuickList <Contact>(NonconvexContactManifold.MaximumContactCount, pool);
     BodyA    = a;
     BodyB    = b;
 }
예제 #5
0
        private PhysicsObject FindObject(StaticHandle staticHandle, BodyHandle bodyHandle)
        {
            foreach (var physicsObject in Bodies)
            {
                if (!physicsObject.Reference.Exists)
                {
                    continue;
                }

                if (physicsObject.Id == bodyHandle.Value)
                {
                    return(physicsObject);
                }
            }

            foreach (var physicsObject in Statics)
            {
                if (!physicsObject.Reference.Exists)
                {
                    continue;
                }

                if (physicsObject.Id == staticHandle.Value)
                {
                    return(physicsObject);
                }
            }

            throw new Exception($"Failed to find physics object: Got {staticHandle}/{bodyHandle}");
        }
예제 #6
0
        private void AddBody <T>() where T : unmanaged, IConvexShape
        {
            T withType = (T)colliderShape;

            colliderShape.ComputeInertia(mass, out BodyInertia inertia);

            if (isStatic)
            {
                staticHandle = PhysicsHandler.Simulation.Statics.Add(
                    new StaticDescription(
                        parent.Movement.Position,
                        new CollidableDescription(
                            PhysicsHandler.Simulation.Shapes.Add(withType),
                            0.1f
                            )
                        )
                    );
            }
            else
            {
                bodyHandle = PhysicsHandler.Simulation.Bodies.Add(
                    BodyDescription.CreateDynamic(
                        parent.Movement.Position,
                        inertia,
                        new CollidableDescription(
                            PhysicsHandler.Simulation.Shapes.Add(withType),
                            0.1f
                            ),
                        new BodyActivityDescription(0.01f)
                        )
                    );
            }
        }
예제 #7
0
        private PhyObject SetUpPhyObject(BodyHandle bodyHandle, ObjectState state)
        {
            PhyObject phy = GetPhyClass(state.type);

            phy.Load(bodyHandle, connectionState, this, state);

            return(phy);
        }
예제 #8
0
        public override void Load(BodyHandle bodyHandle, ConnectionState connectionState, Simulator simulator, ObjectState state)
        {
            base.Load(bodyHandle, connectionState, simulator, state);
            vehicle = new Vehicle(this);

            PhyInterval worker = new PhyInterval(1, simulator);

            worker.Completed += Tick;
            behaviour         = new CrocoBehaviour(this);
        }
예제 #9
0
        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));
        }
예제 #10
0
 public bool GetBody(int columnIndex, int rowIndex, int sliceIndex, out BodyHandle handle, out BodyDescription bodyDescription)
 {
     if (!TryGetId(columnIndex, rowIndex, sliceIndex, out var id))
     {
         handle          = new BodyHandle(-1);
         bodyDescription = new BodyDescription();
         return(false);
     }
     handle = bodyHandles[id];
     bodies.GetDescription(handle, out bodyDescription);
     return(true);
 }
예제 #11
0
        public CharacterInput(CharacterControllers characters, Vector3 initialPosition, Capsule shape,
                              float speculativeMargin, float mass, float maximumHorizontalForce, float maximumVerticalGlueForce,
                              float jumpVelocity, float speed, float maximumSlope = MathF.PI * 0.25f)
        {
            this.characters = characters;
            var shapeIndex = characters.Simulation.Shapes.Add(shape);

            //Because characters are dynamic, they require a defined BodyInertia. For the purposes of the demos, we don't want them to rotate or fall over, so the inverse inertia tensor is left at its default value of all zeroes.
            //This is effectively equivalent to giving it an infinite inertia tensor- in other words, no torque will cause it to rotate.
            bodyHandle = characters.Simulation.Bodies.Add(BodyDescription.CreateDynamic(initialPosition, new BodyInertia {
                InverseMass = 1f / mass
            }, new CollidableDescription(shapeIndex, speculativeMargin), new BodyActivityDescription(shape.Radius * 0.02f)));
            ref var character = ref characters.AllocateCharacter(bodyHandle);
예제 #12
0
        public virtual void Load(BodyHandle bodyHandle, ConnectionState connectionState, Simulator simulator, ObjectState state)
        {
            this.connectionState = connectionState;
            this.bodyHandle      = bodyHandle;
            this.state           = state;
            this.simulator       = simulator;
            this.reference       = GetReference();

            /* if(state.quaternion == new Quaternion(0,0,0,0)){
             *  this.state.quaternion = Quaternion.Identity;
             * }*/

            SendCreateMessage();
        }
예제 #13
0
        private void createObjects()
        {
            for (int a = 0; a < 7000; a++)
            {
                var ringBoxShape = new Box(1, 1, 1);
                ringBoxShape.ComputeInertia(1, out var ringBoxInertia);
                var boxDescription = BodyDescription.CreateDynamic(new Vector3(), ringBoxInertia,
                                                                   new CollidableDescription(Simulation.Shapes.Add(ringBoxShape), 0.1f),
                                                                   new BodyActivityDescription(0.01f));

                boxDescription.Pose = new RigidPose(new Vector3(1, 9, 10 + a), new Quaternion(0, 0, 0, 1));
                bodyHandle          = Simulation.Bodies.Add(boxDescription);
            }
        }
예제 #14
0
        public override void Initialize(ContentArchive content, Camera camera)
        {
            camera.Position = new Vector3(0, 5, 25);
            camera.Yaw      = 0;
            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());

            //Drop a pyramid on top of the sensor so there are more contacts to look at.
            var boxShape = new Box(1, 1, 1);

            boxShape.ComputeInertia(1, out var boxInertia);
            var boxIndex = Simulation.Shapes.Add(boxShape);

            const int rowCount = 20;

            for (int rowIndex = 0; rowIndex < rowCount; ++rowIndex)
            {
                int columnCount = rowCount - rowIndex;
                for (int columnIndex = 0; columnIndex < columnCount; ++columnIndex)
                {
                    Simulation.Bodies.Add(BodyDescription.CreateDynamic(new Vector3(
                                                                            (-columnCount * 0.5f + columnIndex) * boxShape.Width,
                                                                            (rowIndex + 0.5f) * boxShape.Height + 10, 0),
                                                                        boxInertia,
                                                                        new CollidableDescription(boxIndex, 0.1f),
                                                                        new BodyActivityDescription(0.01f)));
                }
            }


            sensorBodyHandle = Simulation.Bodies.Add(BodyDescription.CreateConvexDynamic(new Vector3(0, 0, 1), 10, Simulation.Shapes, new Box(4, 2, 6)));

            //Put a mesh under the sensor so that nonconvex contacts are shown.
            const int planeWidth  = 128;
            const int planeHeight = 128;

            DemoMeshHelper.CreateDeformedPlane(planeWidth, planeHeight,
                                               (int x, int y) =>
            {
                return(new Vector3(x - planeWidth / 2, 1 * MathF.Cos(x / 2f) * MathF.Sin(y / 2f), y - planeHeight / 2));
            }, new Vector3(2, 1, 2), BufferPool, out var planeMesh);
            Simulation.Statics.Add(new StaticDescription(new Vector3(0, -2, 0), QuaternionEx.CreateFromAxisAngle(new Vector3(0, 1, 0), MathF.PI / 2),
                                                         new CollidableDescription(Simulation.Shapes.Add(planeMesh), 0.1f)));
        }
예제 #15
0
파일: GameObject.cs 프로젝트: tottaka/GameX
        public void SetCollider(PhysicsType type)
        {
            if (PhysicsBodyInitialized)
            {
                RemoveCollider();

                if (type == PhysicsType.None)
                {
                    PhysicsType = type;
                    if (Physics.PhysicsObjects.Contains(this))
                    {
                        Physics.PhysicsObjects.Remove(this);
                    }

                    return;
                }
            }

            if (type == PhysicsType.Cube)
            {
                Box shape = new Box(2.0f, 2.0f, 2.0f);
                ShapeIndex = Physics.simulator.Shapes.Add(shape);
                Shape      = shape;
            }
            else if (type == PhysicsType.Sphere)
            {
                Sphere shape = new Sphere(2.0f);
                ShapeIndex = Physics.simulator.Shapes.Add(shape);
                Shape      = shape;
            }

            Shape.ComputeInertia(Mass, out BodyInertia inertia);

            PhysicsDescription = BodyDescription.CreateDynamic(transform.Position, inertia, new CollidableDescription(ShapeIndex, 0.1f), new BodyActivityDescription(0.01f));
            BodyHandle         = Physics.simulator.Bodies.Add(PhysicsDescription);
            BodyReference      = Physics.simulator.Bodies.GetBodyReference(BodyHandle);

            if (!Physics.PhysicsObjects.Contains(this))
            {
                Physics.PhysicsObjects.Add(this);
            }

            PhysicsType            = type;
            PhysicsBodyInitialized = true;
            physicsEnabled         = true;
        }
        public override void Initialize(ContentArchive content, Camera camera)
        {
            camera.Position = new Vector3(0, 5, 25);
            camera.Yaw      = 0;
            camera.Pitch    = 0;
            Simulation      = Simulation.Create(BufferPool, new DemoNarrowPhaseCallbacks(), new DemoPoseIntegratorCallbacks(new Vector3(0, -10, 0)));

            //Drop a pyramid on top of the sensor so there are more contacts to look at.
            var boxShape = new Box(1, 1, 1);

            boxShape.ComputeInertia(1, out var boxInertia);
            var boxIndex = Simulation.Shapes.Add(boxShape);

            const int rowCount = 20;

            for (int rowIndex = 0; rowIndex < rowCount; ++rowIndex)
            {
                int columnCount = rowCount - rowIndex;
                for (int columnIndex = 0; columnIndex < columnCount; ++columnIndex)
                {
                    Simulation.Bodies.Add(BodyDescription.CreateDynamic(new Vector3(
                                                                            (-columnCount * 0.5f + columnIndex) * boxShape.Width,
                                                                            (rowIndex + 0.5f) * boxShape.Height + 10, 0),
                                                                        boxInertia,
                                                                        new CollidableDescription(boxIndex, 0.1f),
                                                                        new BodyActivityDescription(0.01f)));
                }
            }


            sensorBodyHandle = Simulation.Bodies.Add(BodyDescription.CreateConvexDynamic(new Vector3(0, 0, 1), 10, Simulation.Shapes, new Box(4, 2, 6)));

            //Put a mesh under the sensor so that nonconvex contacts are shown.
            const int planeWidth  = 128;
            const int planeHeight = 128;

            DemoMeshHelper.CreateDeformedPlane(planeWidth, planeHeight,
                                               (int x, int y) =>
            {
                return(new Vector3(x - planeWidth / 2, 1 * MathF.Cos(x / 2f) * MathF.Sin(y / 2f), y - planeHeight / 2));
            }, new Vector3(2, 1, 2), BufferPool, out var planeMesh);
            Simulation.Statics.Add(new StaticDescription(new Vector3(0, -2, 0), QuaternionEx.CreateFromAxisAngle(new Vector3(0, 1, 0), MathF.PI / 2),
                                                         new CollidableDescription(Simulation.Shapes.Add(planeMesh), 0.1f)));
        }
예제 #17
0
        protected virtual void DefinePhysicsObject(float size, float mass)
        {
            if (size == 0 || mass == 0)
            {
                throw new Exception("WorldBody defined with zero size or mass");
            }

            var shape      = new Sphere(size);
            var position2d = InitialPosition();

            ShapeHandle = World.Simulation.Shapes.Add(shape);
            BodyHandle  = World.Simulation.Bodies.Add(BodyDescription.CreateDynamic(
                                                          new Vector3(position2d.X, 0, position2d.Y),
                                                          GetBodyInertia(shape, mass),
                                                          new CollidableDescription(ShapeHandle, 150f),
                                                          //new CollidableDescription(ShapeHandle, 0.1f, ContinuousDetectionSettings.Continuous(1e-4f, 1e-4f)),
                                                          new BodyActivityDescription(0.0f)
                                                          ));
        }
예제 #18
0
        public static void BuildLattice <TBodyBuilder, TConstraintBuilder>(TBodyBuilder bodyBuilder, TConstraintBuilder constraintBuilder, int width, int height, int length, Simulation simulation,
                                                                           out BodyHandle[] bodyHandles, out ConstraintHandle[] constraintHandles) where TBodyBuilder : IBodyBuilder where TConstraintBuilder : IConstraintBuilder
        {
            var bodyCount = width * height * length;

            bodyHandles = new BodyHandle[bodyCount];

            var bodyGetter = new LatticeBodyGetter(width, height, length, bodyHandles, simulation.Bodies);

            for (int sliceIndex = 0; sliceIndex < length; ++sliceIndex)
            {
                for (int rowIndex = 0; rowIndex < height; ++rowIndex)
                {
                    for (int columnIndex = 0; columnIndex < width; ++columnIndex)
                    {
                        bodyBuilder.Build(columnIndex, rowIndex, sliceIndex, out var bodyDescription);
                        bodyGetter.TryGetId(columnIndex, rowIndex, sliceIndex, out var id);
                        bodyHandles[id] = simulation.Bodies.Add(bodyDescription);
                    }
                }
            }

            var constraintAdder = new ConstraintAdder(simulation, new List <ConstraintHandle>(width * height * length * 3));

            for (int sliceIndex = 0; sliceIndex < length; ++sliceIndex)
            {
                //The bottom rows are all kinematic, so don't create connections between them.
                for (int rowIndex = 0; rowIndex < height; ++rowIndex)
                {
                    for (int columnIndex = 0; columnIndex < width; ++columnIndex)
                    {
                        bodyGetter.GetBody(columnIndex, rowIndex, sliceIndex, out constraintAdder.LocalBodyHandle, out var bodyDescription);
                        constraintBuilder.BuildConstraintsForBody(sliceIndex, rowIndex, columnIndex, ref bodyDescription, ref bodyGetter, ref constraintAdder);
                    }
                }
            }
            constraintHandles = constraintAdder.ConstraintHandles.ToArray();
        }
예제 #19
0
        public unsafe override void Initialize(ContentArchive content, Camera camera)
        {
            camera.Position = new Vector3(-15f, 20, -15f);
            camera.Yaw      = MathHelper.Pi * 3f / 4;
            camera.Pitch    = MathHelper.Pi * 0.1f;
            //Using minimum sized allocations forces as many resizes as possible.
            Simulation = Simulation.Create(BufferPool, new DemoNarrowPhaseCallbacks(), new DemoPoseIntegratorCallbacks(new Vector3(0, -10, 0)), initialAllocationSizes:
                                           new SimulationAllocationSizes
            {
                Bodies = 1,
                ConstraintCountPerBodyEstimate = 1,
                Constraints             = 1,
                ConstraintsPerTypeBatch = 1,
                Islands       = 1,
                ShapesPerType = 1,
                Statics       = 1
            });

            Simulation.Deterministic = true;

            const int planeWidth  = 8;
            const int planeHeight = 8;

            DemoMeshHelper.CreateDeformedPlane(planeWidth, planeHeight,
                                               (int x, int y) =>
            {
                Vector2 offsetFromCenter = new Vector2(x - planeWidth / 2, y - planeHeight / 2);
                return(new Vector3(offsetFromCenter.X, MathF.Cos(x / 4f) * MathF.Sin(y / 4f) - 0.2f * offsetFromCenter.LengthSquared(), offsetFromCenter.Y));
            }, new Vector3(2, 1, 2), BufferPool, out var staticShape);
            var         staticShapeIndex           = Simulation.Shapes.Add(staticShape);
            const int   staticGridWidthInInstances = 128;
            const float staticSpacing = 8;

            for (int i = 0; i < staticGridWidthInInstances; ++i)
            {
                for (int j = 0; j < staticGridWidthInInstances; ++j)
                {
                    var staticDescription = new StaticDescription
                    {
                        Collidable = new CollidableDescription
                        {
                            Continuity = new ContinuousDetectionSettings {
                                Mode = ContinuousDetectionMode.Discrete
                            },
                            Shape             = staticShapeIndex,
                            SpeculativeMargin = 0.1f
                        },
                        Pose = new RigidPose
                        {
                            Position = new Vector3(
                                -staticGridWidthInInstances * staticSpacing * 0.5f + i * staticSpacing,
                                -4 + 4 * (float)Math.Cos(i * 0.3) + 4 * (float)Math.Cos(j * 0.3),
                                -staticGridWidthInInstances * staticSpacing * 0.5f + j * staticSpacing),
                            Orientation = Quaternion.Identity
                        }
                    };
                    Simulation.Statics.Add(staticDescription);
                }
            }

            //A bunch of kinematic balls do acrobatics as an extra stressor.
            var kinematicShape      = new Sphere(8);
            var kinematicShapeIndex = Simulation.Shapes.Add(kinematicShape);
            var kinematicCount      = 64;
            var anglePerKinematic   = MathHelper.TwoPi / kinematicCount;
            var startingRadius      = 256;

            kinematicHandles = new BodyHandle[kinematicCount];
            for (int i = 0; i < kinematicCount; ++i)
            {
                var angle       = anglePerKinematic * i;
                var description = new BodyDescription
                {
                    Collidable = new CollidableDescription
                    {
                        Continuity = new ContinuousDetectionSettings {
                            Mode = ContinuousDetectionMode.Discrete
                        },
                        Shape             = kinematicShapeIndex,
                        SpeculativeMargin = 0.1f
                    },
                    Pose = new RigidPose
                    {
                        Position = new Vector3(
                            startingRadius * (float)Math.Cos(angle),
                            0,
                            startingRadius * (float)Math.Sin(angle)),
                        Orientation = Quaternion.Identity
                    },
                    Activity = new BodyActivityDescription {
                        SleepThreshold = 0, MinimumTimestepCountUnderThreshold = 4
                    },
                };
                kinematicHandles[i] = Simulation.Bodies.Add(description);
            }

            dynamicHandles = new QuickQueue <BodyHandle>(65536, BufferPool);
            removedStatics = new QuickQueue <StaticDescription>(512, BufferPool);
            random         = new Random(5);
        }
예제 #20
0
        public PhyObject handleToPhyObject(BodyHandle handle)
        {
            PhyObject obj = objectsHandlers[handle];

            return(obj);
        }
예제 #21
0
 public ConstraintAdder(Simulation simulation, List <ConstraintHandle> constraintHandles)
 {
     this.simulation        = simulation;
     this.ConstraintHandles = constraintHandles;
     LocalBodyHandle        = default;
 }
예제 #22
0
 public CollidableReference(CollidableMobility mobility, BodyHandle handle)
     : this(mobility, handle.Value)
 {
     Debug.Assert(mobility == CollidableMobility.Dynamic || mobility == CollidableMobility.Kinematic, "Creating a collidable reference associated with a body requires a body-related mobility.");
 }
예제 #23
0
 void AddBodyImpact(BodyHandle A, CollidableReference impactedCollidable, Vector3 newAVelocity, bool customBounce)
 {
     ref var newImpact = ref BodyImpacts.Allocate(World.BufferPool);
 internal void UnregisterCollider(BodyHandle handle) => collidersB.TryRemove(handle, out _);
 internal ICollitionHandler GetHandler(BodyHandle handle) => collidersB.GetValueOrDefault(handle);
 internal void RegisterCollider(BodyHandle handle, ICollitionHandler handler) => collidersB.TryAdd(handle, handler);
예제 #27
0
        public void Add <T>(ref T description, BodyHandle otherBodyHandle) where T : unmanaged, ITwoBodyConstraintDescription <T>
        {
            var constraintHandle = simulation.Solver.Add(LocalBodyHandle, otherBodyHandle, ref description);

            ConstraintHandles.Add(constraintHandle);
        }
예제 #28
0
        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;

            BodyHandle[] blockHandles = new BodyHandle[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.Add(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));
        }
예제 #29
0
        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;

            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(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 = 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 = Quaternion.Identity
                }
            };

            Simulation.Bodies.Add(groundDescription);
        }
예제 #30
0
 public CylinderBody(PhysicsSimulation simulation, BodyHandle handle) : base(simulation, handle)
 {
 }