Commit c6b27995 authored by Mario Chromik's avatar Mario Chromik
Browse files

introducing ScreenPointToray in engines package, adding MaskProjector config

parent 774790d7
Loading
Loading
Loading
Loading
+68 −0
Original line number Diff line number Diff line
package cz.fidentis.analyst.engines.interactivemask;

import cz.fidentis.analyst.data.octree.Octree;

import javax.vecmath.Vector3d;

public record MaskProjectorConfig(int canvasWidth, int canvasHeight, int panelWidth,
                                  int panelHeight, int fov, Vector3d cameraPosition,
                                  Vector3d cameraCenter, Vector3d cameraUpDirection, Octree octree) {

    @Override
    public Octree octree() {
        return octree;
    }

    public MaskProjectorConfig(int canvasWidth, int canvasHeight, int panelWidth, int panelHeight,
                               int fov, Vector3d cameraPosition, Vector3d cameraCenter, Vector3d cameraUpDirection, Octree octree) {
        this.canvasWidth = canvasWidth;
        this.canvasHeight = canvasHeight;
        this.panelWidth = panelWidth;
        this.panelHeight = panelHeight;
        this.fov = fov;
        this.cameraPosition = cameraPosition;
        this.cameraCenter = cameraCenter;
        this.cameraUpDirection = cameraUpDirection;
        this.octree = octree;
    }

    @Override
    public int canvasWidth() {
        return canvasWidth;
    }

    @Override
    public int canvasHeight() {
        return canvasHeight;
    }

    @Override
    public int panelWidth() {
        return panelWidth;
    }

    @Override
    public int panelHeight() {
        return panelHeight;
    }

    @Override
    public int fov() {
        return fov;
    }

    @Override
    public Vector3d cameraPosition() {
        return cameraPosition;
    }

    @Override
    public Vector3d cameraCenter() {
        return cameraCenter;
    }

    @Override
    public Vector3d cameraUpDirection() {
        return cameraUpDirection;
    }
}
+124 −0
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;
    }
}