示例#1
0
        /// <summary>
        ///     Creates an <see cref="OrientedBoundingBox">OrientedBoundingBox</see> from a <see cref="BoundingBox">BoundingBox</see>.
        /// </summary>
        /// <param name="box">A <see cref="BoundingBox">BoundingBox</see> to create the <see cref="OrientedBoundingBox">OrientedBoundingBox</see> from</param>
        /// <returns>The generated <see cref="OrientedBoundingBox">OrientedBoundingBox</see></returns>
        public static OrientedBoundingBox FromAABB(BoundingBox box)
        {
            var center  = BoundingVolumesExtensions.GetCenter(box);
            var extents = BoundingVolumesExtensions.GetExtents(box);

            return(new OrientedBoundingBox(center, extents));
        }
示例#2
0
        /// <summary>
        ///     Calculates an OBB with a given set of points.
        ///     Tests every orientations between initValues and endValues, stepping through angle intervals with a given step size.
        ///     Goes on until it reaches a step less than 0.01
        /// </summary>
        /// <returns>A generated Oriented Bounding Box that contains the set of points</returns>
        private static OrientedBoundingBox ComputeFromPointsRecursive(Vector3[] points, Vector3 initValues, Vector3 endValues,
                                                                      float step)
        {
            var   minObb = new OrientedBoundingBox();
            var   minimumVolume = float.MaxValue;
            var   minInitValues = Vector3.Zero;
            var   minEndValues = Vector3.Zero;
            var   transformedPoints = new Vector3[points.Length];
            float y, z;

            var x = initValues.X;

            while (x <= endValues.X)
            {
                y = initValues.Y;
                var rotationX = MathHelper.ToRadians(x);
                while (y <= endValues.Y)
                {
                    z = initValues.Z;
                    var rotationY = MathHelper.ToRadians(y);
                    while (z <= endValues.Z)
                    {
                        // Rotation matrix
                        var rotationZ      = MathHelper.ToRadians(z);
                        var rotationMatrix = Matrix.CreateFromYawPitchRoll(rotationY, rotationX, rotationZ);

                        // Transform every point to OBB-Space
                        for (var index = 0; index < transformedPoints.Length; index++)
                        {
                            transformedPoints[index] = Vector3.Transform(points[index], rotationMatrix);
                        }

                        // Obtain an AABB enclosing every transformed point
                        var aabb = BoundingBox.CreateFromPoints(transformedPoints);

                        // Calculate the volume of the AABB
                        var volume = BoundingVolumesExtensions.GetVolume(aabb);

                        // Find lesser volume
                        if (volume < minimumVolume)
                        {
                            minimumVolume = volume;
                            minInitValues = new Vector3(x, y, z);
                            minEndValues  = new Vector3(x + step, y + step, z + step);

                            // Restore the AABB center in World-Space
                            var center = BoundingVolumesExtensions.GetCenter(aabb);
                            center = Vector3.Transform(center, rotationMatrix);

                            // Create OBB
                            minObb             = new OrientedBoundingBox(center, BoundingVolumesExtensions.GetExtents(aabb));
                            minObb.Orientation = rotationMatrix;
                        }

                        z += step;
                    }
                    y += step;
                }
                x += step;
            }

            // Loop again if the step is higher than a given acceptance threshold
            if (step > 0.01f)
            {
                minObb = ComputeFromPointsRecursive(points, minInitValues, minEndValues, step / 10f);
            }

            return(minObb);
        }