コード例 #1
0
    bool VectorIntersectPlane(Vector3 v, Vector3 p, CollisionPlane wall)
    {
        //regarder si intersection entre rayon et plane
        float   d = Vector3.Dot(wall.getPlanePoints()[0], wall.getPlaneNormal());
        Vector3 n = wall.getPlaneNormal();

        //resoudre system equation entre droite du vector et plane de la face
        float alpha = (d - Vector3.Dot(n, p)) / Vector3.Dot(n, v);

        //regarder si intersection est dans vecteur
        if (alpha > 1 || alpha <= 0)
        {
            return(false);
        }
        //regarder si intersection est dans polygon
        Vector3 planeIntersection = p + v * alpha;

        planeIntersection = wall.transform.InverseTransformPoint(planeIntersection);
        if (VerifyIfWithinPolygon(wall.getPlanePointsLocal(), planeIntersection))
        {
            Debug.Log("COLLISION at point:" + p);
            CalculateRebound(n);
            return(true);
        }
        return(false);
    }
コード例 #2
0
        internal void SetWaypoint(CollisionIndex WP, CollisionPlane p)
        {
            LastPlane = p;
            if (this.button1 == null)
            {
                InitializeComponent();
            }
            Current           = WP;
            this.Text         = WP.ToString();// +" matrix=" + WP.GetMatrix((float)WP.Position.Z);
            this.button1.Text = WP.ExtraInfoString(LastPlane);
            int i = 0;

            foreach (Button B in CurrentButtons)
            {
                Controls.Remove(B);
            }

            CurrentButtons.Clear();

            foreach (IMeshedObject O in WP.GetOccupiedObjects(p.MinZ, p.MaxZ))
            {
                i++;
                Button B = new Button();
                B.Location  = new System.Drawing.Point(24, 28 + i * 20);
                B.Name      = "o" + i;
                B.Size      = new System.Drawing.Size(715, 23);
                B.TabIndex  = i;
                B.Text      = O.DebugString();
                B.TextAlign = ContentAlignment.MiddleLeft;
                B.UseVisualStyleBackColor = true;
                B.Click += new System.EventHandler(this.object_click);
                this.Controls.Add(B);
                CurrentButtons.Add(B);
            }
        }
コード例 #3
0
        public static List <Box3Fill> Simplify(List <Box3Fill> simpl)
        {
            try
            {
                return(Simplify1(simpl));
            }
            catch (Exception)
            {
                return(simpl);
            }
            int             bc = simpl.Count;
            int             t0 = Environment.TickCount;
            List <Box3Fill> s0 = Simplify0(new List <Box3Fill>(simpl));
            int             t1 = Environment.TickCount;
            List <Box3Fill> s1 = Simplify1(new List <Box3Fill>(simpl));
            int             t2 = Environment.TickCount;
            int             c0 = s0.Count;
            int             c1 = s1.Count;

            CollisionPlane.Debug("Simplify {0} S0={1}/{2}  S1={3}/{4}  ", bc, t1 - t0, c0, t2 - t1, c1);
            if (c1 < c0)
            {
                return(s1);
            }
            return(s0);
        }
コード例 #4
0
 internal void OnNewCollisionPlane(CollisionPlane found)
 {
     if (CurrentPlane == null)
     {
         CurrentPlane = found;
     }
 }
コード例 #5
0
        public PlanesManager()
        {
            ListOfPlanes = new List <CollisionPlane>();

            //// Bottom
            //int offset1 = StaticData.PlaneOffsetBottom;
            //Vector3 direction1 = new Vector3(0, 1, 0);
            //direction1.Normalize();
            //Rectangle rect1 = new Rectangle(0,
            //                                offset1,
            //                                StaticData.LevelFarWidth,
            //                                10);
            //CollisionPlane plane1 = new CollisionPlane(-(offset1), direction1, Material.Wood,
            //                                           TextureType.DefaultBox,
            //                                           rect1);
            //// Right
            //int offset2 = StaticData.PlaneOffsetRight;
            //Vector3 direction2 = new Vector3(-1, 0, 0);
            //direction2.Normalize();
            //Rectangle rect2 = new Rectangle(offset2,
            //                                0,
            //                                10,
            //                                StaticData.LevelFarWidth);
            //CollisionPlane plane2 = new CollisionPlane(-offset2, direction2, Material.Steel,
            //                                           TextureType.DefaultBox,
            //                                           rect2);

            ////Left
            //int offset3 = StaticData.PlaneOffsetLeft;
            //Vector3 direction3 = new Vector3(1, 0, 0);
            //direction3.Normalize();
            //Rectangle rect3 = new Rectangle(offset3 - 10,
            //                                0,
            //                                10,
            //                                StaticData.LevelFarWidth);
            //CollisionPlane plane3 = new CollisionPlane(-offset3, direction3, Material.Steel,
            //                                           TextureType.DefaultBox,
            //                                           rect3);

            // Up
            int     offset4    = StaticData.PlaneOffsetUp;
            Vector3 direction4 = new Vector3(0, -1, 0);

            direction4.Normalize();
            Rectangle rect4 = new Rectangle(0,
                                            offset4 - 10,
                                            StaticData.LevelFarWidth, 10);
            CollisionPlane plane4 = new CollisionPlane(-offset4, direction4, Material.Steel,
                                                       TextureType.DefaultBox,
                                                       rect4);

            //this.ListOfPlanes.Add(plane1);
            //this.ListOfPlanes.Add(plane2);
            //this.ListOfPlanes.Add(plane3);
            this.ListOfPlanes.Add(plane4);
        }
コード例 #6
0
            public void LineIntersection_GetCollisionPointsReturnsEmptyListWhenThereIsNoCollidingPlanes()
            {
                Line line1 = new Line(new PointD(0, 3), new PointD(4, 7));
                LineIntersections     li              = new LineIntersections(line1);
                CollisionPlane        plane1          = new CollisionPlane(new PointD(3, 0), new PointD(3, 4));
                CollisionPlane        plane2          = new CollisionPlane(new PointD(0, 2), new PointD(4, 2));
                List <CollisionPlane> collisionPlanes = new List <CollisionPlane> {
                    plane1, plane2
                };
                var collisionPoints = li.GetCollisionPoints(collisionPlanes);

                Assert.AreEqual(0, collisionPoints.Count());
            }
コード例 #7
0
            public void LineIntersection_GetCollisionPointsReturnsTwoCollisionPointsForTwoPlaneColliding()
            {
                Line line1 = new Line(new PointD(0, 0), new PointD(4, 4));
                LineIntersections     li              = new LineIntersections(line1);
                CollisionPlane        plane1          = new CollisionPlane(new PointD(3, 0), new PointD(3, 4));
                CollisionPlane        plane2          = new CollisionPlane(new PointD(0, 2), new PointD(4, 2));
                List <CollisionPlane> collisionPlanes = new List <CollisionPlane> {
                    plane1, plane2
                };
                var collisionPoints = li.GetCollisionPoints(collisionPlanes);

                Assert.AreEqual(2, collisionPoints.Count());
            }
コード例 #8
0
        public void LineIntersections_GetCollisionPointsReturnsIntersectionPointOnCollisionPlaneForLineEndingOnIt()
        {
            Line line1               = new Line(new PointD(0, 0), new PointD(200, 200));
            LineIntersections li     = new LineIntersections(line1);
            CollisionPlane    plane1 = new CollisionPlane(new PointD(200, 0), new PointD(200, 400));
            var collisionPoints      = li.GetCollisionPoints(new List <CollisionPlane> {
                plane1
            });

            Assert.AreEqual(1, collisionPoints.Count());
            Assert.AreEqual(200, collisionPoints.First().Point.X, 1e-5);
            Assert.AreEqual(200, collisionPoints.First().Point.Y, 1e-5);
        }
コード例 #9
0
 public void SetOccupied(CallbackXY p, SimZMinMaxLevel MinMaxZ, float detail)
 {
     if (InnerBoxes.Count == 0)
     {
         CollisionPlane.Debug("using outerbox for " + this);
         OuterBox.SetOccupied(p, MinMaxZ, detail);
         return;
     }
     foreach (CollisionObject box in InnerBoxes)
     {
         box.SetOccupied(p, MinMaxZ, detail);
     }
 }
コード例 #10
0
            public void LineIntersection_GetCollisionPointsReturnsOneCollisionForProperCollisionPlane()
            {
                Line line1 = new Line(new PointD(0, 0), new PointD(4, 4));
                LineIntersections     li              = new LineIntersections(line1);
                CollisionPlane        plane1          = new CollisionPlane(new PointD(3, 0), new PointD(3, 4));
                List <CollisionPlane> collisionPlanes = new List <CollisionPlane> {
                    plane1
                };
                var collisionPoints = li.GetCollisionPoints(collisionPlanes);

                Assert.AreEqual(1, collisionPoints.Count());
                Assert.AreEqual(3, collisionPoints.First().Point.X, 1e-5);
                Assert.AreEqual(3, collisionPoints.First().Point.Y, 1e-5);
            }
コード例 #11
0
        public void LineIntersection_GetClosestCollisionPointsReturnsTwoCollisionPointsForTwoPlanesIntersectingInThePointOfCollision()
        {
            Line line1 = new Line(new PointD(0, 0), new PointD(4, 4));
            LineIntersections     li              = new LineIntersections(line1);
            CollisionPlane        plane1          = new CollisionPlane(new PointD(3, 0), new PointD(3, 4));
            CollisionPlane        plane2          = new CollisionPlane(new PointD(0, 3), new PointD(4, 3));
            List <CollisionPlane> collisionPlanes = new List <CollisionPlane> {
                plane1, plane2
            };
            var collisionPoints = li.GetClosestCollisionPoints(collisionPlanes);

            Assert.AreEqual(2, collisionPoints.Count());
            Assert.IsNotNull(collisionPoints.FirstOrDefault(cp => cp.HittableObject == plane1));
            Assert.IsNotNull(collisionPoints.FirstOrDefault(cp => cp.HittableObject == plane2));
        }
コード例 #12
0
        public void LineIntersection_GetClosestCollisionPointsReturnsOneCollisionPointsForTwoPlanesWithDifferentPointsOfCollision()
        {
            Line line1 = new Line(new PointD(0, 0), new PointD(4, 4));
            LineIntersections     li              = new LineIntersections(line1);
            CollisionPlane        plane1          = new CollisionPlane(new PointD(3, 0), new PointD(3, 4));
            CollisionPlane        plane2          = new CollisionPlane(new PointD(0, 2), new PointD(4, 2));
            List <CollisionPlane> collisionPlanes = new List <CollisionPlane> {
                plane1, plane2
            };
            var collisionPoints = li.GetClosestCollisionPoints(collisionPlanes);

            Assert.AreEqual(1, collisionPoints.Count());
            Assert.AreEqual(plane2, collisionPoints.First().HittableObject);
            Assert.AreEqual(2, collisionPoints.First().Point.X);
            Assert.AreEqual(2, collisionPoints.First().Point.Y);
        }
コード例 #13
0
    bool Intersect(CollisionPlane wall)
    {
        float   d        = Vector3.Dot(wall.getPlanePoints()[0], wall.getPlaneNormal());
        Vector3 n        = wall.getPlaneNormal();
        float   distance = Mathf.Abs(Vector3.Dot(n, center) + d);

        if (Mathf.Abs(Vector3.Dot(n, center) + d) <= radius)
        {
            Vector3 intersectPoint = center + distance * n / n.magnitude;
            intersectPoint = wall.transform.InverseTransformPoint(intersectPoint);
            if (VerifyIfWithinPolygon(wall.getPlanePointsLocal(), intersectPoint))
            {
                Debug.Log("COLLISION AT POINT: " + wall.transform.TransformPoint(intersectPoint));
                CalculateRebound(n);
                return(true);
            }
        }
        return(false);
    }
コード例 #14
0
        public bool IsInside(float x, float y, float z)
        {
            // Offset position

            if (OuterBox.IsInside(x, y, z)) // Is possible?
            {
                if (InnerBoxes.Count == 0)
                {
                    CollisionPlane.Debug("using outerbox for " + this);
                    return(true);
                }
                foreach (CollisionObject box in InnerBoxes)
                {
                    if (box.IsInside(x, y, z))
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
コード例 #15
0
        private void object_click(object sender, EventArgs e)
        {
            IList <CollisionObject> occs = (IList <CollisionObject>)Current.GetOccupiedObjects(LastPlane.MinZ, LastPlane.MaxZ);

            try
            {
                if (sender is Button)
                {
                    Button          B    = (Button)sender;
                    string          name = B.Name.Substring(1);
                    int             i    = int.Parse(name) - 1;
                    CollisionObject O    = occs[i];
                    if (O is IMeshedObject)
                    {
                        ((IMeshedObject)O).RemeshObject();
                    }
                }
            }
            catch (Exception ex)
            {
                CollisionPlane.Debug(ex);
            }
        }
コード例 #16
0
 private void SetCurrentPlane(CollisionPlane value)
 {
     if (InvokeRequired)
     {
         this.Invoke(new SetCurrentPlaneDelegate(SetCurrentPlane), new object[] { value });
         return;
     }
     if (value != null && _CurrentPlane != value)
     {
         _CurrentPlane = value;
         if (_CurrentPlane != null)
         {
             PathStore = _CurrentPlane.PathStore;
             PathFinderDemo pfd = PathStore.PanelGUI;
             if (pfd != null)
             {
                 pfd.SetPlane(_CurrentPlane);
                 pfd.Text = String.Format("{0} {1}", PathStore.RegionName, _CurrentPlane);
             }
             _Matrix = _CurrentPlane.ByteMatrix;
         }
         Invalidate();
     }
 }
コード例 #17
0
        internal void SetWaypoint(CollisionIndex WP,CollisionPlane p)
        {
            LastPlane = p;
            if (this.button1 == null)
            {
                InitializeComponent();
            }
            Current = WP;
            this.Text = WP.ToString();// +" matrix=" + WP.GetMatrix((float)WP.Position.Z);
            this.button1.Text = WP.ExtraInfoString(LastPlane);
            int i = 0;

            foreach (Button B in CurrentButtons)
            {
                Controls.Remove(B);
            }

            CurrentButtons.Clear();

            foreach (IMeshedObject O in WP.GetOccupiedObjects(p.MinZ, p.MaxZ))
            {
                i++;
                Button B = new Button();
                B.Location = new System.Drawing.Point(24, 28+i*20);
                B.Name = "o"+i;
                B.Size = new System.Drawing.Size(715, 23);
                B.TabIndex = i;
                B.Text = O.DebugString();
                B.TextAlign = ContentAlignment.MiddleLeft;
                B.UseVisualStyleBackColor = true;
                B.Click += new System.EventHandler(this.object_click);
                this.Controls.Add(B);
                CurrentButtons.Add(B);
            }

        }
コード例 #18
0
        /// <summary>
        /// Berechnet die Geschwindigkeit einer <see cref="Entity"/> nach der Kollision mit der Welt. (Original Lassi)
        /// </summary>
        /// <param name="gameTime">Simulation time</param>
        /// <param name="position">Position der <see cref="Entity"/></param>
        /// <param name="cache"><see cref="ILocalChunkCache"/> as workspace</param>
        /// <param name="radius">Radius der <see cref="Entity"/></param>
        /// <param name="height">Höhe der <see cref="Entity"/></param>
        /// <param name="deltaPosition">Positionsänderung zwischen zwei Simulationsdurchläufen</param>
        /// <param name="velocity">Berechnete Geschwindigkeit</param>
        /// <exception cref="ArgumentNullException">Cache</exception>
        /// <returns>Geschwindigkeit der <see cref="Entity"/> nach der Killisionsprüfung</returns>
        public Vector3 WorldCollision(GameTime gameTime, Coordinate position, ILocalChunkCache cache, float radius, float height,
                                      Vector3 deltaPosition, Vector3 velocity)
        {
            if (cache == null)
            {
                throw new ArgumentNullException(nameof(cache));
            }

            Vector3 move = deltaPosition;

            //Blocks finden die eine Kollision verursachen könnten
            int minx = (int)Math.Floor(Math.Min(
                                           position.BlockPosition.X - radius,
                                           position.BlockPosition.X - radius + deltaPosition.X));
            int maxx = (int)Math.Ceiling(Math.Max(
                                             position.BlockPosition.X + radius,
                                             position.BlockPosition.X + radius + deltaPosition.X));
            int miny = (int)Math.Floor(Math.Min(
                                           position.BlockPosition.Y - radius,
                                           position.BlockPosition.Y - radius + deltaPosition.Y));
            int maxy = (int)Math.Ceiling(Math.Max(
                                             position.BlockPosition.Y + radius,
                                             position.BlockPosition.Y + radius + deltaPosition.Y));
            int minz = (int)Math.Floor(Math.Min(
                                           position.BlockPosition.Z,
                                           position.BlockPosition.Z + deltaPosition.Z));
            int maxz = (int)Math.Ceiling(Math.Max(
                                             position.BlockPosition.Z + height,
                                             position.BlockPosition.Z + height + deltaPosition.Z));

            //Beteiligte Flächen des Spielers
            var playerplanes = CollisionPlane.GetEntityCollisionPlanes(radius, height, velocity, position);

            for (int z = minz; z <= maxz; z++)
            {
                for (int y = miny; y <= maxy; y++)
                {
                    for (int x = minx; x <= maxx; x++)
                    {
                        move = velocity * (float)gameTime.ElapsedGameTime.TotalSeconds;

                        Index3 pos      = new Index3(x, y, z);
                        Index3 blockPos = pos + position.GlobalBlockIndex;
                        ushort block    = cache.GetBlock(blockPos);

                        if (block == 0)
                        {
                            continue;
                        }

                        var blockplanes = CollisionPlane.GetBlockCollisionPlanes(pos, velocity);

                        foreach (var playerPlane in playerplanes)
                        {
                            foreach (var blockPlane in blockplanes)
                            {
                                if (!CollisionPlane.Intersect(blockPlane, playerPlane))
                                {
                                    continue;
                                }

                                var distance = CollisionPlane.GetDistance(blockPlane, playerPlane);
                                if (!CollisionPlane.CheckDistance(distance, move))
                                {
                                    continue;
                                }

                                var subvelocity = (distance / (float)gameTime.ElapsedGameTime.TotalSeconds);
                                var diff        = velocity - subvelocity;

                                float vx;
                                float vy;
                                float vz;

                                if (blockPlane.normal.X != 0 && (velocity.X > 0 && diff.X >= 0 && subvelocity.X >= 0 ||
                                                                 velocity.X < 0 && diff.X <= 0 && subvelocity.X <= 0))
                                {
                                    vx = subvelocity.X;
                                }
                                else
                                {
                                    vx = velocity.X;
                                }

                                if (blockPlane.normal.Y != 0 && (velocity.Y > 0 && diff.Y >= 0 && subvelocity.Y >= 0 ||
                                                                 velocity.Y < 0 && diff.Y <= 0 && subvelocity.Y <= 0))
                                {
                                    vy = subvelocity.Y;
                                }
                                else
                                {
                                    vy = velocity.Y;
                                }

                                if (blockPlane.normal.Z != 0 && (velocity.Z > 0 && diff.Z >= 0 && subvelocity.Z >= 0 ||
                                                                 velocity.Z < 0 && diff.Z <= 0 && subvelocity.Z <= 0))
                                {
                                    vz = subvelocity.Z;
                                }
                                else
                                {
                                    vz = velocity.Z;
                                }

                                velocity = new Vector3(vx, vy, vz);
                                if (vx == 0 && vy == 0 && vz == 0)
                                {
                                    return(velocity);
                                }
                            }
                        }
                    }
                }
            }
            return(velocity);
        }
コード例 #19
0
 public void AddPlane(CollisionPlane plane)
 {
     ListOfPlanes.Add(plane);
 }
コード例 #20
0
        protected override void UpdatePropPanels()
        {
            _updating = true;

            if (pnlPlaneProps.Visible)
            {
                if (_selectedPlanes.Count <= 0)
                {
                    pnlPlaneProps.Visible = false;
                    return;
                }

                CollisionPlane p = _selectedPlanes[0];

                //Material
                cboMaterial.SelectedItem = cboMaterial.Items[p._material];
                //Type
                chkTypeFloor.Checked     = p.IsFloor;
                chkTypeCeiling.Checked   = p.IsCeiling;
                chkTypeLeftWall.Checked  = p.IsLeftWall;
                chkTypeRightWall.Checked = p.IsRightWall;
                //Flags
                chkFallThrough.Checked        = p.IsFallThrough;
                chkLeftLedge.Checked          = p.IsLeftLedge;
                chkRightLedge.Checked         = p.IsRightLedge;
                chkNoWalljump.Checked         = p.IsNoWalljump;
                chkTypeCharacters.Checked     = p.IsCharacters;
                chkTypeItems.Checked          = p.IsItems;
                chkTypePokemonTrainer.Checked = p.IsPokemonTrainer;
                chkTypeRotating.Checked       = p.IsRotating;
                //UnknownFlags
                chkFlagUnknown1.Checked  = p.IsUnknownSSE;
                chkFlagUnknown2.Checked  = p.IsUnknownFlag1;
                chkFlagSuperSoft.Checked = p.IsSuperSoft;
                chkFlagUnknown4.Checked  = p.IsUnknownFlag4;
            }
            else if (pnlPointProps.Visible)
            {
                if (_selectedLinks.Count <= 0)
                {
                    pnlPointProps.Visible = false;
                    return;
                }

                numX.Value = _selectedLinks[0].Value._x;
                numY.Value = _selectedLinks[0].Value._y;
            }
            else if (pnlObjProps.Visible)
            {
                if (_selectedObject == null)
                {
                    pnlObjProps.Visible = false;
                    return;
                }

                txtModel.Text        = _selectedObject._modelName;
                txtBone.Text         = _selectedObject._boneName;
                chkObjUnk.Checked    = _selectedObject.UnknownFlag;
                chkObjModule.Checked = _selectedObject.ModuleControlled;
                chkObjSSEUnk.Checked = _selectedObject.UnknownSSEFlag;
            }

            _updating = false;
        }
コード例 #21
0
ファイル: MoveComponent.cs プロジェクト: marsat02/octoawesome
        private void CheckBoxCollision(GameTime gameTime, Entity entity, MoveableComponent movecomp, PositionComponent poscomp)
        {
            if (!entity.Components.ContainsComponent <BodyComponent>())
            {
                return;
            }

            BodyComponent bc = entity.Components.GetComponent <BodyComponent>();


            Coordinate position = poscomp.Position;

            Vector3 move = movecomp.PositionMove;

            //Blocks finden die eine Kollision verursachen könnten
            int minx = (int)Math.Floor(Math.Min(
                                           position.BlockPosition.X - bc.Radius,
                                           position.BlockPosition.X - bc.Radius + movecomp.PositionMove.X));
            int maxx = (int)Math.Ceiling(Math.Max(
                                             position.BlockPosition.X + bc.Radius,
                                             position.BlockPosition.X + bc.Radius + movecomp.PositionMove.X));
            int miny = (int)Math.Floor(Math.Min(
                                           position.BlockPosition.Y - bc.Radius,
                                           position.BlockPosition.Y - bc.Radius + movecomp.PositionMove.Y));
            int maxy = (int)Math.Ceiling(Math.Max(
                                             position.BlockPosition.Y + bc.Radius,
                                             position.BlockPosition.Y + bc.Radius + movecomp.PositionMove.Y));
            int minz = (int)Math.Floor(Math.Min(
                                           position.BlockPosition.Z,
                                           position.BlockPosition.Z + movecomp.PositionMove.Z));
            int maxz = (int)Math.Ceiling(Math.Max(
                                             position.BlockPosition.Z + bc.Height,
                                             position.BlockPosition.Z + bc.Height + movecomp.PositionMove.Z));

            //Beteiligte Flächen des Spielers
            var playerplanes = CollisionPlane.GetEntityCollisionPlanes(bc.Radius, bc.Height, movecomp.Velocity, poscomp.Position);

            bool abort = false;

            var cache = entity.Components.GetComponent <LocalChunkCacheComponent>().LocalChunkCache;

            for (int z = minz; z <= maxz && !abort; z++)
            {
                for (int y = miny; y <= maxy && !abort; y++)
                {
                    for (int x = minx; x <= maxx && !abort; x++)
                    {
                        move = movecomp.Velocity * (float)gameTime.ElapsedGameTime.TotalSeconds;

                        Index3 pos      = new Index3(x, y, z);
                        Index3 blockPos = pos + position.GlobalBlockIndex;
                        ushort block    = cache.GetBlock(blockPos);
                        if (block == 0)
                        {
                            continue;
                        }



                        var blockplane = CollisionPlane.GetBlockCollisionPlanes(pos, movecomp.Velocity).ToList();

                        var planes = from pp in playerplanes
                                     from bp in blockplane
                                     where CollisionPlane.Intersect(bp, pp)
                                     let distance = CollisionPlane.GetDistance(bp, pp)
                                                    where CollisionPlane.CheckDistance(distance, move)
                                                    select new { BlockPlane = bp, PlayerPlane = pp, Distance = distance };

                        foreach (var plane in planes)
                        {
                            var subvelocity = (plane.Distance / (float)gameTime.ElapsedGameTime.TotalSeconds);
                            var diff        = movecomp.Velocity - subvelocity;

                            float vx;
                            float vy;
                            float vz;

                            if (plane.BlockPlane.normal.X != 0 && (movecomp.Velocity.X > 0 && diff.X >= 0 && subvelocity.X >= 0 || movecomp.Velocity.X < 0 && diff.X <= 0 && subvelocity.X <= 0))
                            {
                                vx = subvelocity.X;
                            }
                            else
                            {
                                vx = movecomp.Velocity.X;
                            }

                            if (plane.BlockPlane.normal.Y != 0 && (movecomp.Velocity.Y > 0 && diff.Y >= 0 && subvelocity.Y >= 0 || movecomp.Velocity.Y < 0 && diff.Y <= 0 && subvelocity.Y <= 0))
                            {
                                vy = subvelocity.Y;
                            }
                            else
                            {
                                vy = movecomp.Velocity.Y;
                            }

                            if (plane.BlockPlane.normal.Z != 0 && (movecomp.Velocity.Z > 0 && diff.Z >= 0 && subvelocity.Z >= 0 || movecomp.Velocity.Z < 0 && diff.Z <= 0 && subvelocity.Z <= 0))
                            {
                                vz = subvelocity.Z;
                            }
                            else
                            {
                                vz = movecomp.Velocity.Z;
                            }

                            movecomp.Velocity = new Vector3(vx, vy, vz);

                            if (vx == 0 && vy == 0 && vz == 0)
                            {
                                abort = true;
                                break;
                            }
                        }
                    }
                }
            }

            // TODO: Was ist für den Fall Gravitation = 0 oder im Scheitelpunkt des Sprungs?
            //movecomp.OnGround = Player.Velocity.Z == 0f;

            movecomp.PositionMove = movecomp.Velocity * (float)gameTime.ElapsedGameTime.TotalSeconds;
        }
コード例 #22
0
 public virtual bool UpdateOccupied(SimPathStore pathStore)
 {
     if (pathStore == null)
     {
         CollisionPlane.Debug("Cant UpdatePathOccupied for {0}", this);// + " pos " + RootObject.DistanceVectorString(RootObject));
         return(false);
     }
     if (!UpdateMeshPaths)
     {
         return(false);
     }
     if (MeshOnlySolids && !IsSolid)
     {
         return(false);
     }
     if (InnerBoxes == null)
     {
         return(false);
     }
     if (InnerBoxes.Count == 0)
     {
         return(false);
     }
     if (!IsRegionAttached())
     {
         return(false);
     }
     //  int t1;
     try
     {
         //lock (PathStore)
         {
             if (PathStore == pathStore)
             {
                 return(false);
             }
             PathStore = pathStore;//.Add(pathStore);
             if (tryFastVersion)
             {
                 //                UpdatePathOccupiedFast(PathStore);
                 // int tc = Environment.TickCount;
                 UpdatePathOccupiedVeryFast(pathStore);
                 // t1 = Environment.TickCount - tc;
                 InnerBoxes = null;
                 PathStore.AddedCount++;
                 //  CollisionPlane.Debug("t1 vs t2 = " + t1 );
                 return(true);
             }
         }
         ForceUpdatePathOccupied(pathStore);
         return(true);
     }
     catch (Exception e)
     {
         //  lock (PathStore)
         {
             PathStore = null;//.Remove(pathStore);
         }
         return(false);
     };
 }
コード例 #23
0
ファイル: ActorHost.cs プロジェクト: BlackOrca/octoawesome
        /// <summary>
        /// Aktualisiert den Spieler (Bewegung, Interaktion)
        /// </summary>
        /// <param name="frameTime">Die aktuelle Zeit.</param>
        public void Update(GameTime frameTime)
        {
            #region Inputverarbeitung

            // Input verarbeiten
            Player.Angle += (float)frameTime.ElapsedGameTime.TotalSeconds * Head.X;
            Player.Tilt  += (float)frameTime.ElapsedGameTime.TotalSeconds * Head.Y;
            Player.Tilt   = Math.Min(1.5f, Math.Max(-1.5f, Player.Tilt));

            #endregion

            #region Physik

            float lookX             = (float)Math.Cos(Player.Angle);
            float lookY             = -(float)Math.Sin(Player.Angle);
            var   velocitydirection = new Vector3(lookX, lookY, 0) * Move.Y;

            float stafeX = (float)Math.Cos(Player.Angle + MathHelper.PiOver2);
            float stafeY = -(float)Math.Sin(Player.Angle + MathHelper.PiOver2);
            velocitydirection += new Vector3(stafeX, stafeY, 0) * Move.X;

            Player.Velocity += PhysicalUpdate(velocitydirection, frameTime.ElapsedGameTime, !Player.FlyMode, Player.FlyMode);

            #endregion

            #region Playerbewegung /Kollision

            Vector3 move = Player.Velocity * (float)frameTime.ElapsedGameTime.TotalSeconds;

            Player.OnGround = false;

            //Blocks finden die eine Kollision verursachen könnten
            int minx = (int)Math.Floor(Math.Min(
                                           Player.Position.BlockPosition.X - Player.Radius,
                                           Player.Position.BlockPosition.X - Player.Radius + move.X));
            int maxx = (int)Math.Ceiling(Math.Max(
                                             Player.Position.BlockPosition.X + Player.Radius,
                                             Player.Position.BlockPosition.X + Player.Radius + move.X));
            int miny = (int)Math.Floor(Math.Min(
                                           Player.Position.BlockPosition.Y - Player.Radius,
                                           Player.Position.BlockPosition.Y - Player.Radius + move.Y));
            int maxy = (int)Math.Ceiling(Math.Max(
                                             Player.Position.BlockPosition.Y + Player.Radius,
                                             Player.Position.BlockPosition.Y + Player.Radius + move.Y));
            int minz = (int)Math.Floor(Math.Min(
                                           Player.Position.BlockPosition.Z,
                                           Player.Position.BlockPosition.Z + move.Z));
            int maxz = (int)Math.Ceiling(Math.Max(
                                             Player.Position.BlockPosition.Z + Player.Height,
                                             Player.Position.BlockPosition.Z + Player.Height + move.Z));

            //Beteiligte Flächen des Spielers
            var playerplanes = CollisionPlane.GetPlayerCollisionPlanes(Player).ToList();

            bool abort = false;

            for (int z = minz; z <= maxz && !abort; z++)
            {
                for (int y = miny; y <= maxy && !abort; y++)
                {
                    for (int x = minx; x <= maxx && !abort; x++)
                    {
                        move = Player.Velocity * (float)frameTime.ElapsedGameTime.TotalSeconds;

                        Index3 pos      = new Index3(x, y, z);
                        Index3 blockPos = pos + Player.Position.GlobalBlockIndex;
                        ushort block    = localChunkCache.GetBlock(blockPos);
                        if (block == 0)
                        {
                            continue;
                        }



                        var blockplane = CollisionPlane.GetBlockCollisionPlanes(pos, Player.Velocity).ToList();

                        var planes = from pp in playerplanes
                                     from bp in blockplane
                                     where CollisionPlane.Intersect(bp, pp)
                                     let distance = CollisionPlane.GetDistance(bp, pp)
                                                    where CollisionPlane.CheckDistance(distance, move)
                                                    select new { BlockPlane = bp, PlayerPlane = pp, Distance = distance };

                        foreach (var plane in planes)
                        {
                            var subvelocity = (plane.Distance / (float)frameTime.ElapsedGameTime.TotalSeconds);
                            var diff        = Player.Velocity - subvelocity;

                            float vx;
                            float vy;
                            float vz;

                            if (plane.BlockPlane.normal.X != 0 && (Player.Velocity.X > 0 && diff.X >= 0 && subvelocity.X >= 0 || Player.Velocity.X < 0 && diff.X <= 0 && subvelocity.X <= 0))
                            {
                                vx = subvelocity.X;
                            }
                            else
                            {
                                vx = Player.Velocity.X;
                            }

                            if (plane.BlockPlane.normal.Y != 0 && (Player.Velocity.Y > 0 && diff.Y >= 0 && subvelocity.Y >= 0 || Player.Velocity.Y < 0 && diff.Y <= 0 && subvelocity.Y <= 0))
                            {
                                vy = subvelocity.Y;
                            }
                            else
                            {
                                vy = Player.Velocity.Y;
                            }

                            if (plane.BlockPlane.normal.Z != 0 && (Player.Velocity.Z > 0 && diff.Z >= 0 && subvelocity.Z >= 0 || Player.Velocity.Z < 0 && diff.Z <= 0 && subvelocity.Z <= 0))
                            {
                                vz = subvelocity.Z;
                            }
                            else
                            {
                                vz = Player.Velocity.Z;
                            }

                            Player.Velocity = new Vector3(vx, vy, vz);

                            if (vx == 0 && vy == 0 && vz == 0)
                            {
                                abort = true;
                                break;
                            }
                        }
                    }
                }
            }

            // TODO: Was ist für den Fall Gravitation = 0 oder im Scheitelpunkt des Sprungs?
            Player.OnGround = Player.Velocity.Z == 0f;

            Coordinate position = Player.Position + Player.Velocity * (float)frameTime.ElapsedGameTime.TotalSeconds;
            position.NormalizeChunkIndexXY(planet.Size);
            Player.Position = position;


            //Beam me up
            KeyboardState ks = Keyboard.GetState();
            if (ks.IsKeyDown(Keys.P))
            {
                Player.Position += new Vector3(0, 0, 10);
            }

            if (Player.Position.ChunkIndex != _oldIndex)
            {
                _oldIndex  = Player.Position.ChunkIndex;
                ReadyState = false;
                localChunkCache.SetCenter(planet, new Index2(Player.Position.ChunkIndex), (success) =>
                {
                    ReadyState = success;
                });
            }



            #endregion

            #region Block Interaction

            if (lastInteract.HasValue)
            {
                ushort lastBlock = localChunkCache.GetBlock(lastInteract.Value);
                localChunkCache.SetBlock(lastInteract.Value, 0);

                if (lastBlock != 0)
                {
                    var blockDefinition = DefinitionManager.Instance.GetBlockDefinitionByIndex(lastBlock);

                    var slot = Player.Inventory.FirstOrDefault(s => s.Definition == blockDefinition);

                    // Wenn noch kein Slot da ist oder der vorhandene voll, dann neuen Slot
                    if (slot == null)
                    {
                        slot = new InventorySlot()
                        {
                            Definition = blockDefinition,
                            Amount     = 0
                        };
                        Player.Inventory.Add(slot);

                        for (int i = 0; i < Player.Tools.Length; i++)
                        {
                            if (Player.Tools[i] == null)
                            {
                                Player.Tools[i] = slot;
                                break;
                            }
                        }
                    }
                    slot.Amount += 125;
                }
                lastInteract = null;
            }

            if (lastApply.HasValue)
            {
                if (ActiveTool != null)
                {
                    Index3 add = new Index3();
                    switch (lastOrientation)
                    {
                    case OrientationFlags.SideWest: add = new Index3(-1, 0, 0); break;

                    case OrientationFlags.SideEast: add = new Index3(1, 0, 0); break;

                    case OrientationFlags.SideSouth: add = new Index3(0, -1, 0); break;

                    case OrientationFlags.SideNorth: add = new Index3(0, 1, 0); break;

                    case OrientationFlags.SideBottom: add = new Index3(0, 0, -1); break;

                    case OrientationFlags.SideTop: add = new Index3(0, 0, 1); break;
                    }

                    if (ActiveTool.Definition is IBlockDefinition)
                    {
                        IBlockDefinition definition = ActiveTool.Definition as IBlockDefinition;

                        Index3 idx       = lastApply.Value + add;
                        var    boxes     = definition.GetCollisionBoxes(localChunkCache, idx.X, idx.Y, idx.Z);
                        float  gap       = 0.01f;
                        var    playerBox = new BoundingBox(
                            new Vector3(
                                Player.Position.GlobalBlockIndex.X + Player.Position.BlockPosition.X - Player.Radius + gap,
                                Player.Position.GlobalBlockIndex.Y + Player.Position.BlockPosition.Y - Player.Radius + gap,
                                Player.Position.GlobalBlockIndex.Z + Player.Position.BlockPosition.Z + gap),
                            new Vector3(
                                Player.Position.GlobalBlockIndex.X + Player.Position.BlockPosition.X + Player.Radius - gap,
                                Player.Position.GlobalBlockIndex.Y + Player.Position.BlockPosition.Y + Player.Radius - gap,
                                Player.Position.GlobalBlockIndex.Z + Player.Position.BlockPosition.Z + Player.Height - gap)
                            );

                        // Nicht in sich selbst reinbauen
                        bool intersects = false;
                        foreach (var box in boxes)
                        {
                            var newBox = new BoundingBox(idx + box.Min, idx + box.Max);
                            if (newBox.Min.X < playerBox.Max.X && newBox.Max.X > playerBox.Min.X &&
                                newBox.Min.Y < playerBox.Max.Y && newBox.Max.X > playerBox.Min.Y &&
                                newBox.Min.Z < playerBox.Max.Z && newBox.Max.X > playerBox.Min.Z)
                            {
                                intersects = true;
                            }
                        }

                        if (!intersects)
                        {
                            localChunkCache.SetBlock(idx, DefinitionManager.Instance.GetBlockDefinitionIndex(definition));

                            ActiveTool.Amount -= 125;
                            if (ActiveTool.Amount <= 0)
                            {
                                Player.Inventory.Remove(ActiveTool);
                                for (int i = 0; i < Player.Tools.Length; i++)
                                {
                                    if (Player.Tools[i] == ActiveTool)
                                    {
                                        Player.Tools[i] = null;
                                    }
                                }
                                ActiveTool = null;
                            }
                        }
                    }

                    // TODO: Fix Interaction ;)
                    //ushort block = _manager.GetBlock(lastApply.Value);
                    //IBlockDefinition blockDefinition = BlockDefinitionManager.GetForType(block);
                    //IItemDefinition itemDefinition = ActiveTool.Definition;

                    //blockDefinition.Hit(blockDefinition, itemDefinition.GetProperties(null));
                    //itemDefinition.Hit(null, blockDefinition.GetProperties(block));
                }

                lastApply = null;
            }

            #endregion
        }