internal static void Validate(Scene scene, IncrementalHierarchy hierarchy)
 {
     ValidateThatHierarchyContainsScene(scene, hierarchy);
     ValidateThatSceneContainsHierarchy(scene, hierarchy);
 }
        internal static void Remove(IncrementalHierarchy hierarchy, NativeArray <int> instances)
        {
            var openInstanceIds = new NativeList <int>(instances.Length, Allocator.Temp);

            openInstanceIds.AddRange(instances);

            var tmpChildren = new NativeList <int>(16, Allocator.Temp);

            // This code currently doesn't make use of the fact that we are always deleting entire subhierarchies
            while (openInstanceIds.Length > 0)
            {
                int id = openInstanceIds[openInstanceIds.Length - 1];
                openInstanceIds.Length -= 1;
                if (!hierarchy.IndexByInstanceId.TryGetValue(id, out int idx))
                {
                    continue;
                }

                {
                    // push children and remove children array entry
                    var iter = hierarchy.ChildIndicesByIndex.GetValuesForKey(idx);
                    while (iter.MoveNext())
                    {
                        openInstanceIds.Add(hierarchy.InstanceId[iter.Current]);
                    }
                    hierarchy.ChildIndicesByIndex.Remove(idx);
                }

                // Remove-and-swap on the arrays
                hierarchy.InstanceId.RemoveAtSwapBack(idx);
                int oldParentIdx = hierarchy.ParentIndex[idx];
                hierarchy.ParentIndex.RemoveAtSwapBack(idx);
                hierarchy.TransformArray.RemoveAtSwapBack(idx);

                // then patch up the lookup tables
                hierarchy.IndexByInstanceId.Remove(id);
                if (oldParentIdx != -1)
                {
                    hierarchy.ChildIndicesByIndex.Remove(oldParentIdx, idx);
                }
                int swappedIdx = hierarchy.InstanceId.Length;
                if (swappedIdx > 0 && swappedIdx != idx)
                {
                    // update index to instance id lookup
                    int swappedId = hierarchy.InstanceId[idx];
                    hierarchy.IndexByInstanceId[swappedId] = idx;

                    // update index to children lookup of parent
                    int swappedParentIdx = hierarchy.ParentIndex[idx];
                    if (swappedParentIdx != -1)
                    {
                        hierarchy.ChildIndicesByIndex.Remove(swappedParentIdx, swappedIdx);
                        hierarchy.ChildIndicesByIndex.Add(swappedParentIdx, idx);
                    }

                    // update index to children lookup of swapped index
                    var iter = hierarchy.ChildIndicesByIndex.GetValuesForKey(swappedIdx);
                    while (iter.MoveNext())
                    {
                        tmpChildren.Add(iter.Current);
                        hierarchy.ParentIndex[iter.Current] = idx;
                    }

                    hierarchy.ChildIndicesByIndex.Remove(swappedIdx);

                    for (int i = 0; i < tmpChildren.Length; i++)
                    {
                        hierarchy.ChildIndicesByIndex.Add(idx, tmpChildren[i]);
                    }
                    tmpChildren.Clear();
                }
            }
        }
        static void ValidateThatHierarchyContainsScene(Scene scene, IncrementalHierarchy hierarchy)
        {
            Stack <GameObject> open = new Stack <GameObject>();

            foreach (var go in scene.GetRootGameObjects())
            {
                open.Push(go);
            }
            var childIndexCache = new List <int>();
            var childIdCache    = new List <int>();

            while (open.Count > 0)
            {
                var go = open.Pop();
                var id = go.GetInstanceID();
                if (hierarchy.IndexByInstanceId.TryGetValue(id, out var idx))
                {
                    if (go.transform != hierarchy.TransformArray[idx])
                    {
                        var otherTransform = hierarchy.TransformArray[idx];
                        var otherId        = otherTransform?.gameObject?.GetInstanceID() ?? 0;
                        Debug.LogError($"Object {go} ({go.GetInstanceID()}) is stored at index {idx}, but the transform stored there is {otherTransform} ({otherId})");
                    }

                    var parentIdx = hierarchy.ParentIndex[idx];
                    if (go.transform.parent == null && parentIdx != -1)
                    {
                        int parentId  = hierarchy.InstanceId[parentIdx];
                        var parentObj = UnityEditor.EditorUtility.InstanceIDToObject(parentId);
                        Debug.LogError(
                            $"Object {go} ({go.GetInstanceID()}) has no parent, but in the hierarchy parent {parentObj} ({parentId}) is stored");
                    }
                    else if (go.transform.parent != null)
                    {
                        int parentId = hierarchy.InstanceId[parentIdx];
                        var parentObjFromTransform = go.transform.parent.gameObject;
                        if (parentObjFromTransform.GetInstanceID() != parentId)
                        {
                            var parentObj = UnityEditor.EditorUtility.InstanceIDToObject(parentId);
                            Debug.LogError(
                                $"Object {go} ({go.GetInstanceID()}) has parent {parentObjFromTransform} ({parentObjFromTransform.GetInstanceID()}), but in the hierarchy parent {parentObj} ({parentId} is stored)");
                        }
                    }

                    // validate children
                    childIndexCache.Clear();
                    childIdCache.Clear();
                    var childIter = hierarchy.ChildIndicesByIndex.GetValuesForKey(idx);
                    while (childIter.MoveNext())
                    {
                        childIndexCache.Add(childIter.Current);
                        childIdCache.Add(hierarchy.InstanceId[childIter.Current]);
                    }

                    if (childIndexCache.Count != go.transform.childCount)
                    {
                        Debug.LogError(
                            $"Object {go} ({go.GetInstanceID()}) has {go.transform.childCount} children, but in the hierarchy {childIndexCache.Count} children are stored");
                    }

                    for (int i = 0; i < go.transform.childCount; i++)
                    {
                        var child   = go.transform.GetChild(i).gameObject;
                        var childId = child.GetInstanceID();
                        if (!childIdCache.Contains(childId))
                        {
                            Debug.LogError(
                                $"Object {go} ({go.GetInstanceID()}) has child {child} ({childId}), but in the hierarchy it is missing");
                        }
                    }
                }
                else
                {
                    Debug.LogError($"Object {go} ({go.GetInstanceID()}) is not present in the hierarchy");
                }

                for (int i = 0; i < go.transform.childCount; i++)
                {
                    open.Push(go.transform.GetChild(i).gameObject);
                }
            }
        }
Exemplo n.º 4
0
 public IncrementalConversionContext(bool isLiveLink)
 {
     Dependencies = new ConversionDependencies(isLiveLink);
     Hierarchy    = default;
     Scene        = default;
 }