Exemple #1
0
 private void PositionCameraAtNode(TrackNode node)
 {
     _cameraNode = node;
     _camera.Position = Engine.Instance.Random.Next() % 2 == 0 ? _cameraNode.GetLeftBoundary() : _cameraNode.GetRightBoundary();
     _camera.Position = _camera.Position + new Vector3(0, Engine.Instance.Random.Next(15, 50), 0);
 }
Exemple #2
0
 public void PlaceOnTrack(Track t, TrackNode startNode)
 {
     Track = t;
     CurrentNode = startNode;
     Position = Vector3.Lerp(startNode.GetLeftVerge(), startNode.GetRightVerge2(), 0.5f);  //center of node
 }
Exemple #3
0
        private void FollowTrackOrientation(TrackNode node, TrackNode nextNode)
        {
            var closestPoint1 = Utility.GetClosestPointOnLine(node.GetLeftBoundary(), node.GetRightBoundary(), Position);
            var closestPoint2 = Utility.GetClosestPointOnLine(nextNode.GetLeftBoundary(), nextNode.GetRightBoundary(), Position);

            var dist = Distance2d(closestPoint1, closestPoint2);
            var carDist = Distance2d(closestPoint1, Position);
            float ratio = Math.Min(carDist / dist, 1.0f);
            TrackPosition = CurrentNode.Number + ratio;

            // if the road is sloping downwards and we have enough speed, unstick from ground
            if (node.Slope - nextNode.Slope > 50 && Speed > 100 && _isOnGround)
            {
                _isOnGround = false;
                _upVelocity = -0.4f;
            }

            if (_isOnGround)
            {
                Up = Vector3.Lerp(node.Up, nextNode.Up, ratio);
                Up = Vector3.Normalize(Up);
                Direction = Vector3.Cross(Up, Right);
                Direction.Normalize();
            }

            _currentHeightOfTrack = MathHelper.Lerp(closestPoint1.Y, closestPoint2.Y, ratio);
            if (_currentHeightOfTrack == -9999)
            {
                throw new Exception();
            }
            if (_isOnGround)
            {
                var newPosition = Position;
                newPosition.Y = _currentHeightOfTrack;
                Position = newPosition;
            }
            //GameConsole.WriteLine("height: " + _position.Y, 0);
            //GameConsole.WriteLine("ratio: " + ratio, 1);
        }
Exemple #4
0
        void ParseTrackNodesBlock(BinaryReader reader)
        {
            reader.BaseStream.Position = 2444;  //start of node list

            TrackNode prevNode = null;

            for (int i = 0; i < 2400; i++)
            {
                var node = new TrackNode();
                node.Number = Nodes.Count;
                float vergeScale = 8000;

                node.DistanceToLeftVerge = reader.ReadByte();
                node.DistanceToLeftVerge *= GameConfig.TerrainScale * vergeScale;
                node.DistanceToRightVerge = reader.ReadByte();
                node.DistanceToRightVerge *= GameConfig.TerrainScale * vergeScale;
                node.DistanceToLeftBarrier = reader.ReadByte();
                node.DistanceToLeftBarrier *= GameConfig.TerrainScale * vergeScale;
                node.DistanceToRightBarrier = reader.ReadByte();
                node.DistanceToRightBarrier *= GameConfig.TerrainScale * vergeScale;

                node.Flag1 = reader.ReadByte();
                node.Flag2 = reader.ReadByte();
                node.Flag3 = reader.ReadByte();
                node.NodeProperty = reader.ReadByte();

                // unused trackNodes are filled with zeroes, so stop when we have a node with a zero position
                if (node.DistanceToLeftVerge == 0 && node.DistanceToRightVerge == 0
                    && node.DistanceToLeftBarrier == 0 && node.DistanceToRightBarrier == 0)
                {
                    break;
                }

                //Debug.WriteLine("{0},{1},{2},{3}", node.b[0], node.b[1], node.b[2], node.b[3]);

                node.Position = new Vector3(reader.ReadInt32(), reader.ReadInt32(), -reader.ReadInt32()) * GameConfig.TerrainScale;

                // Slope is stored as a 2's complement value.  Convert it back to signed value
                Int16 slope = reader.ReadInt16();
                //bool msbSet = (slope & (0x1 << 13)) != 0;
                //if (msbSet)
                //{
                //	slope = (short)~slope;
                //	slope++;
                //	slope *= -1;
                //}
                if (slope > 0x2000)
                {
                    slope -= 0x3FFF;
                }

                node.Slope = slope;

                node.Slant = reader.ReadInt16(); //weird slant-A

                float orientation = (float)reader.ReadInt16();
                //convert to signed degrees
                //0 = forwards, 0x1000 = right, 0x2000 = back, 0x3000 = left, 0x3FFF back to forwards

                if (orientation > 0x2000)
                {
                    orientation -= 0x3FFF;
                }
                node.Orientation = ((orientation / 0x3FFF) * -360);

                node.unk1 = reader.ReadBytes(2);
                node.ZOrientation = reader.ReadInt16();
                node.Slant = reader.ReadInt16(); // slant-B
                node.XOrientation = reader.ReadInt16();
                node.unk2 = reader.ReadBytes(2);

                if (prevNode != null)
                {
                    prevNode.Next = node;
                    node.Prev = prevNode;
                }
                prevNode = node;
                Nodes.Add(node);
            }

            // If this is a circuit track, hook the last node up to the first
            if (Vector3.Distance(Nodes[0].Position, Nodes[Nodes.Count - 1].Position) > 100)
            {
                IsOpenRoad = true;
            }
            else
            {
                prevNode.Next = Nodes[0];
                Nodes[0].Prev = prevNode;
            }

            for (int i = 0; i < Nodes.Count - 1; i++)
            {
                var node = Nodes[i];
                var normal = Vector3.Cross(node.GetRightBoundary() - node.GetLeftBoundary(),
                    node.Next.Position - node.GetLeftBoundary());
                node.Up = Vector3.Normalize(normal);
            }
        }
Exemple #5
0
 // add a driver to the race, placing him in a starting grid
 public void AddDriver(IDriver d, TrackNode startNode)
 {
     d.Vehicle.PlaceOnTrack(Track, startNode);
     if (d is TrafficDriver)
     {
     }
     else if (d is RacingAIDriver || d is PlayerDriver)
     {
         // place on starting grid
         int lane = (Drivers.Count % 2 == 0 ? AIDriver.MaxVirtualLanes - 1 : 1);
         if (d is RacingAIDriver)
         {
             ((RacingAIDriver)d).VirtualLane = lane;
         }
         Vector3 pos = d.Vehicle.CurrentNode.Position;
         pos.Z -= Drivers.Count * 30;
         pos.X = Vector3.Lerp(d.Vehicle.CurrentNode.GetLeftVerge2(), d.Vehicle.CurrentNode.GetRightVerge2(), (float)lane / (AIDriver.MaxVirtualLanes)).X;
         d.Vehicle.Position = pos;
     }
     Drivers.Add(d);
 }
Exemple #6
0
        public void Render(Vector3 cameraPosition, TrackNode currentNode)
        {
            _skybox.Render();
            _effect.View = Engine.Instance.Camera.View;
            _effect.Projection = Engine.Instance.Camera.Projection;
            _effect.World = Matrix.Identity;

            int segmentIndex = currentNode.Number / 4;
            var startSegment = TerrainSegments[segmentIndex];

            var renderedSegments = new List<TerrainSegment>();

            Engine.Instance.Device.SetVertexBuffer(TerrainVertexBuffer);
            _effect.CurrentTechnique.Passes[0].Apply();
            Engine.Instance.Device.RasterizerState = RasterizerState.CullNone;
            Engine.Instance.Device.SamplerStates[0] = GameConfig.WrapSampler;

            var frustum = new BoundingFrustum(Engine.Instance.Camera.View * Engine.Instance.Camera.Projection);

            // draw segments from the player vehicle forwards. Stop when a segment is out of view
            var segment = startSegment;
            for (int i = 0; i < GameConfig.MaxSegmentRenderCount; i++)
            {
                if (segment == null) break;
                if (frustum.Intersects(segment.BoundingBox))
                {
                    RenderSegment(segment);
                    renderedSegments.Add(segment);
                }
                else
                {
                    break;
                }
                segment = segment.Next;
            }

            // draw segments from the player vehicle backwards. Stop when a segment is out of view
            segment = startSegment.Prev;
            for (int i = 0; i < GameConfig.MaxSegmentRenderCount; i++)
            {
                if (segment == null) break;
                if (frustum.Intersects(segment.BoundingBox))
                {
                    RenderSegment(segment);
                    renderedSegments.Add(segment);
                }
                segment = segment.Prev;
            }

            DrawScenery(renderedSegments);

            if (FenceVertexBuffer != null)
            {
                Engine.Instance.Device.SetVertexBuffer(FenceVertexBuffer);
                _effect.World = Matrix.Identity;
                _effect.CurrentTechnique.Passes[0].Apply();
                Engine.Instance.Device.SamplerStates[0] = GameConfig.WrapSampler;
                foreach (var renderedSegment in renderedSegments)
                {
                    DrawFenceStrips(renderedSegment);
                }
            }

            if (GameConfig.DrawDebugInfo)
            {
                var node = currentNode;
                for (int i = 0; i < GameConfig.MaxSegmentRenderCount; i++)
                {
                    Engine.Instance.GraphicsUtils.AddCube(Matrix.CreateTranslation(node.GetLeftBoundary()), Color.Red);
                    Engine.Instance.GraphicsUtils.AddCube(Matrix.CreateTranslation(node.GetRightBoundary()), Color.Red);
                    Engine.Instance.GraphicsUtils.AddCube(Matrix.CreateTranslation(node.GetLeftVerge()), Color.Blue);
                    Engine.Instance.GraphicsUtils.AddCube(Matrix.CreateTranslation(node.GetRightVerge()), Color.Blue);
                    Engine.Instance.GraphicsUtils.AddCube(Matrix.CreateTranslation(node.Position), Color.Yellow);

                    if (node.Number % TriFile.NbrRowsPerSegment == 0)
                    {
                        Engine.Instance.GraphicsUtils.AddLine(node.GetLeftBoundary(), node.GetRightBoundary(), Color.White);
                    }

                    node = node.Next;
                    if (node == null) break;
                }

                GameConsole.WriteLine(String.Format("Position node: {0}, segment: {1}", currentNode.Number, (int)(currentNode.Number / TriFile.NbrRowsPerSegment)));
                GameConsole.WriteLine(String.Format("Node property: {0}, flags: {1}, {2}, {3}", currentNode.NodeProperty, currentNode.Flag1, currentNode.Flag2, currentNode.Flag3));
            }
        }
Exemple #7
0
        public float GetHeightAtPoint(TrackNode node, Vector3 point)
        {
            Vector3 a = node.GetLeftBoundary();
            Vector3 b = node.GetRightBoundary();
            Vector3 c = node.Next.GetRightBoundary();
            Vector3 d = node.Next.GetLeftBoundary();
            Vector3 hitLoc;
            float t;

            Vector3 pos = point; pos.Y += 100;
            if (Utility.FindRayTriangleIntersection(ref pos, Vector3.Down, 1000f, ref a, ref b, ref c, out hitLoc, out t))
            {
                return hitLoc.Y;
            }
            else if (Utility.FindRayTriangleIntersection(ref pos, Vector3.Down, 1000f, ref a, ref c, ref d, out hitLoc, out t))
            {
                return hitLoc.Y;
            }
            else
            {
                return -9999;
            }
        }
Exemple #8
0
 public static Vector3 GetRoadOffsetPosition(TrackNode roadNode, float offset)
 {
     Vector3 position = roadNode.Position + Utility.RotatePoint(new Vector2(offset, 0), -roadNode.Orientation);
     return position;
 }