static void DrawBoxFadeHandle(InfluenceVolumeUI s, SerializedInfluenceVolume d, Editor o, Object sourceAsset, HierarchicalBox box, SerializedProperty positive, SerializedProperty negative)
        {
            box.center     = d.offset.vector3Value - (positive.vector3Value - negative.vector3Value) * 0.5f;
            box.size       = d.boxSize.vector3Value - positive.vector3Value - negative.vector3Value;
            box.monoHandle = !d.editorAdvancedModeEnabled.boolValue;

            //set up parent box too for clamping
            s.boxBaseHandle.center = d.offset.vector3Value;
            s.boxBaseHandle.size   = d.boxSize.vector3Value;

            EditorGUI.BeginChangeCheck();
            box.DrawHandle();
            if (EditorGUI.EndChangeCheck())
            {
                Undo.RecordObject(sourceAsset, "Modified Influence Volume");

                var halfInfluenceSize     = d.boxSize.vector3Value * .5f;
                var blendDistancePositive = d.offset.vector3Value - box.center - box.size * .5f + halfInfluenceSize;
                var blendDistanceNegative = box.center - d.offset.vector3Value - box.size * .5f + halfInfluenceSize;

                positive.vector3Value = Vector3.Min(blendDistancePositive, halfInfluenceSize);
                negative.vector3Value = Vector3.Min(blendDistanceNegative, halfInfluenceSize);

                d.Apply();
            }
        }
Ejemplo n.º 2
0
        static void DrawBoxFadeHandle(SerializedInfluenceVolume serialized, Editor owner, Transform transform, HierarchicalBox box, SerializedProperty positive, SerializedProperty negative)
        {
            using (new Handles.DrawingScope(Matrix4x4.TRS(transform.position, transform.rotation, Vector3.one)))
            {
                box.center     = -(positive.vector3Value - negative.vector3Value) * 0.5f;
                box.size       = serialized.boxSize.vector3Value - positive.vector3Value - negative.vector3Value;
                box.monoHandle = !serialized.editorAdvancedModeEnabled.boolValue;

                EditorGUI.BeginChangeCheck();
                box.DrawHandle();
                box.DrawHull(true);
                if (EditorGUI.EndChangeCheck())
                {
                    var influenceCenter   = Vector3.zero;
                    var halfInfluenceSize = serialized.boxSize.vector3Value * .5f;

                    var centerDiff            = box.center - influenceCenter;
                    var halfSizeDiff          = halfInfluenceSize - box.size * .5f;
                    var positiveNew           = halfSizeDiff - centerDiff;
                    var negativeNew           = halfSizeDiff + centerDiff;
                    var blendDistancePositive = Vector3.Max(Vector3.zero, Vector3.Min(positiveNew, halfInfluenceSize));
                    var blendDistanceNegative = Vector3.Max(Vector3.zero, Vector3.Min(negativeNew, halfInfluenceSize));

                    positive.vector3Value = blendDistancePositive;
                    negative.vector3Value = blendDistanceNegative;
                }
            }
        }
        void OnSceneGUI()
        {
            DensityVolume   densityVolume = target as DensityVolume;
            HierarchicalBox shapeBox      = shapeBoxes[densityVolume];
            HierarchicalBox blendBox      = blendBoxes[densityVolume];

            using (new Handles.DrawingScope(Matrix4x4.TRS(densityVolume.transform.position, densityVolume.transform.rotation, Vector3.one)))
            {
                if (EditMode.editMode == k_EditBlend || EditMode.editMode == k_EditShape)
                {
                    //contained must be initialized in all case
                    shapeBox.center = Vector3.zero;
                    shapeBox.size   = densityVolume.parameters.size;
                }

                if (EditMode.editMode == k_EditBlend)
                {
                    blendBox.monoHandle = !densityVolume.parameters.advancedFade;
                    blendBox.center     = CenterBlendLocalPosition(densityVolume);
                    blendBox.size       = BlendSize(densityVolume);
                    EditorGUI.BeginChangeCheck();
                    blendBox.DrawHandle();
                    if (EditorGUI.EndChangeCheck())
                    {
                        Undo.RecordObject(densityVolume, "Change Density Volume Blend");

                        //work in local space to compute the change on positiveFade and negativeFade
                        Vector3 newCenterBlendLocalPosition = blendBox.center;
                        Vector3 halfSize = blendBox.size * 0.5f;
                        Vector3 size     = densityVolume.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;
                        densityVolume.parameters.positiveFade = posFade;
                        densityVolume.parameters.negativeFade = negFade;
                    }
                }

                if (EditMode.editMode == k_EditShape)
                {
                    shapeBox.monoHandle = !densityVolume.parameters.advancedFade;
                    EditorGUI.BeginChangeCheck();
                    shapeBox.DrawHandle();
                    if (EditorGUI.EndChangeCheck())
                    {
                        Undo.RecordObjects(new Object[] { densityVolume, densityVolume.transform }, "ChangeDensity Volume Bounding Box");
                        densityVolume.transform.position += densityVolume.transform.rotation * shapeBox.center;
                        densityVolume.parameters.size     = shapeBox.size;
                    }
                }
            }
        }
        void OnSceneGUI()
        {
            for (int i = 0; i < m_TypedTargets.Length; ++i)
            {
                var comp = m_TypedTargets[i];
                var tr   = comp.transform;
                var prox = comp.proxyVolume;

                using (new Handles.DrawingScope(Matrix4x4.TRS(Vector3.zero, tr.rotation, Vector3.one)))
                {
                    switch (prox.shape)
                    {
                    case ProxyShape.Box:
                        m_BoxHandle.center = Quaternion.Inverse(tr.rotation) * tr.position;
                        m_BoxHandle.size   = prox.boxSize;
                        EditorGUI.BeginChangeCheck();
                        m_BoxHandle.DrawHull(true);
                        m_BoxHandle.DrawHandle();
                        if (EditorGUI.EndChangeCheck())
                        {
                            Undo.RecordObjects(new Object[] { tr, comp }, "Update Proxy Volume Size");
                            tr.position  = tr.rotation * m_BoxHandle.center;
                            prox.boxSize = m_BoxHandle.size;
                        }
                        break;

                    case ProxyShape.Sphere:
                        m_SphereHandle.center = Quaternion.Inverse(tr.rotation) * tr.position;
                        m_SphereHandle.radius = prox.sphereRadius;
                        EditorGUI.BeginChangeCheck();
                        m_SphereHandle.DrawHull(true);
                        m_SphereHandle.DrawHandle();
                        if (EditorGUI.EndChangeCheck())
                        {
                            Undo.RecordObjects(new Object[] { tr, comp }, "Update Proxy Volume Size");
                            tr.position       = tr.rotation * m_SphereHandle.center;
                            prox.sphereRadius = m_SphereHandle.radius;
                        }
                        break;

                    case ProxyShape.Infinite:
                        break;
                    }
                }
            }
        }
        static void DrawBoxHandle(InfluenceVolumeUI s, SerializedInfluenceVolume d, Editor o, Object sourceAsset, HierarchicalBox box)
        {
            box.center = d.offset.vector3Value;
            box.size   = d.boxSize.vector3Value;

            EditorGUI.BeginChangeCheck();
            box.DrawHandle();
            if (EditorGUI.EndChangeCheck())
            {
                Undo.RecordObject(sourceAsset, "Modified Base Volume AABB");

                d.offset.vector3Value = box.center;

                Vector3 blendPositive       = d.boxBlendDistancePositive.vector3Value;
                Vector3 blendNegative       = d.boxBlendDistanceNegative.vector3Value;
                Vector3 blendNormalPositive = d.boxBlendNormalDistancePositive.vector3Value;
                Vector3 blendNormalNegative = d.boxBlendNormalDistanceNegative.vector3Value;
                Vector3 size = box.size;
                d.boxSize.vector3Value = size;
                Vector3 halfSize = size * .5f;
                for (int i = 0; i < 3; ++i)
                {
                    blendPositive[i]       = Mathf.Clamp(blendPositive[i], 0f, halfSize[i]);
                    blendNegative[i]       = Mathf.Clamp(blendNegative[i], 0f, halfSize[i]);
                    blendNormalPositive[i] = Mathf.Clamp(blendNormalPositive[i], 0f, halfSize[i]);
                    blendNormalNegative[i] = Mathf.Clamp(blendNormalNegative[i], 0f, halfSize[i]);
                }
                d.boxBlendDistancePositive.vector3Value       = blendPositive;
                d.boxBlendDistanceNegative.vector3Value       = blendNegative;
                d.boxBlendNormalDistancePositive.vector3Value = blendNormalPositive;
                d.boxBlendNormalDistanceNegative.vector3Value = blendNormalNegative;

                if (d.editorAdvancedModeEnabled.boolValue)
                {
                    d.editorAdvancedModeBlendDistancePositive.vector3Value       = d.boxBlendDistancePositive.vector3Value;
                    d.editorAdvancedModeBlendDistanceNegative.vector3Value       = d.boxBlendDistanceNegative.vector3Value;
                    d.editorAdvancedModeBlendNormalDistancePositive.vector3Value = d.boxBlendNormalDistancePositive.vector3Value;
                    d.editorAdvancedModeBlendNormalDistanceNegative.vector3Value = d.boxBlendNormalDistanceNegative.vector3Value;
                }
                else
                {
                    d.editorSimplifiedModeBlendDistance.floatValue = Mathf.Min(
                        d.boxBlendDistancePositive.vector3Value.x,
                        d.boxBlendDistancePositive.vector3Value.y,
                        d.boxBlendDistancePositive.vector3Value.z,
                        d.boxBlendDistanceNegative.vector3Value.x,
                        d.boxBlendDistanceNegative.vector3Value.y,
                        d.boxBlendDistanceNegative.vector3Value.z);
                    d.boxBlendDistancePositive.vector3Value = d.boxBlendDistanceNegative.vector3Value = Vector3.one * d.editorSimplifiedModeBlendDistance.floatValue;
                    d.editorSimplifiedModeBlendNormalDistance.floatValue = Mathf.Min(
                        d.boxBlendNormalDistancePositive.vector3Value.x,
                        d.boxBlendNormalDistancePositive.vector3Value.y,
                        d.boxBlendNormalDistancePositive.vector3Value.z,
                        d.boxBlendNormalDistanceNegative.vector3Value.x,
                        d.boxBlendNormalDistanceNegative.vector3Value.y,
                        d.boxBlendNormalDistanceNegative.vector3Value.z);
                    d.boxBlendNormalDistancePositive.vector3Value = d.boxBlendNormalDistanceNegative.vector3Value = Vector3.one * d.editorSimplifiedModeBlendNormalDistance.floatValue;
                }

                d.Apply();
            }
        }
Ejemplo n.º 6
0
        static void DrawBoxHandle(SerializedInfluenceVolume serialized, Editor owner, Transform transform, HierarchicalBox box)
        {
            using (new Handles.DrawingScope(Matrix4x4.TRS(Vector3.zero, transform.rotation, Vector3.one)))
            {
                box.center = Quaternion.Inverse(transform.rotation) * transform.position;
                box.size   = serialized.boxSize.vector3Value;

                EditorGUI.BeginChangeCheck();
                box.DrawHull(true);
                box.DrawHandle();
                if (EditorGUI.EndChangeCheck())
                {
                    var newPosition = transform.rotation * box.center;
                    Undo.RecordObject(transform, "Moving Influence");
                    transform.position = newPosition;

                    // Clamp blend distances
                    var blendPositive       = serialized.boxBlendDistancePositive.vector3Value;
                    var blendNegative       = serialized.boxBlendDistanceNegative.vector3Value;
                    var blendNormalPositive = serialized.boxBlendNormalDistancePositive.vector3Value;
                    var blendNormalNegative = serialized.boxBlendNormalDistanceNegative.vector3Value;
                    var size = box.size;
                    serialized.boxSize.vector3Value = size;
                    var halfSize = size * .5f;
                    for (int i = 0; i < 3; ++i)
                    {
                        blendPositive[i]       = Mathf.Clamp(blendPositive[i], 0f, halfSize[i]);
                        blendNegative[i]       = Mathf.Clamp(blendNegative[i], 0f, halfSize[i]);
                        blendNormalPositive[i] = Mathf.Clamp(blendNormalPositive[i], 0f, halfSize[i]);
                        blendNormalNegative[i] = Mathf.Clamp(blendNormalNegative[i], 0f, halfSize[i]);
                    }
                    serialized.boxBlendDistancePositive.vector3Value       = blendPositive;
                    serialized.boxBlendDistanceNegative.vector3Value       = blendNegative;
                    serialized.boxBlendNormalDistancePositive.vector3Value = blendNormalPositive;
                    serialized.boxBlendNormalDistanceNegative.vector3Value = blendNormalNegative;

                    if (serialized.editorAdvancedModeEnabled.boolValue)
                    {
                        serialized.editorAdvancedModeBlendDistancePositive.vector3Value       = serialized.boxBlendDistancePositive.vector3Value;
                        serialized.editorAdvancedModeBlendDistanceNegative.vector3Value       = serialized.boxBlendDistanceNegative.vector3Value;
                        serialized.editorAdvancedModeBlendNormalDistancePositive.vector3Value = serialized.boxBlendNormalDistancePositive.vector3Value;
                        serialized.editorAdvancedModeBlendNormalDistanceNegative.vector3Value = serialized.boxBlendNormalDistanceNegative.vector3Value;
                    }
                    else
                    {
                        serialized.editorSimplifiedModeBlendDistance.floatValue = Mathf.Min(
                            serialized.boxBlendDistancePositive.vector3Value.x,
                            serialized.boxBlendDistancePositive.vector3Value.y,
                            serialized.boxBlendDistancePositive.vector3Value.z,
                            serialized.boxBlendDistanceNegative.vector3Value.x,
                            serialized.boxBlendDistanceNegative.vector3Value.y,
                            serialized.boxBlendDistanceNegative.vector3Value.z);
                        serialized.boxBlendDistancePositive.vector3Value = serialized.boxBlendDistanceNegative.vector3Value = Vector3.one * serialized.editorSimplifiedModeBlendDistance.floatValue;
                        serialized.editorSimplifiedModeBlendNormalDistance.floatValue = Mathf.Min(
                            serialized.boxBlendNormalDistancePositive.vector3Value.x,
                            serialized.boxBlendNormalDistancePositive.vector3Value.y,
                            serialized.boxBlendNormalDistancePositive.vector3Value.z,
                            serialized.boxBlendNormalDistanceNegative.vector3Value.x,
                            serialized.boxBlendNormalDistanceNegative.vector3Value.y,
                            serialized.boxBlendNormalDistanceNegative.vector3Value.z);
                        serialized.boxBlendNormalDistancePositive.vector3Value = serialized.boxBlendNormalDistanceNegative.vector3Value = Vector3.one * serialized.editorSimplifiedModeBlendNormalDistance.floatValue;
                    }
                }
            }
        }
        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;
            }
        }
        void OnSceneGUI()
        {
            DensityVolume   densityVolume = target as DensityVolume;
            HierarchicalBox shapeBox      = shapeBoxes[densityVolume];
            HierarchicalBox blendBox      = blendBoxes[densityVolume];

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

                    blendBox.monoHandle = !densityVolume.parameters.advancedFade;
                    blendBox.center     = CenterBlendLocalPosition(densityVolume);
                    blendBox.size       = BlendSize(densityVolume);
                    EditorGUI.BeginChangeCheck();
                    blendBox.DrawHandle();
                    if (EditorGUI.EndChangeCheck())
                    {
                        Undo.RecordObject(densityVolume, "Change Density Volume Blend");

                        //work in local space to compute the change on positiveFade and negativeFade
                        Vector3 newCenterBlendLocalPosition = blendBox.center;
                        Vector3 halfSize = blendBox.size * 0.5f;
                        Vector3 size     = densityVolume.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;
                        densityVolume.parameters.positiveFade = posFade;
                        densityVolume.parameters.negativeFade = negFade;
                    }
                }
                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, densityVolume.transform.rotation, Vector3.one)))
                {
                    //contained must be initialized in all case
                    shapeBox.center = Quaternion.Inverse(densityVolume.transform.rotation) * densityVolume.transform.position;
                    shapeBox.size   = densityVolume.parameters.size;

                    shapeBox.monoHandle = !densityVolume.parameters.advancedFade;
                    EditorGUI.BeginChangeCheck();
                    shapeBox.DrawHandle();
                    if (EditorGUI.EndChangeCheck())
                    {
                        Undo.RecordObjects(new Object[] { densityVolume, densityVolume.transform }, "ChangeDensity Volume Bounding Box");

                        densityVolume.parameters.size = shapeBox.size;

                        Vector3 delta = densityVolume.transform.rotation * shapeBox.center - densityVolume.transform.position;
                        densityVolume.transform.position += delta;;
                    }
                }
                break;
            }
        }
        void OnSceneGUI()
        {
            //Note: for each handle to be independent when multi-selecting VolumeFalloff,
            //We cannot rely  hereon VolumeFalloff which is the collection of
            //selected VolumeFalloff. Thus code is almost the same of the UI.

            VolumeFalloff volumeFalloff = target as VolumeFalloff;

            Matrix4x4 m = volumeFalloff.isTransformScaleUsed
                ? volumeFalloff.transform.localToWorldMatrix
                : Matrix4x4.TRS(volumeFalloff.transform.position, volumeFalloff.transform.rotation, Vector3.one);

            m = m * Matrix4x4.TRS(volumeFalloff.center, Quaternion.identity, Vector3.one);

            switch (editMode)
            {
            case VolumeFalloffEditMode.Falloff:
                using (new Handles.DrawingScope(m))
                {
                    //contained must be initialized in all case
                    s_ShapeBox.center = float3.zero;
                    s_ShapeBox.size   = volumeFalloff.size;

                    Color baseColor = volumeFalloff.debugColor;
                    baseColor.a           = 8.0f / 255.0f;
                    s_BlendBox.baseColor  = baseColor;
                    s_BlendBox.monoHandle = false;    //!volumeFalloff.m_EditorAdvancedFade;
                    s_BlendBox.center     = ComputeCenterBlendLocalPosition(volumeFalloff);
                    s_BlendBox.size       = ComputeBlendSize(volumeFalloff);
                    EditorGUI.BeginChangeCheck();
                    s_BlendBox.DrawHandle();
                    if (EditorGUI.EndChangeCheck())
                    {
                        Undo.RecordObject(volumeFalloff, "Change Volume Falloff Falloff Region");

                        //work in local space to compute the change on fadePositive and fadeNegative
                        float3 newCenterBlendLocalPosition = s_BlendBox.center;
                        float3 halfSize = s_BlendBox.size * 0.5f;
                        float3 size     = volumeFalloff.size;
                        float3 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;
                        float3 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;
                        volumeFalloff.fadePositive = posFade;
                        volumeFalloff.fadeNegative = negFade;
                    }
                }
                break;

            case VolumeFalloffEditMode.Bounds:
                //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(m))
                {
                    //contained must be initialized in all case
                    s_ShapeBox.center = float3.zero;
                    s_ShapeBox.size   = volumeFalloff.size;

                    float3 previousSize         = volumeFalloff.size;
                    float3 previousPositiveFade = volumeFalloff.fadePositive;
                    float3 previousNegativeFade = volumeFalloff.fadeNegative;

                    EditorGUI.BeginChangeCheck();
                    s_ShapeBox.DrawHandle();
                    if (EditorGUI.EndChangeCheck())
                    {
                        Undo.RecordObjects(new Object[] { volumeFalloff, volumeFalloff.transform }, "Change Volume Falloff Bounds");

                        float3 newSize = s_ShapeBox.size;
                        volumeFalloff.size = newSize;

                        float3 newPositiveFade = new float3(
                            newSize.x < 0.00001 ? 0.0f : previousPositiveFade.x * previousSize.x / newSize.x,
                            newSize.y < 0.00001 ? 0.0f : previousPositiveFade.y * previousSize.y / newSize.y,
                            newSize.z < 0.00001 ? 0.0f : previousPositiveFade.z * previousSize.z / newSize.z
                            );
                        float3 newNegativeFade = new float3(
                            newSize.x < 0.00001 ? 0.0f : previousNegativeFade.x * previousSize.x / newSize.x,
                            newSize.y < 0.00001 ? 0.0f : previousNegativeFade.y * previousSize.y / newSize.y,
                            newSize.z < 0.00001 ? 0.0f : 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;
                                }
                            }
                        }
                        volumeFalloff.fadePositive = newPositiveFade;
                        volumeFalloff.fadeNegative = newNegativeFade;

                        volumeFalloff.center += (float3)s_ShapeBox.center;
                    }
                }
                break;

            default: Debug.Assert(false, "VolumeFalloffEditor: Encountered unsupported edit mode."); break;
            }
        }