bool _GetBoundingBoxAABB(int DIM_, ref Vector3 boxA, ref Vector3 boxB, float minV, float maxV, ref Matrix4x4 innerTransform)
    {
        BoxCollector boxCollector = new BoxCollector();

        //BoxCollector boxCollector2 = new BoxCollector(); // for Inner

        if (_lineList != null)
        {
            for (int i = 0, count = (int)_lineList.Length / 2 * 2; i < count; i += 2)
            {
                //assert( (int)_lineList[i + 0] < _vertexList.size() && (int)_lineList[i + 1] < _vertexList.size() );
                Vector3 vertex0 = _vertexList[_lineList[i + 0]];
                Vector3 vertex1 = _vertexList[_lineList[i + 1]];
                if (vertex0[DIM_] > vertex1[DIM_])
                {
                    _Swap(ref vertex0, ref vertex1);
                }
                if (vertex0[DIM_] >= maxV || vertex1[DIM_] <= minV)
                {
                    // Out of range.
                }
                else
                {
                    if (vertex0[DIM_] < minV)                           /* Begin point smaller than minV */
                    {
                        if (!_FuzzyZero(vertex0[DIM_] - vertex1[DIM_])) /* Overlap check( Check for 0 divide ) */
                        /* Compute cross point in target area(minV) */
                        {
                            Vector3 modVertex0 = (vertex0 + (vertex1 - vertex0) * (minV - vertex0[DIM_]) / (vertex1[DIM_] - vertex0[DIM_]));
                            boxCollector.Collect(modVertex0);
                        }
                    }
                    else
                    {
                        boxCollector.Collect(vertex0);
                    }
                    if (vertex1[DIM_] > maxV)                           /* End point bigger than maxV */
                    {
                        if (!_FuzzyZero(vertex0[DIM_] - vertex1[DIM_])) /* Overlap check( Check for 0 divide ) */
                        /* Compute cross point in target area(maxV) */
                        {
                            Vector3 modVertex1 = (vertex1 + (vertex0 - vertex1) * (vertex1[DIM_] - maxV) / (vertex1[DIM_] - vertex0[DIM_]));
                            boxCollector.Collect(modVertex1);
                        }
                    }
                    else
                    {
                        boxCollector.Collect(vertex1);
                    }
                }
            }
        }

        boxA = boxCollector.boxA;
        boxB = boxCollector.boxB;
        if (boxA == boxB)
        {
            return(false);
        }
        boxA[DIM_] = minV;
        boxB[DIM_] = maxV;
        return(true);
    }
    bool _MakeSlicedBoundingBoxAABB()
    {
        int   SliceCount   = _sliceCount;
        float f_SliceCount = (float)_sliceCount;

        int   minimumDim    = -1;
        float minimumVolume = 0.0f;

        Vector3[] minimumBoxA = null;
        Vector3[] minimumBoxB = null;

        /* memo: Choose minimum box in 3 direction. */
        for (int i = 0; i < 3; ++i)
        {
            /* Compute AABB in 31 dividing box. */
            List <Vector3> tempBoxA = new List <Vector3>(SliceCount);
            List <Vector3> tempBoxB = new List <Vector3>(SliceCount);
            switch (i)
            {
            case 0:             // X
                if (minimumDim < 0 || _sliceMode == SliceMode.Auto || _sliceMode == SliceMode.X)
                {
                    Matrix4x4 transform = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(45.0f, 0.0f, 0.0f), Vector3.one);                         /* Right Hand(Left Rotation) */

                    // Limit search range
                    Vector3 boundingBoxA = _boundingBoxA;
                    Vector3 boundingBoxB = _boundingBoxB;
                    boundingBoxA[0] += _thicknessA[0];
                    boundingBoxB[0] += _thicknessB[0];

                    float minX       = boundingBoxA.x;
                    float stepX      = (boundingBoxB.x - boundingBoxA.x) / f_SliceCount;
                    float tempVolume = 0.0f;
                    for (int n = 0; n < SliceCount; ++n)
                    {
                        float   maxX = minX + stepX;
                        Vector3 boxA = Vector3.zero, boxB = Vector3.zero;
                        if (_GetBoundingBoxAABB(0, ref boxA, ref boxB, minX, maxX, ref transform))
                        {
                            boxA.x = minX;
                            boxB.x = maxX;
                            tempBoxA.Add(boxA);
                            tempBoxB.Add(boxB);
                            tempVolume += _GetBoxVolume(boxA, boxB);
                        }
                        minX = maxX;
                    }
                    if (tempVolume > Mathf.Epsilon)
                    {
                        minimumDim    = 0;
                        minimumVolume = tempVolume;
                        minimumBoxA   = tempBoxA.ToArray();
                        minimumBoxB   = tempBoxB.ToArray();
                    }
                }
                break;

            case 1:             // Y
                if (minimumDim < 0 || _sliceMode == SliceMode.Auto || _sliceMode == SliceMode.Y)
                {
                    Matrix4x4 transform = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0.0f, 45.0f, 0.0f), Vector3.one);                         /* Right Hand(Left Rotation) */

                    // Limit search range
                    Vector3 boundingBoxA = _boundingBoxA;
                    Vector3 boundingBoxB = _boundingBoxB;
                    boundingBoxA[1] += _thicknessA[1];
                    boundingBoxB[1] += _thicknessB[1];

                    float minY       = boundingBoxA.y;
                    float stepY      = (boundingBoxB.y - boundingBoxA.y) / f_SliceCount;
                    float tempVolume = 0.0f;
                    for (int n = 0; n < SliceCount; ++n)
                    {
                        float   maxY = minY + stepY;
                        Vector3 boxA = Vector3.zero, boxB = Vector3.zero;
                        if (_GetBoundingBoxAABB(1, ref boxA, ref boxB, minY, maxY, ref transform))
                        {
                            boxA.y = minY;
                            boxB.y = maxY;
                            tempBoxA.Add(boxA);
                            tempBoxB.Add(boxB);
                            tempVolume += _GetBoxVolume(boxA, boxB);
                        }
                        minY = maxY;
                    }
                    if (tempVolume > Mathf.Epsilon)
                    {
                        if (_sliceMode == SliceMode.Y || minimumVolume > tempVolume)
                        {
                            minimumDim    = 1;
                            minimumVolume = tempVolume;
                            minimumBoxA   = tempBoxA.ToArray();
                            minimumBoxB   = tempBoxB.ToArray();
                        }
                    }
                }
                break;

            case 2:             // Z
                if (minimumDim < 0 || _sliceMode == SliceMode.Auto || _sliceMode == SliceMode.Z)
                {
                    Matrix4x4 transform = Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(0.0f, 0.0f, 45.0f), Vector3.one);                         /* Right Hand(Left Rotation) */

                    // Limit search range
                    Vector3 boundingBoxA = _boundingBoxA;
                    Vector3 boundingBoxB = _boundingBoxB;
                    boundingBoxA[2] += _thicknessA[2];
                    boundingBoxB[2] += _thicknessB[2];

                    float minZ       = boundingBoxA.z;
                    float stepZ      = (boundingBoxB.z - boundingBoxA.z) / f_SliceCount;
                    float tempVolume = 0.0f;
                    for (int n = 0; n < SliceCount; ++n)
                    {
                        float   maxZ = minZ + stepZ;
                        Vector3 boxA = Vector3.zero, boxB = Vector3.zero;
                        if (_GetBoundingBoxAABB(2, ref boxA, ref boxB, minZ, maxZ, ref transform))
                        {
                            boxA.z = minZ;
                            boxB.z = maxZ;
                            tempBoxA.Add(boxA);
                            tempBoxB.Add(boxB);
                            tempVolume += _GetBoxVolume(boxA, boxB);
                        }
                        minZ = maxZ;
                    }
                    if (tempVolume > Mathf.Epsilon)
                    {
                        if (_sliceMode == SliceMode.Z || minimumVolume > tempVolume)
                        {
                            minimumDim    = 2;
                            minimumVolume = tempVolume;
                            minimumBoxA   = tempBoxA.ToArray();
                            minimumBoxB   = tempBoxB.ToArray();
                        }
                    }
                }
                break;
            }
        }

        if (minimumDim < 0 || minimumBoxA == null || minimumBoxA.Length == 0)
        {
            return(false);
        }

        Vector3 thicknessA = _thicknessA;
        Vector3 thicknessB = _thicknessB;

        thicknessA[minimumDim] = 0;
        thicknessB[minimumDim] = 0;

        if (_minThickness != Vector3.zero)
        {
            for (int i = 0; i < minimumBoxA.Length; ++i)
            {
                if (minimumDim != 0)
                {
                    _ComputeMinThickness(ref minimumBoxA[i].x, ref minimumBoxB[i].x, _minThickness.x);
                }
                if (minimumDim != 1)
                {
                    _ComputeMinThickness(ref minimumBoxA[i].y, ref minimumBoxB[i].y, _minThickness.y);
                }
                if (minimumDim != 2)
                {
                    _ComputeMinThickness(ref minimumBoxA[i].z, ref minimumBoxB[i].z, _minThickness.z);
                }
            }

            int end = minimumBoxA.Length - 1;
            if (minimumDim == 0)
            {
                _ComputeMinThickness(ref minimumBoxA[0].x, ref minimumBoxB[end].x, _minThickness.x);
            }
            if (minimumDim == 1)
            {
                _ComputeMinThickness(ref minimumBoxA[0].y, ref minimumBoxB[end].y, _minThickness.y);
            }
            if (minimumDim == 2)
            {
                _ComputeMinThickness(ref minimumBoxA[0].z, ref minimumBoxB[end].z, _minThickness.z);
            }
        }

        if (_scale != Vector3.one)
        {
            for (int i = 0; i < minimumBoxA.Length; ++i)
            {
                minimumBoxA[i] = ScaledVector(minimumBoxA[i], _scale);
                minimumBoxB[i] = ScaledVector(minimumBoxB[i], _scale);
            }
        }

        if (thicknessA != Vector3.zero || thicknessB != Vector3.zero)
        {
            for (int i = 0; i < minimumBoxA.Length; ++i)
            {
                minimumBoxA[i] += thicknessA;
                minimumBoxB[i] += thicknessB;
            }
        }
        if (_offset != Vector3.zero)
        {
            for (int i = 0; i < minimumBoxA.Length; ++i)
            {
                minimumBoxA[i] += _offset;
                minimumBoxB[i] += _offset;
            }
        }

        {
            BoxCollector boxCollector = new BoxCollector();
            boxCollector.Collect(minimumBoxA);
            boxCollector.Collect(minimumBoxB);
            if (boxCollector.isAnything)
            {
                _reducedBoxA = boxCollector.boxA;
                _reducedBoxB = boxCollector.boxB;
            }
        }

        _slicedDimention    = minimumDim;
        _slicedBoundingBoxA = minimumBoxA.Clone() as Vector3[];
        _slicedBoundingBoxB = minimumBoxB.Clone() as Vector3[];
        _slicedBoundingBoxC = minimumBoxA.Clone() as Vector3[];
        _slicedBoundingBoxD = minimumBoxB.Clone() as Vector3[];

        /* AB ... Plane of begin CD ... Plane of end */
        /* AB / CD are diagonal planes. AB / CD planes are parallel. */
        /* Adjacent CD/AB is equal minimumDim(X,Y,Z). */
        /* Adjacent CD/AB is equal after Combine optimized. */
        for (int i = 0; i < minimumBoxA.Length; ++i)
        {
            _slicedBoundingBoxB[i][minimumDim] = _slicedBoundingBoxA[i][minimumDim];
            _slicedBoundingBoxC[i][minimumDim] = _slicedBoundingBoxD[i][minimumDim];
        }
        /* Combine optimized.(Optimized vertices, exclude begin/end plane.) */
        for (int i = 1; i < minimumBoxA.Length; ++i)
        {
            /* Average VertexA. */
            Vector3 boxA1 = minimumBoxA[i];
            Vector3 boxA0 = minimumBoxA[i - 1];
            boxA0[minimumDim] = boxA1[minimumDim];
            Vector3 boxAM = (boxA1 + boxA0) / 2.0f;
            /* Copy arrangemented vertexA. */
            _slicedBoundingBoxA[i]     = boxAM;
            _slicedBoundingBoxC[i - 1] = boxAM;
            /* Average VertexB */
            Vector3 boxB0 = minimumBoxB[i - 1];
            Vector3 boxB1 = minimumBoxB[i];
            boxB1[minimumDim] = boxB0[minimumDim];
            Vector3 boxBM = (boxB1 + boxB0) / 2.0f;
            /* Copy arrangemented vertexB. */
            _slicedBoundingBoxB[i]     = boxBM;
            _slicedBoundingBoxD[i - 1] = boxBM;
        }

        return(true);
    }