Exemplo n.º 1
0
        private void ComputeQuadrant(FovData data, int deltaX, int deltaY, int maxX, int maxY)
        {
            var activeViews = new List <View>();
            int i;

            var shallowLine = new Line(0, 1, maxX, 0);
            var steepLine   = new Line(1, 0, 0, maxY);

            activeViews.Add(new View(shallowLine, steepLine));
            int viewIndex = 0;

            // Visit the tiles diagonally and going outwards
            //
            // .
            // .
            // 9
            // 58
            // 247
            // @136..
            int maxI = maxX + maxY;

            for (i = 1; i <= maxI && activeViews.Count != 0; ++i)
            {
                int startJ = (0 > i - maxX ? 0 : i - maxX);
                int maxJ   = (i < maxY ? i : maxY);

                int j;
                for (j = startJ; j <= maxJ && viewIndex < activeViews.Count; ++j)
                {
                    VisitPoint(data, i - j, j, deltaX, deltaY, ref viewIndex, activeViews);
                }
            }
        }
Exemplo n.º 2
0
        public HashSet <Point> Compute(int startX, int startY, int radius)
        {
            var data = new FovData
            {
                IsTransparent = isTransparent,
                StartX        = startX,
                StartY        = startY,
                Visited       = new HashSet <Point>()
            };

            // Will always see the centre.
            data.Visited.Add(new Point(startX, startY));

            // Get the dimensions of the actual field of view, making sure not to go off the map or beyond the radius.
            int minExtentX = (startX < radius ? startX : radius);
            int maxExtentX = (mapWidth - startX <= radius ? mapWidth - startX - 1 : radius);
            int minExtentY = (startY < radius ? startY : radius);
            int maxExtentY = (mapHeight - startY <= radius ? mapHeight - startY - 1 : radius);

            ComputeQuadrant(data, 1, 1, maxExtentX, maxExtentY);
            ComputeQuadrant(data, 1, -1, maxExtentX, minExtentY);
            ComputeQuadrant(data, -1, -1, minExtentX, minExtentY);
            ComputeQuadrant(data, -1, 1, minExtentX, maxExtentY);

            return(data.Visited);
        }
Exemplo n.º 3
0
        public Task UpdateCamera(FovData fovData)
        {
            var tcs = new TaskCompletionSource <object>();

            PostAction(() =>
            {
                _tree.UpdateLod(fovData);
                tcs.SetResult(null);
                return(TaskUtils.EmptyCompleted());
            });
            return(tcs.Task);
        }
Exemplo n.º 4
0
 public void UpdateHeightmap()
 {
     _ring1Tree.UpdateLod(FovData.FromCamera(_camera));
 }
Exemplo n.º 5
0
        private static void VisitPoint(FovData data, int x, int y, int deltaX, int deltaY, ref int viewIndex, List <View> activeViews)
        {
            var topLeft     = new Point(x, y + 1);
            var bottomRight = new Point(x + 1, y); // The top left and bottom right corners of the current coordinate.

            for (;
                 viewIndex < activeViews.Count &&
                 activeViews[viewIndex].SteepLine.IsBelowOrCollinear(bottomRight.X, bottomRight.Y);
                 ++viewIndex)
            {
                // The current coordinate is above the current view and is ignored. The steeper fields may need it though.
            }

            if (viewIndex == activeViews.Count ||
                activeViews[viewIndex].ShallowLine.IsAboveOrCollinear(topLeft.X, topLeft.Y)
                )
            {
                // Either the current coordinate is above all of the fields or it is below all of the fields.
                return;
            }

            // It is now known that the current coordinate is between the steep
            // and shallow lines of the current view.

            // The real quadrant coordinates
            int realX = x * deltaX;
            int realY = y * deltaY;


            var pt = new Point(data.StartX + realX, data.StartY + realY);

            data.Visited.Add(new Point(pt.X, pt.Y));

            if (data.IsTransparent(pt))
            {
                // The current coordinate does not block sight and therefore has no effect on the view.
                return;
            }

            // The current coordinate is an obstacle.
            bool shallowLineIsAboveBottomRight =
                activeViews[viewIndex].ShallowLine.IsAbove(bottomRight.X, bottomRight.Y);
            bool steepLineIsBelowTopLeft = activeViews[viewIndex].SteepLine.IsBelow(topLeft.X, topLeft.Y);

            if (shallowLineIsAboveBottomRight && steepLineIsBelowTopLeft)
            {
                // The obstacle is intersected by both lines in the current view. The view is completely blocked.
                activeViews.RemoveAt(viewIndex);
            }
            else if (shallowLineIsAboveBottomRight)
            {
                // The obstacle is intersected by the shallow line of the current view. The shallow line needs to be raised.
                AddShallowBump(topLeft.X, topLeft.Y, activeViews, viewIndex);
                CheckView(activeViews, viewIndex);
            }
            else if (steepLineIsBelowTopLeft)
            {
                // The obstacle is intersected by the steep line of the current view. The steep line needs to be lowered.
                AddSteepBump(bottomRight.X, bottomRight.Y, activeViews, viewIndex);
                CheckView(activeViews, viewIndex);
            }
            else
            {
                // The obstacle is completely between the two lines of the current view.
                // Split the current view into two views above and below the current coordinate.
                int shallowViewIndex = viewIndex;
                int steepViewIndex   = ++viewIndex;

                activeViews.Insert(shallowViewIndex, activeViews[shallowViewIndex].Clone());
                AddSteepBump(bottomRight.X, bottomRight.Y, activeViews, shallowViewIndex);

                if (!CheckView(activeViews, shallowViewIndex))
                {
                    --steepViewIndex;
                }

                AddShallowBump(topLeft.X, topLeft.Y, activeViews, steepViewIndex);
                CheckView(activeViews, steepViewIndex);
            }
        }
        public void Start()
        {
            InitializeWelding();
            /// /// VISIBILITY TEXTURE
            var visibilityTextureSideLength = 16;
            var visibilityTexture           = new Texture2D(visibilityTextureSideLength, visibilityTextureSideLength,
                                                            TextureFormat.RFloat, false);

            visibilityTexture.filterMode = FilterMode.Point;

            var visibilityTextureProcessorProxy =
                new Ring1VisibilityTextureProcessorUTProxy(new Ring1VisibilityTextureProcessor(visibilityTexture));

            _ultraUpdatableContainer.Add(visibilityTextureProcessorProxy);

            var visibilityTextureChangeGrabber = new Ring1VisibilityTextureChangeGrabber();

            var terrainParentGameObject = new GameObject("TerrainParent");

            terrainParentGameObject.transform.localPosition = new Vector3(0, 0, 0);

            var globalSideLength      = _gRingConfiguration.Ring1GlobalSideLength;
            var globalSize            = new Vector2(globalSideLength, globalSideLength);
            var unityCoordsCalculator = new UnityCoordsCalculator(globalSize);
            var orderGrabber          = new Ring1PaintingOrderGrabber();

            var painterProxy = new RingTerrainPainterUTProxy(new RingTerrainPainter(_gRingConfiguration.MakeTerrainVisible));

            _ultraUpdatableContainer.Add(painterProxy);

            painterProxy.Update();

            var mainRespondingProxy = new Ring1NodeEventMainRespondingProxy(new Ring1NodeEventMainResponder());

            _ultraUpdatableContainer.AddOtherThreadProxy(new OtherThreadProxyWithPerPostAction()
            {
                OtherThreadProxy = mainRespondingProxy,
                PerPostAction    =
                    () =>
                {
                    var delta = visibilityTextureChangeGrabber.RetriveVisibilityChanges();

                    if (delta.AnyChange)
                    {
                        var visibilityTextureChagnes =
                            visibilityTextureChangeGrabber.RetriveVisibilityChanges();
                        visibilityTextureProcessorProxy.AddOrder(visibilityTextureChagnes);
                    }

                    if (orderGrabber.IsAnyOrder)
                    {
                        painterProxy.AddOrder(orderGrabber.RetriveOrderAndClear());
                    }
                }
            });

            var stainTerrainResourceCreatorUtProxy =
                new StainTerrainResourceCreatorUTProxy(new StainTerrainResourceCreator());

            _ultraUpdatableContainer.Add(stainTerrainResourceCreatorUtProxy);

            var stainTerrainServiceProxy = new StainTerrainServiceProxy(
                new StainTerrainService(
                    new FromFileStainTerrainResourceGenerator(_configuration.StainTerrainServicePath, _gameInitializationFields.Retrive <CommonExecutorUTProxy>()),
                    //new ComputationStainTerrainResourceGenerator(
                    //    new StainTerrainResourceComposer(
                    //        _stainTerrainResourceCreatorUtProxy
                    //        ),
                    //    new StainTerrainArrayMelder(),
                    //    new DummyStainTerrainArrayFromBiomesGenerator(
                    //        new DebugBiomeContainerGenerator().GenerateBiomesContainer(new BiomesContainerConfiguration()),
                    //        new StainTerrainArrayFromBiomesGeneratorConfiguration()
                    //    )),
                    _gRingConfiguration.Ring1GenerationArea));

            _ultraUpdatableContainer.AddOtherThreadProxy(stainTerrainServiceProxy);

            var ring1Tree      = new Ring1Tree(_gRingConfiguration.Ring1TreeConfiguration);
            var ring1TreeProxy = new Ring1TreeProxy(ring1Tree);

            _gameInitializationFields.Retrive <LateAssignBox <Ring1TreeProxy> >().Set(ring1TreeProxy);
            _ultraUpdatableContainer.AddOtherThreadProxy(ring1TreeProxy);

            var terrainShapeDbInitialization = new FETerrainShapeDbInitialization(_ultraUpdatableContainer,
                                                                                  _gameInitializationFields, _configuration, new FilePathsConfiguration());

            terrainShapeDbInitialization.Start();


            var gRing0NodeTerrainCreator = new GRing0NodeTerrainCreator(
                orderGrabber,
                terrainParentGameObject,
                _gameInitializationFields.Retrive <MeshGeneratorUTProxy>(),
                _gameInitializationFields.Retrive <ITerrainShapeDb>(),
                unityCoordsCalculator,
                _gameInitializationFields.Retrive <GRingSpotUpdater>(),
                _gameInitializationFields.Retrive <HeightArrayWeldingPack>(),
                _gRingConfiguration.GroundShapeProviderConfiguration,
                _gRingConfiguration.TerrainMeshProviderConfiguration);

            var gRing1NodeTerrainCreator = new GRing1NodeTerrainCreator(
                orderGrabber,
                terrainParentGameObject,
                _gameInitializationFields.Retrive <MeshGeneratorUTProxy>(),
                _gameInitializationFields.Retrive <ITerrainShapeDb>(),
                stainTerrainServiceProxy,
                unityCoordsCalculator,
                _gameInitializationFields.Retrive <GRingSpotUpdater>(),
                _gameInitializationFields.Retrive <HeightArrayWeldingPack>(),
                _gRingConfiguration.GroundShapeProviderConfiguration,
                _gRingConfiguration.TerrainMeshProviderConfiguration);

            var gRing2PatchesCreatorProxy = _gameInitializationFields.Retrive <GRing2PatchesCreatorProxy>();

            var gRing2NodeTerrainCreator = new GRing2NodeTerrainCreator(
                orderGrabber,
                terrainParentGameObject,
                _gameInitializationFields.Retrive <MeshGeneratorUTProxy>(),
                _gameInitializationFields.Retrive <ITerrainShapeDb>(),
                unityCoordsCalculator,
                gRing2PatchesCreatorProxy,
                _gameInitializationFields.Retrive <GRingSpotUpdater>(),
                _gameInitializationFields.Retrive <HeightArrayWeldingPack>(),
                _gRingConfiguration.GroundShapeProviderConfiguration,
                _gRingConfiguration.TerrainMeshProviderConfiguration);

            var gDebugNodeTerrainCreator = new GDebugLodNodeTerrainCreator(
                orderGrabber,
                terrainParentGameObject,
                unityCoordsCalculator,
                _gameInitializationFields.Retrive <MeshGeneratorUTProxy>()
                );

            var gDebugTerrainedNodeTerrainCreator = new GDebugTerrainedLodNodeTerrainCreator(
                orderGrabber,
                terrainParentGameObject,
                unityCoordsCalculator,
                _gameInitializationFields.Retrive <MeshGeneratorUTProxy>(),
                _gameInitializationFields.Retrive <ITerrainShapeDb>(),
                _gRingConfiguration.GroundShapeProviderConfiguration,
                _gameInitializationFields.Retrive <GRingSpotUpdater>()
                );


            var gStampedRing2NodeTerrainCreator = new GStampedRing2NodeTerrainCreator(
                orderGrabber,
                terrainParentGameObject,
                _gameInitializationFields.Retrive <MeshGeneratorUTProxy>(),
                _gameInitializationFields.Retrive <ITerrainShapeDb>(),
                unityCoordsCalculator,
                gRing2PatchesCreatorProxy,
                _gameInitializationFields.Retrive <Ring2PatchStamplingOverseerFinalizer>(),
                _gameInitializationFields.Retrive <GRingSpotUpdater>(),
                _gameInitializationFields.Retrive <HeightArrayWeldingPack>(),
                _gRingConfiguration.GroundShapeProviderConfiguration,
                _gRingConfiguration.TerrainMeshProviderConfiguration);

            var gCompositeRing2NodeTerrainCreator = new GCompositeRing2NodeTerrainCreator(
                orderGrabber,
                terrainParentGameObject,
                _gameInitializationFields.Retrive <MeshGeneratorUTProxy>(),
                _gameInitializationFields.Retrive <ITerrainShapeDb>(),
                unityCoordsCalculator,
                gRing2PatchesCreatorProxy,
                _gameInitializationFields.Retrive <GRingSpotUpdater>(),
                _gameInitializationFields.Retrive <HeightArrayWeldingPack>(),
                _gameInitializationFields.Retrive <Ring2PatchStamplingOverseerFinalizer>(),
                _gRingConfiguration.GroundShapeProviderConfiguration,
                _gRingConfiguration.TerrainMeshProviderConfiguration);

            //var gCompositeRing2NodeTerrainCreator = new GCompositeRing2NodeTerrainCreator(
            //    new List<INewGRingListenersCreator>()
            //    {
            //        gRing2NodeTerrainCreator,
            //        gStampedRing2NodeTerrainCreator,
            //    });

            var subCreator = new SupremeGRingNodeTerrainCreator(new List <NewListenersCreatorWithLimitation>()
            {
                //new NewListenersCreatorWithLimitation()
                //{
                //    Creator = gDebugTerrainedNodeTerrainCreator,
                //    MaximumLod = new FlatLod(14),
                //    //PositionLimiter = new NewListenersCreatorPositionLimiter(new Vector2(0.5f, 0.6f), 0.025f)
                //},

                //new NewListenersCreatorWithLimitation()
                //{
                //    Creator = gRing0NodeTerrainCreator,
                //    MaximumLod = new FlatLod(5),
                //},

                new NewListenersCreatorWithLimitation()
                {
                    Creator    = new GVoidNodeTerrainCreator(),
                    MaximumLod = new FlatLod(5),
                    //IsFallthroughCreator = true
                },

                new NewListenersCreatorWithLimitation()
                {
                    Creator    = gRing1NodeTerrainCreator,
                    MaximumLod = new FlatLod(10)
                },

                new NewListenersCreatorWithLimitation()
                {
                    Creator    = gRing2NodeTerrainCreator,
                    MaximumLod = new FlatLod(14)
                },

                new NewListenersCreatorWithLimitation()
                {
                    Creator    = gStampedRing2NodeTerrainCreator,
                    MaximumLod = new FlatLod(13)
                },

                new NewListenersCreatorWithLimitation()
                {
                    Creator    = gCompositeRing2NodeTerrainCreator,
                    MaximumLod = new FlatLod(14)
                }

                //new NewListenersCreatorWithLimitation()
                //{
                //    Creator = gDebugNodeTerrainCreator,
                //    MaximumLod = new FlatLod(11)
                //},
            });

            var eventCollector = new Ring1NodeEventCollector(
                new DynamicFlatLodGRingNodeTerrainCreator(subCreator,
                                                          new FlatLodCalculator(unityCoordsCalculator, _gRingConfiguration.FlatLodConfiguration)));

            _ultraUpdatableContainer.AddOtherThreadProxy(
                new OtherThreadProxyWithPerPostAction()
            {
                OtherThreadProxy = ring1TreeProxy,
                PerPostAction    = () =>
                {
                    if (eventCollector.Any)
                    {
                        mainRespondingProxy.AddOrder(eventCollector.RetriveOrderAndClear());
                    }
                }
            }
                );
            var repositioner = _gameInitializationFields.Retrive <Repositioner>();

            _ultraUpdatableContainer.AddUpdatableElement(new FieldBasedUltraUpdatable()
            {
                UpdateCameraField = (camera) =>
                {
                    if (_configuration.UpdateRingTree)
                    {
                        ring1TreeProxy.UpdateCamera(FovData.FromCamera(camera, repositioner));
                    }
                }
            });

            _ultraUpdatableContainer.AddUpdatableElement(new FieldBasedUltraUpdatable()
            {
                StartCameraField = (camera) =>
                {
                    ring1TreeProxy.CreateHeightmap(
                        new Ring1Tree.RootNodeCreationParameters()
                    {
                        InitialCameraPosition = repositioner.InvMove(camera.Position),
                        NodeListener          = eventCollector,
                        PrecisionDistances    = _gRingConfiguration.QuadLodPrecisionDistances,
                        UnityCoordsCalculator = unityCoordsCalculator
                    });
                }
            });
        }