コード例 #1
0
    public static void create(long key, WayReference endPoint, string materialId)
    {
        bool isNode1 = endPoint.isNode1(NodeIndex.getPosById(key));
        bool isSmall = endPoint.SmallWay;

        Vector3 originalScale = endPoint.gameObject.transform.localScale;
        Vector3 nodeCameraPos = Game.getCameraPosition(isNode1 ? endPoint.node1 : endPoint.node2);

        Vector3 fromPos = nodeCameraPos - new Vector3(0f, originalScale.y / 2f, 0f);
        Vector3 toPos   = fromPos + new Vector3((isSmall ? originalScale.x / 2f : originalScale.y / 2f), originalScale.y, 0f);

        GameObject endPointObj = MapSurface.createPlaneMeshForPoints(fromPos, toPos, MapSurface.Anchor.LEFT_CENTER);

        endPointObj.name = "End of way (" + key + ")";
        Vector3 zOffset = new Vector3(0, 0, Game.WAYS_Z_POSITION);

        endPointObj.transform.position = endPointObj.transform.position + zOffset - (isNode1 ? Vector3.zero : endPoint.transform.rotation * new Vector3(isSmall ? originalScale.x / 2f : originalScale.y / 2f, 0f, 0f));
        endPointObj.transform.parent   = Game.instance.waysParent;
        endPointObj.transform.rotation = endPoint.transform.rotation;
        AutomaticMaterialObject endPointMaterialObject = endPointObj.AddComponent <AutomaticMaterialObject> () as AutomaticMaterialObject;

        endPointMaterialObject.requestMaterial(materialId, null);          // TODO - Default material

        // Add rigidbody and mesh collider, so that they will fall onto the underlying plane
        Misc.AddGravityToWay(endPointObj);
        Misc.AddWayObjectComponent(endPointObj);
    }
コード例 #2
0
        public void RotatePoint()
        {
            var map = new MapSurface();

            map.SetRotation(Math.PI / 2);

            // Rotate about center point 500, 500 -> 0, 0
            map.Rotate_point(1000.0, 0.0, out var toX, out var toY);
            toX.Should().BeApproximately(0.0, 0.0000001);
            toY.Should().BeApproximately(0.0, 0.0000001);
        }
コード例 #3
0
    private void ResetMap()
    {
        MapLevel.ResetArrows();

        var levelInfo = levelGrid[playerPos.x, playerPos.y];

        // Set new positions
        Map.transform.position = levelInfo.Pos;
        Player.FruitEntity.transform.position = levelInfo.Pos;

        MapSurface.ClearSurface();
    }
コード例 #4
0
    // Use this for initialization
    void Start()
    {
        // Grab props from MapSurface
        MapSurface mapSurface = GetComponent <MapSurface>();

        center   = mapSurface.calculatedCenter;
        rotation = mapSurface.calculatedRotation;
        width    = mapSurface.calculatedWidth;
        height   = mapSurface.calculatedHeight;

        // TODO - Doesn't really work right now - continue this later with a fresh mind...
        createLines();
    }
コード例 #5
0
        public void ZeroRotationDoesNotMovepoint(double testX, double testY)
        {
            var map = new MapSurface();

            map.SetRotation(0);

            // Rotate/unrotate about center point 500, 500

            map.Rotate_point(testX, testY, out var toX, out var toY);

            toX.Should().BeApproximately(testX, 0.0000001);
            toY.Should().BeApproximately(testY, 0.0000001);
        }
コード例 #6
0
    private void createLines()
    {
        GameObject linesParent = new GameObject("Lines");

        linesParent.transform.parent        = transform;
        linesParent.transform.localPosition = center + new Vector3(0f, 0f, -0.01f);

        // Side lines
        Vector3    sideLineOuter = new Vector3(LINE_THICKNESS, 0f, 0f);
        Vector3    sideLineInner = new Vector3(width - LINE_THICKNESS, LINE_THICKNESS, 0f);
        GameObject leftLine      = MapSurface.createPlaneMeshForPoints(sideLineOuter, sideLineInner);
        GameObject rightLine     = MapSurface.createPlaneMeshForPoints(sideLineOuter, sideLineInner);

        // Use WayLine for setting white material
        WayLine.SetWhiteMaterial(leftLine);
        WayLine.SetWhiteMaterial(rightLine);

        // Locate left line correctly
        leftLine.name                    = "Left outer";
        leftLine.transform.parent        = linesParent.transform;
        leftLine.transform.localPosition = (Quaternion.Euler(0f, 0f, rotation) * new Vector3(-LINE_THICKNESS, -height / 2f + LINE_THICKNESS * 1.5f, 0f));
        leftLine.transform.rotation      = Quaternion.Euler(0f, 0f, rotation);

        // Locate right line correctly
        rightLine.name                    = "Right outer";
        rightLine.transform.parent        = linesParent.transform;
        rightLine.transform.localPosition = (Quaternion.Euler(0f, 0f, rotation) * new Vector3(LINE_THICKNESS, height / 2f - LINE_THICKNESS * 1.5f, 0f));
        rightLine.transform.rotation      = Quaternion.Euler(0f, 0f, rotation);

        // Goal lines
        Vector3    goalLineOuter = new Vector3(0f, LINE_THICKNESS, 0f);
        Vector3    goalLineInner = new Vector3(LINE_THICKNESS, height - LINE_THICKNESS, 0f);
        GameObject goalLineClose = MapSurface.createPlaneMeshForPoints(goalLineOuter, goalLineInner);
        GameObject goalLineFar   = MapSurface.createPlaneMeshForPoints(goalLineOuter, goalLineInner);

        // Use WayLine for setting white material
        WayLine.SetWhiteMaterial(goalLineClose);
        WayLine.SetWhiteMaterial(goalLineFar);

        // Locate close goal line correctly
        goalLineClose.name                    = "Close goal line";
        goalLineClose.transform.parent        = linesParent.transform;
        goalLineClose.transform.localPosition = (Quaternion.Euler(0f, 0f, rotation) * new Vector3(-width / 2f + LINE_THICKNESS * 1.5f, -LINE_THICKNESS, 0f));
        goalLineClose.transform.rotation      = Quaternion.Euler(0f, 0f, rotation);

        // Locate far goal line correctly
        goalLineFar.name                    = "Far goal line";
        goalLineFar.transform.parent        = linesParent.transform;
        goalLineFar.transform.localPosition = (Quaternion.Euler(0f, 0f, rotation) * new Vector3(width / 2f - LINE_THICKNESS * 1.5f, LINE_THICKNESS, 0f));
        goalLineFar.transform.rotation      = Quaternion.Euler(0f, 0f, rotation);
    }
コード例 #7
0
    private GameObject getLineForWay(Vector3 way, float lineHeight = -1f)
    {
        Vector3 fromPos = -way / 2;
        Vector3 toPos   = way / 2;

        if (lineHeight == -1f)
        {
            lineHeight = GetLineHeight();
        }

        toPos = new Vector3(toPos.x, fromPos.y + lineHeight, toPos.z);

        return(MapSurface.createPlaneMeshForPoints(fromPos, toPos));
    }
コード例 #8
0
        public void RotatePointRoundtrip(double testX, double testY)
        {
            var map = new MapSurface();

            map.SetRotation(Math.PI / 2);

            // Rotate/unrotate about center point 500, 500 -> 1000, 0

            map.Rotate_point(testX, testY, out var toX, out var toY);
            map.Un_rotate_point(toX, toY, out var toX2, out var toY2);

            toX2.Should().BeApproximately(testX, 0.0000001);
            toY2.Should().BeApproximately(testY, 0.0000001);
        }
コード例 #9
0
        /* TODO ColorPaletteClassType()
         * private TICDisplayPaletteBaseClass ColorPaletteClassType()
         *  {
         *  case FMode of
         *    ...Height                  : Result  = TICDisplayPalette_Height;
         *    ...CCV                     : Result  = TICDisplayPalette_CCV;
         *    ...CCVPercent              : Result  = TICDisplayPalette_CCVPercent;
         *    ...Latency                 : Result  = TICDisplayPalette_RadioLatency;
         *    ...PassCount               : Result  = TICDisplayPalette_PassCount;
         *    ...PassCountSummary        : Result  = TICDisplayPalette_PassCountSummary;  // Palettes are fixed three color palettes - display will use direct transitions
         *    ...RMV                     : Result  = TICDisplayPalette_RMV;
         *    ...Frequency               : Result  = TICDisplayPalette_Frequency;
         *    ...Amplitude               : Result  = TICDisplayPalette_Amplitude;
         *    ...CutFill                 : Result  = TICDisplayPalette_CutFill;
         *    ...Moisture                : Result  = TICDisplayPalette_Moisture;
         *    ...TemperatureSummary      : Result  = TICDisplayPaletteBase; //TICDisplayPalette_Temperature;
         *    ...GPSMode                 : Result  = TICDisplayPaletteBase; //TICDisplayPalette_GPSMode;
         *    ...CCVSummary              : Result  = TICDisplayPaletteBase; //TICDisplayPalette_CCVSummary;
         *    ...CCVPercentSummary       : Result  = TICDisplayPalette_CCVPercent;
         *    ...CompactionCoverage      : Result  = TICDisplayPalette_CoverageOverlay;
         *    ...VolumeCoverage          : Result  = TICDisplayPalette_VolumeOverlay;
         *    ...MDP                     : Result  = TICDisplayPalette_MDP; // ajr15167
         *    ...MDPSummary              : Result  = TICDisplayPaletteBase;
         *    ...MDPPercent              : Result  = TICDisplayPalette_MDPPercent;
         *    ...MDPPercentSummary       : Result  = TICDisplayPalette_MDPPercent;
         *    ...MachineSpeed            : Result  = TICDisplayPalette_MachineSpeed;
         *    ...CCVPercentChange        : Result  = TICDisplayPalette_CCVPercent;
         *    ...TargetThicknessSummary  : Result  = TICDisplayPalette_VolumeOverlay;
         *    ...TargetSpeedSummary      : Result  = TICDisplayPalette_SpeedSummary;
         *    ...CCVChange               : Result  = TICDisplayPalette_CCVChange;
         *    ...CCA                     : Result  = TICDisplayPalette_CCA;
         *    ...CCASummary              : Result  = TICDisplayPalette_CCASummary;
         *
         *  else
         *    SIGLogMessage.PublishNoODS(Self, Format('ColorPaletteClassType: Unknown display type: %d', [Ord(FMode)]), ...Assert);
         *    Result  = TICDisplayPaletteBase;
         *  end;
         * end;
         */

        /* TODO: ComputeCCAPalette
         * function ComputeCCAPalette :Boolean;
         * var
         *  I, J, K               :Integer;
         *  ResponseVerb        :...VerbBase;
         *  ServerResult        :TICServerRequestResult;
         *  ResponseDataStream  :TStream;
         *  CCAMinimumPasses    :...CCAMinPassesValue;
         *  CCAColorScale       :...CCAColorScale;
         *  CCAPalette          :TColorPalettes;
         *
         * begin
         *  Result  = False;
         *
         *  ResponseVerb  = nil;
         *  try
         *    if Length(FFilter1.Machines) > 0 then
         *      FMachineID  = FFilter1.Machines[0].ID // Must be set by caller
         *    else
         *      FMachineID  = -1; // will fail call
         *    if not Assigned(ASNodeImplInstance) or ASNodeImplInstance.ServiceStopped then
         *      begin
         *        SIGLogMessage.PublishNoODS(Self, Format('%s.Execute: Aborting request as service has been stopped', [Self.ClassName]), ...Warning);
         *        Exit;
         *      end;
         *
         *    ASNodeImplInstance.PSLoadBalancer.LoadBalancedPSService.GetMachineCCAMinimumPassesValue(FDataModelID, FMachineID, FFilter1.StartTime, FFilter1.EndTime, FFilter1.LayerID, ResponseVerb);
         *    if Assigned(ResponseVerb) then
         *      with ResponseVerb as ...Verb_SendResponse do
         *        begin
         *          ServerResult  = TICServerRequestResult(ResponseCode);
         *      ResponseDataStream  = ResponseData;
         *          if (ServerResult = ...NoError) and assigned(ResponseData) then
         *            begin
         *              CCAMinimumPasses  = ReadSmallIntFromStream(ResponseDataStream);
         *
         *      Result  = CCAMinimumPasses > 0;
         *
         *              if not Result then
         *                Exit;
         *
         *      CCAColorScale  = ...CCAColorScaleManager.CreateCoverageScale(CCAMinimumPasses);
         *              try
         *                SetLength(CCAPalette.Transitions, CCAColorScale.TotalColors);
         *
         *      J  = Low(CCAPalette.Transitions);
         *      k  = High(CCAPalette.Transitions);
         *                for I  = J to K do
         *                  begin
         *                    CCAPalette.Transitions[I].Color  = CCAColorScale.ColorSegments[K - I].Color;
         *      CCAPalette.Transitions[I].Value   = I+1;
         *                  end;
         *                CCAPalette.ConvertRGBToBGR; // gets done again but needed to match Anatoli palette test :)
         *                WorkingColorPalette.PopulateFromPaletteColors(CCAPalette);
         *                WorkingColorPalette.TransitionColors.ValuesCount  = Length(CCAPalette.Transitions);
         *              finally
         *                if Assigned(CCAColorScale) then
         *                  FreeAndNil(CCAColorScale);
         *      end;
         *            end
         *          else
         *            SIGLogMessage.PublishNoODS(Self, Format('%s.Execute: GetMachineCCAMinimumPassesValue Failed for InternalSiteModelMachineIndex: %d. ReturnCode:%d', [Self.ClassName, FMachineID, Ord(ServerResult)]), ...Warning);
         *        end;
         *  finally
         *    if Assigned(ResponseVerb) then
         *      FreeAndNil(ResponseVerb);
         *      end;
         * end;
         */

        /* TODO: CreateAndInitialiseWorkingColorPalette
         * function CreateAndInitialiseWorkingColorPalette :Boolean;
         * begin
         * Result  = True;
         *
         * // Create a scaled palette to use when rendering the data
         * try
         *   if ColorPaletteClassType<> Nil then
         *    begin
         *
         *       WorkingColorPalette  = ColorPaletteClassType.Create;
         *       WorkingColorPalette.SmoothPalette  = FMode = ...CutFill;
         *
         *       // CCASummary is done per machine id
         *       if FMode in [...CCA, ...CCASummary]
         *     then
         *         Result  = ComputeCCAPalette
         *       else
         *         begin
         *           if Length(FColorPalettes.Transitions) = 0 then
         *             WorkingColorPalette.SetToDefaults
         *           else
         *             WorkingColorPalette.PopulateFromPaletteColors(FColorPalettes);
         *     end;
         *
         *       if Result then
         *         WorkingColorPalette.ComputePalette;
         *     end
         *   else
         *     WorkingColorPalette  = Nil;
         *
         * Except
         *   On e:Exception do
         *     SIGLogMessage.PublishNoODS(Self, Format('%s.Execute: Error: %s ', [Self.ClassName, e.Message]), ...Exception);
         * end;
         * end;
         */

        /// <summary>
        /// Renders all sub grids in a representational style that indicates where there is data, but nothing else. This is used for large scale displays
        /// (zoomed out a lot) where meaningful detail cannot be drawn on the tile
        /// </summary>
        private SKBitmap RenderTileAsRepresentationalDueToScale(ISubGridTreeBitMask overallExistenceMap)
        {
            using (var RepresentationalDisplay = PVMDisplayerFactory.GetDisplayer(Mode /*, FICOptions*/))
            {
                using (var mapView = new MapSurface {
                    SquareAspect = false
                })
                {
                    mapView.SetRotation(TileRotation);

                    RepresentationalDisplay.MapView = mapView;

                    RepresentationalDisplay.MapView.SetBounds(NPixelsX, NPixelsY);
                    RepresentationalDisplay.MapView.SetWorldBounds(NEECoords[0].X, NEECoords[0].Y,
                                                                   NEECoords[0].X + WorldTileWidth, NEECoords[0].Y + WorldTileHeight, 0);

                    // Iterate over all the bits in the sub grids drawing a rectangle for each one on the tile being rendered
                    if (overallExistenceMap.ScanSubGrids(RotatedTileBoundingExtents,
                                                         leaf =>
                    {
                        leaf.CalculateWorldOrigin(out var WorldOriginX, out var WorldOriginY);

                        (leaf as SubGridTreeLeafBitmapSubGrid)?.Bits.ForEachSetBit((x, y) =>
                        {
                            RepresentationalDisplay.MapView.DrawRect(WorldOriginX + (x * overallExistenceMap.CellSize),
                                                                     WorldOriginY + (y * overallExistenceMap.CellSize),
                                                                     overallExistenceMap.CellSize, overallExistenceMap.CellSize, true, RepresentColor);
                        });

                        return(true);
                    }))
                    {
                        // Remove the canvas from the map view to prevent it's disposal (it's being returned to the caller)
                        var canvas = RepresentationalDisplay.MapView.BitmapCanvas;
                        RepresentationalDisplay.MapView.BitmapCanvas = null;
                        return(canvas);
                    }
                }
            }

            return(null); // It did not work out...
        }
コード例 #10
0
    public void createBuildingWithXMLNode(XmlNode xmlNode)
    {
        if (xmlNode != null)
        {
//			this.gameObject.name = "BuildingRoof (" + xmlNode.Attributes.GetNamedItem ("id").Value + ")";
            this.id = xmlNode.Attributes.GetNamedItem("id").Value;
            this.gameObject.name = "Building (" + id + ")";
            Rigidbody buildingRigidBody = this.gameObject.AddComponent <Rigidbody>();
            Misc.SetGravityState(this.gameObject, false);

            // Create the roof and set its layer
            roof = new GameObject("BuildingRoof (" + xmlNode.Attributes.GetNamedItem("id").Value + ")");
            roof.transform.parent        = this.transform;
            roof.transform.localPosition = Vector3.zero;
            MapSurface roofSurface = roof.AddComponent <MapSurface>();
            roof.AddComponent <BuildingRoofLayer>();
            roofSurface.createMesh(xmlNode);
            roofSurface.createMeshCollider(false);
        }
    }
コード例 #11
0
        public void Creation()
        {
            var map = new MapSurface();

            map.Should().NotBeNull();
        }
コード例 #12
0
    private static void addMeshToGameObject(GameObject gameObject, Vector2[] vertices2D)
    {
        // Use the triangulator to get indices for creating triangles
        Triangulator tr = new Triangulator(vertices2D);

        int[] indices = tr.Triangulate();

        // Create the Vector3 vertices
        Vector3[] vertices = new Vector3[vertices2D.Length];
        for (int i = 0; i < vertices.Length; i++)
        {
            vertices[i] = new Vector3(vertices2D[i].x, vertices2D[i].y, 0);
        }

        // Create the mesh
        Mesh msh = new Mesh();

        msh.vertices  = vertices;
        msh.triangles = indices;
        msh.uv        = vertices2D;
        msh.RecalculateNormals();
        msh.RecalculateBounds();

        // Calculate mesh area
        float area = Misc.getMeshArea(msh);

        gameObject.AddComponent <MeshArea>().area = area;

        // Add center point to the surface
        MapSurface mapSurface = gameObject.GetComponent <MapSurface>();

        if (mapSurface == null)
        {
            mapSurface = gameObject.AddComponent <MapSurface>();
        }
        mapSurface.calculatedCenter = Misc.GetCenterOfVectorList(vertices2D);
        mapSurface.rect             = Misc.GetRectOfVectorList(vertices2D);

        // Try to guess a rotation and width/height - will only really be applicable for the simplest forms (rectangular'ish)
        // Assume that the rotation is where the longest single line is
        Vector2 longestVector = Misc.GetLongestDistanceVector(vertices2D);
        float   zRotation     = Quaternion.FromToRotation(Vector3.right, longestVector).eulerAngles.z;

        // Debug.Log("Z1: " + Quaternion.FromToRotation(Vector3.right, longestVector).eulerAngles.z + ", Z2: " + Misc.ToDegrees(Mathf.Atan(longestVector.y / longestVector.x)));
        mapSurface.calculatedRotation = zRotation;

        // Debug.Log("Longest vector:");
        // DebugFn.print(longestVector);
        // Debug.Log("Deg: " + mapSurface.calculatedRotation);

        Vector2 longestVectorApprox90Deg = Misc.GetLongestDistanceVector90DegXFrom(vertices2D, mapSurface.calculatedRotation, 15f);

        // Debug.Log("Diff°:" + Quaternion.FromToRotation(longestVector, longestVectorApprox90Deg).eulerAngles.z);
        mapSurface.calculatedWidth  = longestVector.magnitude;
        mapSurface.calculatedHeight = longestVectorApprox90Deg.magnitude;

//		Vector3[] normals = msh.normals;
//		for (int i = 0; i < normals.Length; i++) {
//			normals[i] = normal;
//		}
//		msh.SetNormals (normals.ToList ());
////		msh.RecalculateNormals();
////		msh.RecalculateBounds();

        // Set up game object with mesh;
        gameObject.AddComponent(typeof(MeshRenderer));
        MeshFilter filter = gameObject.AddComponent(typeof(MeshFilter)) as MeshFilter;

        filter.mesh = msh;
    }
コード例 #13
0
    // Update is called once per frame
    public void Update()
    {
        switch (GameState)
        {
        case State.Init:
            break;

        case State.Play:

            if (Player == null || Countdown <= 0)
            {
                mapTimer.Stop();
                GameOver(false);
            }

            foreach (var bot in spawnedBots)
            {
                if (bot == null)
                {
                    continue;
                }

                var other = bot.GetComponentInChildren <FruitEntity>();

                if (other == null || other.Squishes == null || Player == null ||
                    Player.FruitEntity == null || Player.FruitEntity.Squishes == null)
                {
                    continue;
                }

                if (Player.FruitEntity.Squishes.Eatable(other))
                {
                    other.DisplaySquishIndicator(false);
                }
                else if (other.Squishes.Eatable(Player.FruitEntity))
                {
                    other.DisplaySquishIndicator(true);
                }
                else
                {
                    other.HideSquishIndicator();
                }
            }

            PlayerCoverage = MapSurface.PaintCoverage(Player.FruitEntity.Color);
            // Player has enough coverage
            if (PlayerCoverage >= CoverageWinPerc)
            {
                mapTimer.Stop();

                KillAllBots();

                // Complete Level
                var levelInfo = levelGrid[playerPos.x, playerPos.y];
                levelGrid[playerPos.x, playerPos.y].Completed = true;
                levelsCompleted++;

                Game.Find().UIManager.SetLevelCompleted(levelInfo.Id);

                if (levelsCompleted == GridSize * GridSize)
                {
                    GameOver(true);
                }

                Player.FruitEntity.transform.position = levelInfo.Pos;

                StartTravelState();
            }
            break;

        case State.Travel:
            PlayerCoverage = MapSurface.PaintCoverage(Player.FruitEntity.Color);
            break;
        }
    }
コード例 #14
0
    private static void CreateCurvedDashedLines(GameObject parent, long key, List <WayReference> wayReferences)
    {
        GameObject curveDashedLines = new GameObject();

        curveDashedLines.name = "Curved dashed lines";
        curveDashedLines.transform.SetParent(parent.transform);
        curveDashedLines.transform.localPosition = Vector3.zero;

        Pos     centerPos   = NodeIndex.getPosById(key);
        Vector3 posPosition = Game.getCameraPosition(centerPos);

        WayReference firstReference  = wayReferences [0];
        WayReference secondReference = wayReferences [1];

        bool firstIsNode1  = firstReference.isNode1(centerPos);
        bool secondIsNode1 = secondReference.isNode1(centerPos);

        GameObject wayFirst  = firstReference.gameObject;
        GameObject waySecond = secondReference.gameObject;

        // Number of fields in opposite direction
        float fieldsFromPos2 = firstReference.getNumberOfFieldsInDirection(false);

        // Number of fields in own direction
        float fieldsFromPos1 = firstReference.getNumberOfFieldsInDirection(true);

        // Number of fields in total
        float numberOfFields = firstReference.getNumberOfFields();

        List <float> dashedLineFields = new List <float> ();

        for (float field = 1; field < fieldsFromPos2; field++)
        {
            dashedLineFields.Add(field);
        }

        for (float field = 1; field < fieldsFromPos1; field++)
        {
            dashedLineFields.Add(fieldsFromPos2 + field);
        }

        // If ways have same "isNode1", invert y-axis for second way
        bool isSameNode1 = firstIsNode1 == secondIsNode1;

        // Way width
        float wayHeight            = wayFirst.transform.localScale.y;
        float wayHeightCompensated = wayHeight - GetLineHeight() * 2f;

        foreach (float field in dashedLineFields)
        {
            GameObject curveDashes = new GameObject();
            curveDashes.name = "Curved dashes";
            curveDashes.transform.SetParent(curveDashedLines.transform);
            curveDashes.transform.localPosition = Vector3.zero;

            // Percentual position of way width, where to put middle line
            float percentualPositionY = field / numberOfFields;

            // Get our points (center in y-axis)
            float yPositionInWay       = percentualPositionY * wayHeightCompensated;
            float dashYMiddle          = -wayHeightCompensated / 2f + GetLineHeight() + yPositionInWay - GetDashedLineHeight() / 2f;
            float dashYMiddleSameNode1 = wayHeightCompensated / 2f - yPositionInWay + GetDashedLineHeight() / 2f;

            Vector3 firstPosMiddle  = posPosition + wayFirst.transform.rotation * new Vector3((firstIsNode1 ? 1 : -1) * wayHeight / 2f, dashYMiddle, 0);
            Vector3 secondPosMiddle = posPosition + waySecond.transform.rotation * new Vector3((secondIsNode1 ? 1 : -1) * wayHeight / 2f, isSameNode1 ? dashYMiddleSameNode1 : dashYMiddle, 0);

            Vector3 halfDashedLineHeight = new Vector3(0, GetDashedLineHeight() / 2f, 0);

            // Get our points (top in y-axis)
            Vector3 wayFirstHalfDashedHeight  = wayFirst.transform.rotation * halfDashedLineHeight;
            Vector3 waySecondHalfDashedHeight = waySecond.transform.rotation * halfDashedLineHeight;
            Vector3 firstPosTop  = firstPosMiddle - wayFirstHalfDashedHeight;
            Vector3 secondPosTop = secondPosMiddle + (isSameNode1 ? 1 : -1) * waySecondHalfDashedHeight;

            // Get our points (bottom in y-axis)
            Vector3 firstPosBottom  = firstPosMiddle + wayFirstHalfDashedHeight;
            Vector3 secondPosBottom = secondPosMiddle + (isSameNode1 ? -1 : 1) * waySecondHalfDashedHeight;

            Quaternion firstRotation   = firstIsNode1 ? WayHelper.ONEEIGHTY_DEGREES * wayFirst.transform.rotation : wayFirst.transform.rotation;
            Quaternion secondRotation  = secondIsNode1 ? WayHelper.ONEEIGHTY_DEGREES * waySecond.transform.rotation : waySecond.transform.rotation;
            Vector3    firstDirection  = firstRotation * Vector3.right;
            Vector3    secondDirection = secondRotation * Vector3.right;

            Vector3 intersectionPoint;
            Vector3 intersectionPointTop;
            Vector3 intersectionPointBottom;
            bool    intersectionFound = Math3d.LineLineIntersection(out intersectionPoint, firstPosMiddle, firstDirection, secondPosMiddle, secondDirection);
            if (!intersectionFound && firstRotation.eulerAngles.z == secondRotation.eulerAngles.z)
            {
                intersectionFound       = true;
                intersectionPoint       = firstPosMiddle + ((secondPosMiddle - firstPosMiddle) / 2);
                intersectionPointTop    = firstPosTop + ((secondPosTop - firstPosTop) / 2);
                intersectionPointBottom = firstPosBottom + ((secondPosBottom - firstPosBottom) / 2);
            }
            else
            {
                Math3d.LineLineIntersection(out intersectionPointTop, firstPosTop, firstDirection, secondPosTop, secondDirection);
                Math3d.LineLineIntersection(out intersectionPointBottom, firstPosBottom, firstDirection, secondPosBottom, secondDirection);
            }

            // TODO - Shouldn't be needed - debug only
            if (!intersectionFound)
            {
                Debug.Log("ERR: " + key);
                return;
            }

            // 1. Get bezier length for curve
            float bezierLength = Math3d.GetBezierLength(firstPosMiddle, intersectionPoint, secondPosMiddle);

            // 2. Decide how many dashes to fit, with gaps (also calculate each dash and gap length)
            // If only one line
            float numberOfLines   = 1f;
            float dashedLineWidth = bezierLength;
            float dashedLineGap   = 0f;
            // If more lines
            if (bezierLength > DASHED_LINE_WIDTH + CITY_DASHED_LINE_GAP)
            {
                float totalWidth = 0f;
                for (numberOfLines = 2f;  ; numberOfLines++)
                {
                    totalWidth = DASHED_LINE_WIDTH + (DASHED_LINE_WIDTH + CITY_DASHED_LINE_GAP) * (numberOfLines - 1);
                    if (totalWidth >= bezierLength)
                    {
                        break;
                    }
                }
                dashedLineWidth = DASHED_LINE_WIDTH * bezierLength / totalWidth;
                dashedLineGap   = CITY_DASHED_LINE_GAP * bezierLength / totalWidth;
            }


            // 3. Calculate each dash along the line t (time) on bezier curve
            List <KeyValuePair <float, float> > dashTimes = new List <KeyValuePair <float, float> > ();
            if (numberOfLines == 1f)
            {
                dashTimes.Add(new KeyValuePair <float, float>(0f, 1f));
            }
            else
            {
                dashTimes.Add(new KeyValuePair <float, float>(0f, dashedLineWidth / bezierLength));
                for (float lineStart = dashedLineWidth + dashedLineGap; lineStart < bezierLength; lineStart += dashedLineWidth + dashedLineGap)
                {
                    float lineStartTime = lineStart / bezierLength;
                    dashTimes.Add(new KeyValuePair <float, float>(lineStartTime, lineStartTime + dashedLineWidth / bezierLength));
                }
            }

            foreach (KeyValuePair <float, float> dashTime in dashTimes)
            {
                float startTime         = dashTime.Key;
                float endTime           = dashTime.Value;
                float dashLengthPercent = endTime - startTime;
                float numberOfPoints    = Mathf.Max(bezierLength / dashLengthPercent * WayHelper.BEZIER_RESOLUTION, 4f);
                float eachPointTime     = dashLengthPercent / numberOfPoints;

                List <Vector3> dashPoints = new List <Vector3>();

                // Top line
                for (float t = startTime; t <= endTime; t += eachPointTime)
                {
                    dashPoints.Add(Math3d.GetVectorInBezierAtTime(t, firstPosTop, intersectionPointTop, secondPosTop));
                }

                // Bottom line
                for (float t = endTime; t >= startTime; t -= eachPointTime)
                {
                    dashPoints.Add(Math3d.GetVectorInBezierAtTime(t, firstPosBottom, intersectionPointBottom, secondPosBottom));
                }

                GameObject lineMiddle = MapSurface.createPlaneMeshForPoints(dashPoints);
                lineMiddle.name = "Curved dash";
                WayLine.SetWhiteMaterial(lineMiddle);
                lineMiddle.transform.SetParent(curveDashes.transform);
                lineMiddle.transform.localPosition = new Vector3(0, 0, -0.01f);
            }
        }
    }
コード例 #15
0
    private static void CreateCurvedMiddleLine(GameObject parent, long key, List <WayReference> wayReferences)
    {
        Pos     centerPos   = NodeIndex.getPosById(key);
        Vector3 posPosition = Game.getCameraPosition(centerPos);

        WayReference firstReference  = wayReferences [0];
        WayReference secondReference = wayReferences [1];

        bool firstIsNode1  = firstReference.isNode1(centerPos);
        bool secondIsNode1 = secondReference.isNode1(centerPos);

        GameObject wayFirst  = firstReference.gameObject;
        GameObject waySecond = secondReference.gameObject;

        // Number of fields in opposite direction
        float fieldsFromPos2 = firstReference.getNumberOfFieldsInDirection(false);

        // Number of fields in total
        float numberOfFields = firstReference.getNumberOfFields();

        // Percentual position of way width, where to put middle line
        float percentualPositionY = fieldsFromPos2 / numberOfFields;

        // Way width
        float wayHeight = wayFirst.transform.localScale.y - GetLineHeight() * 2f;

        // TODO - What if the wayReference is REALLY short
        Vector3    wayFirstSize                = wayFirst.transform.localScale;
        Quaternion wayFirstRotation            = wayFirst.transform.rotation;
        float      wayFirstWayWidth            = (firstIsNode1 ? 1 : -1) * wayFirstSize.y;
        float      lineFirstPositionAdjustment = percentualPositionY * wayHeight;
        Vector3    wayFirstMiddleLineTopPos    = posPosition + wayFirstRotation * new Vector3(wayFirstWayWidth / 2f, -wayHeight / 2f + lineFirstPositionAdjustment, 0f);
        Vector3    wayFirstMiddleLineBottomPos = posPosition + wayFirstRotation * new Vector3(wayFirstWayWidth / 2f, -wayHeight / 2f + GetLineHeight() + lineFirstPositionAdjustment, 0f);

        Vector3    waySecondSize                = waySecond.transform.localScale;
        Quaternion waySecondRotation            = waySecond.transform.rotation;
        float      waySecondWayWidth            = (secondIsNode1 ? 1 : -1) * waySecondSize.y;
        float      lineSecondPositionAdjustment = percentualPositionY * wayHeight;
        Vector3    waySecondMiddleLineTopPos    = posPosition + waySecondRotation * new Vector3(waySecondWayWidth / 2f, -wayHeight / 2f + lineSecondPositionAdjustment, 0f);
        Vector3    waySecondMiddleLineBottomPos = posPosition + waySecondRotation * new Vector3(waySecondWayWidth / 2f, -wayHeight / 2f + GetLineHeight() + lineSecondPositionAdjustment, 0f);

        if (IsTopAndBottomCrossing(wayFirstMiddleLineTopPos, waySecondMiddleLineTopPos, wayFirstMiddleLineBottomPos, waySecondMiddleLineBottomPos))
        {
            Vector3 tmp = wayFirstMiddleLineBottomPos;
            wayFirstMiddleLineBottomPos = wayFirstMiddleLineTopPos;
            wayFirstMiddleLineTopPos    = tmp;
        }

//		DebugFn.square (wayFirstMiddleLineTopPos);
//		DebugFn.square (wayFirstMiddleLineBottomPos);
//		DebugFn.square (waySecondMiddleLineTopPos);
//		DebugFn.square (waySecondMiddleLineBottomPos);

        List <Vector3> linePoints = new List <Vector3> ();

        linePoints.Add(wayFirstMiddleLineTopPos);
        AddBezierPoints(linePoints, wayFirstMiddleLineTopPos, wayFirstRotation, waySecondMiddleLineTopPos, waySecondRotation);
        linePoints.Add(waySecondMiddleLineBottomPos);
        AddBezierPoints(linePoints, waySecondMiddleLineBottomPos, waySecondRotation, wayFirstMiddleLineBottomPos, wayFirstRotation);

        GameObject lineMiddle = MapSurface.createPlaneMeshForPoints(linePoints);

        lineMiddle.name = "Curved middle line";
        WayLine.SetWhiteMaterial(lineMiddle);
        lineMiddle.transform.SetParent(parent.transform);
        lineMiddle.transform.localPosition = new Vector3(0, 0, -0.01f);
    }
コード例 #16
0
        /// <summary>
        /// Executor that implements requesting and rendering sub grid information to create the rendered tile
        /// </summary>
        public async Task <SKBitmap> ExecuteAsync()
        {
            // WorkingColorPalette  : TICDisplayPaletteBase;

            _log.LogInformation($"Performing Execute for DataModel:{DataModelID}, Mode={Mode}");

            ApplicationServiceRequestStatistics.Instance.NumMapTileRequests.Increment();

            /*
             * if Assigned(ASNodeImplInstance.RequestCancellations) and
             * ASNodeImplInstance.RequestCancellations.IsRequestCancelled(FExternalDescriptor) then
             * begin
             * if ...SvcLocations.Debug_LogDebugRequestCancellationToFile then
             *   SIGLogMessage.PublishNoODS(Self, 'Request cancelled: ' + FExternalDescriptor.ToString, ...Debug);
             *
             * ResultStatus  = ...RequestHasBeenCancelled;
             * InterlockedIncrement64(ASNodeRequestStats.NumMapTileRequestsCancelled);
             * Exit;
             * end;
             *
             * // The governor is intended to restrict the numbers of heavy weight processes
             * // such as pipelines that interact with the PC layer to request sub grids
             * ScheduledWithGovernor  = ASNodeImplInstance.Governor.Schedule(FExternalDescriptor, Self, gqWMS, ResultStatus);
             * if not ScheduledWithGovernor then
             * Exit;
             */

            var RequestDescriptor = Guid.NewGuid();

            if (_log.IsDebugEnabled())
            {
                if (CoordsAreGrid)
                {
                    _log.LogDebug($"RenderPlanViewTiles Execute: Performing render for request={RequestDescriptor} Args: Project={DataModelID}, Mode={Mode}, CutFillDesign=''{CutFillDesign}'' " +
                                  $"Bound[BL/TR:X/Y]=({BLPoint.X} {BLPoint.Y}, {TRPoint.X} {TRPoint.Y}), Width={NPixelsX}, Height={NPixelsY}");
                }
                else
                {
                    _log.LogDebug($"RenderPlanViewTiles Execute: Performing render for request={RequestDescriptor} Args: Project={DataModelID}, Mode={Mode}, CutFillDesign=''{CutFillDesign}'' " +
                                  $"Bound[BL/TR:Lon/Lat]=({BLPoint.X} {BLPoint.Y}, {TRPoint.X} {TRPoint.Y}), Width={NPixelsX}, Height={NPixelsY}");
                }

                // Include the details of the filters with the logged tile parameters
                if (Filters != null)
                {
                    for (var i = 0; i < Filters.Filters.Length; i++)
                    {
                        _log.LogDebug($"Filter({i}): {Filters.Filters[i]}");
                    }
                }
            }

            // Determine the grid (NEE) coordinates of the bottom/left, top/right WGS-84 positions
            // given the project's coordinate system. If there is no coordinate system then exit.

            var SiteModel = DIContext.Obtain <ISiteModels>().GetSiteModel(DataModelID);

            if (SiteModel == null)
            {
                _log.LogWarning($"Failed to locate site model {DataModelID}");
                return(null);
            }

            _log.LogInformation($"Got Site model {DataModelID}, production data extents are {SiteModel.SiteModelExtent}");

            LLHCoords = new[]
            {
                new XYZ(BLPoint.X, BLPoint.Y, 0),
                new XYZ(TRPoint.X, TRPoint.Y, 0),
                new XYZ(BLPoint.X, TRPoint.Y, 0),
                new XYZ(TRPoint.X, BLPoint.Y, 0)
            };
            _log.LogInformation($"LLHCoords for tile request {string.Concat(LLHCoords)}, CoordsAreGrid {CoordsAreGrid}");

            if (CoordsAreGrid)
            {
                NEECoords = LLHCoords;
            }
            else
            {
                NEECoords = DIContext
                            .Obtain <ICoreXWrapper>()
                            .LLHToNEE(SiteModel.CSIB(), LLHCoords.ToCoreX_XYZ(), CoreX.Types.InputAs.Radians)
                            .ToTRex_XYZ();
            }
            _log.LogInformation($"After conversion NEECoords are {string.Concat(NEECoords)}");

            WorldTileHeight = MathUtilities.Hypot(NEECoords[0].X - NEECoords[2].X, NEECoords[0].Y - NEECoords[2].Y);
            WorldTileWidth  = MathUtilities.Hypot(NEECoords[0].X - NEECoords[3].X, NEECoords[0].Y - NEECoords[3].Y);

            var dx = NEECoords[2].X - NEECoords[0].X;
            var dy = NEECoords[2].Y - NEECoords[0].Y;

            // Calculate the tile rotation as the mathematical angle turned from 0 (due east) to the vector defined by dy/dx
            TileRotation = Math.Atan2(dy, dx);

            // Convert TileRotation to represent the angular deviation rather than a bearing
            TileRotation = (Math.PI / 2) - TileRotation;

            RotatedTileBoundingExtents.SetInverted();
            NEECoords.ForEach(xyz => RotatedTileBoundingExtents.Include(xyz.X, xyz.Y));

            _log.LogInformation($"Tile render executing across tile: [Rotation:{TileRotation}, {MathUtilities.RadiansToDegrees(TileRotation)} degrees] " +
                                $" [BL:{NEECoords[0].X}, {NEECoords[0].Y}, TL:{NEECoords[2].X},{NEECoords[2].Y}, " +
                                $"TR:{NEECoords[1].X}, {NEECoords[1].Y}, BR:{NEECoords[3].X}, {NEECoords[3].Y}] " +
                                $"World Width, Height: {WorldTileWidth}, {WorldTileHeight}, Rotated bounding extents: {RotatedTileBoundingExtents}");

            // Construct the renderer, configure it, and set it on its way
            //  WorkingColorPalette = Nil;

            using (var Renderer = new PlanViewTileRenderer())
            {
                try
                {
                    // Intersect the site model extents with the extents requested by the caller
                    var adjustedSiteModelExtents = SiteModel.GetAdjustedDataModelSpatialExtents(null);

                    _log.LogInformation($"Calculating intersection of bounding box and site model {DataModelID}:{adjustedSiteModelExtents}");

                    var dataSelectionExtent = new BoundingWorldExtent3D(RotatedTileBoundingExtents);
                    dataSelectionExtent.Intersect(adjustedSiteModelExtents);
                    if (!dataSelectionExtent.IsValidPlanExtent)
                    {
                        ResultStatus = RequestErrorStatus.InvalidCoordinateRange;
                        _log.LogInformation($"Site model extents {adjustedSiteModelExtents}, do not intersect RotatedTileBoundingExtents {RotatedTileBoundingExtents}");

                        using var mapView = new MapSurface();

                        mapView.SetBounds(NPixelsX, NPixelsY);

                        var canvas = mapView.BitmapCanvas;
                        mapView.BitmapCanvas = null;

                        return(canvas);
                    }

                    // Compute the override cell boundary to be used when processing cells in the sub grids
                    // selected as a part of this pipeline
                    // Increase cell boundary by one cell to allow for cells on the boundary that cross the boundary

                    SubGridTree.CalculateIndexOfCellContainingPosition(dataSelectionExtent.MinX,
                                                                       dataSelectionExtent.MinY, SiteModel.CellSize, SubGridTreeConsts.DefaultIndexOriginOffset,
                                                                       out var CellExtents_MinX, out var CellExtents_MinY);
                    SubGridTree.CalculateIndexOfCellContainingPosition(dataSelectionExtent.MaxX,
                                                                       dataSelectionExtent.MaxY, SiteModel.CellSize, SubGridTreeConsts.DefaultIndexOriginOffset,
                                                                       out var CellExtents_MaxX, out var CellExtents_MaxY);

                    var CellExtents = new BoundingIntegerExtent2D(CellExtents_MinX, CellExtents_MinY, CellExtents_MaxX, CellExtents_MaxY);
                    CellExtents.Expand(1);

                    var filterSet = FilterUtilities.ConstructFilters(Filters, VolumeType);
                    // Construct PipelineProcessor
                    using var processor = DIContext.Obtain <IPipelineProcessorFactory>().NewInstanceNoBuild <SubGridsRequestArgument>(
                              RequestDescriptor,
                              DataModelID,
                              GridDataFromModeConverter.Convert(Mode),
                              new SubGridsPipelinedResponseBase(),
                              filterSet,
                              CutFillDesign,
                              DIContext.Obtain <Func <PipelineProcessorTaskStyle, ITRexTask> >()(PipelineProcessorTaskStyle.PVMRendering),
                              DIContext.Obtain <Func <PipelineProcessorPipelineStyle, ISubGridPipelineBase> >()(PipelineProcessorPipelineStyle.DefaultProgressive),
                              DIContext.Obtain <IRequestAnalyser>(),
                              Utilities.DisplayModeRequireSurveyedSurfaceInformation(Mode) && Utilities.FilterRequireSurveyedSurfaceInformation(Filters),
                              requestRequiresAccessToDesignFileExistenceMap: Utilities.RequestRequiresAccessToDesignFileExistenceMap(Mode, CutFillDesign),
                              CellExtents,
                              LiftParams
                              );
                    if (filterSet.Filters.Length == 3)
                    {
                        var pipeline = processor.Pipeline as SubGridPipelineProgressive <SubGridsRequestArgument, SubGridRequestsResponse>;
                        pipeline.SubGridsRequestComputeStyle = SubGridsRequestComputeStyle.SimpleVolumeThreeWayCoalescing;
                    }

                    // Set the PVM rendering rexTask parameters for progressive processing
                    processor.Task.TRexNodeID = RequestingTRexNodeID;
                    ((IPVMRenderingTask)processor.Task).TileRenderer = Renderer;

                    // Set the spatial extents of the tile boundary rotated into the north reference frame of the cell coordinate system to act as
                    // a final restriction of the spatial extent used to govern data requests
                    processor.OverrideSpatialExtents.Assign(RotatedTileBoundingExtents);

                    // Prepare the processor
                    if (!processor.Build())
                    {
                        _log.LogError($"Failed to build pipeline processor for request to model {SiteModel.ID}");
                        ResultStatus = RequestErrorStatus.FailedToConfigureInternalPipeline;
                        return(null);
                    }

                    // Test to see if the tile can be satisfied with a representational render indicating where
                    // data is but not what it is (this is useful when the zoom level is far enough away that we
                    // cannot meaningfully render the data). If the size of s sub grid is smaller than
                    // the size of a pixel in the requested tile then do this. Just check the X dimension
                    // as the data display is isotropic.
                    // TODO: Could this be done before creation of the pipeline processor?
                    if (Utilities.SubGridShouldBeRenderedAsRepresentationalDueToScale(WorldTileWidth, WorldTileHeight, NPixelsX, NPixelsY, processor.OverallExistenceMap.CellSize))
                    {
                        return(RenderTileAsRepresentationalDueToScale(processor.OverallExistenceMap)); // There is no need to do anything else
                    }

                    /* TODO - Create a scaled palette to use when rendering the data
                     * // Create a scaled palette to use when rendering the data
                     * if not CreateAndInitialiseWorkingColorPalette then
                     *  begin
                     *  SIGLogMessage.PublishNoODS(Self, Format('Failed to create and initialise working color palette for data: %s in datamodel %d', [TypInfo.GetEnumName(TypeInfo(TICDisplayMode), Ord(FMode)), FDataModelID]), ...Warning);
                     *  Exit;
                     *  end;
                     */

                    // Renderer.WorkingPalette = WorkingColorPalette;

                    Renderer.IsWhollyInTermsOfGridProjection = true; // Ensure the renderer knows we are using grid projection coordinates

                    Renderer.SetBounds(RotatedTileBoundingExtents.CenterX - WorldTileWidth / 2,
                                       RotatedTileBoundingExtents.CenterY - WorldTileHeight / 2,
                                       WorldTileWidth, WorldTileHeight,
                                       NPixelsX, NPixelsY);
                    Renderer.TileRotation = TileRotation;

                    var performRenderStopWatch = Stopwatch.StartNew();
                    ResultStatus = Renderer.PerformRender(Mode, processor, ColorPalettes, Filters, LiftParams);
                    _log.LogInformation($"Renderer.PerformRender completed in {performRenderStopWatch.Elapsed}");

                    if (processor.Response.ResultStatus == RequestErrorStatus.OK)
                    {
                        var canvas = Renderer.Displayer.MapView.BitmapCanvas;
                        Renderer.Displayer.MapView.BitmapCanvas = null;
                        return(canvas);
                    }
                }
                catch (Exception e)
                {
                    _log.LogError(e, "Exception occurred");
                    ResultStatus = RequestErrorStatus.Exception;
                }
            }

            return(null);
        }
コード例 #17
0
    public static void create(long key, List <WayReference> wayReferences, string materialId)
    {
        if (off)
        {
            return;
        }
        Pos pos = NodeIndex.getPosById(key);

        // Sort based on rotation in the point closest to the intersection
        wayReferences.Sort(delegate(WayReference x, WayReference y) {
            float angleDiff = AngleAroundNode(pos, x) - AngleAroundNode(pos, y);
            // Ignoring float to int issues (if there are any)
            int angleDiffInt = (int)angleDiff;
            return(angleDiffInt);
        });

        // Gather our way bounds (used for checking if ways intersects each other)
        List <Bounds> wayBounds = getWayBounds(wayReferences);

        // List of positions where to draw the mesh
        List <Vector3> meshPoints;

        List <WayReference> intersectionList = Misc.CloneBaseNodeList(wayReferences);
        bool isComplex = false;

        if (intersectionList.Count == 2 && wayBounds [0].Intersects(wayBounds [1]))
        {
            // Only two ways and they intersect, special logic
            meshPoints = getMeshPointsForComplexTwoWay(intersectionList, wayBounds, pos);
            isComplex  = true;
        }
        else
        {
            meshPoints = getMeshPointsForNonComplex(intersectionList, wayBounds, pos);
        }

//		Debug.Log ("Intersection");
        GameObject intersectionObj = MapSurface.createPlaneMeshForPoints(meshPoints);

        intersectionObj.name = "Intersection " + (isComplex ? "complex " : "") + (intersectionList.Count - 1) + "-way (" + key + ")";
        Vector3 zOffset = new Vector3(0, 0, Game.WAYS_Z_POSITION);

        intersectionObj.transform.position = intersectionObj.transform.position + zOffset;
        intersectionObj.transform.parent   = Game.instance.waysParent;
        AutomaticMaterialObject intersectionMaterialObject = intersectionObj.AddComponent <AutomaticMaterialObject> () as AutomaticMaterialObject;

        intersectionMaterialObject.requestMaterial(materialId, null);          // TODO - Should have same material as connecting way(s)
        Misc.AddGravityToWay(intersectionObj);
        Misc.AddWayObjectComponent(intersectionObj);

        // Need waylines for all straight ways
        if (wayReferences.Count == 2)
        {
            bool wayQualifiedForCrossing = wayReferences[0].way.WayWidthFactor >= WayHelper.LIMIT_WAYWIDTH && wayReferences[0].way.CarWay;
            if (pos.getTagValue("highway") == "crossing" && wayQualifiedForCrossing)
            {
                WayCrossing.Create(intersectionObj, key, wayReferences);
            }
            else
            {
                WayLine.CreateCurved(intersectionObj, key, wayReferences);
            }
        }
    }
コード例 #18
0
    public IEnumerator getCountryData()
    {
        // Get country metadata
        WWW www = CacheWWW.Get(Game.endpointBaseUrl + Game.countryMetaDataRelativeUrl);

        yield return(www);

        XmlDocument xmlDoc = new XmlDocument();

        xmlDoc.LoadXml(www.text);

        XmlNodeList countries = xmlDoc.SelectNodes("/countries/country");
        int         numLeft   = countries.Count;

        foreach (XmlNode country in countries)
        {
            // TODO - Remove debug log - and to break after a few
            Debug.Log(numLeft--);
//            if (numLeft < 227) {
//                break;
//            }

            XmlAttributeCollection countryAttributes = country.Attributes;

            string code = Misc.xmlString(countryAttributes.GetNamedItem("code"));
            string name = Misc.xmlString(countryAttributes.GetNamedItem("name"));
            // TODO
//            string code = "ZA";
//            string name = "South Africa";

            // Country parent
            GameObject countryParent = new GameObject(name);
            Country    countryObj    = countryParent.AddComponent <Country> ();
            countryObj.countryName         = name;
            countryObj.code                = code;
            countryObj.tag                 = "Country";
            countryParent.transform.parent = transform;

            // Landarea parent
            GameObject landareaParent = new GameObject("Land");
            landareaParent.transform.parent = countryParent.transform;

            // Get country full outline data
            WWW countryWWW = CacheWWW.Get(Game.endpointBaseUrl + Game.countryMetaDataRelativeUrl + Game.countryCodeDataQuerystringPrefix + code);
            yield return(countryWWW);

            XmlDocument countryDataDoc = new XmlDocument();
            countryDataDoc.LoadXml(countryWWW.text);

            XmlNodeList polygons   = countryDataDoc.SelectNodes("/country/polygons/polygon");
            int         outerIndex = 0;
            int         innerIndex = 0;
            foreach (XmlNode polygon in polygons)
            {
                // Outer coordinates
                List <Vector3> outerCoordinates = new List <Vector3>();
                yield return(getCoordinates(polygon, "outer", outerCoordinates));

                if (outerCoordinates.Count > 0)
                {
                    GameObject outerPart = MapSurface.createPlaneMeshForPoints(outerCoordinates);
                    outerPart.name             = "Outer" + outerIndex++;
                    outerPart.transform.parent = landareaParent.transform;
                    countryObj.addCoords(outerCoordinates);
                }

                // Inner coordinates
                List <Vector3> innerCoordinates = new List <Vector3>();
                yield return(getCoordinates(polygon, "inner", innerCoordinates));

                if (innerCoordinates.Count > 0)
                {
                    GameObject innerPart = MapSurface.createPlaneMeshForPoints(innerCoordinates);
                    innerPart.name                    = "Inner" + innerIndex++;
                    innerPart.transform.parent        = landareaParent.transform;
                    innerPart.transform.localPosition = new Vector3(innerPart.transform.localPosition.x, innerPart.transform.localPosition.y, innerPart.transform.localPosition.z - 0.1f);
                    countryObj.addCoords(innerCoordinates, false);
                }
            }

            // Country name
            GameObject countryNameContainerInstance = Instantiate(countryNameContainer, countryObj.transform) as GameObject;
            TextMesh   countryNameTextMesh          = countryNameContainerInstance.GetComponentInChildren <TextMesh> ();
            countryNameTextMesh.text = name;
            countryObj.setupDone();
            countryObj.saveMeshes();

//            break; // TODO
        }

        analyzeAndMergeInners();


        Debug.Log("Done!");
    }