/// <summary>
        /// Convert the given <see cref="Renderer"/> into a single Hybrid Rendered entity that uses
        /// the first <see cref="Material"/> configured in the <see cref="Renderer"/>.
        /// </summary>
        public void ConvertToSingleEntity(
            EntityManager dstEntityManager,
            GameObjectConversionSystem conversionSystem,
            RenderMeshDescription renderMeshDescription,
            Renderer renderer)
        {
            var entity = conversionSystem.GetPrimaryEntity(renderer);

            var lightmappedMaterial = ConfigureHybridStaticLighting(
                entity,
                dstEntityManager,
                renderer,
                renderMeshDescription.RenderMesh.material);

            if (lightmappedMaterial != null)
            {
                renderMeshDescription.RenderMesh.material = lightmappedMaterial;
            }

            RenderMeshUtility.AddComponents(
                entity,
                dstEntityManager,
                renderMeshDescription);

            conversionSystem.ConfigureEditorRenderData(entity, renderer.gameObject, true);
        }
        /// <summary>
        /// Convert the given <see cref="Renderer"/> into a multiple Hybrid Rendered entities such that every
        /// <see cref="Material"/> in the <see cref="Renderer"/> is converted into one entity that uses that <see cref="Material"/>
        /// with the corresponding sub-mesh from <see cref="RenderMesh.mesh"/>. All created entities will be parented
        /// to the entity created from <see cref="root"/>.
        /// </summary>
        public void ConvertToMultipleEntities(
            EntityManager dstEntityManager,
            GameObjectConversionSystem conversionSystem,
            RenderMeshDescription renderMeshDescription,
            Renderer renderer,
            List <Material> sharedMaterials,
            Transform root)
        {
            int materialCount = sharedMaterials.Count;

            float4x4 localToWorld = root.localToWorldMatrix;
            var      rootEntity   = conversionSystem.GetPrimaryEntity(root);

            for (var m = 0; m != materialCount; m++)
            {
                var meshEntity = conversionSystem.CreateAdditionalEntity(renderer);

                // required for incremental conversion to work without a dependency on the transform itself.
                dstEntityManager.AddComponent <CopyTransformFromPrimaryEntityTag>(meshEntity);
                dstEntityManager.AddComponentData(meshEntity, new LocalToWorld {
                    Value = localToWorld
                });
                if (!dstEntityManager.HasComponent <Static>(meshEntity))
                {
                    dstEntityManager.AddComponentData(meshEntity, new Parent {
                        Value = rootEntity
                    });
                    dstEntityManager.AddComponentData(meshEntity,
                                                      new LocalToParent {
                        Value = float4x4.identity
                    });
                }

                var material = sharedMaterials[m];

                var lightmappedMaterial = ConfigureHybridLightMapping(
                    meshEntity,
                    dstEntityManager,
                    renderer,
                    material);

                if (lightmappedMaterial != null)
                {
                    material = lightmappedMaterial;
                }

                renderMeshDescription.RenderMesh.subMesh  = m;
                renderMeshDescription.RenderMesh.material = material;

                RenderMeshUtility.AddComponents(
                    meshEntity,
                    dstEntityManager,
                    renderMeshDescription);

                RemoveLightProbeComponentsFromLightMappedEntities(meshEntity, dstEntityManager);

                conversionSystem.ConfigureEditorRenderData(meshEntity, renderer.gameObject, true);
            }
        }
        /// <summary>
        /// Construct a <see cref="RenderMeshDescription"/> using defaults from the given
        /// <see cref="Renderer"/> and <see cref="Mesh"/> objects.
        /// </summary>
        /// <param name="renderer">The renderer object (e.g. a <see cref="MeshRenderer"/>) to get default settings from.</param>
        /// <param name="mesh">The mesh to use and get default bounds from.</param>
        /// <param name="sharedMaterials">The list of materials to render the entity with.
        /// If the list is null or empty, <see cref="Renderer.GetSharedMaterials"/> will be used to obtain the list.
        /// An explicit list can be supplied if you have already called <see cref="Renderer.GetSharedMaterials"/> previously,
        /// or if you want to use different materials.</param>
        /// <param name="subMeshIndex">The sub-mesh of the mesh to use for rendering. The corresponding material index
        /// from <see cref="sharedMaterials"/> will be used as the material for that sub-mesh.</param>
        public RenderMeshDescription(
            Renderer renderer,
            Mesh mesh,
            List <Material> sharedMaterials = null,
            int subMeshIndex = 0)
        {
            Debug.Assert(renderer != null, "Must have a non-null Renderer to create RenderMeshDescription.");
            Debug.Assert(mesh != null, "Must have a non-null Mesh to create RenderMeshDescription.");

            if (sharedMaterials is null)
            {
                sharedMaterials = new List <Material>(capacity: 10);
            }

            if (sharedMaterials.Count == 0)
            {
                renderer.GetSharedMaterials(sharedMaterials);
            }

            Debug.Assert(subMeshIndex >= 0 && subMeshIndex < sharedMaterials.Count,
                         "Sub-mesh index out of bounds, no matching material.");

            var motionVectorGenerationMode = renderer.motionVectorGenerationMode;
            var needMotionVectorPass       =
                (motionVectorGenerationMode == MotionVectorGenerationMode.Object) ||
                (motionVectorGenerationMode == MotionVectorGenerationMode.ForceNoMotion);

            RenderMesh = new RenderMesh
            {
                mesh                 = mesh,
                material             = sharedMaterials[subMeshIndex],
                subMesh              = subMeshIndex,
                layer                = renderer.gameObject.layer,
                castShadows          = renderer.shadowCastingMode,
                receiveShadows       = renderer.receiveShadows,
                needMotionVectorPass = needMotionVectorPass,
            };

            RenderingLayerMask = renderer.renderingLayerMask;
            FlipWinding        = false;
            MotionMode         = motionVectorGenerationMode;

            var staticLightingMode = RenderMeshUtility.StaticLightingModeFromRenderer(renderer);
            var lightProbeUsage    = renderer.lightProbeUsage;

            LightProbeUsage = (staticLightingMode == StaticLightingMode.LightProbes)
                ? lightProbeUsage
                : LightProbeUsage.Off;
        }
        private Material ConfigureHybridLightMapping(
            Entity entity,
            EntityManager entityManager,
            Renderer renderer,
            Material material)
        {
#if USE_HYBRID_LIGHT_MAPS
            var staticLightingMode = RenderMeshUtility.StaticLightingModeFromRenderer(renderer);
            if (staticLightingMode == StaticLightingMode.LightMapped)
            {
                var lightMapRef = m_LightMapConversionContext.GetLightMapReference(renderer);

                if (lightMapRef != null)
                {
                    Material lightMappedMaterial =
                        m_LightMapConversionContext.GetLightMappedMaterial(material, lightMapRef);

                    entityManager.AddComponentData(entity,
                                                   new BuiltinMaterialPropertyUnity_LightmapST()
                    {
                        Value = renderer.lightmapScaleOffset
                    });
                    entityManager.AddComponentData(entity,
                                                   new BuiltinMaterialPropertyUnity_LightmapIndex()
                    {
                        Value = lightMapRef.LightMapIndex
                    });
                    entityManager.AddSharedComponentData(entity, lightMapRef.LightMaps);

                    return(lightMappedMaterial);
                }
            }
#endif

            return(null);
        }