static Vector3 BlendSize(LocalVolumetricFog localVolumetricFog)
        {
            Vector3 size = localVolumetricFog.parameters.size;

            if (localVolumetricFog.parameters.m_EditorAdvancedFade)
            {
                Vector3 blendSize = (Vector3.one - localVolumetricFog.parameters.m_EditorPositiveFade - localVolumetricFog.parameters.m_EditorNegativeFade);
                blendSize.x *= size.x;
                blendSize.y *= size.y;
                blendSize.z *= size.z;
                return(blendSize);
            }
            else
            {
                return(size - localVolumetricFog.parameters.m_EditorUniformFade * 2f * Vector3.one);
            }
        }
 static Vector3 CenterBlendLocalPosition(LocalVolumetricFog localVolumetricFog)
 {
     if (localVolumetricFog.parameters.m_EditorAdvancedFade)
     {
         Vector3 size     = localVolumetricFog.parameters.size;
         Vector3 posBlend = localVolumetricFog.parameters.m_EditorPositiveFade;
         posBlend.x *= size.x;
         posBlend.y *= size.y;
         posBlend.z *= size.z;
         Vector3 negBlend = localVolumetricFog.parameters.m_EditorNegativeFade;
         negBlend.x *= size.x;
         negBlend.y *= size.y;
         negBlend.z *= size.z;
         Vector3 localPosition = (negBlend - posBlend) * 0.5f;
         return(localPosition);
     }
     else
     {
         return(Vector3.zero);
     }
 }
        static void DrawGizmosSelected(LocalVolumetricFog localVolumetricFog, GizmoType gizmoType)
        {
            if (s_BlendBox == null || s_BlendBox.Equals(null) ||
                s_ShapeBox == null || s_ShapeBox.Equals(null))
            {
                return;
            }

            using (new Handles.DrawingScope(Matrix4x4.TRS(localVolumetricFog.transform.position, localVolumetricFog.transform.rotation, Vector3.one)))
            {
                // Blend box
                s_BlendBox.center = CenterBlendLocalPosition(localVolumetricFog);
                s_BlendBox.size   = BlendSize(localVolumetricFog);
                Color baseColor = localVolumetricFog.parameters.albedo;
                baseColor.a          = 8 / 255f;
                s_BlendBox.baseColor = baseColor;
                s_BlendBox.DrawHull(EditMode.editMode == k_EditBlend);

                // Bounding box.
                s_ShapeBox.center = Vector3.zero;
                s_ShapeBox.size   = localVolumetricFog.parameters.size;
                s_ShapeBox.DrawHull(EditMode.editMode == k_EditShape);
            }
        }
        void OnSceneGUI()
        {
            //Note: for each handle to be independent when multi-selecting LocalVolumetricFog,
            //We cannot rely  hereon SerializedLocalVolumetricFog which is the collection of
            //selected LocalVolumetricFog. Thus code is almost the same of the UI.

            LocalVolumetricFog localVolumetricFog = target as LocalVolumetricFog;

            switch (EditMode.editMode)
            {
            case k_EditBlend:
                using (new Handles.DrawingScope(Matrix4x4.TRS(localVolumetricFog.transform.position, localVolumetricFog.transform.rotation, Vector3.one)))
                {
                    //contained must be initialized in all case
                    s_ShapeBox.center = Vector3.zero;
                    s_ShapeBox.size   = localVolumetricFog.parameters.size;

                    Color baseColor = localVolumetricFog.parameters.albedo;
                    baseColor.a           = 8 / 255f;
                    s_BlendBox.baseColor  = baseColor;
                    s_BlendBox.monoHandle = !localVolumetricFog.parameters.m_EditorAdvancedFade;
                    s_BlendBox.center     = CenterBlendLocalPosition(localVolumetricFog);
                    s_BlendBox.size       = BlendSize(localVolumetricFog);
                    EditorGUI.BeginChangeCheck();
                    s_BlendBox.DrawHandle();
                    if (EditorGUI.EndChangeCheck())
                    {
                        Undo.RecordObject(localVolumetricFog, L10n.Tr("Change Local Volumetric Fog Blend"));

                        if (localVolumetricFog.parameters.m_EditorAdvancedFade)
                        {
                            //work in local space to compute the change on positiveFade and negativeFade
                            Vector3 newCenterBlendLocalPosition = s_BlendBox.center;
                            Vector3 halfSize = s_BlendBox.size * 0.5f;
                            Vector3 size     = localVolumetricFog.parameters.size;
                            Vector3 posFade  = newCenterBlendLocalPosition + halfSize;
                            posFade.x = 0.5f - posFade.x / size.x;
                            posFade.y = 0.5f - posFade.y / size.y;
                            posFade.z = 0.5f - posFade.z / size.z;
                            Vector3 negFade = newCenterBlendLocalPosition - halfSize;
                            negFade.x = 0.5f + negFade.x / size.x;
                            negFade.y = 0.5f + negFade.y / size.y;
                            negFade.z = 0.5f + negFade.z / size.z;
                            localVolumetricFog.parameters.m_EditorPositiveFade = posFade;
                            localVolumetricFog.parameters.m_EditorNegativeFade = negFade;
                        }
                        else
                        {
                            float uniformDistance = (s_ShapeBox.size.x - s_BlendBox.size.x) * 0.5f;
                            float max             = Mathf.Min(s_ShapeBox.size.x, s_ShapeBox.size.y, s_ShapeBox.size.z) * 0.5f;
                            localVolumetricFog.parameters.m_EditorUniformFade = Mathf.Clamp(uniformDistance, 0f, max);
                        }
                    }
                }
                break;

            case k_EditShape:
                //important: if the origin of the handle's space move along the handle,
                //handles displacement will appears as moving two time faster.
                using (new Handles.DrawingScope(Matrix4x4.TRS(Vector3.zero, localVolumetricFog.transform.rotation, Vector3.one)))
                {
                    //contained must be initialized in all case
                    s_ShapeBox.center = Quaternion.Inverse(localVolumetricFog.transform.rotation) * localVolumetricFog.transform.position;
                    s_ShapeBox.size   = localVolumetricFog.parameters.size;

                    Vector3 previousSize         = localVolumetricFog.parameters.size;
                    Vector3 previousPositiveFade = localVolumetricFog.parameters.m_EditorPositiveFade;
                    Vector3 previousNegativeFade = localVolumetricFog.parameters.m_EditorNegativeFade;

                    EditorGUI.BeginChangeCheck();
                    s_ShapeBox.DrawHandle();
                    if (EditorGUI.EndChangeCheck())
                    {
                        Undo.RecordObjects(new Object[] { localVolumetricFog, localVolumetricFog.transform }, L10n.Tr("Change Local Volumetric Fog Bounding Box"));

                        Vector3 newSize = s_ShapeBox.size;
                        localVolumetricFog.parameters.size = newSize;

                        Vector3 newPositiveFade = new Vector3(
                            newSize.x < 0.00001 ? 0 : previousPositiveFade.x * previousSize.x / newSize.x,
                            newSize.y < 0.00001 ? 0 : previousPositiveFade.y * previousSize.y / newSize.y,
                            newSize.z < 0.00001 ? 0 : previousPositiveFade.z * previousSize.z / newSize.z
                            );
                        Vector3 newNegativeFade = new Vector3(
                            newSize.x < 0.00001 ? 0 : previousNegativeFade.x * previousSize.x / newSize.x,
                            newSize.y < 0.00001 ? 0 : previousNegativeFade.y * previousSize.y / newSize.y,
                            newSize.z < 0.00001 ? 0 : previousNegativeFade.z * previousSize.z / newSize.z
                            );
                        for (int axeIndex = 0; axeIndex < 3; ++axeIndex)
                        {
                            if (newPositiveFade[axeIndex] + newNegativeFade[axeIndex] > 1)
                            {
                                float overValue = (newPositiveFade[axeIndex] + newNegativeFade[axeIndex] - 1f) * 0.5f;
                                newPositiveFade[axeIndex] -= overValue;
                                newNegativeFade[axeIndex] -= overValue;

                                if (newPositiveFade[axeIndex] < 0)
                                {
                                    newNegativeFade[axeIndex] += newPositiveFade[axeIndex];
                                    newPositiveFade[axeIndex]  = 0f;
                                }
                                if (newNegativeFade[axeIndex] < 0)
                                {
                                    newPositiveFade[axeIndex] += newNegativeFade[axeIndex];
                                    newNegativeFade[axeIndex]  = 0f;
                                }
                            }
                        }
                        localVolumetricFog.parameters.m_EditorPositiveFade = newPositiveFade;
                        localVolumetricFog.parameters.m_EditorNegativeFade = newNegativeFade;

                        //update normal mode blend
                        float max            = Mathf.Min(newSize.x, newSize.y, newSize.z) * 0.5f;
                        float newUniformFade = Mathf.Clamp(localVolumetricFog.parameters.m_EditorUniformFade, 0f, max);
                        localVolumetricFog.parameters.m_EditorUniformFade = newUniformFade;

                        //update engine used percents
                        if (localVolumetricFog.parameters.m_EditorAdvancedFade)
                        {
                            localVolumetricFog.parameters.positiveFade = newPositiveFade;
                            localVolumetricFog.parameters.negativeFade = newNegativeFade;
                        }
                        else
                        {
                            localVolumetricFog.parameters.positiveFade     =
                                localVolumetricFog.parameters.negativeFade = new Vector3(
                                    1.0f - (newSize.x > 0.00000001 ? (newSize.x - newUniformFade) / newSize.x : 0f),
                                    1.0f - (newSize.y > 0.00000001 ? (newSize.y - newUniformFade) / newSize.y : 0f),
                                    1.0f - (newSize.z > 0.00000001 ? (newSize.z - newUniformFade) / newSize.z : 0f));
                        }

                        Vector3 delta = localVolumetricFog.transform.rotation * s_ShapeBox.center - localVolumetricFog.transform.position;
                        localVolumetricFog.transform.position += delta;
                    }
                }
                break;
            }
        }