示例#1
0
        private static void CreateBoolUI(Vector2 position, DictionaryIntToModelGroupImportSettings importSettings, string valueName, int index, string onFalseName = null, string onTrueName = null)
        {
            var type         = typeof(ModelGroupImportSettings);
            var valueField   = type.GetField(valueName);
            var onFalseField = onFalseName != null?type.GetField(onFalseName) : null;

            var onTrueField = onTrueName != null?type.GetField(onTrueName) : null;

            var newValue = EditorGUI.Toggle(new Rect(position, new Vector2(16, 16)), (bool)valueField.GetValue(importSettings[index]));

            valueField.SetValue(importSettings[index], newValue);

            if (onFalseField != null && !newValue)
            {
                onFalseField.SetValue(importSettings[index], false);
            }
            if (onTrueField != null && newValue)
            {
                onTrueField.SetValue(importSettings[index], true);
            }
        }
示例#2
0
        private static void CreateAllLODsUI(Vector2 position, DictionaryIntToModelGroupImportSettings importSettings)
        {
            var lodSet = new HashSet <int>();

            foreach (var key in new List <int>(importSettings.Keys))
            {
                lodSet.Add(importSettings[key].lod);
            }

            EditorGUI.showMixedValue = lodSet.Count > 1;
            EditorGUI.BeginChangeCheck();
            var newValue = EditorGUI.Popup(new Rect(position, new Vector2(64, 16)), importSettings[0].lod, lodOptions);

            if (EditorGUI.EndChangeCheck())
            {
                foreach (var key in new List <int>(importSettings.Keys))
                {
                    importSettings[key].lod = newValue;
                }
            }

            EditorGUI.showMixedValue = false;
        }
示例#3
0
        private static void CreateAllBoolsUI(Vector2 position, DictionaryIntToModelGroupImportSettings importSettings, string valueName, string onFalseName = null, string onTrueName = null)
        {
            var type         = typeof(ModelGroupImportSettings);
            var valueField   = type.GetField(valueName);
            var onFalseField = onFalseName != null?type.GetField(onFalseName) : null;

            var onTrueField = onTrueName != null?type.GetField(onTrueName) : null;

            EditorGUI.showMixedValue = importSettings.Values.Any(setting => (bool)valueField.GetValue(setting)) && importSettings.Values.Any(setting => !(bool)valueField.GetValue(setting));
            EditorGUI.BeginChangeCheck();
            var newValue = EditorGUI.Toggle(new Rect(position, new Vector2(16, 16)), (bool)valueField.GetValue(importSettings[0]));

            if (EditorGUI.EndChangeCheck())
            {
                foreach (var key in new List <int>(importSettings.Keys))
                {
                    valueField.SetValue(importSettings[key], newValue);
                }
                if (onFalseField != null && !newValue)
                {
                    foreach (var key in new List <int>(importSettings.Keys))
                    {
                        onFalseField.SetValue(importSettings[key], false);
                    }
                }
                if (onTrueField != null && newValue)
                {
                    foreach (var key in new List <int>(importSettings.Keys))
                    {
                        onTrueField.SetValue(importSettings[key], true);
                    }
                }
            }

            EditorGUI.showMixedValue = false;
        }
示例#4
0
        public static void ReimportModelGroup(LXFMLDoc lxfml, ModelGroup group, ModelGroupImportSettings importSettings, bool detectConnectivity = false)
        {
            // Assign the new group import settings to the group.
            group.importSettings = importSettings;

            // We assume that the group can be found, so reimport it.
            if (group.processed)
            {
                // Remove all processed meshes.
                var renderers = group.GetComponentsInChildren <MeshRenderer>();
                foreach (var renderer in renderers)
                {
                    // FIXME Destroy the mesh? Prevents undo..
                    var filter = renderer.GetComponent <MeshFilter>();
                    //Undo.DestroyObjectImmediate(filter.sharedMesh);

                    if (renderer.GetComponent <ModelGroup>() == null)
                    {
                        // Destroy submesh game objects entirely.
                        Undo.DestroyObjectImmediate(renderer.gameObject);
                    }
                    else
                    {
                        // Destroy mesh related components on group game object.
                        Object.DestroyImmediate(filter);
                        Object.DestroyImmediate(renderer);
                    }
                }
            }

            // FIXME Check if bricks are referenced.
            // FIXME Check if bricks have custom components attached.

            // Remove group bricks.
            var existingBricks = group.GetComponentsInChildren <Brick>();

            foreach (var brick in existingBricks)
            {
                Undo.DestroyObjectImmediate(brick.gameObject);
            }

            var groupLightMapped = group.importSettings.isStatic && group.importSettings.lightmapped;

            SetStaticAndGIParams(group.gameObject, group.importSettings.isStatic, groupLightMapped);

            // Move group to origo to ensure that bricks are instantiated in the correct positions.
            var originalGroupLocalPosition = group.transform.localPosition;
            var originalGroupLocalRotation = group.transform.localRotation;
            var originalGroupLocalScale    = group.transform.localScale;
            var originalGroupParent        = group.transform.parent;
            var originalGroupSiblingIndex  = group.transform.GetSiblingIndex();

            group.transform.SetParent(null);
            group.transform.localPosition = Vector3.zero;
            group.transform.localRotation = Quaternion.identity;
            group.transform.localScale    = Vector3.one;

            // Create dictionary with just this group.
            var modelGroupImportSettingsDictionary = new DictionaryIntToModelGroupImportSettings();

            modelGroupImportSettingsDictionary.Add(group.number, group.importSettings);

            // Instantiate group bricks.
            var resultBricks = new Dictionary <int, Brick>(lxfml.bricks.Count);

            InstantiateModelBricks(lxfml, modelGroupImportSettingsDictionary, ref resultBricks, group.number);

            // Assign bricks to group.
            foreach (var brick in resultBricks.Values)
            {
                brick.transform.SetParent(group.transform);
            }
            ModelGroupUtility.RecomputePivot(group, false, ModelGroupUtility.UndoBehavior.withoutUndo);

            // Move group back to original location.
            group.transform.SetParent(originalGroupParent);
            group.transform.SetSiblingIndex(originalGroupSiblingIndex);
            group.transform.localPosition = originalGroupLocalPosition;
            group.transform.localRotation = originalGroupLocalRotation;
            group.transform.localScale    = originalGroupLocalScale;

            /*if (group.processed)
             * {
             *  // Process the group again.
             *  // FIXME Is this even a good idea?
             *  if (group.type == GroupType.Environment || group.type == GroupType.Static)
             *  {
             *      Vector2Int vertCount = Vector2Int.zero;
             *      Vector2Int triCount = Vector2Int.zero;
             *      Vector2Int meshCount = Vector2Int.zero;
             *      Vector2Int colliderCount = Vector2Int.zero;
             *      ModelProcessor.ProcessModelGroup(group, ref vertCount, ref triCount, ref meshCount, ref colliderCount);
             *
             *      Debug.Log($"Process result (before/after):\nVerts {vertCount.x}/{vertCount.y}, tris {triCount.x}/{triCount.y}, meshes {meshCount.x}/{meshCount.y}, colliders {colliderCount.x}/{colliderCount.y}");
             *  }
             * }*/

            if (detectConnectivity && group.importSettings.connectivity)
            {
                var sceneBricks = new HashSet <Brick>(StageUtility.GetCurrentStageHandle().FindComponentsOfType <Brick>());
                DetectConnectivity(new HashSet <Brick>(resultBricks.Values), sceneBricks);
            }

            EditorUtility.ClearProgressBar();
        }
示例#5
0
        public static void ReimportModel(LXFMLDoc lxfml, Model model, DictionaryIntToModelGroupImportSettings importSettings)
        {
            var brickBuilding = SceneBrickBuilder.GetToggleBrickBuildingStatus();

            if (brickBuilding)
            {
                SceneBrickBuilder.ToggleBrickBuilding();
            }

            // FIXME Next version could include option to match groups up manually.

            var groups = model.GetComponentsInChildren <ModelGroup>();

            for (var i = groups.Length - 1; i >= 0; i--)
            {
                var group = groups[i];
                if (group.autoGenerated)
                {
                    Undo.DestroyObjectImmediate(group.gameObject);
                }
                else if (group.number >= lxfml.groups.Length)
                {
                    Debug.LogWarning("Group " + group.number + " " + group.groupName + " does not match up with files. Wiping.");
                    Undo.DestroyObjectImmediate(group.gameObject);
                }
            }

            groups = model.GetComponentsInChildren <ModelGroup>();

            var removedGroups = new List <LXFMLDoc.BrickGroup>();

            for (var i = 0; i < lxfml.groups.Length; i++)
            {
                LXFMLDoc.BrickGroup group = lxfml.groups[i];
                bool exists = false;
                for (var j = 0; j < groups.Length; j++)
                {
                    if (groups[j].number == group.number)
                    {
                        exists = true;
                        break;
                    }
                }

                if (!exists)
                {
                    removedGroups.Add(group);
                }
            }

            // Assign the new model import settings to the model.
            model.importSettings = new DictionaryIntToModelGroupImportSettings(importSettings);
            var bricksWithConnectivity = new HashSet <Brick>();

            if (removedGroups.Count > 0)
            {
                var resultBricks = new Dictionary <int, Brick>(lxfml.bricks.Count);
                foreach (var group in removedGroups)
                {
                    var number = group.number;
                    InstantiateModelBricks(lxfml, model.importSettings, ref resultBricks, number);
                    var groupGO = InstantiateModelGroup(group, number, model.gameObject, model.absoluteFilePath, model.relativeFilePath, ref resultBricks, false, importSettings[number]);
                    groupGO.transform.position = model.transform.position;
                    Undo.RegisterCreatedObjectUndo(groupGO, "Re-creating model group");
                    if (importSettings[number].connectivity)
                    {
                        bricksWithConnectivity.UnionWith(groupGO.GetComponentsInChildren <Brick>());
                    }
                }
            }

            foreach (var group in groups)
            {
                group.absoluteFilePath = model.absoluteFilePath;
                group.relativeFilePath = model.relativeFilePath;
                ReimportModelGroup(lxfml, group, importSettings[group.number]);
                if (group.importSettings.connectivity)
                {
                    bricksWithConnectivity.UnionWith(group.GetComponentsInChildren <Brick>());
                }
            }

            if (bricksWithConnectivity.Count > 0)
            {
                var sceneBricks = new HashSet <Brick>(StageUtility.GetCurrentStageHandle().FindComponentsOfType <Brick>());
                DetectConnectivity(bricksWithConnectivity, sceneBricks);
            }

            if (brickBuilding)
            {
                SceneBrickBuilder.ToggleBrickBuilding();
            }

            if (SceneBrickBuilder.GetAutoUpdateHierarchy())
            {
                groups = model.GetComponentsInChildren <ModelGroup>();
                var bricks = new HashSet <Brick>();
                foreach (var group in groups)
                {
                    if (group.importSettings.connectivity)
                    {
                        var groupBricks = group.GetComponentsInChildren <Brick>();
                        foreach (var brick in groupBricks)
                        {
                            bricks.Add(brick);
                        }
                    }
                }

                // On reimport, the model will be positioned weirdly compared to the rest of the scene, so we just ignore all other bricks
                ModelGroupUtility.RecomputeModelGroups(bricks);
            }

            EditorUtility.ClearProgressBar();
        }
示例#6
0
        /// <summary>
        /// Instantiate all bricks and groups in an LXFML document
        /// </summary>
        /// <param name="lxfml">The LXFML document</param>
        /// <param name="nameOfObject">Path of the LXFML document</param>
        public static GameObject InstantiateModel(LXFMLDoc lxfml, string filePath, Model.Pivot pivot, DictionaryIntToModelGroupImportSettings importSettings)
        {
            //Create "root" LXFML gameobject
            GameObject parent = new GameObject(Path.GetFileNameWithoutExtension(filePath));

            Undo.RegisterCreatedObjectUndo(parent, "Model");
            parent.transform.position = Vector3.zero;

            var model = parent.AddComponent <Model>();

            model.absoluteFilePath = filePath;
            model.relativeFilePath = PathUtils.GetRelativePath(Directory.GetCurrentDirectory(), filePath);
            model.pivot            = pivot;
            model.importSettings   = new DictionaryIntToModelGroupImportSettings(importSettings);

            EditorUtility.DisplayProgressBar("Importing", "Creating bricks.", 0.0f);

            var resultBricks = new Dictionary <int, Brick>(lxfml.bricks.Count);

            InstantiateModelBricks(lxfml, importSettings, ref resultBricks);

            EditorUtility.DisplayProgressBar("Importing", "Creating groups.", 0.8f);

            if (resultBricks.Count > 0)
            {
                var bricksWithConnectivity = new HashSet <Brick>();
                var groups = lxfml.groups;

                for (int i = 0; i < groups.Length; i++)
                {
                    var        number      = groups[i].number;
                    GameObject groupParent = InstantiateModelGroup(groups[i], i, parent, filePath, model.relativeFilePath, ref resultBricks, false, importSettings[number]);
                    if (importSettings[number].connectivity)
                    {
                        bricksWithConnectivity.UnionWith(groupParent.GetComponentsInChildren <Brick>());
                    }
                }

                if (bricksWithConnectivity.Count > 0)
                {
                    var sceneBricks = new HashSet <Brick>(StageUtility.GetCurrentStageHandle().FindComponentsOfType <Brick>());
                    DetectConnectivity(bricksWithConnectivity, sceneBricks);
                }


                if (SceneBrickBuilder.GetAutoUpdateHierarchy())
                {
                    var bricks = new HashSet <Brick>();
                    foreach (var pair in resultBricks)
                    {
                        foreach (var part in pair.Value.parts)
                        {
                            if (part.connectivity)
                            {
                                bricks.Add(pair.Value);
                                break;
                            }
                        }
                    }

                    // On import, the model will be positioned weirdly compared to the rest of the scene, so we just ignore all other bricks
                    ModelGroupUtility.RecomputeModelGroups(bricks, false, ModelGroupUtility.UndoBehavior.withoutUndo);
                }
            }

            // Change the pivot.
            if (pivot != Model.Pivot.Original)
            {
                EditorUtility.DisplayProgressBar("Importing", "Computing bounds.", 0.9f);

                var bounds   = ComputeBounds(parent.transform);
                var newPivot = bounds.center;
                switch (pivot)
                {
                case Model.Pivot.BottomCenter:
                {
                    newPivot += -parent.transform.up * bounds.extents.y;
                    break;
                }
                }

                foreach (Transform child in parent.transform)
                {
                    child.position -= newPivot;
                }
                parent.transform.position += newPivot;
            }

            // Add LEGOModelAsset component.
            parent.AddComponent <LEGOModelAsset>();

            EditorUtility.ClearProgressBar();

            return(parent);
        }
示例#7
0
        /// <summary>
        /// Instantiate game objects for each brick in an LXFML-file
        /// </summary>
        /// <param name="lxfml">The LXFML-file</param>
        /// <param name="colliders">Add colliders to part</param>
        /// <param name="connectivity">Add connectivity to part</param>
        /// <param name="isStatic">Make the part static</param>
        /// <param name="lightmapped">Instantiate meshes with or without lightmap UVs</param>
        /// <param name="randomizeRotation">Slightly rotate rotation of part</param>
        /// <param name="preferLegacy">Choose legacy meshes if available</param>
        /// <param name="lod">Instantiate meshes of a certain LOD</param>
        /// <param name="resultBricks">Dictionary that contains brick component, using refID as key</param>
        /// <param name="groupNumber">If non-negative, only instantiate bricks from the specified group number</param>
        public static void InstantiateModelBricks(LXFMLDoc lxfml, DictionaryIntToModelGroupImportSettings importSettings, ref Dictionary <int, Brick> resultBricks, int groupNumber = -1)
        {
            for (var i = 0; i < lxfml.bricks.Count; ++i)
            {
                if (i % 200 == 0)
                {
                    EditorUtility.DisplayProgressBar("Importing", "Creating bricks.", ((float)i / lxfml.bricks.Count) * 0.7f);
                }

                var brick = lxfml.bricks[i];

                var group = FindGroup(lxfml, brick);

                // Discard bricks from other groups if group number is specified.
                if (groupNumber >= 0 && group != null && group.number != groupNumber)
                {
                    continue;
                }

                // Determine whether or not to be static and to generate light map UVs.
                var brickStatic      = (group != null ? importSettings[group.number].isStatic : false);
                var brickLightmapped = brickStatic && (group != null ? importSettings[group.number].lightmapped : false);
                var brickLod         = (group != null ? importSettings[group.number].lod : 0);

                var brickGO   = new GameObject(brick.designId, typeof(Brick));
                var brickComp = brickGO.GetComponent <Brick>();
                Undo.RegisterCreatedObjectUndo(brickGO, "Brick");

                foreach (var part in brick.parts)
                {
                    GameObject partToInstantiate = null;

                    var partExistenceResult = PartUtility.UnpackPart(part.partDesignId, brickLightmapped, group != null ? importSettings[group.number].preferLegacy : false, brickLod);

                    if (partExistenceResult.existence != PartUtility.PartExistence.None)
                    {
                        // FIXME Make a note of changed design ids.
                        partToInstantiate = PartUtility.LoadPart(partExistenceResult.designID, brickLightmapped, partExistenceResult.existence == PartUtility.PartExistence.Legacy, brickLod);
                    }

                    if (partToInstantiate == null)
                    {
                        Debug.LogError("Missing part FBX -> " + partExistenceResult.designID);
                        continue;
                    }
                    var partGO = Object.Instantiate(partToInstantiate);
                    partGO.name = partToInstantiate.name;

                    // Assign legacy, material IDs and set up references.
                    var partComp = partGO.AddComponent <Part>();
                    partComp.designID = Convert.ToInt32(part.partDesignId);
                    partComp.legacy   = partExistenceResult.existence == PartUtility.PartExistence.Legacy;
                    foreach (var material in part.materials)
                    {
                        partComp.materialIDs.Add(material.colorId);
                    }
                    partComp.brick = brickComp;
                    brickComp.parts.Add(partComp);


                    if (partExistenceResult.existence == PartUtility.PartExistence.New)
                    {
                        // FIXME Handle normal mapped model.
                        InstantiateKnobsAndTubes(partComp, brickLightmapped, brickLod);
                    }

                    // Create collider and connectivity information.
                    var brickColliders    = (group != null ? importSettings[group.number].colliders : false);
                    var brickConnectivity = brickColliders && (group != null ? importSettings[group.number].connectivity : false);

                    if (brickColliders)
                    {
                        GameObject collidersToInstantiate = null;

                        var collidersAvailable = PartUtility.UnpackCollidersForPart(partExistenceResult.designID);
                        if (collidersAvailable)
                        {
                            collidersToInstantiate = PartUtility.LoadCollidersPrefab(partExistenceResult.designID);
                        }

                        if (collidersToInstantiate == null && partExistenceResult.existence != PartUtility.PartExistence.Legacy)
                        {
                            Debug.LogError("Missing part collider information -> " + partExistenceResult.designID);
                        }

                        if (collidersToInstantiate)
                        {
                            var collidersGO = Object.Instantiate(collidersToInstantiate);
                            collidersGO.name = "Colliders";
                            collidersGO.transform.SetParent(partGO.transform, false);
                            var colliderComps = collidersGO.GetComponentsInChildren <Collider>();
                            partComp.colliders.AddRange(colliderComps);
                        }
                    }

                    if (brickConnectivity)
                    {
                        GameObject connectivityToInstantiate = null;

                        var connectivityAvailable = PartUtility.UnpackConnectivityForPart(partExistenceResult.designID);
                        if (connectivityAvailable)
                        {
                            connectivityToInstantiate = PartUtility.LoadConnectivityPrefab(partExistenceResult.designID);
                        }

                        if (connectivityToInstantiate == null && partExistenceResult.existence != PartUtility.PartExistence.Legacy)
                        {
                            Debug.LogError("Missing part connectivity information -> " + partExistenceResult.designID);
                        }

                        if (connectivityToInstantiate)
                        {
                            var connectivityGO = Object.Instantiate(connectivityToInstantiate);
                            connectivityGO.name = "Connectivity";
                            connectivityGO.transform.SetParent(partGO.transform, false);
                            var connectivityComp = connectivityGO.GetComponent <Connectivity>();
                            partComp.connectivity = connectivityComp;
                            brickComp.totalBounds.Encapsulate(connectivityComp.extents);
                            connectivityComp.part = partComp;

                            foreach (var field in connectivityComp.connectionFields)
                            {
                                foreach (var connection in field.connections)
                                {
                                    MatchConnectionWithKnob(connection, partComp.knobs);
                                    MatchConnectionWithTubes(connection, partComp.tubes);
                                }
                            }
                        }
                    }

                    SetMaterials(partComp, part.materials, partExistenceResult.existence == PartUtility.PartExistence.Legacy);
                    SetDecorations(partComp, part.decorations, partExistenceResult.existence == PartUtility.PartExistence.Legacy);

                    SetStaticAndGIParams(partGO, brickStatic, brickLightmapped, true);

                    // Set Position & Rotation
                    SetPositionRotation(partGO, part);

                    if (group != null ? importSettings[group.number].randomizeRotation : false)
                    {
                        RandomizeRotation(partComp, brickConnectivity);
                    }

                    // If first part, place brick at same position.
                    if (brickGO.transform.childCount == 0)
                    {
                        brickGO.transform.position   = partGO.transform.position;
                        brickGO.transform.rotation   = partGO.transform.rotation;
                        brickGO.transform.localScale = Vector3.one;
                    }
                    partGO.transform.SetParent(brickGO.transform, true);

                    if (!brickConnectivity)
                    {
                        var worldBounds = ComputeBounds(partGO.transform);
                        worldBounds.SetMinMax(brickComp.transform.InverseTransformPoint(worldBounds.min), brickComp.transform.InverseTransformPoint(worldBounds.max));
                        brickComp.totalBounds.Encapsulate(worldBounds);
                    }
                }

                // If all parts were missing, discard brick.
                if (brickGO.transform.childCount == 0)
                {
                    Undo.DestroyObjectImmediate(brickGO);
                    continue;
                }

                SetStaticAndGIParams(brickGO, brickStatic, brickLightmapped);

                // Assign uuid
                brickComp.designID = Convert.ToInt32(brick.designId);
                brickComp.uuid     = brick.uuid;

                // Add LEGOAsset component.
                brickGO.AddComponent <LEGOAsset>();

                resultBricks[brick.refId] = brickComp;
            }
        }
示例#8
0
 private static void CreateLODUI(Vector2 position, DictionaryIntToModelGroupImportSettings importSettings, int index)
 {
     importSettings[index].lod = EditorGUI.Popup(new Rect(position, new Vector2(64, 16)), importSettings[index].lod, lodOptions);
 }
示例#9
0
 public DictionaryIntToModelGroupImportSettings(DictionaryIntToModelGroupImportSettings dictionary) : base(dictionary)
 {
 }
示例#10
0
        public static void ReimportModelGroup(LXFMLDoc lxfml, ModelGroup group, ModelGroupImportSettings importSettings, bool detectConnectivity = false)
        {
            // Assign the new group import settings to the group.
            group.importSettings = importSettings;

            // We assume that the group can be found, so reimport it.
            if (group.processed)
            {
                // Remove all processed meshes.
                var renderers = group.GetComponentsInChildren <MeshRenderer>();
                foreach (var renderer in renderers)
                {
                    // FIXME Destroy the mesh? Prevents undo..
                    var filter = renderer.GetComponent <MeshFilter>();
                    //Undo.DestroyObjectImmediate(filter.sharedMesh);

                    if (renderer.GetComponent <ModelGroup>() == null)
                    {
                        // Destroy submesh game objects entirely.
                        Undo.DestroyObjectImmediate(renderer.gameObject);
                    }
                    else
                    {
                        // Destroy mesh related components on group game object.
                        Object.DestroyImmediate(filter);
                        Object.DestroyImmediate(renderer);
                    }
                }
            }

            // FIXME Check if bricks are referenced.
            // FIXME Check if bricks have custom components attached.

            // Remove group bricks.
            var existingBricks = group.GetComponentsInChildren <Brick>();

            foreach (var brick in existingBricks)
            {
                Undo.DestroyObjectImmediate(brick.gameObject);
            }

            var groupLightMapped = group.importSettings.isStatic && group.importSettings.lightmapped;

            SetStaticAndGIParams(group.gameObject, group.importSettings.isStatic, groupLightMapped);

            // Move group to origo to ensure that bricks are instantiated in the correct positions.
            var originalGroupParent       = group.transform.parent;
            var originalGroupSiblingIndex = group.transform.GetSiblingIndex();

            group.transform.parent        = null;
            group.transform.localPosition = Vector3.zero;
            group.transform.localRotation = Quaternion.identity;
            group.transform.localScale    = Vector3.one;

            // Create dictionary with just this group.
            var modelGroupImportSettingsDictionary = new DictionaryIntToModelGroupImportSettings();

            modelGroupImportSettingsDictionary.Add(group.number, group.importSettings);

            // Instantiate group bricks.
            var resultBricks = new Dictionary <int, Brick>(lxfml.bricks.Count);

            InstantiateModelBricks(lxfml, modelGroupImportSettingsDictionary, ref resultBricks, group.number);

            // Assign bricks to group.
            foreach (var brick in resultBricks.Values)
            {
                brick.transform.SetParent(group.transform);
            }

            // Set parent of group back to original.
            group.transform.parent = originalGroupParent;
            group.transform.SetSiblingIndex(originalGroupSiblingIndex);

            if (detectConnectivity && group.importSettings.connectivity)
            {
                var sceneBricks = new HashSet <Brick>(StageUtility.GetCurrentStageHandle().FindComponentsOfType <Brick>());
                DetectConnectivity(new HashSet <Brick>(resultBricks.Values), sceneBricks);
            }

            EditorUtility.ClearProgressBar();
        }
示例#11
0
        public static void ReimportModel(LXFMLDoc lxfml, Model model, Model.Pivot previousPivot, DictionaryIntToModelGroupImportSettings importSettings)
        {
            var brickBuilding = SceneBrickBuilder.GetToggleBrickBuildingStatus();

            if (brickBuilding)
            {
                SceneBrickBuilder.ToggleBrickBuilding();
            }

            // FIXME Next version could include option to match groups up manually.

            var oldPosition = model.transform.position;
            var oldRotation = model.transform.rotation;

            model.transform.position = Vector3.zero;
            model.transform.rotation = Quaternion.identity;

            var groups = model.GetComponentsInChildren <ModelGroup>();

            for (var i = groups.Length - 1; i >= 0; i--)
            {
                var group = groups[i];
                if (group.autoGenerated)
                {
                    Undo.DestroyObjectImmediate(group.gameObject);
                }
                else if (group.number >= lxfml.groups.Length)
                {
                    Debug.LogWarning("Group " + group.number + " " + group.groupName + " does not match up with files. Wiping.");
                    Undo.DestroyObjectImmediate(group.gameObject);
                }
            }

            groups = model.GetComponentsInChildren <ModelGroup>();

            var removedGroups = new List <LXFMLDoc.BrickGroup>();

            for (var i = 0; i < lxfml.groups.Length; i++)
            {
                LXFMLDoc.BrickGroup group = lxfml.groups[i];
                bool exists = false;
                for (var j = 0; j < groups.Length; j++)
                {
                    if (groups[j].number == group.number)
                    {
                        exists = true;
                        break;
                    }
                }

                if (!exists)
                {
                    removedGroups.Add(group);
                }
            }

            // Assign the new model import settings to the model.
            model.importSettings = new DictionaryIntToModelGroupImportSettings(importSettings);
            var bricksWithConnectivity = new HashSet <Brick>();

            if (removedGroups.Count > 0)
            {
                var resultBricks = new Dictionary <int, Brick>(lxfml.bricks.Count);
                foreach (var group in removedGroups)
                {
                    var number = group.number;
                    InstantiateModelBricks(lxfml, model.importSettings, ref resultBricks, number);
                    var groupGO = InstantiateModelGroup(group, number, model.gameObject, model.absoluteFilePath, model.relativeFilePath, ref resultBricks, false, importSettings[number]);
                    groupGO.transform.position = model.transform.position;
                    Undo.RegisterCreatedObjectUndo(groupGO, "Re-creating model group");
                    if (importSettings[number].connectivity)
                    {
                        bricksWithConnectivity.UnionWith(groupGO.GetComponentsInChildren <Brick>());
                    }
                }
            }

            foreach (var group in groups)
            {
                group.absoluteFilePath = model.absoluteFilePath;
                group.relativeFilePath = model.relativeFilePath;
                ReimportModelGroup(lxfml, group, importSettings[group.number]);
                if (group.importSettings.connectivity)
                {
                    bricksWithConnectivity.UnionWith(group.GetComponentsInChildren <Brick>());
                }
            }

            if (bricksWithConnectivity.Count > 0)
            {
                var sceneBricks = new HashSet <Brick>(StageUtility.GetCurrentStageHandle().FindComponentsOfType <Brick>());
                DetectConnectivity(bricksWithConnectivity, sceneBricks);
            }

            if (SceneBrickBuilder.GetAutoUpdateHierarchy())
            {
                groups = model.GetComponentsInChildren <ModelGroup>();
                var bricks = new HashSet <Brick>();
                foreach (var group in groups)
                {
                    if (group.importSettings.connectivity)
                    {
                        var groupBricks = group.GetComponentsInChildren <Brick>();
                        foreach (var brick in groupBricks)
                        {
                            bricks.Add(brick);
                        }
                    }
                }
                ModelGroupUtility.RecomputeHierarchy(bricks, false, ModelGroupUtility.UndoBehavior.withUndo);

                var oldToNew = model.transform.position;
                model.transform.rotation = oldRotation;
                model.transform.position = oldPosition;
                oldToNew = model.transform.TransformVector(oldToNew);

                if ((previousPivot == Model.Pivot.Center || previousPivot == Model.Pivot.BottomCenter) && model.pivot == Model.Pivot.Original)
                {
                    ModelGroupUtility.RecomputePivot(model.transform, previousPivot, true, ModelGroupUtility.UndoBehavior.withoutUndo);
                    var oldPivotPos = model.transform.position;
                    model.transform.position = oldPosition;
                    var diff = model.transform.position - oldPivotPos;
                    model.transform.position += diff;
                    foreach (var brick in model.GetComponentsInChildren <Brick>())
                    {
                        brick.transform.position -= diff;
                    }
                    model.transform.rotation = oldRotation;
                }

                if (model.pivot != Model.Pivot.Original && previousPivot == Model.Pivot.Original)
                {
                    model.transform.position += oldToNew;
                    model.transform.rotation  = oldRotation;
                }

                if (model.pivot != Model.Pivot.Original && previousPivot != Model.Pivot.Original)
                {
                    if (model.pivot != previousPivot)
                    {
                        ModelGroupUtility.RecomputePivot(model.transform, previousPivot, true, ModelGroupUtility.UndoBehavior.withoutUndo);
                        model.transform.position = oldPosition;
                        ModelGroupUtility.RecomputePivot(model, false, ModelGroupUtility.UndoBehavior.withoutUndo);
                        model.transform.rotation = oldRotation;
                    }
                }
            }

            if (brickBuilding)
            {
                SceneBrickBuilder.ToggleBrickBuilding();
            }

            EditorUtility.ClearProgressBar();
        }