Exemplo n.º 1
0
        public static AxisAlignedBox3D Union(AxisAlignedBox3D b, AxisAlignedBox3D b2)
        {
            AxisAlignedBox3D ret;

            ret.Min.X = CheckedMin(b.Min.X, b2.Min.X);
            ret.Min.Y = CheckedMin(b.Min.Y, b2.Min.Y);
            ret.Min.Z = CheckedMin(b.Min.Z, b2.Min.Z);
            ret.Max.X = CheckedMax(b.Max.X, b2.Max.X);
            ret.Max.Y = CheckedMax(b.Max.Y, b2.Max.Y);
            ret.Max.Z = CheckedMax(b.Max.Z, b2.Max.Z);
            return(ret);
        }
Exemplo n.º 2
0
        public static AxisAlignedBox3D Union(AxisAlignedBox3D b, Point3D p)
        {
            AxisAlignedBox3D ret = b;

            ret.Min.X = CheckedMin(b.Min.X, p.X);
            ret.Min.Y = CheckedMin(b.Min.Y, p.Y);
            ret.Min.Z = CheckedMin(b.Min.Z, p.Z);
            ret.Max.X = CheckedMax(b.Max.X, p.X);
            ret.Max.Y = CheckedMax(b.Max.Y, p.Y);
            ret.Max.Z = CheckedMax(b.Max.Z, p.Z);
            return(ret);
        }
Exemplo n.º 3
0
        public AxisAlignedBox3D Transform(Matrix3D matrix)
        {
            AxisAlignedBox3D result = new AxisAlignedBox3D(matrix.Transform(new Point3D(Min.X, Min.Y, Min.Z)));

            result = Union(result, new AxisAlignedBox3D(matrix.Transform(new Point3D(Max.X, Min.Y, Min.Z))));
            result = Union(result, new AxisAlignedBox3D(matrix.Transform(new Point3D(Min.X, Max.Y, Min.Z))));
            result = Union(result, new AxisAlignedBox3D(matrix.Transform(new Point3D(Min.X, Min.Y, Max.Z))));
            result = Union(result, new AxisAlignedBox3D(matrix.Transform(new Point3D(Min.X, Max.Y, Max.Z))));
            result = Union(result, new AxisAlignedBox3D(matrix.Transform(new Point3D(Max.X, Max.Y, Min.Z))));
            result = Union(result, new AxisAlignedBox3D(matrix.Transform(new Point3D(Max.X, Min.Y, Max.Z))));
            result = Union(result, new AxisAlignedBox3D(matrix.Transform(new Point3D(Max.X, Max.Y, Max.Z))));
            return(result);
        }
Exemplo n.º 4
0
        public ContainmentType Contains(AxisAlignedBox3D box)
        {
            // FIXME: Is this a bug?
            // If the bounding box is of W * D * H = 0, then return disjoint
            if (box.Min == box.Max)
            {
                return(ContainmentType.Disjoint);
            }

            int             i;
            ContainmentType contained;

            Point3D[] corners = box.GetCorners();

            // First we assume completely disjoint. So if we find a point that is contained, we break out of this loop
            for (i = 0; i < corners.Length; i++)
            {
                if (Contains(corners[i]) != ContainmentType.Disjoint)
                {
                    break;
                }
            }

            if (i == corners.Length)             // This means we checked all the corners and they were all disjoint
            {
                return(ContainmentType.Disjoint);
            }

            if (i != 0)                         // if i is not equal to zero, we can fastpath and say that this box intersects
            {                                   // because we know at least one point is outside and one is inside.
                return(ContainmentType.Intersects);
            }

            // If we get here, it means the first (and only) point we checked was actually contained in the frustum.
            // So we assume that all other points will also be contained. If one of the points is disjoint, we can
            // exit immediately saying that the result is Intersects
            i++;
            for (; i < corners.Length; i++)
            {
                if (Contains(corners[i]) != ContainmentType.Contains)
                {
                    return(ContainmentType.Intersects);
                }
            }

            // If we get here, then we know all the points were actually contained, therefore result is Contains
            return(ContainmentType.Contains);
        }
Exemplo n.º 5
0
 public static AxisAlignedBox3D Union(AxisAlignedBox3D b, Point3D p)
 {
     AxisAlignedBox3D ret = b;
     ret.Min.X = CheckedMin(b.Min.X, p.X);
     ret.Min.Y = CheckedMin(b.Min.Y, p.Y);
     ret.Min.Z = CheckedMin(b.Min.Z, p.Z);
     ret.Max.X = CheckedMax(b.Max.X, p.X);
     ret.Max.Y = CheckedMax(b.Max.Y, p.Y);
     ret.Max.Z = CheckedMax(b.Max.Z, p.Z);
     return ret;
 }
Exemplo n.º 6
0
 public AxisAlignedBox3D Transform(Matrix3D matrix)
 {
     AxisAlignedBox3D result = new AxisAlignedBox3D(matrix.Transform(new Point3D(Min.X, Min.Y, Min.Z)));
     result = Union(result, new AxisAlignedBox3D(matrix.Transform(new Point3D(Max.X, Min.Y, Min.Z))));
     result = Union(result, new AxisAlignedBox3D(matrix.Transform(new Point3D(Min.X, Max.Y, Min.Z))));
     result = Union(result, new AxisAlignedBox3D(matrix.Transform(new Point3D(Min.X, Min.Y, Max.Z))));
     result = Union(result, new AxisAlignedBox3D(matrix.Transform(new Point3D(Min.X, Max.Y, Max.Z))));
     result = Union(result, new AxisAlignedBox3D(matrix.Transform(new Point3D(Max.X, Max.Y, Min.Z))));
     result = Union(result, new AxisAlignedBox3D(matrix.Transform(new Point3D(Max.X, Min.Y, Max.Z))));
     result = Union(result, new AxisAlignedBox3D(matrix.Transform(new Point3D(Max.X, Max.Y, Max.Z))));
     return result;
 }
Exemplo n.º 7
0
        public AxisAlignedBox3D CreateTransformedBoundingVolume(Matrix3D transform)
        {
            AxisAlignedBox3D result = new AxisAlignedBox3D();

            // For all three axes.
            for (int i = 0; i < 3; ++i)
            {
                // Start by adding in translation.
                result.Min[i] = result.Max[i] = transform[i, 3];

                // Form extent by summing smaller and larger terms respectively.
                for (int j = 0; j < 3; ++j)
                {
                    float e = transform[i, j] * Min[j];
                    float f = transform[i, j] * Max[j];
                    if (e < f)
                    {
                        result.Min[i] += e;
                        result.Max[i] += f;
                    }
                    else
                    {
                        result.Min[i] += f;
                        result.Max[i] += e;
                    }
                }
            }

            return result;
        }
Exemplo n.º 8
0
 public static AxisAlignedBox3D Union(AxisAlignedBox3D b, AxisAlignedBox3D b2)
 {
     AxisAlignedBox3D ret;
     ret.Min.X = CheckedMin(b.Min.X, b2.Min.X);
     ret.Min.Y = CheckedMin(b.Min.Y, b2.Min.Y);
     ret.Min.Z = CheckedMin(b.Min.Z, b2.Min.Z);
     ret.Max.X = CheckedMax(b.Max.X, b2.Max.X);
     ret.Max.Y = CheckedMax(b.Max.Y, b2.Max.Y);
     ret.Max.Z = CheckedMax(b.Max.Z, b2.Max.Z);
     return ret;
 }
Exemplo n.º 9
0
        public static PerspectiveCamera CreateFromBounds(AxisAlignedBox3D bounds, Viewport3D viewport,
			float fieldOfView, float yaw = 0.0f, float pitch = 0.0f, float zoom = 1.0f)
        {
            // Calculate initial guess at camera settings.
            Matrix3D transform = Matrix3D.CreateFromYawPitchRoll(yaw, pitch, 0);
            Vector3D cameraDirection = Vector3D.Normalize(transform.Transform(Vector3D.Forward));
            PerspectiveCamera initialGuess = new PerspectiveCamera
            {
                FieldOfView = fieldOfView,
                NearPlaneDistance = 1.0f,
                FarPlaneDistance = bounds.Size.Length() * 10,
                Position = bounds.Center - cameraDirection * bounds.Size.Length() * 2,
                LookDirection = cameraDirection,
                UpDirection = Vector3D.Up
            };

            Matrix3D projection = initialGuess.GetProjectionMatrix(viewport.AspectRatio);
            Matrix3D view = initialGuess.GetViewMatrix();

            // Project bounding box corners onto screen, and calculate screen bounds.
            float closestZ = float.MaxValue;
            Box2D? screenBounds = null;
            Point3D[] corners = bounds.GetCorners();
            foreach (Point3D corner in corners)
            {
                Point3D screenPoint = viewport.Project(corner,
                    projection, view, Matrix3D.Identity);

                if (screenPoint.Z < closestZ)
                    closestZ = screenPoint.Z;

                IntPoint2D intScreenPoint = new IntPoint2D((int) screenPoint.X, (int) screenPoint.Y);
                if (screenBounds == null)
                    screenBounds = new Box2D(intScreenPoint, intScreenPoint);
                else
                {
                    Box2D value = screenBounds.Value;
                    value.Expand(intScreenPoint);
                    screenBounds = value;
                }
            }

            // Now project back from screen bounds into scene, setting Z to the minimum bounding box Z value.
            IntPoint2D minScreen = screenBounds.Value.Min;
            IntPoint2D maxScreen = screenBounds.Value.Max;
            Point3D min = viewport.Unproject(new Point3D(minScreen.X, minScreen.Y, closestZ),
                projection, view, Matrix3D.Identity);
            Point3D max = viewport.Unproject(new Point3D(maxScreen.X, maxScreen.Y, closestZ),
                projection, view, Matrix3D.Identity);

            // Use these new values to calculate the distance the camera should be from the AABB centre.
            Vector3D size = Vector3D.Abs(max - min);
            float radius = size.Length();
            float dist = radius / (2 * MathUtility.Tan(fieldOfView * viewport.AspectRatio / 2));

            Point3D closestBoundsCenter = (min + (max - min) / 2);
            Point3D position = closestBoundsCenter - cameraDirection * dist * (1 / zoom);

            return new PerspectiveCamera
            {
                FieldOfView = fieldOfView,
                NearPlaneDistance = 1.0f,
                FarPlaneDistance = dist * 10,
                Position = position,
                LookDirection = cameraDirection,
                UpDirection = Vector3D.Up
            };
        }
Exemplo n.º 10
0
 public bool Intersects(AxisAlignedBox3D box)
 {
     return(Contains(box) != ContainmentType.Disjoint);
 }
Exemplo n.º 11
0
 public AxisAlignedBox3D Transform(AxisAlignedBox3D box)
 {
     return box.Transform(Value);
 }