Commit 4788c4a1 authored by Mario Chromik's avatar Mario Chromik
Browse files

moving ScreenPointToRay inside MaskProjector, updating documentation

parent 05618231
Loading
Loading
Loading
Loading
+122 −2
Original line number Diff line number Diff line
@@ -8,8 +8,9 @@ import cz.fidentis.analyst.data.shapes.SurfaceMask;
import cz.fidentis.analyst.data.shapes.SurfaceMask2D;
import cz.fidentis.analyst.engines.raycasting.RayIntersectionConfig;
import cz.fidentis.analyst.engines.raycasting.RayIntersectionServices;

import java.awt.*;
import javax.vecmath.Point3d;
import javax.vecmath.Vector3d;
import java.awt.Point;
import java.util.Objects;

/**
@@ -66,4 +67,123 @@ public class MaskProjector implements OctreeVisitor {
                        ri.getHitTriangle().getFacet(),
                        ri.getHitTriangle().computeOrientedNormal()));
    }

    /**
     * Utility class for converting screen position to ray
     *
     * @author Mario Chromik
     *
     * @deprecated The implementation is not correct and was replaced by
     * the {@link cz.fidentis.analyst.rendering.SceneRenderer#castRayThroughPixel(int, int, Camera)}
     * method, which is mased on the {@code gluUnProject} reverse mapping of the projection and modelview
     * OpenGL matrices.
     */
    @Deprecated(forRemoval = true)
    private class ScreenPointToRay {

        /**
         * converts screen point to ray by first calculating position on near plane,
         * constructing a coordinate frame and calculates direction from camera
         * position to point on near plane within this frame
         * @param screenX screen x coordinate
         * @param screenY screen y coordinate
         * @param width view port width
         * @param height view port height
         * @param camPos position of camera within scene
         * @param camCenter direction the camera is pointing
         * @param camUpDir camera up direction
         * @return ray
         */
        public static Ray convert(int screenX, int screenY, int width, int height, int fov, Vector3d camPos, Vector3d camCenter, Vector3d camUpDir) {
            Point3d nearPlanePos = calculatePositionOnNearPlane(screenX, screenY, width, height);

            double fovY = fov * Math.PI / 180.0;
            double fovX = fovY * width/height;

            Vector3d camDir = calculateCameraDirection(camPos, camCenter);
            Vector3d camRight = calculateOrthogonalCameraRight(camUpDir, camDir);
            Vector3d camUp = calculateOrthogonalCameraUp(camDir, camRight);

            double alpha = nearPlanePos.x * Math.tan(fovX / 2) * nearPlanePos.z;
            double beta = nearPlanePos.y * Math.tan(fovY / 2) * nearPlanePos.z;

            Vector3d upScaled = new Vector3d(beta * camUp.x, beta * camUp.y, beta * camUp.z);
            Vector3d rightScaled = new Vector3d(alpha * camRight.x, alpha * camRight.y, alpha * camRight.z);

            camDir.negate();
            upScaled.add(rightScaled);
            upScaled.add(camDir);

            Vector3d dir = new Vector3d();
            dir.normalize(upScaled);

            Point3d origin = new Point3d(camPos);

            return new Ray(origin, dir);
        }

        /**
         * Converts pixel coordinates to Normalized Device Coordinates
         *
         * @param screenX screen x coordinate
         * @param screenY screen y coordinate
         * @param width width of view port
         * @param height height of view port
         * @return Normalized Device Coordinates of the pixel's location in the range from -1 to 1 for both X and Y axes.
         */
        private static Point3d calculatePositionOnNearPlane(int screenX, int screenY, int width, int height) {
            double x = (2.0 * screenX) / width - 1.0;
            double y = 1.0 - (2.0 * screenY) / height;
            double z = 1.0;

            return new Point3d(x, y, z);
        }

        /**
         * calculates camera direction
         * direction from camera position to center of scene
         * @param Vector3d positionCam position of camera
         * @param Vector3d centerCam  center of camera
         * @return camera direction
         */
        private static Vector3d calculateCameraDirection(Vector3d positionCam, Vector3d centerCam) {
            Vector3d camPos = new Vector3d(positionCam);
            Vector3d center = new Vector3d(centerCam);
            center.negate();
            camPos.add(center);
            Vector3d camDir = new Vector3d();
            camDir.normalize(camPos);
            camDir.scale(1);

            return camDir;
        }

        /**
         * calculates orthogonal camera right direction
         * @param up camera's up direction
         * @param camDir direction to the center of the scene
         * @return camera right
         */
        private static Vector3d calculateOrthogonalCameraRight(Vector3d up, Vector3d camDir) {
            Vector3d right = new Vector3d();
            right.cross(up, camDir);
            right.normalize();

            return right;
        }

        /**
         * calculates orthogonal camera up direction
         * @param camDir
         * @param camRight
         * @return orthogonal camera up direction
         */
        private static Vector3d calculateOrthogonalCameraUp(Vector3d camDir, Vector3d camRight) {
            Vector3d up = new Vector3d();
            up.cross(camDir, camRight);
            up.normalize();

            return up;
        }
    }
}
+0 −124
Original line number Diff line number Diff line
package cz.fidentis.analyst.engines.interactivemask;

import cz.fidentis.analyst.data.ray.Ray;

import javax.swing.JOptionPane;
import javax.vecmath.Point3d;
import javax.vecmath.Vector3d;

/**
 * Utility class for converting screen position to ray
 * 
 * @author Mario Chromik
 *
 * @deprecated The implementation is not correct and was replaced by
 * the {@link cz.fidentis.analyst.rendering.SceneRenderer#castRayThroughPixel(int, int, Camera)}
 * method, which is mased on the {@code gluUnProject} reverse mapping of the projection and modelview
 * OpenGL matrices.
 */
@Deprecated(forRemoval = true)
public class ScreenPointToRay {

    /**
     * converts screen point to ray by first calculating position on near plane,
     * constructing a coordinate frame and calculates direction from camera 
     * position to point on near plane within this frame
     * @param screenX screen x coordinate
     * @param screenY screen y coordinate
     * @param width view port width
     * @param height view port height
     * @param camera camera
     * @return ray
     */
    public static Ray convert(int screenX, int screenY, int width, int height, int fov, Vector3d camPos, Vector3d camCenter, Vector3d camUpDir) {
        Point3d nearPlanePos = calculatePositionOnNearPlane(screenX, screenY, width, height);
        
        double fovY = fov * Math.PI / 180.0;
        double fovX = fovY * width/height;
        
        Vector3d camDir = calculateCameraDirection(camPos, camCenter);
        Vector3d camRight = calculateOrthogonalCameraRight(camUpDir, camDir);
        Vector3d camUp = calculateOrthogonalCameraUp(camDir, camRight);
        
        double alpha = nearPlanePos.x * Math.tan(fovX / 2) * nearPlanePos.z;
        double beta = nearPlanePos.y * Math.tan(fovY / 2) * nearPlanePos.z;

        Vector3d upScaled = new Vector3d(beta * camUp.x, beta * camUp.y, beta * camUp.z);
        Vector3d rightScaled = new Vector3d(alpha * camRight.x, alpha * camRight.y, alpha * camRight.z);
        
        camDir.negate();
        upScaled.add(rightScaled);
        upScaled.add(camDir);
        
        Vector3d dir = new Vector3d();
        dir.normalize(upScaled);
        
        Point3d origin = new Point3d(camPos);
        
        return new Ray(origin, dir);
    }

    /**
     * Converts pixel coordinates to Normalized Device Coordinates
     *
     * @param screenX screen x coordinate
     * @param screenY screen y coordinate
     * @param width width of view port
     * @param height height of view port
     * @return Normalized Device Coordinates of the pixel's location in the range from -1 to 1 for both X and Y axes.
     */
    private static Point3d calculatePositionOnNearPlane(int screenX, int screenY, int width, int height) {
        double x = (2.0 * screenX) / width - 1.0;
        double y = 1.0 - (2.0 * screenY) / height;
        double z = 1.0;
        
        return new Point3d(x, y, z);
    }
    
    /**
     * calculates camera direction 
     * direction from camera position to center of scene
     * @param Vector3d positionCam position of camera
     * @param Vector3d centerCam  center of camera
     * @return camera direction
     */
    private static Vector3d calculateCameraDirection(Vector3d positionCam, Vector3d centerCam) {
        Vector3d camPos = new Vector3d(positionCam);
        Vector3d center = new Vector3d(centerCam);
        center.negate();
        camPos.add(center);
        Vector3d camDir = new Vector3d();
        camDir.normalize(camPos);
        camDir.scale(1);
        
        return camDir;
    }
    
    /**
     * calculates orthogonal camera right direction 
     * @param up camera's up direction
     * @param camDir direction to the center of the scene
     * @return camera right
     */
    private static Vector3d calculateOrthogonalCameraRight(Vector3d up, Vector3d camDir) {
        Vector3d right = new Vector3d();
        right.cross(up, camDir);
        right.normalize();
        
        return right;
    }
    
    /**
     * calculates orthogonal camera up direction
     * @param camDir
     * @param camRight
     * @return 
     */
    private static Vector3d calculateOrthogonalCameraUp(Vector3d camDir, Vector3d camRight) {
        Vector3d up = new Vector3d();
        up.cross(camDir, camRight);
        up.normalize();
        
        return up;
    }
}