コード例 #1
0
        public LevelEntity_Media(short index, Media media, LevelEntity_Level level)
        {
            NativeIndex  = index;
            NativeObject = media;
            ParentLevel  = level;

            BeginRuntimeStyleBehavior();
        }
コード例 #2
0
        public virtual void InitializeEntity(LevelEntity_Level parentLevel, short nativeIndex, object nativeObject)
        {
            ParentLevel       = parentLevel;
            NativeIndex       = nativeIndex;
            this.NativeObject = nativeObject;

            AssembleEntity();
        }
コード例 #3
0
ファイル: LevelData.cs プロジェクト: deramscholzara/ForgePlus
        private async Task BuildLevel()
        {
#if !UNITY_EDITOR
            GarbageCollector.GCMode = GarbageCollector.Mode.Disabled;
#endif

            var initializeLevelStartTime = DateTime.Now;

            runtimeLevel       = new GameObject($"Level ({LevelName})").AddComponent <LevelEntity_Level>();
            runtimeLevel.Level = level;
            runtimeLevel.Index = (short)LevelIndex;

            runtimeLevel.Polygons         = new Dictionary <short, LevelEntity_Polygon>();
            runtimeLevel.Lines            = new Dictionary <short, LevelEntity_Line>();
            runtimeLevel.Sides            = new Dictionary <short, LevelEntity_Side>();
            runtimeLevel.Lights           = new Dictionary <short, LevelEntity_Light>();
            runtimeLevel.Medias           = new Dictionary <short, LevelEntity_Media>();
            runtimeLevel.CeilingPlatforms = new Dictionary <short, LevelEntity_Platform>();
            runtimeLevel.FloorPlatforms   = new Dictionary <short, LevelEntity_Platform>();
            runtimeLevel.MapObjects       = new Dictionary <short, LevelEntity_MapObject>();
            runtimeLevel.Annotations      = new Dictionary <short, LevelEntity_Annotation>();

            runtimeLevel.EditableSurface_Polygons = new List <EditableSurface_Polygon>();
            runtimeLevel.EditableSurface_Sides    = new List <EditableSurface_Side>();
            runtimeLevel.EditableSurface_Medias   = new List <EditableSurface_Media>();

            // Clear out Walls Materials so it can be repopulated with the correct set
            MaterialGeneration_Geometry.ClearCollection();

            Debug.Log($"--- LevelBuild: Initialized Level in timespan: {DateTime.Now - initializeLevelStartTime}");

            await Task.Yield();

            #region Initialization_Textures
            var buildTexturesStartTime = DateTime.Now;

#if !NO_EDITING
            // Initialize Textures here so they in proper index order for the texturing interface
            var landscapeShapeDescriptor = new ShapeDescriptor();
            // Note: Landscape collections in Shapes are respectively sequential to Landscape map info starting at 27
            landscapeShapeDescriptor.Collection = (byte)(level.Landscape + 27);
            MaterialGeneration_Geometry.GetTexture(landscapeShapeDescriptor, returnPlaceholderIfNotFound: false);

            var wallShapeDescriptor = new ShapeDescriptor();
            // Note: Walls collections in Shapes are respectively sequential to Environment map info starting at 17
            wallShapeDescriptor.Collection = (byte)(level.Environment + 17);
            for (var i = 0; i < 256; i++)
            {
                wallShapeDescriptor.Bitmap = (byte)i;
                if (!MaterialGeneration_Geometry.GetTexture(wallShapeDescriptor, returnPlaceholderIfNotFound: false))
                {
                    break;
                }
            }
#endif

            Debug.Log($"--- LevelBuild: Built Textures in timespan: {DateTime.Now - buildTexturesStartTime}");
            #endregion Initialization_Textures

            await Task.Yield();

            #region Initialization_Lights
            var buildLightsStartTime = DateTime.Now;

            // Initialize Lights here so they are in proper index order
            for (var i = 0; i < level.Lights.Count; i++)
            {
                runtimeLevel.Lights[(short)i] = new LevelEntity_Light((short)i, level.Lights[i], runtimeLevel);
            }

            Debug.Log($"--- LevelBuild: Built & started Lights in timespan: {DateTime.Now - buildLightsStartTime}");
            #endregion Initialization_Lights

            await Task.Yield();

            #region Initialization_Medias
            var buildMediasStartTime = DateTime.Now;

            // Initialize Medias here so they are in proper index order
            for (var i = 0; i < level.Medias.Count; i++)
            {
                runtimeLevel.Medias[(short)i] = new LevelEntity_Media((short)i, level.Medias[i], runtimeLevel);
            }

            Debug.Log($"--- LevelBuild: Built & started Medias in timespan: {DateTime.Now - buildMediasStartTime}");
            #endregion Initialization_Medias

            await Task.Yield();

#if USE_TEXTURE_ARRAYS
            MaterialGeneration_Geometry.TextureArraysArePopulating = true;
#endif

            var chunkLoadStartTime = DateTime.Now;

            #region Polygons_And_Media
            var buildPolygonsStartTime = DateTime.Now;

            var polygonsGroupGO = new GameObject("Polygons");
            polygonsGroupGO.transform.SetParent(runtimeLevel.transform);

            for (short polygonIndex = 0; polygonIndex < level.Polygons.Count; polygonIndex++)
            {
                var polygon = level.Polygons[polygonIndex];

                var polygonRootGO = new GameObject($"Polygon ({polygonIndex})");
                polygonRootGO.transform.SetParent(polygonsGroupGO.transform);

                var runtimePolygon = polygonRootGO.AddComponent <LevelEntity_Polygon>();
                runtimeLevel.Polygons[polygonIndex] = runtimePolygon;
                runtimePolygon.InitializeEntity(runtimeLevel, polygonIndex, polygon);

                chunkLoadStartTime = await ChunkLoadYield(chunkLoadStartTime);
            }

            Debug.Log($"--- LevelBuild: Built Polygons, Medias, & Platforms in timespan: {DateTime.Now - buildPolygonsStartTime}");
            #endregion Polygons_And_Media

            await Task.Yield();

            #region Lines_And_Sides
            var buildSidesStartTime = DateTime.Now;

            var linesGroupGO = new GameObject("Lines");
            linesGroupGO.transform.SetParent(runtimeLevel.transform);

            for (short lineIndex = 0; lineIndex < level.Lines.Count; lineIndex++)
            {
                GameObject lineRootGO = new GameObject($"Line ({lineIndex})");
                lineRootGO.transform.SetParent(linesGroupGO.transform);

                var line = level.Lines[lineIndex];

                var runtimeLine = lineRootGO.AddComponent <LevelEntity_Line>();
                runtimeLevel.Lines[lineIndex] = runtimeLine;
                runtimeLine.NativeIndex       = lineIndex;
                runtimeLine.NativeObject      = line;
                runtimeLine.ParentLevel       = runtimeLevel;

                runtimeLine.GenerateSurfaces();

                chunkLoadStartTime = await ChunkLoadYield(chunkLoadStartTime);
            }

            Debug.Log($"--- LevelBuild: Built Lines & Sides in timespan: {DateTime.Now - buildSidesStartTime}");
            #endregion Lines_And_Sides

            await Task.Yield();

#if USE_TEXTURE_ARRAYS
            MaterialGeneration_Geometry.ApplyTextureArrays();

            MaterialGeneration_Geometry.TextureArraysArePopulating = false;

            await Task.Yield();
#endif

            #region Objects_And_Placements
            var buildObjectsStartTime = DateTime.Now;

            var mapObjectsGroupGO = new GameObject("MapObjects");
            mapObjectsGroupGO.transform.SetParent(runtimeLevel.transform);

            for (short objectIndex = 0; objectIndex < level.Objects.Count; objectIndex++)
            {
                var mapObject = level.Objects[objectIndex];

                var mapObjectRootGO = new GameObject($"MapObject: {mapObject.Type} ({objectIndex})");
                mapObjectRootGO.transform.SetParent(mapObjectsGroupGO.transform);

                var runtimeMapObject = mapObjectRootGO.AddComponent <LevelEntity_MapObject>();
                runtimeLevel.MapObjects[(short)objectIndex] = runtimeMapObject;
                runtimeMapObject.NativeIndex  = (short)objectIndex;
                runtimeMapObject.NativeObject = mapObject;
                runtimeMapObject.ParentLevel  = runtimeLevel;

                runtimeMapObject.GenerateObject();

                chunkLoadStartTime = await ChunkLoadYield(chunkLoadStartTime);
            }

            Debug.Log($"--- LevelBuild: Built Objects in timespan: {DateTime.Now - buildObjectsStartTime}");
            #endregion Objects_And_Placements

            await Task.Yield();

            #region Annotations
            var annotationsGroupGO = new GameObject("Annotations");
            annotationsGroupGO.transform.SetParent(runtimeLevel.transform);

            for (var i = 0; i < level.Annotations.Count; i++)
            {
                var annotation         = level.Annotations[i];
                var annotationInstance = UnityEngine.Object.Instantiate(LevelEntity_Annotation.Prefab);
                annotationInstance.NativeIndex  = (short)i;
                annotationInstance.NativeObject = annotation;
                annotationInstance.ParentLevel  = runtimeLevel;

                annotationInstance.RefreshLabel();

                var positionalHeight = (runtimeLevel.Polygons[annotation.PolygonIndex].NativeObject.FloorHeight + runtimeLevel.Polygons[annotation.PolygonIndex].NativeObject.CeilingHeight) / 2f / GeometryUtilities.WorldUnitIncrementsPerMeter;
                annotationInstance.transform.position = new Vector3(annotation.X / GeometryUtilities.WorldUnitIncrementsPerMeter, positionalHeight, -annotation.Y / GeometryUtilities.WorldUnitIncrementsPerMeter);

                annotationInstance.transform.SetParent(annotationsGroupGO.transform, worldPositionStays: true);

                runtimeLevel.Annotations[(short)i] = annotationInstance;
            }
            #endregion Annotations

            await Task.Yield();

#if !UNITY_EDITOR
            GarbageCollector.GCMode = GarbageCollector.Mode.Enabled;
#endif
        }
コード例 #4
0
 public override void InitializeEntity(LevelEntity_Level parentLevel, short nativeIndex, object nativeObject)
 {
     base.InitializeEntity(parentLevel, nativeIndex, nativeObject);
 }
コード例 #5
0
        public static LevelEntity_Side AssembleEntity(LevelEntity_Level level, bool isClockwise, short lineIndex)
        {
            var line = level.Level.Lines[lineIndex];

            var sideIndex = isClockwise ? line.ClockwisePolygonSideIndex : line.CounterclockwisePolygonSideIndex;

            // Note: A null-side may still be created as an untextured side
            var side = sideIndex < level.Level.Sides.Count && sideIndex >= 0 ? level.Level.Sides[sideIndex] : null;

            #region Facing_Elevations
            var facingPolygonIndex = isClockwise ? line.ClockwisePolygonOwner : line.CounterclockwisePolygonOwner;

            if (facingPolygonIndex < 0)
            {
                return(null);
            }

            var facingPolygon = level.Level.Polygons[facingPolygonIndex];

            Platform facingPlatform;
            facingPlatform = GeometryUtilities.GetPlatformForPolygon(level.Level, facingPolygon);

            var highestFacingCeiling = facingPolygon.CeilingHeight;
            var lowestFacingFloor    = facingPolygon.FloorHeight;

            if (facingPlatform != null)
            {
                if (facingPlatform.ComesFromFloor && facingPlatform.ComesFromCeiling)
                {
                    var roundedMidpoint = (short)Mathf.RoundToInt((facingPlatform.RuntimeMinimumHeight(level.Level) + facingPlatform.RuntimeMaximumHeight(level.Level)) * 0.5f);

                    highestFacingCeiling = (short)Mathf.Max(highestFacingCeiling, roundedMidpoint);
                    lowestFacingFloor    = (short)Mathf.Min(lowestFacingFloor, roundedMidpoint);
                }
                else if (facingPlatform.ComesFromFloor)
                {
                    lowestFacingFloor = (short)Mathf.Min(lowestFacingFloor, facingPlatform.RuntimeMinimumHeight(level.Level));
                }
                else if (facingPlatform.ComesFromCeiling)
                {
                    highestFacingCeiling = (short)Mathf.Max(highestFacingCeiling, facingPlatform.RuntimeMaximumHeight(level.Level));
                }
            }
            #endregion Facing_Elevations

            #region Opposing_Elevations
            var opposingPolygonIndex = isClockwise ? line.CounterclockwisePolygonOwner : line.ClockwisePolygonOwner;
            var hasOpposingPolygon   = opposingPolygonIndex >= 0;

            var opposingPolygon = hasOpposingPolygon ? level.Level.Polygons[opposingPolygonIndex] : null;

            Platform opposingPlatform = null;
            if (opposingPolygon != null)
            {
                opposingPlatform = GeometryUtilities.GetPlatformForPolygon(level.Level, opposingPolygon);
            }

            var lowestOpposingCeiling  = hasOpposingPolygon ? opposingPolygon.CeilingHeight : highestFacingCeiling;
            var highestOpposingCeiling = lowestOpposingCeiling;

            var highestOpposingFloor = hasOpposingPolygon ? opposingPolygon.FloorHeight : lowestFacingFloor;
            var lowestOpposingFloor  = highestOpposingFloor;

            if (opposingPlatform != null)
            {
                if (opposingPlatform.ComesFromFloor && opposingPlatform.ComesFromCeiling)
                {
                    var roundedMidpoint = (short)Mathf.RoundToInt((opposingPlatform.RuntimeMinimumHeight(level.Level) + opposingPlatform.RuntimeMaximumHeight(level.Level)) * 0.5f);

                    highestOpposingFloor  = (short)Mathf.Max(highestOpposingFloor, roundedMidpoint);
                    lowestOpposingCeiling = (short)Mathf.Min(lowestOpposingCeiling, roundedMidpoint);
                }
                else if (opposingPlatform.ComesFromFloor)
                {
                    highestOpposingFloor = (short)Mathf.Max(highestOpposingFloor, opposingPlatform.RuntimeMaximumHeight(level.Level));
                    lowestOpposingFloor  = opposingPlatform.RuntimeMinimumHeight(level.Level);
                }
                else if (opposingPlatform.ComesFromCeiling)
                {
                    highestOpposingCeiling = opposingPlatform.RuntimeMaximumHeight(level.Level);
                    lowestOpposingCeiling  = (short)Mathf.Min(lowestOpposingCeiling, opposingPlatform.RuntimeMinimumHeight(level.Level));
                }
            }
            #endregion Opposing_Elevations

            #region Exposure_Determination
            // Data-driven surface-exposure
            var dataExpectsFullSide = side != null &&
                                      side.Type == SideType.Full &&
                                      !side.Primary.Texture.IsEmpty();
            var dataExpectsTop = !dataExpectsFullSide &&
                                 side != null &&
                                 (side.Type == SideType.High || side.Type == SideType.Split);

            // Geometry-driven surface-exposure
            var exposesTop = !dataExpectsFullSide &&
                             hasOpposingPolygon &&
                             highestFacingCeiling > lowestOpposingCeiling;

            var exposesMiddle = (!hasOpposingPolygon ||
                                 (line.Flags & LineFlags.HasTransparentSide) != 0 ||
                                 dataExpectsFullSide) &&
                                highestFacingCeiling > lowestFacingFloor &&
                                (highestOpposingCeiling > lowestOpposingFloor || dataExpectsFullSide);

            var exposesBottom = !dataExpectsFullSide &&
                                hasOpposingPolygon &&
                                highestOpposingFloor > lowestFacingFloor;
            #endregion Exposure_Determination

            #region Surface_Assembly
            LevelEntity_Side runtimeSide = null;

            if (exposesTop)
            {
                // Top is always Primary
                var sideDataSource = DataSources.Primary;

                var highHeight = highestFacingCeiling;
                var lowHeight  = lowestOpposingCeiling;

                CreateSideRoot(ref runtimeSide, isClockwise, sideIndex, side, level, lineIndex);

                runtimeSide.PrimaryHighElevation = highHeight;
                runtimeSide.PrimaryLowElevation  = lowHeight;

                var surface = new GameObject($"Side Top ({sideIndex}) (High - Source:{sideDataSource})").AddComponent <RuntimeSurfaceGeometry>();
                surface.transform.SetParent(runtimeSide.transform);
                surface.InitializeRuntimeSurface(runtimeSide, sideDataSource);

                runtimeSide.PrimarySurface = surface;
                runtimeSide.TopSurface     = surface;
            }

            if (exposesMiddle)
            {
                // Primary if there's no opposing polygon or it's explicitly "full", Transparent otherwise
                var sideDataSource = (!hasOpposingPolygon || dataExpectsFullSide) ? DataSources.Primary : DataSources.Transparent;

                var hasLayeredTransparentSide = side.HasLayeredTransparentSide(level.Level);
                var highHeight = dataExpectsFullSide ? highestFacingCeiling : line.LowestAdjacentCeiling;
                var lowHeight  = dataExpectsFullSide ? lowestFacingFloor : line.HighestAdjacentFloor;

                var typeDescriptor = hasOpposingPolygon ? $"Transparent - HasTransparentSide - Source:{sideDataSource}" : $"Full - Unopposed - Source:{sideDataSource}";

                CreateSideRoot(ref runtimeSide, isClockwise, sideIndex, side, level, lineIndex);

                if (sideDataSource == DataSources.Primary)
                {
                    runtimeSide.PrimaryHighElevation = highHeight;
                    runtimeSide.PrimaryLowElevation  = lowHeight;
                }

                if (sideDataSource == DataSources.Transparent || hasLayeredTransparentSide)
                {
                    runtimeSide.TransparentHighElevation = highHeight;
                    runtimeSide.TransparentLowElevation  = lowHeight;
                }

                var surface = new GameObject($"Side Middle ({sideIndex}) - ({typeDescriptor})").AddComponent <RuntimeSurfaceGeometry>();
                surface.transform.SetParent(runtimeSide.transform);
                surface.InitializeRuntimeSurface(runtimeSide, sideDataSource);

                if (sideDataSource == DataSources.Primary)
                {
                    runtimeSide.PrimarySurface = surface;
                }

                if (sideDataSource == DataSources.Transparent || hasLayeredTransparentSide)
                {
                    runtimeSide.TransparentSurface = surface;
                }

                runtimeSide.MiddleSurface = surface;
            }

            if (exposesBottom)
            {
                // Secondary if there is an exposable or expected (in data) top section
                var sideDataSource = dataExpectsTop ? DataSources.Secondary : DataSources.Primary;

                var highHeight = highestOpposingFloor;
                var lowHeight  = lowestFacingFloor;

                CreateSideRoot(ref runtimeSide, isClockwise, sideIndex, side, level, lineIndex);

                if (sideDataSource == DataSources.Primary)
                {
                    runtimeSide.PrimaryHighElevation = highHeight;
                    runtimeSide.PrimaryLowElevation  = lowHeight;
                }
                else
                {
                    runtimeSide.SecondaryHighElevation = highHeight;
                    runtimeSide.SecondaryLowElevation  = lowHeight;
                }

                var surface = new GameObject($"Side Bottom ({sideIndex}) (Low - Source:{sideDataSource})").AddComponent <RuntimeSurfaceGeometry>();
                surface.transform.SetParent(runtimeSide.transform);
                surface.InitializeRuntimeSurface(runtimeSide, sideDataSource);

                if (sideDataSource == DataSources.Primary)
                {
                    runtimeSide.PrimarySurface = surface;
                }
                else
                {
                    runtimeSide.SecondarySurface = surface;
                }

                runtimeSide.BottomSurface = surface;
            }
            #endregion Surface_Assembly

            return(runtimeSide);
        }
コード例 #6
0
        private static void CreateSideRoot(ref LevelEntity_Side runtimeSide, bool isClockwise, short sideIndex, Side side, LevelEntity_Level parentLevel, short parentLineIndex)
        {
            if (!runtimeSide)
            {
                var sideGO = new GameObject(isClockwise ? $"Clockwise ({sideIndex})" : $"Counterclockwise ({sideIndex})");
                runtimeSide = sideGO.AddComponent <LevelEntity_Side>();
                runtimeSide.ParentLineIndex = parentLineIndex;
                runtimeSide.IsClockwise     = isClockwise;

                runtimeSide.InitializeEntity(parentLevel, sideIndex, side);

                parentLevel.Sides[sideIndex] = runtimeSide;
            }
        }