public static void ConvertVersion_0_To_1(Connectivity connectivity)
 {
     Debug.Log($"Updating Connectivity 0 -> 1 on {connectivity.name}");
     PartUtility.UnpackConnectivityForPart(connectivity.name, true);
 }
Example #2
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;
            }
        }
        private static bool UpdateConnections(Brick[] bricks)
        {
            var updated = false;

            foreach (var brick in bricks)
            {
                if (PrefabUtility.IsPartOfPrefabInstance(brick))
                {
                    continue;
                }

                foreach (var part in brick.parts)
                {
                    var designID = part.designID.ToString();
                    if (!PartUtility.CheckIfConnectivityForPartIsUnpacked(designID))
                    {
                        PartUtility.UnpackConnectivityForPart(designID);
                    }

                    var connectivity = part.connectivity;
                    if (!connectivity)
                    {
                        // Unsupported or legacy.
                        continue;
                    }

                    if (connectivity.version == currentVersion)
                    {
                        // Already up to date.
                        continue;
                    }

                    var connectivityToInstantiate = PartUtility.LoadConnectivityPrefab(designID);
                    if (connectivityToInstantiate)
                    {
                        GameObject.DestroyImmediate(connectivity.gameObject, true);
                        var connectivityGO = UnityEngine.Object.Instantiate(connectivityToInstantiate);
                        connectivityGO.name = "Connectivity";
                        connectivityGO.transform.SetParent(part.transform, false);
                        var connectivityComp = connectivityGO.GetComponent <Connectivity>();
                        part.connectivity = connectivityComp;
                        part.brick.totalBounds.Encapsulate(connectivityComp.extents);
                        connectivityComp.part = part;

                        updated = true;

                        foreach (var tube in part.tubes)
                        {
                            tube.connections.Clear();
                            tube.field = null;
                        }

                        foreach (var knob in part.knobs)
                        {
                            knob.field           = null;
                            knob.connectionIndex = -1;
                        }

                        foreach (var field in connectivityComp.connectionFields)
                        {
                            foreach (var connection in field.connections)
                            {
                                ModelImporter.MatchConnectionWithKnob(connection, part.knobs);
                                ModelImporter.MatchConnectionWithTubes(connection, part.tubes);
                            }
                        }
                    }
                }
            }
            return(updated);
        }