Esempio n. 1
0
        static void AddCollider(GameObject gameObject, bool hasPhysics)
        {
            // If no mesh is defined skip this GameObject
            var meshFilter = gameObject.GetComponent <MeshFilter>();
            var sharedMesh = meshFilter ? meshFilter.sharedMesh : null;

            if (!sharedMesh)
            {
                return;
            }

            var colliderTarget = gameObject;
            var lodGroup       = gameObject.GetComponentInParent <LODGroup>();

            if (lodGroup)
            {
                colliderTarget = lodGroup.gameObject;
            }

            // If target already has colliders do not modify
            if (colliderTarget.GetComponentsInChildren <Collider>().Length > 0)
            {
                return;
            }

            // Add a mesh collider to this object
            var meshCollider = EP.AddComponent <MeshCollider>(colliderTarget);

            meshCollider.sharedMesh = sharedMesh;
            meshCollider.convex     = hasPhysics;
        }
Esempio n. 2
0
        public static LightProbeGroup CreateLightProbes(GameObject gameObject)
        {
            // Light probe positions are evaluated relative to LightProbeGroup
            // https://docs.unity3d.com/ScriptReference/LightProbeGroup-probePositions.html
            var group = gameObject.GetComponent <LightProbeGroup>();

            if (!group)
            {
                group = EP.AddComponent <LightProbeGroup>(gameObject);
            }

            // IDEA: Find child LightProbeGroups and exclude probes in those volumes
            // This would enable adjusting the probe density in different areas.

            // TODO: Enable configuration to use other placement strategies
            group.probePositions = LightProbeGrid(gameObject, probeSpaces);
            return(group);
        }
Esempio n. 3
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);
        }
Esempio n. 4
0
        /// <summary>
        /// Configure the light probe proxy volume for lower levels of detail in group
        /// </summary>
        public static void ConfigureLODGroup(LODGroup lodGroup)
        {
            // TODO: Check if group is static - if not, also configure the lowest level of detail.

            // Only lower levels of detail will use probes
            // IMPORTANT: Proxy volumes always update, so only generate them if they will be used.
            var lods = lodGroup.GetLODs();

            if (lods.Length < 2)
            {
                return;
            }

            // FIXME: Local bounds are needed
            var worldBounds = RendererWorldBounds(lodGroup.gameObject);
            // TEMP: Assume that only axis swaps pertain
            var localBounds = new Bounds();

            localBounds.center = lodGroup.transform.InverseTransformPoint(worldBounds.center);
            localBounds.size   = lodGroup.transform.InverseTransformDirection(worldBounds.size);
            localBounds.size   = new Vector3(Mathf.Abs(localBounds.size.x), Mathf.Abs(localBounds.size.y), Mathf.Abs(localBounds.size.z));

            // If object bounds > probe spacing in any dimension use a proxy volume
            var useProxy = false;

            for (var i = 0; i < 3; ++i)
            {
                useProxy |= localBounds.size[i] > probeSpaces[i];
            }
            var proxy = lodGroup.gameObject.GetComponent <LightProbeProxyVolume>();

            if (useProxy)
            {
                if (!proxy)
                {
                    proxy = EP.AddComponent <LightProbeProxyVolume>(lodGroup.gameObject);
                }

                // Configure proxy bounds
                proxy.boundingBoxMode = LightProbeProxyVolume.BoundingBoxMode.Custom;
                proxy.originCustom    = localBounds.center;
                proxy.sizeCustom      = localBounds.size;

                // Configure spacing
                proxy.probePositionMode = LightProbeProxyVolume.ProbePositionMode.CellCorner;
                proxy.resolutionMode    = LightProbeProxyVolume.ResolutionMode.Custom;
                proxy.gridResolutionX   = ProxyResolution(localBounds.size.x / probeSpaces.x);
                proxy.gridResolutionY   = ProxyResolution(localBounds.size.y / probeSpaces.y);
                proxy.gridResolutionZ   = ProxyResolution(localBounds.size.z / probeSpaces.z);

                // Remaining settings
                proxy.qualityMode = LightProbeProxyVolume.QualityMode.Normal;
                proxy.refreshMode = LightProbeProxyVolume.RefreshMode.Automatic;
            }
            else
            {
                if (proxy)
                {
                    EP.Destroy(proxy);
                }
                proxy = null;
            }

            // Configure all lower levels of detail to use probes
            for (var l = 1; l < lods.Length; ++l)
            {
                foreach (var renderer in lods[l].renderers)
                {
                    renderer.lightProbeUsage = useProxy ? UnityEngine.Rendering.LightProbeUsage.UseProxyVolume : UnityEngine.Rendering.LightProbeUsage.BlendProbes;
                    renderer.lightProbeProxyVolumeOverride = lodGroup.gameObject;

                    var meshRender = renderer as MeshRenderer;
                    if (!meshRender)
                    {
                        continue;
                    }
                    meshRender.receiveGI = ReceiveGI.LightProbes;
                }
            }
        }
Esempio n. 5
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);
                    }
                }
            }
        }