Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 22 additions & 23 deletions examples/distortionPreview.js
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,19 @@ async function init() {
cameraModels = {};
result.forEach( c => {

// convert the CAHVORE arrays to vectors
const model = c.model;
model.type = c.type;
for ( const key in model ) {

if ( Array.isArray( model[ key ] ) ) {

model[ key ] = new THREE.Vector3( ...model[ key ] );

}

}

cameraModels[ c.name ] = c;

} );
Expand Down Expand Up @@ -278,17 +291,10 @@ function buildGUI() {

function updateRenderTarget() {

// TODO: simplify
const model = cameraModels[ params.camera ];
const m = { ...model, ...model.model };
for ( const key in m ) {

if ( Array.isArray( m[ key ] ) ) m[ key ] = new THREE.Vector3( ...m[ key ] );

}
const camera = cameraModels[ params.camera ];

// get the width and height differences
const { minFrameBounds, maxFrameBounds } = getLinearFrustumInfo( m );
const { minFrameBounds, maxFrameBounds } = getLinearFrustumInfo( camera.model );
const minHeight = minFrameBounds.top - minFrameBounds.bottom;
const maxHeight = maxFrameBounds.top - maxFrameBounds.bottom;
const minWidth = minFrameBounds.right - minFrameBounds.left;
Expand All @@ -315,18 +321,11 @@ function updateRenderTarget() {

function updateFrustums() {

// TODO: simplify
const model = cameraModels[ params.camera ];
const m = { ...model, ...model.model };
for ( const key in m ) {

if ( Array.isArray( m[ key ] ) ) m[ key ] = new THREE.Vector3( ...m[ key ] );

}
const camera = cameraModels[ params.camera ];

// generate the frustums
const matrix = new THREE.Matrix4();
const linearInfo = getLinearFrustumInfo( m );
const linearInfo = getLinearFrustumInfo( camera.model );
if ( params.rendering === 'minimum' ) {

// set the frustum shape based on the minimum linear frustum
Expand All @@ -342,10 +341,10 @@ function updateFrustums() {
} else {

// set the frustum shape based on the CAHVORE parameters
m.near = params.near;
m.far = params.far;
m.planarProjectionFactor = params.planarProjectionFactor;
frustumMesh.setFromCahvoreParameters( m );
camera.near = params.near;
camera.far = params.far;
camera.planarProjectionFactor = params.planarProjectionFactor;
frustumMesh.setFromCahvoreParameters( camera );
frameBoundsToProjectionMatrix( linearInfo.maxFrameBounds, params.near, params.far, matrix );

}
Expand Down Expand Up @@ -373,7 +372,7 @@ function updateFrustums() {
// update the distortion material
pass.material.checkerboard = params.rendering === 'checkerboard';
pass.material.passthrough = params.rendering === 'minimum' || params.rendering === 'maximum';
pass.material.setFromCameraModel( m );
pass.material.setFromCameraModel( camera.model );

updateRenderTarget();

Expand Down
37 changes: 22 additions & 15 deletions examples/frustumDisplay.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,19 @@ async function init() {
cameraModels = {};
result.forEach( c => {

// convert the CAHVORE arrays to vectors
const model = c.model;
model.type = c.type;
for ( const key in model ) {

if ( Array.isArray( model[ key ] ) ) {

model[ key ] = new THREE.Vector3( ...model[ key ] );

}

}

cameraModels[ c.name ] = c;

} );
Expand Down Expand Up @@ -209,30 +222,24 @@ function buildGUI() {

function updateFrustums() {

// TODO: simplify
const model = cameraModels[ params.camera ];
const m = { ...model, ...model.model };
for ( const key in m ) {

if ( Array.isArray( m[ key ] ) ) m[ key ] = new THREE.Vector3( ...m[ key ] );

}
const camera = cameraModels[ params.camera ];
const model = camera.model;

// init the cahvore frustum volume
m.near = params.near;
m.far = params.far;
m.widthSegments = params.widthSegments;
m.heightSegments = params.heightSegments;
m.planarProjectionFactor = params.planarProjectionFactor;
distortedFrustum.setFromCahvoreParameters( m );
camera.near = params.near;
camera.far = params.far;
camera.widthSegments = params.widthSegments;
camera.heightSegments = params.heightSegments;
camera.planarProjectionFactor = params.planarProjectionFactor;
distortedFrustum.setFromCahvoreParameters( camera );

distortedLines.geometry.dispose();
distortedLines.geometry = new THREE.EdgesGeometry( distortedFrustum.geometry, 35 );

// generate the linear frustums
const minMatrix = new THREE.Matrix4();
const maxMatrix = new THREE.Matrix4();
const linearInfo = getLinearFrustumInfo( m );
const linearInfo = getLinearFrustumInfo( model );
frameBoundsToProjectionMatrix( linearInfo.minFrameBounds, params.near, params.far, minMatrix );
frameBoundsToProjectionMatrix( linearInfo.maxFrameBounds, params.near, params.far, maxMatrix );

Expand Down
10 changes: 7 additions & 3 deletions src/cahvore-utilities/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ Functions for using the camera model known locally as CAHVOR. This model is an e
### getRay

```js
getRay( model : Object, sample : Vector2, outRay : Ray ) : void
getRay( model : CahvoreParamaters, sample : Vector2, outRay : Ray ) : void
```

Returns the outgoing ray from the camera model given an image sample coordinate. Internally calls the appropriate camera model to ray function.
Expand All @@ -127,7 +127,7 @@ The "sample" vector is in pixel values that must fall within the model.width and
### getLinearFrustumInfo

```js
getLinearFrustumInfo( model : Object ) : LinearFrustumInfo
getLinearFrustumInfo( model : CahvoreParamaters ) : LinearFrustumInfo
```

Function takes a camera model and returns an object describing the resulting local camera frame and minimum and maximum frustums.
Expand All @@ -145,6 +145,10 @@ frameBoundsToProjectionMatrix(

Function that takes a frame bounds description of a bounding box 1m out in the camera frame and sets the "target" matrix to an off axis projection matrix with the apex at the current origin.

## CahvoreParameters

See `CahvoreParamaters` description [here](../frustum-mesh/README.md#CahvoreParamaters).

## FrameBounds

### .left
Expand Down Expand Up @@ -229,7 +233,7 @@ If true then a checkerboard modeling the distortion is rendered.
### .setFromCameraModel

```js
setFromCameraModel( cahvoreModel : Object ) : void
setFromCameraModel( model : CahvoreParameters ) : void
```

Sets the necessary uniforms to properly distort the camera preview.
58 changes: 35 additions & 23 deletions src/frustum-mesh/FrustumMesh.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@ const tempRay = new Ray();
* options from createFrustumGeometry
* positions the flat array of positions we are modifying
*/
function updateFrustumPositions( options, positions ) {
function updateFrustumPositions( camera, positions ) {

// if projectEnds is true then the near and far distances for the rays
// are projected onto the near and far planes
const projectDirection = options.A.clone().normalize();
const { model, near, far, planarProjectionFactor } = camera;
const projectDirection = model.A.clone().normalize();

for ( let i = 0, l = positions.count; i < l; i ++ ) {

Expand All @@ -26,22 +27,22 @@ function updateFrustumPositions( options, positions ) {

// convert them into image space
// This is why the range must be between [0, 1]
position.x = position.x * options.width;
position.y = position.y * options.height;
position.x = position.x * model.width;
position.y = position.y * model.height;

getRay( options, position, tempRay );
getRay( model, position, tempRay );

// get the point at the given distance along the ray
tempRay.at( position.z < 0 ? options.near : options.far, tempVec );
tempRay.at( position.z < 0 ? near : far, tempVec );

// get the plane-projected version of the near / far point
const zSign = position.z < 0;
tempRay.direction.normalize();
tempRay.direction.multiplyScalar( 1 / tempRay.direction.dot( projectDirection ) );
planeProjectedVec.copy( tempRay.origin ).addScaledVector( tempRay.direction, zSign ? options.near : options.far );
planeProjectedVec.copy( tempRay.origin ).addScaledVector( tempRay.direction, zSign ? near : far );

// interpolate to the plane vector based on planar factor
tempVec.lerp( planeProjectedVec, options.planarProjectionFactor );
tempVec.lerp( planeProjectedVec, planarProjectionFactor );

// set the position
positions.setXYZ( i, tempVec.x, tempVec.y, tempVec.z );
Expand All @@ -51,15 +52,16 @@ function updateFrustumPositions( options, positions ) {
}

/*
* Create the geometry for the frustum. Takes CahvoreParameters.
* Create the geometry for the frustum. Takes CameraInfo.
*/
function createCahvoreFrustumGeometry( options ) {
function createCahvoreFrustumGeometry( camera ) {

const geom = new BoxGeometry( 1, 1, 1, options.widthSegments, options.heightSegments, 1 );
const { widthSegments, heightSegments } = camera;
const geom = new BoxGeometry( 1, 1, 1, widthSegments, heightSegments, 1 );
geom.translate( 0.5, 0.5, 0 );

const positions = geom.getAttribute( 'position' );
updateFrustumPositions( options, positions );
updateFrustumPositions( camera, positions );

geom.setAttribute( 'position', positions );
geom.computeVertexNormals();
Expand All @@ -68,7 +70,7 @@ function createCahvoreFrustumGeometry( options ) {
}

/**
* @typedef {Object} CahvoreParameters
* @typedef {Object} CameraParameters
* @param {('CAHV'|'CAHVOR'|'CAHVORE')} type CAHV, CAHVOR, or CAHVORE
* @param {Number} width max number of pixels in width
* @param {Number} height max number of pixels in height
Expand All @@ -80,6 +82,11 @@ function createCahvoreFrustumGeometry( options ) {
* @param {Vector3|null} [R=null] radial-distortion, only required for CAHVORE
* @param {Vector3|null} [E=null] entrance-pupil, only required for CAHVORE
* @param {Number} [linearity=1] linearity parameter, only required for CAHVORE
*/

/**
* @typedef {Object} CameraInfo
* @param {CameraParameters} model
* @param {Number} [near=0.085] the distance between the camera model and the near plane
* @param {Number} [far=10.0] the distance between the camera model and the far plane
* @param {Number} [widthSegments=16] the number of segments to create along the x axis (all sides)
Expand All @@ -106,11 +113,21 @@ export class FrustumMesh extends Mesh {

/**
* Update the parameters of the CAHVORE frustum geometry.
* @param {CahvoreParameters} parameters
* @param {CameraInfo} camera
*/
setFromCahvoreParameters( parameters ) {
setFromCahvoreParameters( camera ) {

const defaultedParams = {
const defaultedCamera = {
model: {},
near: 0.085,
far: 10.0,
widthSegments: 16,
heightSegments: 16,
planarProjectionFactor: 0,
...camera,
};

defaultedCamera.model = {
type: 'CAHV',
C: null,
A: null,
Expand All @@ -123,16 +140,11 @@ export class FrustumMesh extends Mesh {
width: 1,
height: 1,

near: 0.085,
far: 10.0,
widthSegments: 16,
heightSegments: 16,
planarProjectionFactor: 0,
...parameters,
...defaultedCamera.model,
};

this.geometry.dispose();
this.geometry = createCahvoreFrustumGeometry( defaultedParams );
this.geometry = createCahvoreFrustumGeometry( defaultedCamera );

}

Expand Down
14 changes: 12 additions & 2 deletions src/frustum-mesh/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ scene.add( distortedFrustum );

## CahvoreParameters

Set of options for passing into the `Frustum` object to generate the distorted frustum.

### .width

```js
Expand Down Expand Up @@ -107,6 +105,18 @@ linearity : Number = 1

Linearity parameter. Only required for CAHVORE models.

## CameraInfo

Set of options for passing into the `Frustum` object to generate the distorted frustum.

### .model

```js
model : CahvoreParameters
```

Object representing the CAHVORE parameters of the camera to represent.

### .near

```js
Expand Down