示例#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);
 }
示例#2
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);
            }
        }
示例#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);
        }
示例#4
0
文件: Track.cs 项目: STPKITT/OpenNFS1
        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;
            }
        }