Ejemplo n.º 1
0
        private static void AddPoints(TsRoadItem road)
        {
            if (!road.HasPoints())
            {
                var startNode = road.GetStartNode();
                var endNode   = road.GetEndNode();

                var newPoints = new List <PointF>();

                var sx = startNode.X;
                var sz = startNode.Z;
                var ex = endNode.X;
                var ez = endNode.Z;

                var radius = Math.Sqrt(Math.Pow(sx - ex, 2) + Math.Pow(sz - ez, 2));

                var tanSx = Math.Cos(-(Math.PI * 0.5f - startNode.Rotation)) * radius;
                var tanEx = Math.Cos(-(Math.PI * 0.5f - endNode.Rotation)) * radius;
                var tanSz = Math.Sin(-(Math.PI * 0.5f - startNode.Rotation)) * radius;
                var tanEz = Math.Sin(-(Math.PI * 0.5f - endNode.Rotation)) * radius;

                for (var i = 0; i < 8; i++)
                {
                    var s = i / (float)(8 - 1);
                    var x = (float)TsRoadLook.Hermite(s, sx, ex, tanSx, tanEx);
                    var z = (float)TsRoadLook.Hermite(s, sz, ez, tanSz, tanEz);
                    newPoints.Add(new PointF(x, z));
                }

                road.AddPoints(newPoints);
            }
        }
Ejemplo n.º 2
0
        public void Parse()
        {
            Version = BitConverter.ToInt32(Stream, 0x0);

            if (Version < 825)
            {
                Log.Msg($"{FilePath} version ({Version}) is too low, min. is 825");
                return;
            }

            var itemCount = BitConverter.ToUInt32(Stream, 0x10);

            if (itemCount == 0)
            {
                _empty = true;
            }
            if (_empty)
            {
                return;
            }

            var lastOffset = 0x14;

            for (var i = 0; i < itemCount; i++)
            {
                var type = (TsItemType)MemoryHelper.ReadUInt32(Stream, lastOffset);
                if (Version <= 825)
                {
                    type++;                 // after version 825 all types were pushed up 1
                }
                switch (type)
                {
                case TsItemType.Road:
                {
                    var item = new TsRoadItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    if (item.Valid)
                    {
                        Mapper.Roads.Add(item);
                    }
                    break;
                }

                case TsItemType.Prefab:
                {
                    var item = new TsPrefabItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    if (item.Valid)
                    {
                        Mapper.Prefabs.Add(item);
                    }
                    break;
                }

                case TsItemType.Company:
                {
                    var item = new TsCompanyItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    if (item.Valid)
                    {
                        Mapper.Companies.Add(item);
                    }
                    break;
                }

                case TsItemType.Service:
                {
                    var item = new TsServiceItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    break;
                }

                case TsItemType.CutPlane:
                {
                    var item = new TsCutPlaneItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    break;
                }

                case TsItemType.City:
                {
                    var item = new TsCityItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    if (item.Valid)
                    {
                        Mapper.Cities.Add(item);
                    }
                    break;
                }

                case TsItemType.MapOverlay:
                {
                    var item = new TsMapOverlayItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    if (item.Valid)
                    {
                        Mapper.MapOverlays.Add(item);
                    }
                    break;
                }

                case TsItemType.Ferry:
                {
                    var item = new TsFerryItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    if (item.Valid)
                    {
                        Mapper.FerryConnections.Add(item);
                    }
                    break;
                }

                case TsItemType.Garage:
                {
                    var item = new TsGarageItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    break;
                }

                case TsItemType.Trigger:
                {
                    var item = new TsTriggerItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    if (item.Valid)
                    {
                        Mapper.Triggers.Add(item);
                    }
                    break;
                }

                case TsItemType.FuelPump:
                {
                    var item = new TsFuelPumpItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    break;
                }

                case TsItemType.RoadSideItem:
                {
                    var item = new TsRoadSideItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    break;
                }

                case TsItemType.BusStop:
                {
                    var item = new TsBusStopItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    break;
                }

                case TsItemType.TrafficRule:
                {
                    var item = new TsTrafficRuleItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    break;
                }

                case TsItemType.TrajectoryItem:
                {
                    var item = new TsTrajectoryItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    break;
                }

                case TsItemType.MapArea:
                {
                    var item = new TsMapAreaItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    if (item.Valid)
                    {
                        Mapper.MapAreas.Add(item);
                    }
                    break;
                }

                default:
                {
                    Log.Msg($"Unknown Type: {type} in {Path.GetFileName(FilePath)} @ {lastOffset}");
                    break;
                }
                }
            }

            var nodeCount = MemoryHelper.ReadInt32(Stream, lastOffset);

            for (var i = 0; i < nodeCount; i++)
            {
                TsNode node = new TsNode(this, lastOffset += 0x04);
                Mapper.UpdateEdgeCoords(node);
                if (!Mapper.Nodes.ContainsKey(node.Uid))
                {
                    Mapper.Nodes.Add(node.Uid, node);
                }
                lastOffset += 0x34;
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Given two roads it search for a path that are inside prefabs between them using a DFS search
        /// </summary>
        private Tuple <bool, float> SetInternalRoutePrefab(TsRoadItem Start, TsRoadItem End)
        {
            TsNode startNode = null;
            Dictionary <TsPrefabItem, bool> visited = new Dictionary <TsPrefabItem, bool>();
            Stack <List <Tuple <TsNode, TsPrefabItem> > > prefabsToCheck = new Stack <List <Tuple <TsNode, TsPrefabItem> > >();
            List <List <Tuple <TsNode, TsPrefabItem> > >  possiblePaths  = new List <List <Tuple <TsNode, TsPrefabItem> > >();

            if (GetNodeByUid(Start.StartNodeUid).BackwardItem.Type == TsItemType.Prefab || GetNodeByUid(Start.StartNodeUid).ForwardItem.Type == TsItemType.Prefab)
            {
                startNode = GetNodeByUid(Start.StartNodeUid);
                var prefab = startNode.BackwardItem.Type == TsItemType.Prefab ? (TsPrefabItem)startNode.BackwardItem : (TsPrefabItem)startNode.ForwardItem;
                var temp   = new List <Tuple <TsNode, TsPrefabItem> >();
                temp.Add(new Tuple <TsNode, TsPrefabItem>(startNode, prefab));
                prefabsToCheck.Push(temp);
            }
            if (GetNodeByUid(Start.EndNodeUid).BackwardItem.Type == TsItemType.Prefab || GetNodeByUid(Start.EndNodeUid).ForwardItem.Type == TsItemType.Prefab)
            {
                startNode = GetNodeByUid(Start.EndNodeUid);
                var prefab = startNode.BackwardItem.Type == TsItemType.Prefab ? (TsPrefabItem)startNode.BackwardItem : (TsPrefabItem)startNode.ForwardItem;
                var temp   = new List <Tuple <TsNode, TsPrefabItem> >();
                temp.Add(new Tuple <TsNode, TsPrefabItem>(startNode, prefab));
                prefabsToCheck.Push(temp);
            }
            while (prefabsToCheck.Count != 0)
            {
                List <Tuple <TsNode, TsPrefabItem> > actualPath   = prefabsToCheck.Pop();
                Tuple <TsNode, TsPrefabItem>         actualPrefab = actualPath.LastOrDefault();

                if (visited.ContainsKey(actualPrefab.Item2))
                {
                    continue;
                }
                visited[actualPrefab.Item2] = true;

                var lastNode = actualPrefab.Item2.NodeIteminPrefab(this, End);
                if (lastNode != null)
                {
                    actualPath.Add(new Tuple <TsNode, TsPrefabItem>(lastNode, null));
                    possiblePaths.Add(actualPath);
                    continue;
                }

                foreach (var prefab in actualPrefab.Item2.NodePrefabinPrefab(this))
                {
                    var newPath = new List <Tuple <TsNode, TsPrefabItem> >(actualPath);
                    newPath.Add(prefab);
                    prefabsToCheck.Push(newPath);
                }
            }
            var returnValue = new Tuple <bool, float>(false, 0);

            foreach (var path in possiblePaths)
            {
                bool  success     = true;
                float totalLength = 0.0f;
                for (int i = 0; i < path.Count - 1; i++)
                {
                    var tempData = AddPrefabPath(path[i].Item2, path[i].Item1, path[i + 1].Item1);
                    if (!tempData.Item1)
                    {
                        success = false;
                        break;
                    }
                    totalLength += tempData.Item2;
                }
                if (success && path.Count >= 1)
                {
                    return(new Tuple <bool, float>(true, totalLength / Start.RoadLook.GetWidth()));
                }
            }
            return(returnValue);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Loads navigation inside TsItem objects
        /// </summary>
        private void LoadNavigation()
        {
            foreach (var prefab in Prefabs)
            {
                foreach (var nodeStr in prefab.Nodes)
                {
                    var           node     = GetNodeByUid(nodeStr);
                    TsItem        road     = null;
                    TsNode        precnode = node;
                    TsItem        precitem = prefab;
                    TsNode        nextnode;
                    TsItem        nextitem;
                    List <TsItem> roads       = new List <TsItem>();
                    var           totalLength = 0.0f;
                    if (node.ForwardItem != null && node.ForwardItem.Type == TsItemType.Road)
                    {
                        road = node.ForwardItem;
                    }
                    else if (node.BackwardItem != null && node.BackwardItem.Type == TsItemType.Road)
                    {
                        road = node.BackwardItem;
                    }
                    if (road != null)
                    {
                        int direction = 0;
                        if (road.EndNodeUid == node.Uid)
                        {
                            direction = 1;
                        }
                        while (road != null && road.Type != TsItemType.Prefab && !road.Hidden)
                        {
                            var        length  = (float)Math.Sqrt(Math.Pow(GetNodeByUid(road.StartNodeUid).X - GetNodeByUid(road.EndNodeUid).X, 2) + Math.Pow(GetNodeByUid(road.StartNodeUid).Z - GetNodeByUid(road.EndNodeUid).Z, 2));
                            TsRoadItem roadObj = (TsRoadItem)road;
                            totalLength += length / roadObj.RoadLook.GetWidth();

                            /*if (roadObj.RoadLook.IsHighway) totalLength += (length / 2) / roadObj.RoadLook.GetWidth();
                             * else if (roadObj.RoadLook.IsLocal) totalLength += (length / 1.75f) / roadObj.RoadLook.GetWidth();
                             * else if (roadObj.RoadLook.IsExpress) totalLength += (length / 1.25f) / roadObj.RoadLook.GetWidth();
                             * else length += length * 2;*/
                            roads.Add(road);
                            if (GetNodeByUid(road.StartNodeUid) == precnode)
                            {
                                nextnode = GetNodeByUid(road.EndNodeUid);
                                precnode = GetNodeByUid(road.EndNodeUid);
                            }
                            else
                            {
                                nextnode = GetNodeByUid(road.StartNodeUid);
                                precnode = GetNodeByUid(road.StartNodeUid);
                            }
                            if (nextnode.BackwardItem == road || nextnode.BackwardItem == precitem)
                            {
                                nextitem = nextnode.ForwardItem;
                                precitem = nextnode.ForwardItem;
                            }
                            else
                            {
                                nextitem = nextnode.BackwardItem;
                                precitem = nextnode.BackwardItem;
                            }
                            road = nextitem;
                        }
                        if (road != null && !road.Hidden)
                        {
                            TsPrefabItem prevPrefab = (TsPrefabItem)prefab;
                            TsPrefabItem nextPrefab = (TsPrefabItem)road;
                            TsRoadLook   look       = ((TsRoadItem)roads.LastOrDefault()).RoadLook;
                            if (prevPrefab.Hidden || nextPrefab.Hidden)
                            {
                                continue;
                            }
                            if (prevPrefab.Navigation.ContainsKey(nextPrefab) == false && (look.IsBidirectional() || direction == 0))
                            {
                                prevPrefab.Navigation.Add(nextPrefab, new Tuple <float, List <TsItem> >(totalLength, roads));
                            }
                            if (nextPrefab.Navigation.ContainsKey(prevPrefab) == false && (look.IsBidirectional() || direction == 1))
                            {
                                var reverse = new List <TsItem>(roads);
                                reverse.Reverse();
                                nextPrefab.Navigation.Add(prevPrefab, new Tuple <float, List <TsItem> >(totalLength, reverse));
                            }
                        }
                    }
                    else if (node.ForwardItem != null && node.BackwardItem != null)
                    {
                        TsPrefabItem forwardPrefab  = (TsPrefabItem)node.ForwardItem;
                        TsPrefabItem backwardPrefab = (TsPrefabItem)node.BackwardItem;
                        if (forwardPrefab.Hidden || backwardPrefab.Hidden)
                        {
                            continue;
                        }
                        if (forwardPrefab.Navigation.ContainsKey(backwardPrefab) == false)
                        {
                            forwardPrefab.Navigation.Add(backwardPrefab, new Tuple <float, List <TsItem> >(0, null));
                        }
                        if (backwardPrefab.Navigation.ContainsKey(forwardPrefab) == false)
                        {
                            backwardPrefab.Navigation.Add(forwardPrefab, new Tuple <float, List <TsItem> >(0, null));
                        }
                    }
                }
            }

            Dictionary <ulong, TsPrefabItem> ferryToPrefab = new Dictionary <ulong, TsPrefabItem>();

            foreach (var port in FerryConnections)
            {
                float        min          = float.MaxValue;
                TsPrefabItem closerPrefab = null;
                foreach (var prefab in Prefabs)
                {
                    float distance = (float)Math.Sqrt(Math.Pow(port.X - prefab.X, 2) + Math.Pow(port.Z - prefab.Z, 2));
                    if (distance < min && prefab.Navigation.Count > 1 && !prefab.Hidden)
                    {
                        min          = distance;
                        closerPrefab = prefab;
                    }
                }
                ferryToPrefab[port.FerryPortId] = closerPrefab;
            }
            foreach (var port in FerryConnections)
            {
                foreach (var connection in LookupFerryConnection(port.FerryPortId))
                {
                    var ports = new List <TsItem>();
                    ports.Add(FerryPortbyId[connection.StartPortToken]);
                    ports.Add(FerryPortbyId[connection.EndPortToken]);
                    ferryToPrefab[connection.StartPortToken].Navigation.Add(ferryToPrefab[connection.EndPortToken], new Tuple <float, List <TsItem> >(connection.Distance, ports));
                    ports.Reverse();
                    ferryToPrefab[connection.EndPortToken].Navigation.Add(ferryToPrefab[connection.StartPortToken], new Tuple <float, List <TsItem> >(connection.Distance, ports));
                }
            }
        }
Ejemplo n.º 5
0
        public void Parse()
        {
            Version = BitConverter.ToInt32(Stream, 0x0); // 853 = 1.31+
            var itemCount = BitConverter.ToUInt32(Stream, 0x10);

            if (itemCount == 0)
            {
                _empty = true;
            }
            if (_empty)
            {
                return;
            }

            var lastOffset = 0x14;

            for (var i = 0; i < itemCount; i++)
            {
                var type = (TsItemType)BitConverter.ToUInt32(Stream, lastOffset);

                switch (type)
                {
                case TsItemType.Road:
                {
                    var item = new TsRoadItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    if (item.Valid)
                    {
                        Mapper.Roads.Add(item);
                    }
                    break;
                }

                case TsItemType.Prefab:
                {
                    var item = new TsPrefabItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    if (item.Valid)
                    {
                        Mapper.Prefabs.Add(item);
                    }
                    break;
                }

                case TsItemType.Company:
                {
                    var item = new TsCompanyItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    if (item.Valid)
                    {
                        Mapper.Companies.Add(item);
                    }
                    break;
                }

                case TsItemType.Service:
                {
                    var item = new TsServiceItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    break;
                }

                case TsItemType.CutPlane:
                {
                    var item = new TsCutPlaneItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    break;
                }

                case TsItemType.City:
                {
                    var item = new TsCityItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    if (item.Valid)
                    {
                        Mapper.Cities.Add(item);
                    }
                    break;
                }

                case TsItemType.MapOverlay:
                {
                    var item = new TsMapOverlayItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    if (item.Valid)
                    {
                        Mapper.MapOverlays.Add(item);
                    }
                    break;
                }

                case TsItemType.Ferry:
                {
                    var item = new TsFerryItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    if (item.Valid)
                    {
                        Mapper.FerryPortbyId.Add(item.FerryPortId, item);
                    }
                    if (item.Valid)
                    {
                        Mapper.FerryConnections.Add(item);
                    }
                    break;
                }

                case TsItemType.Garage:
                {
                    var item = new TsGarageItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    break;
                }

                case TsItemType.Trigger:
                {
                    var item = new TsTriggerItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    break;
                }

                case TsItemType.FuelPump:
                {
                    var item = new TsFuelPumpItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    break;
                }

                case TsItemType.RoadSideItem:
                {
                    var item = new TsRoadSideItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    break;
                }

                case TsItemType.BusStop:
                {
                    var item = new TsBusStopItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    break;
                }

                case TsItemType.TrafficRule:
                {
                    var item = new TsTrafficRuleItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    break;
                }

                case TsItemType.TrajectoryItem:
                {
                    var item = new TsTrajectoryItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    break;
                }

                case TsItemType.MapArea:
                {
                    var item = new TsMapAreaItem(this, lastOffset);
                    lastOffset += item.BlockSize;
                    break;
                }

                default:
                {
                    Log.Msg($"Unknown Type: {type} in {Path.GetFileName(FilePath)} @ {lastOffset}");
                    break;
                }
                }
            }

            var nodeCount = BitConverter.ToInt32(Stream, lastOffset);

            for (var i = 0; i < nodeCount; i++)
            {
                TsNode node = new TsNode(this, lastOffset += 0x04);
                if (!Mapper.Nodes.ContainsKey(node.Uid))
                {
                    Mapper.Nodes.Add(node.Uid, node);
                }
                lastOffset += 0x34;
            }
        }