Exemple #1
0
        // PROBLEM: If multiple intermediate levels of the hierarchy have the same name
        // then children will be randomly assigned. This could happen if Av0 has children,
        // Av1 does not and is added, but then Av2 has children, which could be parented to
        // either Av1 or Av0. Or, if the original model uses a name multiple times.
        // TODO: Identify problem and warn.

        static void Merge(Transform mergeFrom, Transform mergeTo)
        {
            // When names match, merge
            var mergeChildren = new List <Transform>();

            foreach (var childFrom in mergeFrom.Children())
            {
                var childTo = mergeTo.NameFindInChildren(childFrom.name);
                if (childTo.Length == 0)
                {
                    // ChildFrom is not in the hierarchy
                    mergeChildren.Add(childFrom);
                    continue;
                }
                if (PrefabUtility.GetPrefabAssetType(childFrom) != PrefabAssetType.NotAPrefab)
                {
                    // ChildFrom is a Prefab and is already present in hierarchy since childTo != null
                    continue;
                }
                if (childFrom.transform.childCount == 0)
                {
                    // ChildFrom is a distinct instance even if childTo is present
                    mergeChildren.Add(childFrom);
                    continue;
                }
                // ChildFrom and ChildTo match, so merge children instead
                Merge(childFrom, childTo[0].transform);
            }
            foreach (var childFrom in mergeChildren)
            {
                EP.SetParent(childFrom, mergeTo);
            }
        }
Exemple #2
0
        // PROBLEM: Light source meshes are generally small and could use a lower level of detail
        // in most cases. Prefabs with custom meshes could address this for sphere and cylinder

        // OPTION: Provide a component to monitor the light intensity and update the emissive material
        // accordingly - both static and dynamic. This could also tag actual child light sources.

        public static GameObject CreatePrimitiveSource(Light light, PrimitiveType primitiveType)
        {
            var source = GameObject.CreatePrimitive(primitiveType);

            source.SetActive(light.enabled);
            source.layer = light.gameObject.layer;
            // Make source constitent with search
            source.name = ConfigureName(light.name);
            EP.SetParent(source.transform, light.transform);

            // Position source around light
            source.transform.localPosition = Vector3.zero;
            source.transform.localRotation = Quaternion.identity;
            // Source scale depends on light type

            Object.DestroyImmediate(source.GetComponent <Collider>());

            if (light.gameObject.isStatic)
            {
                var staticFlags = (StaticEditorFlags) ~0;
                staticFlags &= ~StaticEditorFlags.OccluderStatic;
                staticFlags &= ~StaticEditorFlags.ContributeGI;
                GameObjectUtility.SetStaticEditorFlags(source, staticFlags);
            }
            else
            {
                source.isStatic = false;
            }

            LightSourceMeshRenderer(light, source.GetComponent <MeshRenderer>());

            Undo.RegisterCreatedObjectUndo(source, "Create Primitive Light Source");
            return(source);
        }
Exemple #3
0
        // Model export generates meshes in world coordinates
        // In order to retain information, each prefab is replaced with a transformed tetrahedron
        static void ConfigurePrefab(Transform placeholder, CachedPrefab cached)
        {
            var prefab = (PrefabUtility.InstantiatePrefab(cached.prefab) as GameObject).transform;

            EP.SetParent(prefab, placeholder.parent);
            prefab.localPosition = placeholder.localPosition;
            prefab.localRotation = placeholder.localRotation;
            prefab.localScale    = placeholder.localScale;
            prefab.name          = placeholder.name;
        }
Exemple #4
0
        // TODO: This, like a grid, is a standard layout
        // IDEA: When TransformData is included, provide utilities to generate layouts, and to replicate gameobjects over them
        static GameObject[] RotateCopies(GameObject original, Quaternion rotation, int count)
        {
            var copyList = new GameObject[count];

            copyList[0] = original;
            for (int c = 1; c < count; ++c)
            {
                var copy = EP.Instantiate(original);
                EP.SetParent(copy.transform, original.transform.parent);
                copy.transform.localPosition = rotation * copyList[c - 1].transform.localPosition;
                copy.transform.localRotation = rotation * copyList[c - 1].transform.localRotation;
                copyList[c] = copy;
            }
            return(copyList);
        }
Exemple #5
0
        static void CreateLinearYSource(Light light)
        {
            // Create a self-illuminated cylinder
            var source = CreatePrimitiveSource(light, PrimitiveType.Cylinder);

            source.transform.localScale = new Vector3(pointDiameter, light.areaSize.y / 2f, pointDiameter);

            // Create planes covering all emission directions
            var side0 = MakeAreaCopy(light, new Vector2(pointDiameter, light.areaSize.y));

            EP.SetParent(side0.transform, light.transform);
            var sideList = RotateCopies(side0, Quaternion.Euler(360f / linearSources, 0f, 0f), linearSources);

            for (int s = 0; s < sideList.Length; ++s)
            {
                sideList[s].name = light.name + "_Side" + s;
            }
        }
Exemple #6
0
        /// <summary>
        /// Make a copy of light source as area light, with equivalent illumination
        /// </summary>
        /// <remarks>
        /// Intensity is scaled relative to the area of the light
        /// </remarks>
        public static GameObject MakeAreaCopy(Light light, Vector2 areaSize)
        {
            var gameObject = EP.Instantiate();

            GameObjectUtility.SetStaticEditorFlags(gameObject, (StaticEditorFlags) ~0);
            EP.SetParent(gameObject.transform, light.transform.parent);
            gameObject.transform.localPosition = light.transform.localPosition;
            gameObject.transform.localRotation = light.transform.localRotation;
            var areaLight = EP.AddComponent <Light>(gameObject);

            areaLight.lightmapBakeType = LightmapBakeType.Baked;
            areaLight.type             = LightType.Rectangle;
            areaLight.areaSize         = areaSize;
            areaLight.intensity        = light.intensity / (areaSize.x * areaSize.y);
            areaLight.color            = light.color;
            areaLight.range            = light.range;
            return(gameObject);
        }
Exemple #7
0
        static void MergeGroup(string pathName, List <GameObject> group)
        {
            // Gather LODGroup and Renderers
            LODGroup lodGroup  = null;
            var      renderers = new List <RendererSort>();

            foreach (var gameObject in group)
            {
                var renderer = gameObject.GetComponent <Renderer>();
                if (renderer)
                {
                    renderers.Add(new RendererSort(renderer));
                }
                var isGroup = gameObject.GetComponent <LODGroup>();
                if (isGroup)
                {
                    var lods = isGroup.GetLODs();
                    foreach (var lod in lods)
                    {
                        foreach (var lodRenderer in lod.renderers)
                        {
                            // Renderers must begin as siblings of LODGroup
                            EP.SetParent(lodRenderer.transform, isGroup.transform.parent);
                            renderers.Add(new RendererSort(lodRenderer));
                        }
                    }

                    if (!!lodGroup || !!renderer)
                    {
                        // LODGroup manager cannot be duplicated, and cannot have renderer component
                        Debug.LogWarning($"Removing LODGroup found on {gameObject.Path()}");
                        EP.Destroy(isGroup);
                        continue;
                    }
                    lodGroup = isGroup;
                }
            }
            if (!lodGroup)
            {
                lodGroup = EP.AddComponent <LODGroup>(EP.Instantiate());
            }

            // renderers[0] has the lowest vertex count
            renderers.Sort((l, m) => l.vertexCount - m.vertexCount);
            // Remove missing meshes and duplicate levels of detail
            var vertexCount     = 0;
            var removeRenderers = new List <RendererSort>();

            foreach (var renderer in renderers)
            {
                if (vertexCount == renderer.vertexCount)
                {
                    removeRenderers.Add(renderer);
                    continue;
                }
                vertexCount = renderer.vertexCount;
            }
            foreach (var renderer in removeRenderers)
            {
                renderers.Remove(renderer);
                EP.Destroy(renderer.renderer.gameObject);
                // NOTE: Duplicate mesh asset could be removed
            }
            if (renderers.Count == 0)
            {
                EP.Destroy(lodGroup.gameObject);
                return;
            }
            // renderers[0] has the highest vertrex count
            renderers.Reverse();

            // Configure manager in hierarchy
            lodGroup.gameObject.name = pathName.Substring(pathName.LastIndexOf('/') + 1);
            EP.SetParent(lodGroup.transform, renderers[0].renderer.transform.parent);
            lodGroup.transform.localPosition = renderers[0].renderer.transform.localPosition;
            lodGroup.transform.localRotation = renderers[0].renderer.transform.localRotation;
            lodGroup.transform.localScale    = renderers[0].renderer.transform.localScale;
            for (var r = 0; r < renderers.Count; ++r)
            {
                var renderer = renderers[r].renderer;
                // TODO: Used PathNameExtension for this!
                var lodIndex = renderer.gameObject.name.LastIndexOf(lodSuffix);
                if (lodIndex >= 0)
                {
                    renderer.gameObject.name = renderer.gameObject.name.Substring(0, lodIndex);
                }
                renderer.gameObject.name += lodSuffix + r.ToString();
                EP.SetParent(renderer.transform, lodGroup.transform);
            }

            // Configure the group
            var lodList = new LOD[renderers.Count];

            for (var r = 0; r < renderers.Count; ++r)
            {
                lodList[r].renderers = new[] { renderers[r].renderer }
            }
            ;
            ConfigureLODGroup(lodGroup, lodList);

            // Configure the renderers and materials
            foreach (var lod in lodGroup.GetLODs())
            {
                foreach (var renderer in lod.renderers)
                {
                    SetLightmapScale(renderer);
                    foreach (var material in renderer.sharedMaterials)
                    {
                        UseFadingShader(material);
                    }
                }
            }
        }