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; }
/// <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); }
/// <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; }
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; } } }
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; }
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); }
/// <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; }
/// <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; }
public PrismaticJoint(JitterWorld world, RigidBody body1, RigidBody body2) : base(world) { fixedAngle = new FixedAngle(body1, body2); pointOnLine = new PointOnLine(body1, body2, body1.position, body2.position); }
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); }
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); }
/// <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;}
public void UpdateWorld(JitterWorld world, IGameContext gameContext, IUpdateContext updateContext) { world.Step((float)gameContext.GameTime.ElapsedGameTime.TotalSeconds, true); }