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; }