Ejemplo n.º 1
0
        public void Update(List <AbstractBlock> collidingTerrain)
        {
            OnGround    = false;
            velocity.Y += TEMP_velJump;
            //   velocity.Y -= 0.1f;
            //velocity.X = -0.01f;
            //  if (!OnGround)
            {
                TEMP_velJump -= (9.8f / 200);
            }

            if (position.Y + velocity.Y <= 0)
            {
                TEMP_velJump = 0;
                velocity.Y   = 0;
                //   OnGround = true;
            }

            Matrix rotationMatrix = Matrix.CreateRotationY(rotation.Y);

            Vector3 vec = new Vector3(-1, 0, 0);

            Vector3 transformedReferenceDirection = Vector3.Transform(vec, rotationMatrix);
            Vector3 direction = position + transformedReferenceDirection;

            facingLine = new List <VertexPositionColor>();

            facingLine.Add(new VertexPositionColor(position, Color.Orange));
            facingLine.Add(new VertexPositionColor(direction, Color.Orange));


            //   BoundingBox = new BoundingBox(position + new Vector3(-0.5f, 0, -0.5f), position + new Vector3(0.5f, 2, 0.5f));

            Vector3 desiredVelocity = Vector3.Transform(velocity, rotationMatrix);
            Vector3 desiredPosition = position + desiredVelocity;
            Vector3 TEMP_DrawVel    = new Vector3(desiredVelocity.X, desiredVelocity.Y, desiredVelocity.Z);

            BoundingBox lookAheadBox = new BoundingBox(desiredPosition + new Vector3(-(float)Math.Sqrt(_collisionBox.LengthX / 2), 0, -(float)Math.Sqrt(_collisionBox.LengthZ / 2)), desiredPosition + new Vector3((float)Math.Sqrt(_collisionBox.LengthX / 2), _collisionBox.Height, (float)Math.Sqrt(_collisionBox.LengthZ / 2)));

            //BoundingBox lookAheadBox = new BoundingBox(desiredPosition + new Vector3(-0.5f, 0, -0.5f), desiredPosition + new Vector3(0.5f, 2, 0.5f));

            // bool stopX = false, stopY = false, stopZ = false;
            Ray?mouseRay = null;

            if (TEMP_MouseClick != null && camera != null)
            {
                mouseRay = GetPointRay((Vector2)TEMP_MouseClick, camera);
            }
            float         nearestBlockDist = float.MaxValue;
            AbstractBlock nearestBlock     = null;

            foreach (AbstractBlock block in collidingTerrain)
            {
                BoundingBox voxelBox = new BoundingBox(block.TEMPMinPoint, block.TEMPMaxPoint);

                if (mouseRay != null)
                {
                    float?dist = ((Ray)mouseRay).Intersects(voxelBox);
                    if (dist != null && ((float)dist) < nearestBlockDist)
                    {
                        nearestBlock     = block;
                        nearestBlockDist = (float)dist;
                        //    block.OnHit();
                        //     mouseRay = null;
                    }
                }

                Vector3 nor = new Vector3(desiredVelocity.X, desiredVelocity.Y, desiredVelocity.Z);
                nor.Normalize();

                Vector3 p1 = new Vector3(BoundingBox.Min.X, BoundingBox.Min.Y, BoundingBox.Min.Z);
                Vector3 p2 = new Vector3(BoundingBox.Min.X, BoundingBox.Min.Y, BoundingBox.Max.Z);
                Vector3 p3 = new Vector3(BoundingBox.Max.X, BoundingBox.Min.Y, BoundingBox.Min.Z);
                Vector3 p4 = new Vector3(BoundingBox.Max.X, BoundingBox.Min.Y, BoundingBox.Min.Z);

                List <Ray> rays = new List <Ray>();
                rays.Add(new Ray(p1, nor));
                rays.Add(new Ray(p2, nor));
                rays.Add(new Ray(p3, nor));
                rays.Add(new Ray(p4, nor));
                rays.Add(new Ray(position, nor));

                bool rayIntersects = false;
                foreach (Ray r in rays)
                {
                    if (r.Intersects(voxelBox) != null)
                    {
                        rayIntersects = true;
                        break;
                    }
                }
                if (lookAheadBox.Intersects(voxelBox) || rayIntersects)
                {
                    //1. Get all collision faces for Voxel
                    Dictionary <Direction, BlockCollisionFace> collisionFaces = block.GetCollisionFaceDirections();
                    List <BlockCollisionFace> collisionFaceList = new List <BlockCollisionFace>();
                    Direction firstFace = GetFirstFace(BoundingBox, position, voxelBox);

                    if (firstFace != Direction.NULL && collisionFaces.ContainsKey(firstFace))
                    {
                        collisionFaceList.Add(collisionFaces[firstFace]);
                    }

                    List <BlockCollisionFace> unorderedCollisionFaces = new List <BlockCollisionFace>();

                    foreach (var pair in collisionFaces)
                    {
                        if (pair.Key != firstFace)
                        {
                            unorderedCollisionFaces.Add(pair.Value);
                        }
                    }
                    //2. Order them by distance from position
                    unorderedCollisionFaces = unorderedCollisionFaces.OrderBy(x => x.GetDistanceFrom(position)).ToList <BlockCollisionFace>();
                    collisionFaceList.AddRange(unorderedCollisionFaces);


                    //3. Test for collision. If collision resolve and check further faces against resolved velocity
                    foreach (BlockCollisionFace face in collisionFaceList)//CollisionFace face = collisionFaces[0];
                    {
                        desiredPosition = position + desiredVelocity;
                        lookAheadBox    = new BoundingBox(desiredPosition + new Vector3(-(float)Math.Sqrt(_collisionBox.LengthX / 2), 0, -(float)Math.Sqrt(_collisionBox.LengthZ / 2)), desiredPosition + new Vector3((float)Math.Sqrt(_collisionBox.LengthX / 2), _collisionBox.Height, (float)Math.Sqrt(_collisionBox.LengthZ / 2)));

                        nor = new Vector3(desiredVelocity.X, desiredVelocity.Y, desiredVelocity.Z);
                        if (nor != Vector3.Zero)
                        {
                            nor.Normalize();
                        }

                        rays = new List <Ray>();
                        rays.Add(new Ray(p1, nor));
                        rays.Add(new Ray(p2, nor));
                        rays.Add(new Ray(p3, nor));
                        rays.Add(new Ray(p4, nor));
                        rays.Add(new Ray(position, nor));

                        rayIntersects = false;
                        foreach (Ray r in rays)
                        {
                            if (r.Intersects(voxelBox) != null)
                            {
                                rayIntersects = true;
                                break;
                            }
                        }


                        if (lookAheadBox.Intersects(voxelBox) || rayIntersects)
                        {
                            //NOTE: Collisions disabled
                            //    desiredVelocity = face.ResolveCollisionAABB(lookAheadBox, desiredVelocity);
                        }
                    }
                }
            }

            //if (nearestBlock != null)
            //{
            //    if (TEMP_ColourBlock)
            //    {
            //        if (nearestBlock.BlockTextures[Direction.Up] == TextureName.Stone)
            //        {
            //            nearestBlock.BlockTextures[Direction.Up] = TextureName.Dirt;
            //        }
            //        else
            //        {
            //            nearestBlock.BlockTextures[Direction.Up] = TextureName.Stone;
            //        }

            //        nearestBlock.SetFaces();
            //        nearestBlock.TEMP_RequestBuildBuffers();
            //    }

            //    else if (TEMP_removeBlock)
            //    {
            //         nearestBlock.OnHit();
            //    }
            //    else
            //    {
            //        Direction nearestFaceDirection = Direction.NULL;
            //        float nearestBlockFaceDist = float.MaxValue;
            //        BlockCollisionFace nearestFace = null;
            //        foreach (KeyValuePair<Direction,BlockCollisionFace> face in nearestBlock.GetCollisionFaces())//CollisionFace face = collisionFaces[0];
            //        {
            //            if (mouseRay != null)
            //            {
            //                float? dist = face.Value.Intersects((Ray)mouseRay); //((Ray)mouseRay).Intersects(face.Value.Plane);

            //                if (dist != null && ((float)dist) < nearestBlockFaceDist)
            //                {
            //                    nearestBlockFaceDist = (float)dist;
            //                    nearestFaceDirection = face.Value.Facing;
            //                    nearestFace = face.Value;
            //                }
            //            }

            //        }

            //        if (nearestFace != null&&mouseRay!=null)
            //        {
            //            Vector3 ? pointOnFace=nearestFace.GetRayFaceIntersectionPoint((Ray)mouseRay);
            //            if (pointOnFace != null)
            //            {
            //                Vector3 point = (Vector3)pointOnFace;
            //                //Get nearest wall anchor (i.e val.5)

            //                float xDecimal;
            //                 float yDecimal;
            //                float zDecimal;
            //                //NOTE: Current code makes angle walls difficult to draw
            //                if(point.X>=0)
            //                    xDecimal = (int)point.X + 0.5f;
            //                else
            //                    xDecimal = (int)point.X - 0.5f;

            //                  if(point.Y>=0)
            //                yDecimal= (int)point.Y + 0.5f;
            //                  else
            //                       yDecimal= (int)point.Y - 0.5f;

            //                  if(point.Z>=0)
            //                 zDecimal = (int)point.Z + 0.5f;
            //                else
            //                      zDecimal = (int)point.Z - 0.5f ;

            //                Vector3 wallAnchor = new Vector3(xDecimal, yDecimal, zDecimal);

            //                if (TEMP_secondWallPoint == null)
            //                {
            //                    if (TEMP_firstWallPoint == null)//If no existing point
            //                    {
            //                        TEMP_firstWallPoint = wallAnchor;
            //                    }
            //                    else if ((Vector3)TEMP_firstWallPoint != wallAnchor)//If current point = existing point
            //                    {
            //                        //NOTE: Check that second point is within range of first
            //                        TEMP_secondWallPoint = new Vector3(wallAnchor.X, ((Vector3)TEMP_firstWallPoint).Y, wallAnchor.Z);//Ensure that both points have same Y value
            //                    }
            //                }

            //                if (TEMP_secondWallPoint != null)
            //                {
            //                    if (Math.Abs(((Vector3)TEMP_firstWallPoint).X - ((Vector3)wallAnchor).X) <= 1 &&
            //                       Math.Abs(((Vector3)TEMP_firstWallPoint).Z - ((Vector3)wallAnchor).Z) <= 1 &&
            //                       ((Vector3)TEMP_firstWallPoint).Y == ((Vector3)wallAnchor).Y)
            //                    {
            //                        TEMP_secondWallPoint = wallAnchor;
            //                    }
            //                    else
            //                    {

            //                        //Check that second point is within range of first
            //                        if (Math.Abs(((Vector3)TEMP_firstWallPoint).X - ((Vector3)TEMP_secondWallPoint).X) <= 1 &&
            //                            Math.Abs(((Vector3)TEMP_firstWallPoint).Z - ((Vector3)TEMP_secondWallPoint).Z) <= 1 &&
            //                            ((Vector3)TEMP_firstWallPoint).Y == ((Vector3)TEMP_secondWallPoint).Y)
            //                        {
            //                            for (int i = 1; i <= TEMP_WallHeight; i++)
            //                            {
            //                                ChunkManager.GetInstance().AddWall((Vector3)TEMP_firstWallPoint + new Vector3(0, i - 1, 0), (Vector3)TEMP_secondWallPoint + new Vector3(0, i - 1, 0));
            //                            }

            //                        }
            //                        TEMP_firstWallPoint = TEMP_secondWallPoint;
            //                        TEMP_secondWallPoint = null;
            //                    }
            //                }
            //            }
            //        }

            //       /* if (nearestFaceDirection != Direction.NULL)
            //        {
            //            //NOTE: Need to determine the face that was clicked to determine where to place block
            //            ChunkManager.GetInstance().AddWall(new Vector3(nearestBlock.Position.X + 0.5f, nearestBlock.Position.Y + 0.5f, nearestBlock.Position.Z + 0.5f),
            //                new Vector3(nearestBlock.Position.X + 0.5f, nearestBlock.Position.Y + 0.5f, nearestBlock.Position.Z + 1.5f));

            //         //   nearestBlock.OnAddBlock(nearestFaceDirection, new DirtBlock(BlockShape.Cube, Direction.North));
            //        }*/
            //    }
            //}

            //----Detailed Collision - NOTE: NOT WORKING---------

            // //1. Get all collision faces for Voxel
            // List<CollisionFace> collisionFaces = b.GetCollisionFaces();

            // //2. Order them by distance from position
            //collisionFaces=collisionFaces.OrderBy(x=>x.GetDistanceFrom(position)).ToList<CollisionFace>();

            // //3. Test for collision. If collision resolve and check further faces against resolved velocity
            //foreach (CollisionFace face in collisionFaces)//CollisionFace face = collisionFaces[0];
            //{
            //    desiredVelocity = face.ResolveCollision(_collisionBox, desiredVelocity);
            //}

            movementLines = new List <List <VertexPositionColor> >();
            List <VertexPositionColor> movementLine = new List <VertexPositionColor>();

            movementLine.Add(new VertexPositionColor(position, Color.LightBlue));
            movementLine.Add(new VertexPositionColor((position + /*desiredVelocity*5*/ TEMP_DrawVel), Color.LightBlue));

            movementLines.Add(movementLine);

            xAxisLine = new List <VertexPositionColor>();
            xAxisLine.Add(new VertexPositionColor(position, Color.Red));
            xAxisLine.Add(new VertexPositionColor(new Vector3(position.X + 1, position.Y, position.Z), Color.Red));

            zAxisLine = new List <VertexPositionColor>();
            zAxisLine.Add(new VertexPositionColor(position, Color.Blue));
            zAxisLine.Add(new VertexPositionColor(new Vector3(position.X, position.Y, position.Z + 1), Color.Blue));

            foreach (Vector3 v in _collisionBox.GetVertices())
            {
                List <VertexPositionColor> line = new List <VertexPositionColor>();
                line.Add(new VertexPositionColor(v, Color.LightBlue));
                line.Add(new VertexPositionColor((v + /*desiredVelocity*5*/ TEMP_DrawVel), Color.LightBlue));
                movementLines.Add(line);
            }

            _collisionBox.Update(position, rotation.Y);

            BoundingBox = new BoundingBox(_collisionBox.Position + new Vector3(-(float)Math.Sqrt(_collisionBox.LengthX / 2), 0, -(float)Math.Sqrt(_collisionBox.LengthZ / 2)), _collisionBox.Position + new Vector3((float)Math.Sqrt(_collisionBox.LengthX / 2), _collisionBox.Height, (float)Math.Sqrt(_collisionBox.LengthZ / 2)));

            position = position + desiredVelocity;
        }