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); }