GetCorners() 공개 메소드

public GetCorners ( ) : Point3D[]
리턴 Point3D[]
예제 #1
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);
        }
예제 #2
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
            };
        }