public void BlockIntersectFromOutside()
        {
            // X-Achse links zu weit weg (keine Bewegung)
            Axis? collisionAxis;
            float?distance = block.Intersect(
                new Index3(10, 20, 30),
                new BoundingBox(new Vector3(5, 20, 30), new Vector3(6, 21, 31)),
                new Vector3(), out collisionAxis);

            Assert.AreEqual(null, collisionAxis);
            Assert.AreEqual(null, distance);

            // X-Achse links zu weit weg (bewegung nach links)
            distance = block.Intersect(
                new Index3(10, 20, 30),
                new BoundingBox(new Vector3(5, 20, 30), new Vector3(6, 21, 31)), new Vector3(-4, 0, 0), out collisionAxis);
            Assert.AreEqual(null, collisionAxis);
            Assert.AreEqual(null, distance);

            // X-Achse links zu weit weg (bewegung nach rechts)
            distance = block.Intersect(new Index3(10, 20, 30), new BoundingBox(new Vector3(5, 20, 30), new Vector3(6, 21, 31)), new Vector3(4, 0, 0), out collisionAxis);
            Assert.AreEqual(null, collisionAxis);
            Assert.AreEqual(null, distance);
        }
Esempio n. 2
0
        private void Move()
        {
            bool collision = false;
            int  loop      = 0;

            do
            {
                BoundingBox playerBox = new BoundingBox(
                    new Vector3(
                        player.GlobalPosition.X - playerRadius,
                        player.GlobalPosition.Y - playerRadius,
                        player.GlobalPosition.Z),
                    new Vector3(
                        player.GlobalPosition.X + playerRadius,
                        player.GlobalPosition.Y + playerRadius,
                        player.GlobalPosition.Z + playerHeight));

                collision = false;
                float min     = 1f;
                Axis  minAxis = Axis.None;

                foreach (var pos in blocks.Keys)
                {
                    BlockDefinition block = blocks[pos];
                    if (block == null)
                    {
                        continue;
                    }

                    Axis? localAxis;
                    float?moveFactor = block.Intersect(pos, playerBox, move, out localAxis);

                    if (moveFactor.HasValue && moveFactor.Value < min)
                    {
                        collision = true;
                        min       = moveFactor.Value;
                        minAxis   = localAxis.Value;
                    }
                }

                player += (move * min);
                move   *= (1f - min);
                switch (minAxis)
                {
                case Axis.X:
                    player += new Vector3(move.X > 0 ? -gap : gap, 0, 0);
                    move.X  = 0f;
                    break;

                case Axis.Y:
                    player += new Vector3(0, move.Y > 0 ? -gap : gap, 0);
                    move.Y  = 0f;
                    break;

                case Axis.Z:
                    player += new Vector3(0, 0, move.Z > 0 ? -gap : gap);
                    move.Z  = 0f;
                    break;
                }

                // Koordinate normalisieren (Rundwelt)
                // player.NormalizeChunkIndexXY(planet.Size);

                loop++;
            }while (collision && loop < 3);
        }
        public void SlidingWall()
        {
            // ###
            //  3#
            //  2#
            // 1

            Dictionary <Index3, BlockDefinition> blocks = new Dictionary <Index3, BlockDefinition>();

            blocks.Add(new Index3(2, 2, 1), new TestBlock());
            blocks.Add(new Index3(3, 2, 1), new TestBlock());
            blocks.Add(new Index3(4, 2, 1), new TestBlock());
            blocks.Add(new Index3(4, 3, 1), new TestBlock());
            blocks.Add(new Index3(4, 4, 1), new TestBlock());

            BoundingBox player = new BoundingBox(new Vector3(2, 5, 1), new Vector3(3, 6, 1));
            Vector3     move   = new Vector3(0.75f, -0.75f, 0);
            Axis?       collisionAxis;
            float?      distance;

            // Step 1 (2/5 -> 2.75/4.25 (keine Kollision)
            foreach (var pos in blocks.Keys)
            {
                BlockDefinition block = blocks[pos];
                distance = block.Intersect(pos, player, move, out collisionAxis);
                Assert.IsNull(collisionAxis);
                Assert.IsNull(distance);
            }

            // Step 2 (2.75/4.25 -> 3.5/3.5 (kollision X) -> 3.0/3.5
            player = new BoundingBox(player.Min + move, player.Max + move);
            foreach (var pos in blocks.Keys)
            {
                BlockDefinition block = blocks[pos];
                distance = block.Intersect(pos, player, move, out collisionAxis);

                if (pos == new Index3(4, 3, 1) || pos == new Index3(4, 4, 1))
                {
                    Assert.AreEqual(Axis.X, collisionAxis);
                    Assert.AreEqual(1f / 3f, distance);
                }
                else
                {
                    Assert.IsNull(collisionAxis);
                    Assert.IsNull(distance);
                }
            }

            // Step 3 (3.0/3.5 -> 3.75/2.75 (Kollision X & Y) -> 3/3
            player = new BoundingBox(new Vector3(3, 3.5f, 1), new Vector3(4, 4.5f, 1));
            foreach (var pos in blocks.Keys)
            {
                BlockDefinition block = blocks[pos];
                distance = block.Intersect(pos, player, move, out collisionAxis);

                if (pos == new Index3(4, 3, 1) || pos == new Index3(4, 4, 1))
                {
                    Assert.AreEqual(Axis.X, collisionAxis);
                    Assert.AreEqual(0f, distance);
                }
                else if (pos == new Index3(2, 2, 1) || pos == new Index3(3, 2, 1) || pos == new Index3(4, 2, 1))
                {
                    Assert.AreEqual(Axis.Y, collisionAxis);
                    Assert.AreEqual(2f / 3f, distance);
                }
                else
                {
                    Assert.IsNull(collisionAxis);
                    Assert.IsNull(distance);
                }
            }

            // Step 4 (freeze) 3/3 -> 3.75/2.25 (Kollision X & Y) -> 3/3
            player = new BoundingBox(new Vector3(3, 3, 1), new Vector3(4, 3, 1));
            foreach (var pos in blocks.Keys)
            {
                BlockDefinition block = blocks[pos];
                distance = block.Intersect(pos, player, move, out collisionAxis);

                if (pos == new Index3(4, 2, 1) || pos == new Index3(4, 3, 1))
                {
                    Assert.AreEqual(Axis.X, collisionAxis);
                    Assert.AreEqual(0f, distance);
                }
                else if (pos == new Index3(2, 2, 1) || pos == new Index3(3, 2, 1))
                {
                    Assert.AreEqual(Axis.Y, collisionAxis);
                    Assert.AreEqual(0, distance);
                }
                else
                {
                    Assert.IsNull(collisionAxis);
                    Assert.IsNull(distance);
                }
            }
        }