protected override void Update(GameTime gameTime) { padState = GamePad.GetState(PlayerIndex.One); keyState = Keyboard.GetState(); mouseState = Mouse.GetState(); // let the user escape the demo if (PressedOnce(Keys.Escape, Buttons.Back)) this.Exit(); // change threading mode if (PressedOnce(Keys.M, Buttons.A)) multithread = !multithread; #region drag and drop physical objects with the mouse JVector mouseLocation = Camera.ScreenToWorldSpace(new JVector(mouseState.X, mouseState.Y)); // MouseDown if (mouseState.LeftButton == ButtonState.Pressed && mousePreviousState.LeftButton == ButtonState.Released) { JBBox mouseBox = new JBBox(mouseLocation - new JVector(0.01f), mouseLocation + new JVector(0.01f)); World.CollisionSystem.Query((foundItem) => { grabBody = foundItem as RigidBody; // don't continue return false; }, ref mouseBox); if (grabBody != null) { if (grabSpring != null) World.RemoveSpring(grabSpring); // convert mouse coordinates to foundBody's local space var localMouseLocation = JVector.Transform(mouseLocation - grabBody.Position, JMatrix.CreateRotationZ(-grabBody.Orientation)); grabBody.IsActive = true; grabSpring = new FixedLinearSpring(grabBody, localMouseLocation, mouseLocation, 50 * grabBody.Mass, 15 * grabBody.Mass); grabSpring.IsOnlyPull = true; grabSpring.Length = 1; World.AddSpring(grabSpring); } } // MouseMove if (mouseState.LeftButton == ButtonState.Pressed) { if (grabBody != null) { grabSpring.WorldAnchor = mouseLocation; } } // MouseUp else if (mouseState.LeftButton == ButtonState.Released && mousePreviousState.LeftButton == ButtonState.Pressed) { if (grabSpring != null) World.RemoveSpring(grabSpring); grabSpring = null; grabBody = null; } #endregion #region create random primitives Random r = new Random(); if (PressedOnce(Keys.Space, Buttons.B)) { Random rand = new Random(); RigidBody body = new RigidBody(new BoxShape(5.5f, 5.5f)) { EnableDebugDraw = true, //Position = new JVector((float)rand.NextDouble(), 0), AngularVelocity = 0, LinearVelocity = new JVector(0, -10), Orientation = 0.0f,//0.001f + (float)rand.NextDouble(), Material = new Material() { DynamicFriction = 1f, StaticFriction = 1f, Restitution = 0f, }, Position = new JVector(0, 15), }; World.AddBody(body); } #endregion #region switch through physic scenes if (PressedOnce(Keys.Add, Buttons.X)) { DestroyCurrentScene(); currentScene++; currentScene = currentScene % PhysicScenes.Count; PhysicScenes[currentScene].Build(); } if (PressedOnce(Keys.Subtract, Buttons.Y)) { DestroyCurrentScene(); currentScene += PhysicScenes.Count - 1; currentScene = currentScene % PhysicScenes.Count; PhysicScenes[currentScene].Build(); } #endregion UpdateDisplayText(gameTime); float step = (float)gameTime.ElapsedGameTime.TotalSeconds; if (step > 1.0f / 60.0f) step = 1.0f / 60.0f; World.Step(step, multithread); // TODO - add options for variable timestep vs fixed //World.Step((float)gameTime.ElapsedGameTime.TotalSeconds, multithread, 1f/ 100f, 1); gamePadPreviousState = padState; keyboardPreviousState = keyState; mousePreviousState = mouseState; base.Update(gameTime); }
// NOTE- this is brute force for now!!! public override void Query(Func<IBroadphaseEntity, bool> callback, ref JBBox box) { for (int i = 0; i < this.bodyList.Count; i++) { if (CheckBoundingBoxes(this.bodyList[i].BoundingBox, box)) { if (callback(this.bodyList[i])) { continue; } } } }
/// <summary> /// Query a bounding box for overlapping shapes. /// </summary> /// <param name="callback"></param> /// <param name="box"></param> public abstract void Query(Func<IBroadphaseEntity, bool> callback, ref JBBox box);
/// <summary> /// Gets the axis aligned bounding box of the orientated shape. /// </summary> /// <param name="orientation">The orientation of the shape.</param> /// <param name="box">The axis aligned bounding box of the shape.</param> public override void GetBoundingBox(ref float orientation, out JBBox box) { JMatrix xForm = JMatrix.CreateRotationZ(-orientation); JMatrix abs; JMath.Absolute(ref xForm, out abs); JVector temp; JVector.Transform(ref halfSize, ref abs, out temp); box.Max = temp; JVector.Negate(ref temp, out box.Min); }
/// <summary> /// Calculates the bounding box of the sphere. /// </summary> /// <param name="orientation">The orientation of the shape.</param> /// <param name="box">The resulting axis aligned bounding box.</param> public override void GetBoundingBox(ref float orientation, out JBBox box) { box.Min.X = -radius -0.01f; box.Min.Y = -radius -0.01f; box.Max.X = radius +0.01f; box.Max.Y = radius +0.01f; }
public bool CheckBoundingBoxes(JBBox box1, JBBox box2) { return ((box1.Max.Y >= box2.Min.Y) && (box1.Min.Y <= box2.Max.Y)) && ((box1.Max.X >= box2.Min.X) && (box1.Min.X <= box2.Max.X)); }
/// <summary> /// Uses the supportMapping to calculate the bounding box. Should be overidden /// to make this faster. /// </summary> /// <param name="orientation">The orientation of the shape.</param> /// <param name="box">The resulting axis aligned bounding box.</param> public virtual void GetBoundingBox(ref float rotation, out JBBox box) { JVector vec = JVector.Zero; JMatrix orientation = JMatrix.CreateRotationZ(rotation); vec.Set(orientation.M11, orientation.M21); SupportMapping(ref vec, out vec); box.Max.X = orientation.M11 * vec.X + orientation.M21 * vec.Y + orientation.M31; vec.Set(orientation.M12, orientation.M22); SupportMapping(ref vec, out vec); box.Max.Y = orientation.M12 * vec.X + orientation.M22 * vec.Y + orientation.M32; vec.Set(-orientation.M11, -orientation.M21); SupportMapping(ref vec, out vec); box.Min.X = orientation.M11 * vec.X + orientation.M21 * vec.Y + orientation.M31; vec.Set(-orientation.M12, -orientation.M22); SupportMapping(ref vec, out vec); box.Min.Y = orientation.M12 * vec.X + orientation.M22 * vec.Y + orientation.M32; }
/// <summary> /// Checks whether another bounding box is inside, outside or intersecting /// this box. /// </summary> /// <param name="box">The other bounding box to check.</param> /// <returns>The ContainmentType of the box.</returns> public ContainmentType Contains(ref JBBox box) { ContainmentType result = ContainmentType.Disjoint; if (((this.Max.X >= box.Min.X) && (this.Min.X <= box.Max.X)) && ((this.Max.Y >= box.Min.Y) && (this.Min.Y <= box.Max.Y))) { result = (((this.Min.X <= box.Min.X) && (box.Max.X <= this.Max.X)) && ((this.Min.Y <= box.Min.Y) && (box.Max.Y <= this.Max.Y))) ? ContainmentType.Contains : ContainmentType.Intersects; } return result; }
public ContainmentType Contains(JBBox box) { return this.Contains(ref box); }
/// <summary> /// Creates a new box containing the two given ones. /// </summary> /// <param name="original">First box.</param> /// <param name="additional">Second box.</param> /// <param name="result">A JBBox containing the two given boxes.</param> public static void CreateMerged(ref JBBox original, ref JBBox additional, out JBBox result) { JVector vector; JVector vector2; JVector.Min(ref original.Min, ref additional.Min, out vector2); JVector.Max(ref original.Max, ref additional.Max, out vector); result.Min = vector2; result.Max = vector; }
public static JBBox CreateMerged(JBBox original, JBBox additional) { JBBox result; JBBox.CreateMerged(ref original, ref additional, out result); return result; }