예제 #1
0
        public PhysicsShadowWorld(
            IEventEngine <IPhysicsEventContext> physicsEventEngine,
            IHierarchy hierarchy,
            IDebugRenderer debugRenderer,
            IConsoleHandle consoleHandle)
        {
            _physicsEventEngine = physicsEventEngine;
            _hierarchy          = hierarchy;
            _debugRenderer      = debugRenderer;
            _consoleHandle      = consoleHandle;

            var collisionSystem = new CollisionSystemPersistentSAP
            {
                EnableSpeculativeContacts = true
            };

            _physicsWorld = new JitterWorld(collisionSystem);
            _physicsWorld.ContactSettings.MaterialCoefficientMixing =
                ContactSettings.MaterialCoefficientMixingType.TakeMinimum;

            _physicsWorld.Gravity = new JVector(0, -10f, 0);

            _rigidBodyMappings = new List <RigidBodyMapping>();

            _lastFramePosition = new Dictionary <int, Vector3>();
            _lastFrameRotation = new Dictionary <int, Quaternion>();
            _transformCache    = new Dictionary <int, WeakReference <IHasTransform> >();

            _physicsWorld.Events.BodiesBeginCollide += EventsOnBodiesBeginCollide;
            _physicsWorld.Events.BodiesEndCollide   += EventsOnBodiesEndCollide;
        }
        /// <summary>
        /// Initializes a new instance of the HingeJoint class.
        /// </summary>
        /// <param name="world">The world class where the constraints get added to.</param>
        /// <param name="body1">The first body connected to the second one.</param>
        /// <param name="body2">The second body connected to the first one.</param>
        /// <param name="position">The position in world space where both bodies get connected.</param>
        /// <param name="hingeAxis">The axis if the hinge.</param>
        public LimitedHingeJoint(JitterWorld world, RigidBody body1, RigidBody body2, JVector position, JVector hingeAxis,
            float hingeFwdAngle, float hingeBckAngle)
            : base(world)
        {
            // Create the hinge first, two point constraints

            worldPointConstraint = new PointOnPoint[2];

            hingeAxis *= 0.5f;

            JVector pos1 = position; JVector.Add(ref pos1, ref hingeAxis, out pos1);
            JVector pos2 = position; JVector.Subtract(ref pos2, ref hingeAxis, out pos2);

            worldPointConstraint[0] = new PointOnPoint(body1, body2, pos1);
            worldPointConstraint[1] = new PointOnPoint(body1, body2, pos2);


            // Now the limit, one max distance constraint

            hingeAxis.Normalize();

            // choose a direction that is perpendicular to the hinge
            JVector perpDir = JVector.Up;

            if (JVector.Dot(perpDir, hingeAxis) > 0.1f) perpDir = JVector.Right;

            // now make it perpendicular to the hinge
            JVector sideAxis = JVector.Cross(hingeAxis, perpDir);
            perpDir = JVector.Cross(sideAxis, hingeAxis);
            perpDir.Normalize();

            // the length of the "arm" TODO take this as a parameter? what's
            // the effect of changing it?
            float len = 10.0f * 3;

            // Choose a position using that dir. this will be the anchor point
            // for body 0. relative to hinge
            JVector hingeRelAnchorPos0 = perpDir * len;


            // anchor point for body 2 is chosen to be in the middle of the
            // angle range.  relative to hinge
            float angleToMiddle = 0.5f * (hingeFwdAngle - hingeBckAngle);
            JVector hingeRelAnchorPos1 = JVector.Transform(hingeRelAnchorPos0, JMatrix.CreateFromAxisAngle(hingeAxis, -angleToMiddle / 360.0f * 2.0f * JMath.Pi));

            // work out the "string" length
            float hingeHalfAngle = 0.5f * (hingeFwdAngle + hingeBckAngle);
            float allowedDistance = len * 2.0f * (float)System.Math.Sin(hingeHalfAngle * 0.5f / 360.0f * 2.0f * JMath.Pi);

            JVector hingePos = body1.Position;
            JVector relPos0c = hingePos + hingeRelAnchorPos0;
            JVector relPos1c = hingePos + hingeRelAnchorPos1;

            distance = new PointPointDistance(body1, body2, relPos0c, relPos1c);
            distance.Distance = allowedDistance;
            distance.Behavior = PointPointDistance.DistanceBehavior.LimitMaximumDistance;

        }
            public PhysicsControllerConstraint(JitterWorld world, RigidBody body) : base(body, null)
            {
                _world = world;

                var vec    = JVector.Down;
                var result = JVector.Zero;

                body.Shape.SupportMapping(ref vec, out result);

                _feetPosition = result * JVector.Down;
            }
예제 #4
0
        /// <summary>
        /// Initializes a new instance of the HingeJoint class.
        /// </summary>
        /// <param name="world">The world class where the constraints get added to.</param>
        /// <param name="body1">The first body connected to the second one.</param>
        /// <param name="body2">The second body connected to the first one.</param>
        /// <param name="position">The position in world space where both bodies get connected.</param>
        /// <param name="hingeAxis">The axis if the hinge.</param>
        public HingeJoint(JitterWorld world, RigidBody body1, RigidBody body2, JVector position, JVector hingeAxis) : base(world)
        {
            worldPointConstraint = new PointOnPoint[2];

            hingeAxis *= 0.5f;

            JVector pos1 = position; JVector.Add(ref pos1,ref hingeAxis,out pos1);
            JVector pos2 = position; JVector.Subtract(ref pos2,ref hingeAxis,out pos2);

            worldPointConstraint[0] = new PointOnPoint(body1,body2,pos1);
            worldPointConstraint[1] = new PointOnPoint(body1,body2,pos2);
        }
예제 #5
0
        /// <summary>
        /// Initializes a new instance of the HingeJoint class.
        /// </summary>
        /// <param name="world">The world class where the constraints get added to.</param>
        /// <param name="body1">The first body connected to the second one.</param>
        /// <param name="body2">The second body connected to the first one.</param>
        /// <param name="position">The position in world space where both bodies get connected.</param>
        /// <param name="hingeAxis">The axis if the hinge.</param>
        public HingeJoint(JitterWorld world, RigidBody body1, RigidBody body2, JVector position, JVector hingeAxis) : base(world)
        {
            worldPointConstraint = new PointOnPoint[2];

            hingeAxis *= 0.5f;

            JVector pos1 = position; JVector.Add(ref pos1, ref hingeAxis, out pos1);
            JVector pos2 = position; JVector.Subtract(ref pos2, ref hingeAxis, out pos2);

            worldPointConstraint[0] = new PointOnPoint(body1, body2, pos1);
            worldPointConstraint[1] = new PointOnPoint(body1, body2, pos2);
        }
        public PrismaticJoint(JitterWorld world, RigidBody body1, RigidBody body2,float minimumDistance, float maximumDistance)
            : base(world)
        {
            fixedAngle = new FixedAngle(body1, body2);
            pointOnLine = new PointOnLine(body1, body2, body1.position, body2.position);

            minDistance = new PointPointDistance(body1, body2, body1.position, body2.position);
            minDistance.Behavior = PointPointDistance.DistanceBehavior.LimitMinimumDistance;
            minDistance.Distance = minimumDistance;

            maxDistance = new PointPointDistance(body1, body2, body1.position, body2.position);
            maxDistance.Behavior = PointPointDistance.DistanceBehavior.LimitMaximumDistance;
            maxDistance.Distance = maximumDistance;
        }
예제 #7
0
        public PrismaticJoint(JitterWorld world, RigidBody body1, RigidBody body2, float minimumDistance, float maximumDistance)
            : base(world)
        {
            fixedAngle  = new FixedAngle(body1, body2);
            pointOnLine = new PointOnLine(body1, body2, body1.position, body2.position);

            minDistance          = new PointPointDistance(body1, body2, body1.position, body2.position);
            minDistance.Behavior = PointPointDistance.DistanceBehavior.LimitMinimumDistance;
            minDistance.Distance = minimumDistance;

            maxDistance          = new PointPointDistance(body1, body2, body1.position, body2.position);
            maxDistance.Behavior = PointPointDistance.DistanceBehavior.LimitMaximumDistance;
            maxDistance.Distance = maximumDistance;
        }
        public void Update(ComponentizedEntity entity, IGameContext gameContext, IUpdateContext updateContext)
        {
            if (!Enabled)
            {
                return;
            }

            if (_jitterWorld != _physicsEngine.GetInternalPhysicsWorld())
            {
                // TODO: Deregister rigid bodies from old world.
                if (_jitterWorld != null && _physicsControllerConstraint != null)
                {
                    _jitterWorld.RemoveConstraint(_physicsControllerConstraint);
                    _physicsControllerConstraint = null;
                }
                _jitterWorld = _physicsEngine.GetInternalPhysicsWorld();
            }

            if (_physicalComponent.RigidBodies.Length > 0 && _physicalComponent.RigidBodies[0] != _rigidBody)
            {
                if (_physicsControllerConstraint != null)
                {
                    _jitterWorld.RemoveConstraint(_physicsControllerConstraint);
                    _physicsControllerConstraint = null;
                }
            }

            if (_physicalComponent.RigidBodies.Length > 0)
            {
                if (_physicsControllerConstraint == null)
                {
                    _physicsControllerConstraint = new PhysicsControllerConstraint(
                        _jitterWorld,
                        _physicalComponent.RigidBodies[0]);
                    _jitterWorld.AddConstraint(_physicsControllerConstraint);
                }

                _physicsControllerConstraint.TargetVelocity = TargetVelocity.ToJitterVector();
                _physicsControllerConstraint.TryJump        = TryJump;
                _physicsControllerConstraint.JumpVelocity   = JumpVelocity;
                _physicsControllerConstraint.Stiffness      = Stiffness;

                if (TargetVelocity.LengthSquared() > 0f)
                {
                    // Wake up the rigid body.
                    _physicalComponent.RigidBodies[0].IsActive = true;
                }
            }
        }
예제 #9
0
        public void RunSimulation()
        {
            CollisionSystem collision = new CollisionSystemSAP();
            JitterWorld     world     = new JitterWorld(collision);

            world.Gravity = new JVector(0, -10, -0);

            Shape     shape = new BoxShape(20.0f, 1.0f, 20.0f);
            RigidBody floor = new RigidBody(shape);

            floor.IsStatic = true;
            floor.Position = new JVector(0.0f, -15.0f, 0.0f);

            shape = new SphereShape(0.5f);
            RigidBody body = new RigidBody(shape);

            body.Position             = new JVector(0.0f, 3.0f, 0.0f);
            body.Material.Restitution = 0.8f;

            world.AddBody(floor);
            world.AddBody(body);

            for (int i = 0; i < 600; i++)
            {
                world.Step(1.0f / 30.0f, true);

                SunflowAPI sunflow = new SunflowAPI();
                SetupSunflow(sunflow);

                sunflow.geometry("sphere", "sphere");

                //Instancing the big metal sphere.
                JVector v = body.Position;
                sunflow.parameter("transform", Matrix4.translation(v.X, v.Y, v.Z).multiply(Matrix4.scale(1)));
                sunflow.parameter("shaders", "metal");
                sunflow.instance("sphere.instance", "sphere");


                sunflow.render(SunflowAPI.DEFAULT_OPTIONS, new FileDisplay("spherecube" + i + ".png"));


                // do other stuff, like drawing
            }
        }
        public PhysicsCharacterController(JitterWorld world, RigidBody body)
            : base(body, null)
        {
            this.World        = world;
            this.JumpVelocity = 0.5f;
            this.Stiffness    = 0.02f;

            // determine the position of the feets of the character
            // this can be done by supportmapping in the down direction.
            // (furthest point away in the down direction)
            JVector vec    = JVector.Down;
            JVector result = JVector.Zero;

            // Note: the following works just for normal shapes, for multishapes (compound for example)
            // you have to loop through all sub-shapes -> easy.
            body.Shape.SupportMapping(ref vec, out result);

            // feet position is now the distance between body.Position and the feets
            // Note: the following '*' is the dot product.
            feetPosition = result * JVector.Down;
        }
예제 #11
0
 public PrismaticJoint(JitterWorld world, RigidBody body1, RigidBody body2, JVector pointOnBody1, JVector pointOnBody2, float maximumDistance, float minimumDistance)
     : base(world)
 {
     fixedAngle  = new FixedAngle(body1, body2);
     pointOnLine = new PointOnLine(body1, body2, pointOnBody1, pointOnBody2);
 }
예제 #12
0
        /// <summary>
        /// Initializes a new instance of the HingeJoint class.
        /// </summary>
        /// <param name="world">The world class where the constraints get added to.</param>
        /// <param name="body1">The first body connected to the second one.</param>
        /// <param name="body2">The second body connected to the first one.</param>
        /// <param name="position">The position in world space where both bodies get connected.</param>
        /// <param name="hingeAxis">The axis if the hinge.</param>
        public LimitedHingeJoint(JitterWorld world, RigidBody body1, RigidBody body2, JVector position, JVector hingeAxis,
                                 float hingeFwdAngle, float hingeBckAngle)
            : base(world)
        {
            // Create the hinge first, two point constraints

            worldPointConstraint = new PointOnPoint[2];

            hingeAxis *= 0.5f;

            JVector pos1 = position; JVector.Add(ref pos1, ref hingeAxis, out pos1);
            JVector pos2 = position; JVector.Subtract(ref pos2, ref hingeAxis, out pos2);

            worldPointConstraint[0] = new PointOnPoint(body1, body2, pos1);
            worldPointConstraint[1] = new PointOnPoint(body1, body2, pos2);


            // Now the limit, one max distance constraint

            hingeAxis.Normalize();

            // choose a direction that is perpendicular to the hinge
            JVector perpDir = JVector.Up;

            if (JVector.Dot(perpDir, hingeAxis) > 0.1f)
            {
                perpDir = JVector.Right;
            }

            // now make it perpendicular to the hinge
            JVector sideAxis = JVector.Cross(hingeAxis, perpDir);

            perpDir = JVector.Cross(sideAxis, hingeAxis);
            perpDir.Normalize();

            // the length of the "arm" TODO take this as a parameter? what's
            // the effect of changing it?
            float len = 10.0f * 3;

            // Choose a position using that dir. this will be the anchor point
            // for body 0. relative to hinge
            JVector hingeRelAnchorPos0 = perpDir * len;


            // anchor point for body 2 is chosen to be in the middle of the
            // angle range.  relative to hinge
            float   angleToMiddle      = 0.5f * (hingeFwdAngle - hingeBckAngle);
            JVector hingeRelAnchorPos1 = JVector.Transform(hingeRelAnchorPos0, JMatrix.CreateFromAxisAngle(hingeAxis, -angleToMiddle / 360.0f * 2.0f * JMath.Pi));

            // work out the "string" length
            float hingeHalfAngle  = 0.5f * (hingeFwdAngle + hingeBckAngle);
            float allowedDistance = len * 2.0f * (float)System.Math.Sin(hingeHalfAngle * 0.5f / 360.0f * 2.0f * JMath.Pi);

            JVector hingePos = body1.Position;
            JVector relPos0c = hingePos + hingeRelAnchorPos0;
            JVector relPos1c = hingePos + hingeRelAnchorPos1;

            distance          = new PointPointDistance(body1, body2, relPos0c, relPos1c);
            distance.Distance = allowedDistance;
            distance.Behavior = PointPointDistance.DistanceBehavior.LimitMaximumDistance;
        }
예제 #13
0
 /// <summary>
 /// Creates a new instance of the Joint class.
 /// </summary>
 /// <param name="world">The world class to which the internal constraints
 /// should be added.</param>
 public Joint(JitterWorld world)
 {
     this.World = world;
 }
예제 #14
0
 public PrismaticJoint(JitterWorld world, RigidBody body1, RigidBody body2)
     : base(world)
 {
     fixedAngle  = new FixedAngle(body1, body2);
     pointOnLine = new PointOnLine(body1, body2, body1.position, body2.position);
 }
예제 #15
0
 public PrismaticJoint(JitterWorld world, RigidBody body1, RigidBody body2, JVector pointOnBody1, JVector pointOnBody2, float maximumDistance, float minimumDistance)
     : base(world)
 {
     fixedAngle = new FixedAngle(body1, body2);
     pointOnLine = new PointOnLine(body1, body2, pointOnBody1, pointOnBody2);
 }
예제 #16
0
 public PrismaticJoint(JitterWorld world, RigidBody body1, RigidBody body2, JVector pointOnBody1,JVector pointOnBody2)
     : base(world)
 {
     fixedAngle = new FixedAngle(body1, body2);
     pointOnLine = new PointOnLine(body1, body2, pointOnBody1, pointOnBody2);
 }
예제 #17
0
 public PrismaticJoint(JitterWorld world, RigidBody body1, RigidBody body2, JVector pointOnBody1, JVector pointOnBody2)
     : base(world)
 {
     fixedAngle  = new FixedAngle(body1, body2);
     pointOnLine = new PointOnLine(body1, body2, pointOnBody1, pointOnBody2);
 }
예제 #18
0
 /// <summary>
 /// Creates a new instance of the Joint class.
 /// </summary>
 /// <param name="world">The world class to which the internal constraints
 /// should be added.</param>
 public Joint(JitterWorld world) {this.World = world;}
예제 #19
0
 public PrismaticJoint(JitterWorld world, RigidBody body1, RigidBody body2)
     : base(world)
 {
     fixedAngle = new FixedAngle(body1, body2);
     pointOnLine = new PointOnLine(body1, body2, body1.position, body2.position);
 }
예제 #20
0
 public void UpdateWorld(JitterWorld world, IGameContext gameContext, IUpdateContext updateContext)
 {
     world.Step((float)gameContext.GameTime.ElapsedGameTime.TotalSeconds, true);
 }