protected override void Update(GameTime gameTime)
        {
            if (codeFormVisible) return;

            KeyboardState keyState = Keyboard.GetState();
            MouseState mouseState = Mouse.GetState();

            if (keyState.IsKeyDown(Keys.Escape)) this.Exit();

            bool leftHold = (mouseState.LeftButton == ButtonState.Pressed);
            bool spaceHold = (keyState.IsKeyDown(Keys.Space));
            bool enterHold = (keyState.IsKeyDown(Keys.Enter));
            bool mHold = (keyState.IsKeyDown(Keys.M));

            #region Turn multithreading on/off
            if (mHold)
            {
                if (!mClicked) { multithread = !multithread; mClicked = true; }
            }
            #endregion

            #region Object drag & drop

            if (leftHold && !leftClicked)
            {
                JVector ray = Conversion.ToJitterVector(RayTo(mouseState.X, mouseState.Y)); ray.Normalize();
                JVector camp = Conversion.ToJitterVector(Camera.Position);

                float fraction;
                bool result = world.CollisionSystem.Raycast(camp, ray * 100, RaycastCallback, out resBody, out hitNormal, out fraction);

                if (result)
                {
                    hitPoint = camp + fraction * ray * 100;

                    if (wp != null) world.RemoveConstraint(wp);

                    JVector lanchor = hitPoint - resBody.Position;
                    lanchor = JVector.Transform(lanchor, JMatrix.Transpose(resBody.Orientation));

                    wp = new WorldPointConstraint(resBody, lanchor);

                    world.AddConstraint(wp);
                    hitDistance = (Conversion.ToXNAVector(hitPoint) - Camera.Position).Length();
                    scrollWheel = mouseState.ScrollWheelValue;
                    wp.Anchor = hitPoint;
                }

                leftClicked = true;

            }

            if (mouseState.LeftButton == ButtonState.Pressed)
            {
                hitDistance += (mouseState.ScrollWheelValue - scrollWheel) * 0.001f;
                scrollWheel = mouseState.ScrollWheelValue;

                if (resBody != null)
                {
                    Vector3 ray = RayTo(mouseState.X, mouseState.Y); ray.Normalize();
                    wp.Anchor = Conversion.ToJitterVector(Camera.Position + ray * hitDistance);
                }
            }
            else
            {
                resBody = null;
                if (wp != null) world.RemoveConstraint(wp);
            }

            #endregion

            #region Show code form

            if (enterHold && !enterClicked && gameTime.TotalGameTime.TotalSeconds > 0.1f)
            {
                display.DisplayText[5] = string.Empty;

                System.Windows.Forms.Form form =
                        (System.Windows.Forms.Form)System.Windows.Forms.Control.FromHandle(this.Window.Handle);

                codeFormVisible = true;
                System.Windows.Forms.DialogResult result = codeForm.ShowDialog(form);
                codeFormVisible = false;

                enterClicked = true;
            }
            #endregion

            #region Spawn random primitive
            if (spaceHold && !spaceClicked)
            {
                int rndn = random.Next(6);

                RigidBody body;

                if (rndn == 0)
                {
                    body = new RigidBody(new ConeShape((float)random.Next(5, 50) / 20.0f, (float)random.Next(10, 20) / 20.0f));
                }
                else if (rndn == 1)
                {
                    body = new RigidBody(new BoxShape(new JVector(
                        (float)random.Next(10, 30) / 20.0f,
                        (float)random.Next(10, 30) / 20.0f, (float)random.Next(10, 30) / 20.0f)));
                }
                else if (rndn == 2)
                {
                    body = new RigidBody(new SphereShape((float)random.Next(30,100) /100.0f));
                }
                else if (rndn == 3)
                {
                    body = new RigidBody(new CylinderShape(1.0f, 0.5f));
                }
                else if (rndn == 4)
                {
                    body = new RigidBody(new CapsuleShape(1.0f, 0.5f));
                }
                else
                {
                    Shape b1 = new BoxShape(new JVector(3, 1, 1));
                    Shape b2 = new BoxShape(new JVector(1, 1, 3));
                    Shape b3 = new CylinderShape(2.0f, 0.5f);

                    CompoundShape.TransformedShape t1 = new CompoundShape.TransformedShape(b1, JMatrix.Identity, JVector.Zero);
                    CompoundShape.TransformedShape t2 = new CompoundShape.TransformedShape(b2, JMatrix.Identity, JVector.Zero);
                    CompoundShape.TransformedShape t3 = new CompoundShape.TransformedShape(b3, JMatrix.Identity, new JVector(0, 0, 0));

                    CompoundShape ms = new CompoundShape(new CompoundShape.TransformedShape[3] { t1, t2, t3 });

                    body = new RigidBody(ms);
                }

                world.AddBody(body);

                body.Position = Conversion.ToJitterVector(Camera.Position);
                body.LinearVelocity = Conversion.ToJitterVector((Camera.Target - Camera.Position) * 40.0f);
                body.Update();

                spaceClicked = true;
            }
            #endregion

            spaceClicked = spaceHold;
            leftClicked = leftHold;
            enterClicked = enterHold;
            mClicked = mHold;

            int contactCount = 0;
            foreach (Arbiter ar in world.ArbiterMap.Values)
                contactCount += ar.ContactList.Count;

            display.DisplayText[0] = "Arbitercount: " + world.ArbiterMap.Values.Count.ToString() + ";" + " Contactcount: " + contactCount.ToString();
            display.DisplayText[2] = "Bodycount: " + world.RigidBodies.Count;
            display.DisplayText[3] = (multithread) ? "Multithreaded" : "Single Threaded";

            float elapsedTime = (float)gameTime.ElapsedGameTime.TotalSeconds;
            if (elapsedTime > 1.0f / 100.0f) elapsedTime = 1.0f / 100.0f;
            world.Step(elapsedTime, multithread);

            base.Update(gameTime);
        }
Пример #2
0
        public void CreateScene(int sceneNumber)
        {
            _physics.Clear();
            _markers.Clear();

            Room room = new Room(this);

            _physics.Add(room);
            _physics.Gravity = new Vector3(0f, 0f, -9.8f);

            Model cubeModel     = this.Content.Load <Model>("models/small_cube");
            Model obeliskModel  = this.Content.Load <Model>("models/obelisk");
            Model sphereModel   = this.Content.Load <Model>("models/sphere");
            Model capsuleModel  = this.Content.Load <Model>("models/capsule");
            Model torusModel    = this.Content.Load <Model>("models/torus");
            Model slabModel     = this.Content.Load <Model>("models/slab");
            Model triangleModel = this.Content.Load <Model>("models/triangle");

            switch (sceneNumber)
            {
            case 1:
            {
                for (int i = 0; i < 12; i++)
                {
                    var cube = new SolidThing(this, cubeModel);
                    cube.SetWorld(new Vector3(0f, 0f, 0.25f + 0.51f * i));
                    _physics.Add(cube);
                }
            }
            break;

            case 2:
            {
                for (int i = 0; i < 7; i++)
                {
                    for (int j = 0; j < 7 - i; j++)
                    {
                        var cube = new SolidThing(this, cubeModel);
                        cube.SetWorld(new Vector3(0f, 0.501f * j + 0.25f * i, 0.5f + 0.55f * i));
                        _physics.Add(cube);
                    }
                }
            }
            break;

            case 3:
            {
                for (int i = 0; i < 6; i++)
                {
                    for (int j = 0; j < 6 - i; j++)
                    {
                        var cube = new SolidThing(this, cubeModel);
                        cube.SetWorld(new Vector3(0f, 2.2f * j + 1f * i - 4.1f, 0.75f * i + 0.25f));
                        _physics.Add(cube);
                    }
                }
                for (int i = 0; i < 6; i++)
                {
                    for (int j = 0; j < 5 - i; j++)
                    {
                        var plank = new SolidThing(this, obeliskModel);
                        plank.SetWorld(new Vector3(0f, 2.2f * j + 1f * i + 1f - 4f, 0.75f * i + 0.65f),
                                       Quaternion.CreateFromAxisAngle(Vector3.UnitZ, MathHelper.ToRadians(90f)));
                        _physics.Add(plank);
                    }
                }
            }
            break;

            case 4:
            {
                int size = 9;
#if WINDOWS
#else
                size = 4;
#endif
                for (int i = 0; i < size; i++)
                {
                    for (int j = 0; j < size - i; j++)
                    {
                        for (int k = 0; k < size - i; k++)
                        {
                            var sphere = new SolidThing(this, sphereModel);
                            sphere.SetWorld(new Vector3(
                                                0.501f * j + 0.25f * i,
                                                0.501f * k + 0.25f * i,
                                                0.501f * i + 0.5f
                                                ), Quaternion.Identity);
                            _physics.Add(sphere);
                        }
                    }
                }
            }
            break;

            case 5:
            {
                var plank = new SolidThing(this, obeliskModel);
                plank.SetWorld(new Vector3(0.0f, 0.0f, 4.0f),
                               Quaternion.CreateFromAxisAngle(Vector3.UnitY, MathHelper.ToRadians(15f)));
                MassProperties immovableMassProperties = new MassProperties(float.PositiveInfinity, Matrix.Identity);
                plank.MassProperties = immovableMassProperties;
                _physics.Add(plank);

                var sphere = new SolidThing(this, sphereModel);
                sphere.SetWorld(new Vector3(-4.9f, 0.0f, 9.0f), Quaternion.Identity);
                _physics.Add(sphere);


//                        int size = 9;
//#if WINDOWS
//#else
//                        size = 4;
//#endif
//                        var models = new Model[] { cubeModel, sphereModel };
//                        for (int i = 0; i < size; i++)
//                        {
//                            for (int j = 0; j < size - i; j++)
//                            {
//                                for (int k = 0; k < size - i; k++)
//                                {
//                                    var sphere = new SolidThing(this, i % 2 == 0 ? sphereModel : cubeModel);
//                                    sphere.SetWorld(new Vector3(
//                                        0.501f * j + 0.25f * i,
//                                        0.501f * k + 0.25f * i,
//                                        0.501f * i + 0.5f
//                                        ), Quaternion.Identity);
//                                    _physics.Add(sphere);
//                                }
//                            }
//                        }
            }
            break;

            case 6:
            {
                int size = 9;
#if WINDOWS
#else
                size = 4;
#endif
                var models = new Model[] { cubeModel, sphereModel, capsuleModel };
                for (int i = 0; i < size; i++)
                {
                    for (int j = 0; j < size - i; j++)
                    {
                        for (int k = 0; k < size - i; k++)
                        {
                            var sphere = new SolidThing(this, models[_rand.Next(3)]);
                            sphere.SetWorld(new Vector3(
                                                0.501f * j + 0.25f * i,
                                                0.501f * k + 0.25f * i,
                                                1f * i + 0.5f));
                            _physics.Add(sphere);
                        }
                    }
                }
            }
            break;

            case 7:
            {
                var o = new SolidThing(this, torusModel);
                o.SetWorld(new Vector3(0f, 0f, 0.5f), Quaternion.CreateFromAxisAngle(Vector3.UnitY, -MathHelper.PiOver2));
                _physics.Add(o);

                o = new SolidThing(this, torusModel);
                o.SetWorld(new Vector3(0f, 0f, 4f), Quaternion.CreateFromAxisAngle(Vector3.UnitY, -MathHelper.PiOver4));
                _physics.Add(o);

                o = new SolidThing(this, slabModel);
                o.SetWorld(new Vector3(-4f, 4f, 2f));
                _physics.Add(o);

                o = new SolidThing(this, this.Content.Load <Model>("models/cone"));
                o.SetWorld(new Vector3(-4f, -4f, 1f), Quaternion.CreateFromAxisAngle(Vector3.UnitZ, MathHelper.PiOver2));
                _physics.Add(o);

                o = new SolidThing(this, cubeModel);
                o.SetWorld(new Vector3(-4f, 6.1f, 3f));
                _physics.Add(o);
            }
            break;

            case 8:
            {
                RigidBody oLast = null;
                for (int i = 0; i < 10; i++)
                {
                    var o = new SolidThing(this, capsuleModel);
                    o.SetWorld(new Vector3(0f, 0f, 9.5f - i));
                    _physics.Add(o);
                    if (i == 0)
                    {
                        var j = new PointConstraint(o, room, new Vector3(0f, 0f, 10f));
                        j.IsCollisionEnabled = false;
                        _physics.Add(j);
                    }
                    else
                    {
                        var j = new PointConstraint(oLast, o, new Vector3(0f, 0f, 10f - (float)i));
                        j.IsCollisionEnabled = false;
                        _physics.Add(j);
                    }
                    oLast = o;
                }

                var a = new SolidThing(this, cubeModel);
                a.SetWorld(new Vector3(1f, 0f, 0.25f));
                _physics.Add(a);
                var b = new SolidThing(this, cubeModel);
                b.SetWorld(new Vector3(1f, 0f, 0.75f));
                _physics.Add(b);
                var j2 = new RevoluteJoint(b, a, new Vector3(1.25f, 0f, 0.5f), Vector3.UnitY,
                                           0f, MathHelper.PiOver2);
                j2.IsCollisionEnabled = false;
                _physics.Add(j2);

                a = new SolidThing(this, cubeModel);
                a.SetWorld(new Vector3(1f, 1f, 0.25f));
                _physics.Add(a);
                b = new SolidThing(this, cubeModel);
                b.SetWorld(new Vector3(1f, 1f, 0.75f));
                _physics.Add(b);
                var j4 = new GenericConstraint(b, a, new Frame(new Vector3(1f, 1f, 0.5f)),
                                               Axes.All, Vector3.Zero, new Vector3(0f, 0f, 0.5f),
                                               Axes.All, Vector3.Zero, Vector3.Zero);
                j4.IsCollisionEnabled = false;
                _physics.Add(j4);

                a = new SolidThing(this, cubeModel);
                a.SetWorld(new Vector3(1f, 2f, 0.25f));
                _physics.Add(a);
                b = new SolidThing(this, cubeModel);
                b.SetWorld(new Vector3(1f, 2f, 0.75f));
                _physics.Add(b);
                var j5 = new GenericConstraint(b, a, new Frame(new Vector3(1f, 2f, 0.5f)),
                                               Axes.All, new Vector3(-0.125f, -0.125f, 0f), new Vector3(0.125f, 0.125f, 0f),
                                               Axes.All, Vector3.Zero, Vector3.Zero);
                j5.IsCollisionEnabled = false;
                _physics.Add(j5);

                a = new SolidThing(this, sphereModel);
                a.SetWorld(new Vector3(2f, 0f, 2f));
                _physics.Add(a);
                b = new SolidThing(this, sphereModel);
                b.SetWorld(new Vector3(2f, 0f, 1f));
                _physics.Add(b);
                var g1 = new SpringForce(a, b, Vector3.Zero, Vector3.Zero, 1f, 5f, 0.05f);
                _physics.Add(g1);
                var j3 = new WorldPointConstraint(a, new Vector3(2f, 0f, 2f));
                _physics.Add(j3);
            }
            break;

            case 9:
            {
                var a = new SolidThing(this, sphereModel);
                a.Skin.Remove(a.Skin[0]);
                a.Skin.Add(new SpherePart(new Sphere(Vector3.Zero, 0.25f)), new Material(0f, 0.5f));
                a.SetWorld(7.0f, new Vector3(0f, 0f, 5f), Quaternion.Identity);
                a.MassProperties = MassProperties.Immovable;
                _physics.Add(a);

                _physics.Add(new SingularityForce(new Vector3(0f, 0f, 5f), 1E12f));

                _physics.Gravity = Vector3.Zero;

                var b = new SolidThing(this, cubeModel);
                b.SetWorld(new Vector3(0f, 0f, 8f),
                           Quaternion.CreateFromAxisAngle(Vector3.UnitX, MathHelper.PiOver4 / 2.0f) *
                           Quaternion.CreateFromAxisAngle(Vector3.UnitY, MathHelper.PiOver4)
                           );
                _physics.Add(b);
            }
            break;

            default:
                break;
            }
        }
        protected override void Update(GameTime gameTime)
        {
            if (codeFormVisible)
            {
                return;
            }

            KeyboardState keyState   = Keyboard.GetState();
            MouseState    mouseState = Mouse.GetState();

            if (keyState.IsKeyDown(Keys.Escape))
            {
                this.Exit();
            }

            bool leftHold  = (mouseState.LeftButton == ButtonState.Pressed);
            bool spaceHold = (keyState.IsKeyDown(Keys.Space));
            bool enterHold = (keyState.IsKeyDown(Keys.Enter));
            bool mHold     = (keyState.IsKeyDown(Keys.M));

            #region Turn multithreading on/off
            if (mHold)
            {
                if (!mClicked)
                {
                    multithread = !multithread; mClicked = true;
                }
            }
            #endregion

            #region Object drag & drop

            if (leftHold && !leftClicked)
            {
                JVector ray  = Conversion.ToJitterVector(RayTo(mouseState.X, mouseState.Y)); ray.Normalize();
                JVector camp = Conversion.ToJitterVector(Camera.Position);

                float fraction;
                bool  result = world.CollisionSystem.Raycast(camp, ray * 100, RaycastCallback, out resBody, out hitNormal, out fraction);

                if (result)
                {
                    hitPoint = camp + fraction * ray * 100;

                    if (wp != null)
                    {
                        world.RemoveConstraint(wp);
                    }

                    JVector lanchor = hitPoint - resBody.Position;
                    lanchor = JVector.Transform(lanchor, JMatrix.Transpose(resBody.Orientation));

                    wp = new WorldPointConstraint(resBody, lanchor);

                    world.AddConstraint(wp);
                    hitDistance = (Conversion.ToXNAVector(hitPoint) - Camera.Position).Length();
                    scrollWheel = mouseState.ScrollWheelValue;
                    wp.Anchor   = hitPoint;
                }

                leftClicked = true;
            }

            if (mouseState.LeftButton == ButtonState.Pressed)
            {
                hitDistance += (mouseState.ScrollWheelValue - scrollWheel) * 0.001f;
                scrollWheel  = mouseState.ScrollWheelValue;

                if (resBody != null)
                {
                    Vector3 ray = RayTo(mouseState.X, mouseState.Y); ray.Normalize();
                    wp.Anchor = Conversion.ToJitterVector(Camera.Position + ray * hitDistance);
                }
            }
            else
            {
                resBody = null;
                if (wp != null)
                {
                    world.RemoveConstraint(wp);
                }
            }

            #endregion

            #region Show code form

            if (enterHold && !enterClicked && gameTime.TotalGameTime.TotalSeconds > 0.1f)
            {
                display.DisplayText[5] = string.Empty;

                System.Windows.Forms.Form form =
                    (System.Windows.Forms.Form)System.Windows.Forms.Control.FromHandle(this.Window.Handle);

                codeFormVisible = true;
                System.Windows.Forms.DialogResult result = codeForm.ShowDialog(form);
                codeFormVisible = false;

                enterClicked = true;
            }
            #endregion

            #region Spawn random primitive
            if (spaceHold && !spaceClicked)
            {
                int rndn = random.Next(6);

                RigidBody body;

                if (rndn == 0)
                {
                    body = new RigidBody(new ConeShape((float)random.Next(5, 50) / 20.0f, (float)random.Next(10, 20) / 20.0f));
                }
                else if (rndn == 1)
                {
                    body = new RigidBody(new BoxShape(new JVector(
                                                          (float)random.Next(10, 30) / 20.0f,
                                                          (float)random.Next(10, 30) / 20.0f, (float)random.Next(10, 30) / 20.0f)));
                }
                else if (rndn == 2)
                {
                    body = new RigidBody(new SphereShape((float)random.Next(30, 100) / 100.0f));
                }
                else if (rndn == 3)
                {
                    body = new RigidBody(new CylinderShape(1.0f, 0.5f));
                }
                else if (rndn == 4)
                {
                    body = new RigidBody(new CapsuleShape(1.0f, 0.5f));
                }
                else
                {
                    Shape b1 = new BoxShape(new JVector(3, 1, 1));
                    Shape b2 = new BoxShape(new JVector(1, 1, 3));
                    Shape b3 = new CylinderShape(2.0f, 0.5f);

                    CompoundShape.TransformedShape t1 = new CompoundShape.TransformedShape(b1, JMatrix.Identity, JVector.Zero);
                    CompoundShape.TransformedShape t2 = new CompoundShape.TransformedShape(b2, JMatrix.Identity, JVector.Zero);
                    CompoundShape.TransformedShape t3 = new CompoundShape.TransformedShape(b3, JMatrix.Identity, new JVector(0, 0, 0));

                    CompoundShape ms = new CompoundShape(new CompoundShape.TransformedShape[3] {
                        t1, t2, t3
                    });

                    body = new RigidBody(ms);
                }

                world.AddBody(body);

                body.Position       = Conversion.ToJitterVector(Camera.Position);
                body.LinearVelocity = Conversion.ToJitterVector((Camera.Target - Camera.Position) * 40.0f);
                body.Update();

                spaceClicked = true;
            }
            #endregion

            spaceClicked = spaceHold;
            leftClicked  = leftHold;
            enterClicked = enterHold;
            mClicked     = mHold;

            int contactCount = 0;
            foreach (Arbiter ar in world.ArbiterMap.Values)
            {
                contactCount += ar.ContactList.Count;
            }

            display.DisplayText[0] = "Arbitercount: " + world.ArbiterMap.Values.Count.ToString() + ";" + " Contactcount: " + contactCount.ToString();
            display.DisplayText[2] = "Bodycount: " + world.RigidBodies.Count;
            display.DisplayText[3] = (multithread) ? "Multithreaded" : "Single Threaded";

            float elapsedTime = (float)gameTime.ElapsedGameTime.TotalSeconds;
            if (elapsedTime > 1.0f / 100.0f)
            {
                elapsedTime = 1.0f / 100.0f;
            }
            world.Step(elapsedTime, multithread);

            base.Update(gameTime);
        }