示例#1
0
        protected override void OnUpdate()
        {
            // UI text conversion
            Entities.ForEach((TextMeshProUGUI displayText) =>
            {
                // We are converting an entity (textEntity) and creating another (eSubText).
                // Why?
                // We want to use the Rectangle Transform system to also position text, rather
                // than introduce something special. So we need a parent element that is the frame
                // of the text (textEntity) and a child element that has a pivet on the text string
                // itself. Systems later will process the child element.

                var textEntity = GetPrimaryEntity(displayText);

                // Sub-text child transform
                SceneSection sceneSection = DstEntityManager.GetSharedComponentData <SceneSection>(textEntity);
                var eSubText = DstEntityManager.CreateEntity();
                DstEntityManager.AddSharedComponentData(eSubText, sceneSection);

                DstEntityManager.AddComponentData(eSubText, new Tiny.UI.RectTransform
                {
                    AnchorMin        = 0.5f,
                    AnchorMax        = 0.5f,
                    SizeDelta        = 1f,
                    AnchoredPosition = 0f,
                    Pivot            = 0.5f
                });

                DstEntityManager.AddComponentData(eSubText, new UIName()
                {
                    Name = displayText.name
                });

                DstEntityManager.AddComponentData(eSubText, new RectParent()
                {
                    Value = textEntity
                });

                DstEntityManager.AddComponentData(eSubText, new Unity.Tiny.Rendering.CameraMask
                {
                    mask = (ulong)(1 << displayText.gameObject.layer)
                });

                DstEntityManager.AddComponent <RectTransformResult>(eSubText);

                var fontAsset = GetPrimaryEntity(displayText.font);
                DstEntityManager.AddComponentData(eSubText, new Tiny.Text.TextRenderer
                {
                    FontMaterial        = fontAsset,
                    MeshColor           = displayText.color.linear.ToTiny(),
                    Size                = displayText.fontSize * 10,
                    HorizontalAlignment = ConvertHorizontalAlignment(displayText.alignment),
                    VerticalAlignment   = ConvertVerticalAlignment(displayText.alignment),
                });

                var text = displayText.text;
                DstEntityManager.AddBufferFromString <TextRendererString>(eSubText, text);
                DstEntityManager.AddComponent <LocalToWorld>(eSubText);
            });
        }
示例#2
0
        Entity ConstructScreenSpaceCamera(Entity e, UnityEngine.RectTransform urc)
        {
            SceneSection sceneSection = DstEntityManager.GetSharedComponentData <SceneSection>(e);
            Entity       eCam         = DstEntityManager.CreateEntity();

            DstEntityManager.AddSharedComponentData(eCam, sceneSection);

            var sizeDelta = urc.sizeDelta;

            var camera = new Unity.Tiny.Rendering.Camera
            {
                clearFlags      = Tiny.Rendering.CameraClearFlags.DepthOnly,
                backgroundColor = new Unity.Tiny.Color(0, 0, 0, 0),
                viewportRect    = new Tiny.Rect(0, 0, 1, 1),
                depth           = 0.0f,
                fov             = sizeDelta.y * 0.5f,
                mode            = ProjectionMode.Orthographic,
                clipZNear       = 0,
                clipZFar        = 102,
                aspect          = sizeDelta.x / sizeDelta.y
            };

            DstEntityManager.AddComponentData(eCam, camera);
            DstEntityManager.AddComponentData(eCam,
                                              new Unity.Tiny.Rendering.CameraMask {
                mask = (ulong)(1 << urc.gameObject.layer)
            });

            // For CameraSettings2D
            float3 customSortAxisSetting = new float3(0, 0, 1.0f);

            if (UnityEngine.Rendering.GraphicsSettings.transparencySortMode ==
                UnityEngine.TransparencySortMode.CustomAxis)
            {
                customSortAxisSetting = UnityEngine.Rendering.GraphicsSettings.transparencySortAxis;
            }
            DstEntityManager.AddComponentData(eCam, new Unity.Tiny.Rendering.CameraSettings2D
            {
                customSortAxis = customSortAxisSetting
            });

            // tag the camera as auto aspect
            DstEntityManager.AddComponentData(eCam, new CameraAutoAspectFromNode {
                Node = Entity.Null
            });

            DstEntityManager.AddComponentData(eCam, new LocalToWorld {
                Value = float4x4.identity
            });
            DstEntityManager.AddComponentData(eCam,
                                              new Translation {
                Value = new float3(sizeDelta.x / 2, sizeDelta.y / 2, -10)
            });
            DstEntityManager.AddComponentData(eCam, new Rotation {
                Value = quaternion.identity
            });
            DstEntityManager.AddComponent <UICamera>(eCam);
            return(eCam);
        }
示例#3
0
        public System.Collections.Generic.List <byte> __encode()
        {
            var data = new System.Collections.Generic.List <byte>();

            if (this.section == null)
            {
                this.section = new SceneSection();
            }
            data.AddRange(this.section.__encode());
            return(data);
        }
示例#4
0
    void RecursivelySetSection(Transform transform, SceneSection section)
    {
        foreach (var entity in GetEntities(transform.gameObject))
        {
            DstEntityManager.SetSharedComponentData(entity, section);
        }

        for (int i = 0; i != transform.childCount; i++)
        {
            RecursivelySetSection(transform.GetChild(i), section);
        }
    }
示例#5
0
        private void UpdateSceneLoading(out NativeList <SceneSection> sceneSectionsToInit)
        {
            NativeList <SceneSection> completeSceneSections = new NativeList <SceneSection>(4, Allocator.Temp);

            EntityCommandBuffer ecb = _ecbSystem.CreateCommandBuffer();

            Entities.WithNone <PersistentSceneSectionLoadComplete>().ForEach((Entity entity, ref RequestPersistentSceneSectionLoaded requestInfo, in SceneSectionData sceneSectionData) =>
            {
                if (requestInfo.CurrentLoadingStage == RequestPersistentSceneSectionLoaded.Stage.Complete)
                {
                    return;
                }

                SceneSection sceneSection = new SceneSection
                {
                    Section   = sceneSectionData.SubSectionIndex,
                    SceneGUID = sceneSectionData.SceneGUID
                };

                if (requestInfo.CurrentLoadingStage == RequestPersistentSceneSectionLoaded.Stage.InitialStage)
                {
                    ecb.AddComponent <PersistentSceneSection>(entity);
                    ecb.AddComponent(entity, new RequestSceneLoaded()
                    {
                        LoadFlags = requestInfo.LoadFlags
                    });
                    requestInfo.CurrentLoadingStage = RequestPersistentSceneSectionLoaded.Stage.WaitingForSceneLoad;
                }
                if (requestInfo.CurrentLoadingStage == RequestPersistentSceneSectionLoaded.Stage.WaitingForSceneLoad)
                {
                    // Pls make SceneSectionStreamingSystem.StreamingState public :) @unity
                    _sceneSectionLoadedCheckQuery.SetSharedComponentFilter(sceneSection);
                    if (_sceneSectionLoadedCheckQuery.CalculateChunkCount() > 0)
                    {
                        completeSceneSections.Add(sceneSection);
                        ecb.AddComponent <PersistentSceneSectionLoadComplete>(entity);
                        requestInfo.CurrentLoadingStage = RequestPersistentSceneSectionLoaded.Stage.Complete;
                    }
                }
            }).WithoutBurst().Run();

            _sceneSectionLoadedCheckQuery.ResetFilter();
            sceneSectionsToInit = completeSceneSections;
        }
示例#6
0
 public int __decode(byte[] binData, ref int pos)
 {
     this.section = new SceneSection();
     this.section.__decode(binData, ref pos);
     return(pos);
 }
示例#7
0
 public SceneSectionNotice(SceneSection section)
 {
     this.section = section;
 }
示例#8
0
 public SceneSectionNotice()
 {
     section = new SceneSection();
 }
        public static SceneData[] WriteEntityScene(Scene scene, Hash128 sceneGUID, ConversionFlags conversionFlags)
        {
            var world         = new World("ConversionWorld");
            var entityManager = world.EntityManager;

            ConvertScene(scene, sceneGUID, world, conversionFlags);
            EntitySceneOptimization.Optimize(world);

            var sceneSections = new List <SceneData>();

            var subSectionList = new List <SceneSection>();

            entityManager.GetAllUniqueSharedComponentData(subSectionList);
            var extRefInfoEntities = new NativeArray <Entity>(subSectionList.Count, Allocator.Temp);

            NativeArray <Entity> entitiesInMainSection;

            var sectionQuery = entityManager.CreateEntityQuery(
                new EntityQueryDesc
            {
                All     = new[] { ComponentType.ReadWrite <SceneSection>() },
                Options = EntityQueryOptions.IncludePrefab | EntityQueryOptions.IncludeDisabled
            }
                );

            var sectionBoundsQuery = entityManager.CreateEntityQuery(
                new EntityQueryDesc
            {
                All     = new[] { ComponentType.ReadWrite <SceneBoundingVolume>(), ComponentType.ReadWrite <SceneSection>() },
                Options = EntityQueryOptions.IncludePrefab | EntityQueryOptions.IncludeDisabled
            }
                );

            {
                var section = new SceneSection {
                    SceneGUID = sceneGUID, Section = 0
                };
                sectionQuery.SetFilter(new SceneSection {
                    SceneGUID = sceneGUID, Section = 0
                });
                sectionBoundsQuery.SetFilter(new SceneSection {
                    SceneGUID = sceneGUID, Section = 0
                });
                entitiesInMainSection = sectionQuery.ToEntityArray(Allocator.TempJob);


                var bounds = GetBoundsAndDestroy(entityManager, sectionBoundsQuery);

                // Each section will be serialized in its own world, entities that don't have a section are part of the main scene.
                // An entity that holds the array of external references to the main scene is required for each section.
                // We need to create them all before we start moving entities to section scenes,
                // otherwise they would reuse entities that have been moved and mess up the remapping tables.
                for (int sectionIndex = 1; sectionIndex < subSectionList.Count; ++sectionIndex)
                {
                    if (subSectionList[sectionIndex].Section == 0)
                    {
                        // Main section, the only one that doesn't need an external ref array
                        continue;
                    }

                    var extRefInfoEntity = entityManager.CreateEntity();
                    entityManager.AddSharedComponentData(extRefInfoEntity, subSectionList[sectionIndex]);
                    extRefInfoEntities[sectionIndex] = extRefInfoEntity;
                }

                // Public references array, only on the main section.
                var refInfoEntity = entityManager.CreateEntity();
                entityManager.AddBuffer <PublicEntityRef>(refInfoEntity);
                entityManager.AddSharedComponentData(refInfoEntity, section);
                var publicRefs = entityManager.GetBuffer <PublicEntityRef>(refInfoEntity);

//                entityManager.Debug.CheckInternalConsistency();

                //@TODO do we need to keep this index? doesn't carry any additional info
                for (int i = 0; i < entitiesInMainSection.Length; ++i)
                {
                    PublicEntityRef.Add(ref publicRefs,
                                        new PublicEntityRef {
                        entityIndex = i, targetEntity = entitiesInMainSection[i]
                    });
                }

                Debug.Assert(publicRefs.Length == entitiesInMainSection.Length);

                // Save main section
                var sectionWorld   = new World("SectionWorld");
                var sectionManager = sectionWorld.EntityManager;

                var entityRemapping = entityManager.CreateEntityRemapArray(Allocator.TempJob);
                sectionManager.MoveEntitiesFrom(entityManager, sectionQuery, entityRemapping);

                // The section component is only there to break the conversion world into different sections
                // We don't want to store that on the disk
                //@TODO: Component should be removed but currently leads to corrupt data file. Figure out why.
                //sectionManager.RemoveComponent(sectionManager.UniversalQuery, typeof(SceneSection));

                var sectionFileSize = WriteEntityScene(sectionManager, sceneGUID, "0");
                sceneSections.Add(new SceneData
                {
                    FileSize             = sectionFileSize,
                    SceneGUID            = sceneGUID,
                    SharedComponentCount = sectionManager.GetSharedComponentCount() - 1,
                    SubSectionIndex      = 0,
                    BoundingVolume       = bounds
                });

                entityRemapping.Dispose();
                sectionWorld.Dispose();
            }

            {
                // Index 0 is the default value of the shared component, not an actual section
                for (int subSectionIndex = 0; subSectionIndex < subSectionList.Count; ++subSectionIndex)
                {
                    var subSection = subSectionList[subSectionIndex];
                    if (subSection.Section == 0)
                    {
                        continue;
                    }

                    sectionQuery.SetFilter(subSection);
                    sectionBoundsQuery.SetFilter(subSection);

                    var bounds = GetBoundsAndDestroy(entityManager, sectionBoundsQuery);

                    var entitiesInSection = sectionQuery.ToEntityArray(Allocator.TempJob);

                    if (entitiesInSection.Length > 0)
                    {
                        // Fetch back the external reference entity we created earlier to not disturb the mapping
                        var refInfoEntity = extRefInfoEntities[subSectionIndex];
                        entityManager.AddBuffer <ExternalEntityRef>(refInfoEntity);
                        var externRefs = entityManager.GetBuffer <ExternalEntityRef>(refInfoEntity);

                        // Store the mapping to everything in the main section
                        //@TODO maybe we don't need all that? is this worth worrying about?
                        for (int i = 0; i < entitiesInMainSection.Length; ++i)
                        {
                            ExternalEntityRef.Add(ref externRefs, new ExternalEntityRef {
                                entityIndex = i
                            });
                        }

                        var entityRemapping = entityManager.CreateEntityRemapArray(Allocator.TempJob);

                        // Entities will be remapped to a contiguous range in the section world, but they will
                        // also come with an unpredictable amount of meta entities. We have the guarantee that
                        // the entities in the main section won't be moved over, so there's a free range of that
                        // size at the end of the remapping table. So we use that range for external references.
                        var externEntityIndexStart = entityRemapping.Length - entitiesInMainSection.Length;

                        entityManager.AddComponentData(refInfoEntity,
                                                       new ExternalEntityRefInfo
                        {
                            SceneGUID        = sceneGUID,
                            EntityIndexStart = externEntityIndexStart
                        });

                        var sectionWorld   = new World("SectionWorld");
                        var sectionManager = sectionWorld.EntityManager;

                        // Insert mapping for external references, conversion world entity to virtual index in section
                        for (int i = 0; i < entitiesInMainSection.Length; ++i)
                        {
                            EntityRemapUtility.AddEntityRemapping(ref entityRemapping, entitiesInMainSection[i],
                                                                  new Entity {
                                Index = i + externEntityIndexStart, Version = 1
                            });
                        }

                        sectionManager.MoveEntitiesFrom(entityManager, sectionQuery, entityRemapping);

                        // Now that all the required entities have been moved over, we can get rid of the gap between
                        // real entities and external references. This allows remapping during load to deal with a
                        // smaller remap table, containing only useful entries.

                        int highestEntityIndexInUse = 0;
                        for (int i = 0; i < externEntityIndexStart; ++i)
                        {
                            var targetIndex = entityRemapping[i].Target.Index;
                            if (targetIndex < externEntityIndexStart && targetIndex > highestEntityIndexInUse)
                            {
                                highestEntityIndexInUse = targetIndex;
                            }
                        }

                        var oldExternEntityIndexStart = externEntityIndexStart;
                        externEntityIndexStart = highestEntityIndexInUse + 1;

                        sectionManager.SetComponentData
                        (
                            EntityRemapUtility.RemapEntity(ref entityRemapping, refInfoEntity),
                            new ExternalEntityRefInfo
                        {
                            SceneGUID        = sceneGUID,
                            EntityIndexStart = externEntityIndexStart
                        }
                        );

                        // When writing the scene, references to missing entities are set to Entity.Null by default
                        // (but only if they have been used, otherwise they remain untouched)
                        // We obviously don't want that to happen to our external references, so we add explicit mapping
                        // And at the same time, we put them back at the end of the effective range of real entities.
                        for (int i = 0; i < entitiesInMainSection.Length; ++i)
                        {
                            var src = new Entity {
                                Index = i + oldExternEntityIndexStart, Version = 1
                            };
                            var dst = new Entity {
                                Index = i + externEntityIndexStart, Version = 1
                            };
                            EntityRemapUtility.AddEntityRemapping(ref entityRemapping, src, dst);
                        }

                        // The section component is only there to break the conversion world into different sections
                        // We don't want to store that on the disk
                        //@TODO: Component should be removed but currently leads to corrupt data file. Figure out why.
                        //sectionManager.RemoveComponent(sectionManager.UniversalQuery, typeof(SceneSection));

                        var fileSize = WriteEntityScene(sectionManager, sceneGUID, subSection.Section.ToString(), entityRemapping);
                        sceneSections.Add(new SceneData
                        {
                            FileSize             = fileSize,
                            SceneGUID            = sceneGUID,
                            SharedComponentCount = sectionManager.GetSharedComponentCount() - 1,
                            SubSectionIndex      = subSection.Section,
                            BoundingVolume       = bounds
                        });

                        entityRemapping.Dispose();
                        sectionWorld.Dispose();
                    }

                    entitiesInSection.Dispose();
                }
            }

            {
                var noSectionQuery = entityManager.CreateEntityQuery(
                    new EntityQueryDesc
                {
                    None    = new[] { ComponentType.ReadWrite <SceneSection>() },
                    Options = EntityQueryOptions.IncludePrefab | EntityQueryOptions.IncludeDisabled
                }
                    );
                if (noSectionQuery.CalculateLength() != 0)
                {
                    Debug.LogWarning($"{noSectionQuery.CalculateLength()} entities in the scene '{scene.path}' had no SceneSection and as a result were not serialized at all.");
                }
            }

            sectionQuery.Dispose();
            sectionBoundsQuery.Dispose();
            entitiesInMainSection.Dispose();
            world.Dispose();

            // Save the new header
            var header = ScriptableObject.CreateInstance <SubSceneHeader>();

            header.Sections = sceneSections.ToArray();

            WriteHeader(sceneGUID, header);

            return(sceneSections.ToArray());
        }
示例#10
0
        public static SceneSectionData[] WriteEntityScene(Scene scene, GameObjectConversionSettings settings, List <ReferencedUnityObjects> sectionRefObjs = null)
        {
            int framesToRetainBlobAssets = RetainBlobAssetsSetting.GetFramesToRetainBlobAssets(settings.BuildConfiguration);

            var world         = new World("ConversionWorld");
            var entityManager = world.EntityManager;

            settings.DestinationWorld = world;

            bool disposeBlobAssetCache = false;

            if (settings.BlobAssetStore == null)
            {
                settings.BlobAssetStore = new BlobAssetStore();
                disposeBlobAssetCache   = true;
            }

            List <(int, LogEventData)> journalData = null;

            settings.ConversionWorldPreDispose += conversionWorld =>
            {
                var mappingSystem = conversionWorld.GetExistingSystem <GameObjectConversionMappingSystem>();
                journalData = mappingSystem.JournalData.SelectLogEventsOrdered().ToList();
            };

            ConvertScene(scene, settings);
            EntitySceneOptimization.Optimize(world);

            if (settings.AssetImportContext != null)
            {
                using (var allTypes = new NativeHashMap <ComponentType, int>(100, Allocator.Temp))
                    using (var archetypes = new NativeList <EntityArchetype>(Allocator.Temp))
                    {
                        entityManager.GetAllArchetypes(archetypes);
                        foreach (var archetype in archetypes)
                        {
                            using (var componentTypes = archetype.GetComponentTypes())
                                foreach (var componentType in componentTypes)
                                {
                                    if (allTypes.TryAdd(componentType, 0))
                                    {
                                        TypeDependencyCache.AddDependency(settings.AssetImportContext, componentType);
                                    }
                                }
                        }
                    }

                TypeDependencyCache.AddAllSystemsDependency(settings.AssetImportContext);
            }


            var sceneSections = new List <SceneSectionData>();

            var subSectionList = new List <SceneSection>();

            entityManager.GetAllUniqueSharedComponentData(subSectionList);
            var extRefInfoEntities = new NativeArray <Entity>(subSectionList.Count, Allocator.Temp);

            NativeArray <Entity> entitiesInMainSection;

            var sectionQuery = entityManager.CreateEntityQuery(
                new EntityQueryDesc
            {
                All     = new[] { ComponentType.ReadWrite <SceneSection>() },
                Options = EntityQueryOptions.IncludePrefab | EntityQueryOptions.IncludeDisabled
            }
                );

            var sectionBoundsQuery = entityManager.CreateEntityQuery(
                new EntityQueryDesc
            {
                All     = new[] { ComponentType.ReadWrite <SceneBoundingVolume>(), ComponentType.ReadWrite <SceneSection>() },
                Options = EntityQueryOptions.IncludePrefab | EntityQueryOptions.IncludeDisabled
            }
                );

            var sceneGUID = settings.SceneGUID;

            {
                var section = new SceneSection {
                    SceneGUID = sceneGUID, Section = 0
                };
                sectionQuery.SetSharedComponentFilter(new SceneSection {
                    SceneGUID = sceneGUID, Section = 0
                });
                sectionBoundsQuery.SetSharedComponentFilter(new SceneSection {
                    SceneGUID = sceneGUID, Section = 0
                });
                entitiesInMainSection = sectionQuery.ToEntityArray(Allocator.TempJob);


                var bounds = GetBoundsAndRemove(entityManager, sectionBoundsQuery);

                // Each section will be serialized in its own world, entities that don't have a section are part of the main scene.
                // An entity that holds the array of external references to the main scene is required for each section.
                // We need to create them all before we start moving entities to section scenes,
                // otherwise they would reuse entities that have been moved and mess up the remapping tables.
                for (int sectionIndex = 1; sectionIndex < subSectionList.Count; ++sectionIndex)
                {
                    if (subSectionList[sectionIndex].Section == 0)
                    {
                        // Main section, the only one that doesn't need an external ref array
                        continue;
                    }

                    var extRefInfoEntity = entityManager.CreateEntity();
                    entityManager.AddSharedComponentData(extRefInfoEntity, subSectionList[sectionIndex]);
                    extRefInfoEntities[sectionIndex] = extRefInfoEntity;
                }

                // Public references array, only on the main section.
                var refInfoEntity = entityManager.CreateEntity();
                entityManager.AddBuffer <PublicEntityRef>(refInfoEntity);
                entityManager.AddSharedComponentData(refInfoEntity, section);
                var publicRefs = entityManager.GetBuffer <PublicEntityRef>(refInfoEntity);

//                entityManager.Debug.CheckInternalConsistency();

                //@TODO do we need to keep this index? doesn't carry any additional info
                for (int i = 0; i < entitiesInMainSection.Length; ++i)
                {
                    PublicEntityRef.Add(ref publicRefs,
                                        new PublicEntityRef {
                        entityIndex = i, targetEntity = entitiesInMainSection[i]
                    });
                }

                UnityEngine.Debug.Assert(publicRefs.Length == entitiesInMainSection.Length);

                // Save main section
                var sectionWorld   = new World("SectionWorld");
                var sectionManager = sectionWorld.EntityManager;

                var entityRemapping = entityManager.CreateEntityRemapArray(Allocator.TempJob);
                sectionManager.MoveEntitiesFrom(entityManager, sectionQuery, entityRemapping);

                AddRetainBlobAssetsEntity(sectionManager, framesToRetainBlobAssets);

                // The section component is only there to break the conversion world into different sections
                // We don't want to store that on the disk
                //@TODO: Component should be removed but currently leads to corrupt data file. Figure out why.
                //sectionManager.RemoveComponent(sectionManager.UniversalQuery, typeof(SceneSection));

                var sectionFileSize = WriteEntityScene(sectionManager, sceneGUID, "0", settings, out var objectRefCount, out var objRefs);
                sectionRefObjs?.Add(objRefs);
                sceneSections.Add(new SceneSectionData
                {
                    FileSize             = sectionFileSize,
                    SceneGUID            = sceneGUID,
                    ObjectReferenceCount = objectRefCount,
                    SubSectionIndex      = 0,
                    BoundingVolume       = bounds
                });

                entityRemapping.Dispose();
                sectionWorld.Dispose();
            }

            {
                // Index 0 is the default value of the shared component, not an actual section
                for (int subSectionIndex = 0; subSectionIndex < subSectionList.Count; ++subSectionIndex)
                {
                    var subSection = subSectionList[subSectionIndex];
                    if (subSection.Section == 0)
                    {
                        continue;
                    }

                    sectionQuery.SetSharedComponentFilter(subSection);
                    sectionBoundsQuery.SetSharedComponentFilter(subSection);

                    var bounds = GetBoundsAndRemove(entityManager, sectionBoundsQuery);

                    var entitiesInSection = sectionQuery.ToEntityArray(Allocator.TempJob);

                    if (entitiesInSection.Length > 0)
                    {
                        // Fetch back the external reference entity we created earlier to not disturb the mapping
                        var refInfoEntity = extRefInfoEntities[subSectionIndex];
                        entityManager.AddBuffer <ExternalEntityRef>(refInfoEntity);
                        var externRefs = entityManager.GetBuffer <ExternalEntityRef>(refInfoEntity);

                        // Store the mapping to everything in the main section
                        //@TODO maybe we don't need all that? is this worth worrying about?
                        for (int i = 0; i < entitiesInMainSection.Length; ++i)
                        {
                            ExternalEntityRef.Add(ref externRefs, new ExternalEntityRef {
                                entityIndex = i
                            });
                        }

                        var entityRemapping = entityManager.CreateEntityRemapArray(Allocator.TempJob);

                        // Entities will be remapped to a contiguous range in the section world, but they will
                        // also come with an unpredictable amount of meta entities. We have the guarantee that
                        // the entities in the main section won't be moved over, so there's a free range of that
                        // size at the end of the remapping table. So we use that range for external references.
                        var externEntityIndexStart = entityRemapping.Length - entitiesInMainSection.Length;

                        entityManager.AddComponentData(refInfoEntity,
                                                       new ExternalEntityRefInfo
                        {
                            SceneGUID        = sceneGUID,
                            EntityIndexStart = externEntityIndexStart
                        });

                        var sectionWorld   = new World("SectionWorld");
                        var sectionManager = sectionWorld.EntityManager;

                        // Insert mapping for external references, conversion world entity to virtual index in section
                        for (int i = 0; i < entitiesInMainSection.Length; ++i)
                        {
                            EntityRemapUtility.AddEntityRemapping(ref entityRemapping, entitiesInMainSection[i],
                                                                  new Entity {
                                Index = i + externEntityIndexStart, Version = 1
                            });
                        }

                        sectionManager.MoveEntitiesFrom(entityManager, sectionQuery, entityRemapping);

                        AddRetainBlobAssetsEntity(sectionManager, framesToRetainBlobAssets);
                        // Now that all the required entities have been moved over, we can get rid of the gap between
                        // real entities and external references. This allows remapping during load to deal with a
                        // smaller remap table, containing only useful entries.

                        int highestEntityIndexInUse = 0;
                        for (int i = 0; i < externEntityIndexStart; ++i)
                        {
                            var targetIndex = entityRemapping[i].Target.Index;
                            if (targetIndex < externEntityIndexStart && targetIndex > highestEntityIndexInUse)
                            {
                                highestEntityIndexInUse = targetIndex;
                            }
                        }

                        var oldExternEntityIndexStart = externEntityIndexStart;
                        externEntityIndexStart = highestEntityIndexInUse + 1;

                        sectionManager.SetComponentData
                        (
                            EntityRemapUtility.RemapEntity(ref entityRemapping, refInfoEntity),
                            new ExternalEntityRefInfo
                        {
                            SceneGUID        = sceneGUID,
                            EntityIndexStart = externEntityIndexStart
                        }
                        );

                        // When writing the scene, references to missing entities are set to Entity.Null by default
                        // (but only if they have been used, otherwise they remain untouched)
                        // We obviously don't want that to happen to our external references, so we add explicit mapping
                        // And at the same time, we put them back at the end of the effective range of real entities.
                        for (int i = 0; i < entitiesInMainSection.Length; ++i)
                        {
                            var src = new Entity {
                                Index = i + oldExternEntityIndexStart, Version = 1
                            };
                            var dst = new Entity {
                                Index = i + externEntityIndexStart, Version = 1
                            };
                            EntityRemapUtility.AddEntityRemapping(ref entityRemapping, src, dst);
                        }

                        // The section component is only there to break the conversion world into different sections
                        // We don't want to store that on the disk
                        //@TODO: Component should be removed but currently leads to corrupt data file. Figure out why.
                        //sectionManager.RemoveComponent(sectionManager.UniversalQuery, typeof(SceneSection));
                        var fileSize = WriteEntityScene(sectionManager, sceneGUID, subSection.Section.ToString(), settings, out var objectRefCount, out var objRefs, entityRemapping);
                        sectionRefObjs?.Add(objRefs);
                        sceneSections.Add(new SceneSectionData
                        {
                            FileSize             = fileSize,
                            SceneGUID            = sceneGUID,
                            ObjectReferenceCount = objectRefCount,
                            SubSectionIndex      = subSection.Section,
                            BoundingVolume       = bounds
                        });

                        entityRemapping.Dispose();
                        sectionWorld.Dispose();
                    }

                    entitiesInSection.Dispose();
                }
            }

            {
                var noSectionQuery = entityManager.CreateEntityQuery(
                    new EntityQueryDesc
                {
                    None    = new[] { ComponentType.ReadWrite <SceneSection>() },
                    Options = EntityQueryOptions.IncludePrefab | EntityQueryOptions.IncludeDisabled
                }
                    );
                if (noSectionQuery.CalculateEntityCount() != 0)
                {
                    Debug.LogWarning($"{noSectionQuery.CalculateEntityCount()} entities in the scene '{scene.path}' had no SceneSection and as a result were not serialized at all.");
                }
            }

            sectionQuery.Dispose();
            sectionBoundsQuery.Dispose();
            entitiesInMainSection.Dispose();
            world.Dispose();

            // Save the new header

            var sceneSectionsArray = sceneSections.ToArray();

            WriteHeader(sceneGUID, sceneSectionsArray, scene.name, settings.AssetImportContext);

            // If we are writing assets to assets folder directly, then we need to make sure the asset database see them so they can be loaded.
            if (settings.AssetImportContext == null)
            {
                AssetDatabase.Refresh();
            }

            if (disposeBlobAssetCache)
            {
                settings.BlobAssetStore.Dispose();
            }

            // Save the log of issues that happened during conversion

            WriteConversionLog(sceneGUID, journalData, scene.name, settings.AssetImportContext);

            return(sceneSectionsArray);
        }
        internal static SceneSectionData[] WriteEntitySceneInternal(EntityManager entityManager, Hash128 sceneGUID,
                                                                    string sceneName, AssetImportContext importContext, int framesToRetainBlobAssets,
                                                                    List <ReferencedUnityObjects> sectionRefObjs, WriteEntitySceneSettings writeEntitySceneSettings, ref ConversionJournalData journalData)
        {
            using (var allTypes = new NativeHashMap <ComponentType, int>(100, Allocator.Temp))
                using (var archetypes = new NativeList <EntityArchetype>(Allocator.Temp))
                {
                    entityManager.GetAllArchetypes(archetypes);
                    for (int i = 0; i < archetypes.Length; i++)
                    {
                        var archetype = archetypes[i];
                        unsafe
                        {
                            if (archetype.Archetype->EntityCount == 0)
                            {
                                continue;
                            }
                        }

                        using (var componentTypes = archetype.GetComponentTypes())
                            foreach (var componentType in componentTypes)
                            {
                                if (allTypes.TryAdd(componentType, 0))
                                {
                                    if (importContext != null)
                                    {
                                        TypeDependencyCache.AddDependency(importContext, componentType);
                                    }
                                }
                            }
                    }
                    //Add exported types and assets to the journal data
                    using (var types = allTypes.GetKeyArray(Allocator.Temp))
                    {
                        CheckExportedTypes(writeEntitySceneSettings, true, types.Select(t => TypeManager.GetTypeInfo(t.TypeIndex)), ref journalData);
                    }
                }
            if (importContext != null)
            {
                TypeDependencyCache.AddAllSystemsDependency(importContext);
            }

            var sceneSections = new List <SceneSectionData>();

            var subSectionList = new List <SceneSection>();

            entityManager.GetAllUniqueSharedComponentData(subSectionList);
            //Order sections by section id
            subSectionList.Sort(Comparer <SceneSection> .Create((a, b) => a.Section.CompareTo(b.Section)));

            var extRefInfoEntities = new NativeArray <Entity>(subSectionList.Count, Allocator.Temp);

            NativeArray <Entity> entitiesInMainSection;

            var sectionQuery = entityManager.CreateEntityQuery(
                new EntityQueryDesc
            {
                All     = new[] { ComponentType.ReadWrite <SceneSection>() },
                Options = EntityQueryOptions.IncludePrefab | EntityQueryOptions.IncludeDisabled
            }
                );

            var sectionBoundsQuery = entityManager.CreateEntityQuery(
                new EntityQueryDesc
            {
                All     = new[] { ComponentType.ReadWrite <SceneBoundingVolume>(), ComponentType.ReadWrite <SceneSection>() },
                Options = EntityQueryOptions.IncludePrefab | EntityQueryOptions.IncludeDisabled
            }
                );

            {
                var section = new SceneSection {
                    SceneGUID = sceneGUID, Section = 0
                };
                sectionQuery.SetSharedComponentFilter(new SceneSection {
                    SceneGUID = sceneGUID, Section = 0
                });
                sectionBoundsQuery.SetSharedComponentFilter(new SceneSection {
                    SceneGUID = sceneGUID, Section = 0
                });
                entitiesInMainSection = sectionQuery.ToEntityArray(Allocator.TempJob);

                var bounds = GetBoundsAndRemove(entityManager, sectionBoundsQuery);

                // Each section will be serialized in its own world, entities that don't have a section are part of the main scene.
                // An entity that holds the array of external references to the main scene is required for each section.
                // We need to create them all before we start moving entities to section scenes,
                // otherwise they would reuse entities that have been moved and mess up the remapping tables.
                for (int sectionIndex = 1; sectionIndex < subSectionList.Count; ++sectionIndex)
                {
                    if (subSectionList[sectionIndex].Section == 0)
                    {
                        // Main section, the only one that doesn't need an external ref array
                        continue;
                    }

                    var extRefInfoEntity = entityManager.CreateEntity();
                    entityManager.AddSharedComponentData(extRefInfoEntity, subSectionList[sectionIndex]);
                    extRefInfoEntities[sectionIndex] = extRefInfoEntity;
                }

                // Public references array, only on the main section.
                var refInfoEntity = entityManager.CreateEntity();
                entityManager.AddBuffer <PublicEntityRef>(refInfoEntity);
                entityManager.AddSharedComponentData(refInfoEntity, section);
                var publicRefs = entityManager.GetBuffer <PublicEntityRef>(refInfoEntity);

//                entityManager.Debug.CheckInternalConsistency();

                //@TODO do we need to keep this index? doesn't carry any additional info
                for (int i = 0; i < entitiesInMainSection.Length; ++i)
                {
                    PublicEntityRef.Add(ref publicRefs,
                                        new PublicEntityRef {
                        entityIndex = i, targetEntity = entitiesInMainSection[i]
                    });
                }

                UnityEngine.Debug.Assert(publicRefs.Length == entitiesInMainSection.Length);

                // Save main section
                var sectionWorld   = new World("SectionWorld");
                var sectionManager = sectionWorld.EntityManager;

                var entityRemapping = entityManager.CreateEntityRemapArray(Allocator.TempJob);
                sectionManager.MoveEntitiesFrom(entityManager, sectionQuery, entityRemapping);

                AddRetainBlobAssetsEntity(sectionManager, framesToRetainBlobAssets);

                // The section component is only there to break the conversion world into different sections
                // We don't want to store that on the disk
                //@TODO: Component should be removed but currently leads to corrupt data file. Figure out why.
                //sectionManager.RemoveComponent(sectionManager.UniversalQuery, typeof(SceneSection));

                var(decompressedSectionFileSize, compressedSectionFileSize) = WriteEntitySceneSection(sectionManager, sceneGUID, "0",
                                                                                                      importContext, writeEntitySceneSettings, out var objectRefCount, out var objRefs, default);
示例#12
0
        public static SceneData[] WriteEntityScene(Scene scene, Hash128 sceneGUID, ConversionFlags conversionFlags)
        {
            var world         = new World("ConversionWorld");
            var entityManager = world.GetOrCreateManager <EntityManager>();

            var boundsEntity = entityManager.CreateEntity(typeof(SceneBoundingVolume));

            entityManager.SetComponentData(boundsEntity, new SceneBoundingVolume {
                Value = MinMaxAABB.Empty
            });

            ConvertScene(scene, sceneGUID, world, conversionFlags);
            EntitySceneOptimization.Optimize(world);

            var bounds = entityManager.GetComponentData <SceneBoundingVolume>(boundsEntity).Value;

            entityManager.DestroyEntity(boundsEntity);

            var sceneSections = new List <SceneData>();

            var subSectionList = new List <SceneSection>();

            entityManager.GetAllUniqueSharedComponentData(subSectionList);
            var extRefInfoEntities = new NativeArray <Entity>(subSectionList.Count, Allocator.Temp);

            NativeArray <Entity> entitiesInMainSection;

            var sectionGrp = entityManager.CreateComponentGroup(
                new EntityArchetypeQuery
            {
                All     = new[] { ComponentType.ReadWrite <SceneSection>() },
                Options = EntityArchetypeQueryOptions.IncludePrefab | EntityArchetypeQueryOptions.IncludeDisabled
            }
                );

            {
                var section = new SceneSection {
                    SceneGUID = sceneGUID, Section = 0
                };
                sectionGrp.SetFilter(new SceneSection {
                    SceneGUID = sceneGUID, Section = 0
                });
                entitiesInMainSection = sectionGrp.ToEntityArray(Allocator.TempJob);

                // Each section will be serialized in its own world, entities that don't have a section are part of the main scene.
                // An entity that holds the array of external references to the main scene is required for each section.
                // We need to create them all before we start moving entities to section scenes,
                // otherwise they would reuse entities that have been moved and mess up the remapping tables.
                for (int sectionIndex = 1; sectionIndex < subSectionList.Count; ++sectionIndex)
                {
                    var extRefInfoEntity = entityManager.CreateEntity();
                    entityManager.AddSharedComponentData(extRefInfoEntity, subSectionList[sectionIndex]);
                    extRefInfoEntities[sectionIndex] = extRefInfoEntity;
                }

                // Public references array, only on the main section.
                var refInfoEntity = entityManager.CreateEntity();
                entityManager.AddBuffer <PublicEntityRef>(refInfoEntity);
                entityManager.AddSharedComponentData(refInfoEntity, section);
                var publicRefs = entityManager.GetBuffer <PublicEntityRef>(refInfoEntity);

//                entityManager.Debug.CheckInternalConsistency();

                //@TODO do we need to keep this index? doesn't carry any additional info
                for (int i = 0; i < entitiesInMainSection.Length; ++i)
                {
                    PublicEntityRef.Add(ref publicRefs,
                                        new PublicEntityRef {
                        entityIndex = i, targetEntity = entitiesInMainSection[i]
                    });
                }

                Debug.Assert(publicRefs.Length == entitiesInMainSection.Length);

                // Save main section
                var sectionWorld   = new World("SectionWorld");
                var sectionManager = sectionWorld.GetOrCreateManager <EntityManager>();

                var entityRemapping = entityManager.CreateEntityRemapArray(Allocator.TempJob);
                sectionManager.MoveEntitiesFrom(entityManager, sectionGrp, entityRemapping);

                // The section component is only there to break the conversion world into different sections
                // We don't want to store that on the disk
                //@TODO: Component should be removed but currently leads to corrupt data file. Figure out why.
                //sectionManager.RemoveComponent(sectionManager.UniversalGroup, typeof(SceneSection));

                var sectionFileSize = WriteEntityScene(sectionManager, sceneGUID, "0");
                sceneSections.Add(new SceneData
                {
                    FileSize             = sectionFileSize,
                    SceneGUID            = sceneGUID,
                    SharedComponentCount = sectionManager.GetSharedComponentCount() - 1,
                    SubSectionIndex      = 0,
                    BoundingVolume       = bounds
                });

                entityRemapping.Dispose();
                sectionWorld.Dispose();
            }

            {
                // Index 0 is the default value of the shared component, not an actual section
                for (int subSectionIndex = 0; subSectionIndex < subSectionList.Count; ++subSectionIndex)
                {
                    var subSection = subSectionList[subSectionIndex];
                    if (subSection.Section == 0)
                    {
                        continue;
                    }

                    sectionGrp.SetFilter(subSection);
                    var entitiesInSection = sectionGrp.ToEntityArray(Allocator.TempJob);

                    if (entitiesInSection.Length > 0)
                    {
                        // Fetch back the external reference entity we created earlier to not disturb the mapping
                        var refInfoEntity = extRefInfoEntities[subSectionIndex];
                        entityManager.AddBuffer <ExternalEntityRef>(refInfoEntity);
                        var externRefs = entityManager.GetBuffer <ExternalEntityRef>(refInfoEntity);

                        // Store the mapping to everything in the main section
                        //@TODO maybe we don't need all that? is this worth worrying about?
                        for (int i = 0; i < entitiesInMainSection.Length; ++i)
                        {
                            ExternalEntityRef.Add(ref externRefs, new ExternalEntityRef {
                                entityIndex = i
                            });
                        }

                        // Entities will be remapped to a contiguous range in the section world,
                        // so any range after that is fine for the external references
                        //@TODO why are we not mapping anything to entity 0? we use the range [1;count], hence +1
                        var externEntityIndexStart = entitiesInSection.Length + 1;

                        entityManager.AddComponentData(refInfoEntity,
                                                       new ExternalEntityRefInfo
                        {
                            SceneGUID        = sceneGUID,
                            EntityIndexStart = externEntityIndexStart
                        });

                        var sectionWorld   = new World("SectionWorld");
                        var sectionManager = sectionWorld.GetOrCreateManager <EntityManager>();

                        var entityRemapping = entityManager.CreateEntityRemapArray(Allocator.TempJob);

                        // Insert mapping for external references, conversion world entity to virtual index in section
                        for (int i = 0; i < entitiesInMainSection.Length; ++i)
                        {
                            EntityRemapUtility.AddEntityRemapping(ref entityRemapping, entitiesInMainSection[i],
                                                                  new Entity {
                                Index = i + externEntityIndexStart, Version = 1
                            });
                        }

                        sectionManager.MoveEntitiesFrom(entityManager, sectionGrp, entityRemapping);

                        // When writing the scene, references to missing entities are set to Entity.Null by default
                        // We obviously don't want that to happen to our external references, so we add explicit mapping
                        for (int i = 0; i < entitiesInMainSection.Length; ++i)
                        {
                            var entity = new Entity {
                                Index = i + externEntityIndexStart, Version = 1
                            };
                            EntityRemapUtility.AddEntityRemapping(ref entityRemapping, entity, entity);
                        }

                        // The section component is only there to break the conversion world into different sections
                        // We don't want to store that on the disk
                        //@TODO: Component should be removed but currently leads to corrupt data file. Figure out why.
                        //sectionManager.RemoveComponent(sectionManager.UniversalGroup, typeof(SceneSection));

                        var fileSize = WriteEntityScene(sectionManager, sceneGUID, subSection.Section.ToString(), entityRemapping);
                        sceneSections.Add(new SceneData
                        {
                            FileSize             = fileSize,
                            SceneGUID            = sceneGUID,
                            SharedComponentCount = sectionManager.GetSharedComponentCount() - 1,
                            SubSectionIndex      = subSection.Section,
                            BoundingVolume       = bounds
                        });

                        entityRemapping.Dispose();
                        sectionWorld.Dispose();
                    }

                    entitiesInSection.Dispose();
                }
            }

            {
                var noSectionGrp = entityManager.CreateComponentGroup(
                    new EntityArchetypeQuery
                {
                    None    = new[] { ComponentType.ReadWrite <SceneSection>() },
                    Options = EntityArchetypeQueryOptions.IncludePrefab | EntityArchetypeQueryOptions.IncludeDisabled
                }
                    );
                if (noSectionGrp.CalculateLength() != 0)
                {
                    Debug.LogWarning($"{noSectionGrp.CalculateLength()} entities in the scene '{scene.path}' had no SceneSection and as a result were not serialized at all.");
                }
            }

            sectionGrp.Dispose();
            entitiesInMainSection.Dispose();
            world.Dispose();

            // Save the new header
            var header = ScriptableObject.CreateInstance <SubSceneHeader>();

            header.Sections = sceneSections.ToArray();

            WriteHeader(sceneGUID, header);

            return(sceneSections.ToArray());
        }
示例#13
0
        private unsafe void InitSceneSection(SceneSection sceneSection)
        {
            Hash128 containerIdentifier          = sceneSection.SceneGUID;
            PersistencyContainerTag containerTag = new PersistencyContainerTag()
            {
                DataIdentifier = containerIdentifier
            };

            if (PersistentDataStorage.IsInitialized(containerIdentifier))
            {
                PersistentDataContainer latestState = PersistentDataStorage.GetReadContainerForLatestWriteIndex(containerIdentifier, out bool isInitial);
                _beginFrameSystem.RequestApply(latestState);
            }
            else
            {
                _scenePersistencyInfoQuery.SetSharedComponentFilter(containerTag);
                if (_scenePersistencyInfoQuery.CalculateEntityCount() != 1)
                {
                    return;
                }
                var scenePersistencyInfoRef        = _scenePersistencyInfoQuery.GetSingleton <ScenePersistencyInfoRef>();
                ref ScenePersistencyInfo sceneInfo = ref scenePersistencyInfoRef.InfoRef.Value;

                int offset      = 0;
                var dataLayouts = new NativeArray <PersistencyArchetypeDataLayout>(sceneInfo.PersistencyArchetypes.Length, Allocator.Persistent);
                for (var i = 0; i < sceneInfo.PersistencyArchetypes.Length; i++)
                {
                    ref PersistencyArchetype persistencyArchetype = ref sceneInfo.PersistencyArchetypes[i];

                    var hashFilter = new PersistableTypeCombinationHash
                    {
                        Value = persistencyArchetype.PersistableTypeHandleCombinationHash
                    };

                    var dataLayout = new PersistencyArchetypeDataLayout()
                    {
                        Amount = persistencyArchetype.AmountEntities,
                        ArchetypeIndexInContainer = (ushort)i,
                        PersistedTypeInfoArrayRef = persistencyArchetype.BuildTypeInfoBlobAsset(PersistencySettings, persistencyArchetype.AmountEntities, out int sizePerEntity),
                        SizePerEntity             = sizePerEntity,
                        Offset = offset,
                        PersistableTypeHandleCombinationHash = hashFilter.Value
                    };
                    offset += persistencyArchetype.AmountEntities * sizePerEntity;

                    dataLayouts[i] = dataLayout;
                }

                // BlobData is disposed if the owning entity is destroyed, we need this data even if the scene is unloaded
                NativeArray <PersistableTypeHandle> allUniqueTypeHandles = new NativeArray <PersistableTypeHandle>(sceneInfo.AllUniqueTypeHandles.Length, Allocator.Persistent);
                UnsafeUtility.MemCpy(allUniqueTypeHandles.GetUnsafePtr(), sceneInfo.AllUniqueTypeHandles.GetUnsafePtr(), allUniqueTypeHandles.Length * sizeof(PersistableTypeHandle));

                // this function takes ownership over the dataLayouts array & allUniqueTypeHandles array
                PersistentDataStorage.InitializeSceneContainer(containerIdentifier, dataLayouts, allUniqueTypeHandles,
                                                               out PersistentDataContainer initialStateContainer, out PersistentDataContainer containerToApply);
                _beginFrameSystem.RequestInitialStatePersist(initialStateContainer);
                if (containerToApply.IsCreated)
                {
                    // containerToApply only exists if it was already added as uninitialized raw data beforehand (e.g. read from disk)
                    _beginFrameSystem.RequestApply(containerToApply);
                }
            }