Reputation: 99
I am editing a path file in THREEJS, because I want the camera to always be looking perpendicular to the path it is travelling (whereas the original file allows the user to alter the camera target using the mouse). The project is a 3D art gallery.
Basically, what I am trying to do, I have created an array of view vectors that correspond to spline points on the camera path, and what I am trying to do, is each time the camera position reaches the next spline point, to reset the camera view. However, it seems to me, that each time I try to call the camera position as I loop through the spline points to see if the spline point matches the camera position, all I get is (0,0,0) for the camera position.
The line alert(this.object.position.z); just says zero, yet the z position of the camera is not 0 at the start nor most of the points. I don't seem to be calling the camera position. Any help would be appreciated.
/**
* @author alteredq / http://alteredqualia.com/
*/
THREE.PathControls = function ( object, domElement ) {
//var lookvector;
var cc = new Array();
cc[0]= new THREE.Vector3(0,0,-1);
var aa = 1;
this.object = object;
this.domElement = ( domElement !== undefined ) ? domElement : document;
this.id = "PathControls" + THREE.PathControlsIdCounter ++;
// API
this.duration = 10 * 1000; // milliseconds
this.waypoints = [];
this.spline = [];
this.useConstantSpeed = true;
this.resamplingCoef = 50;
this.debugPath = new THREE.Object3D();
this.debugDummy = new THREE.Object3D();
this.animationParent = new THREE.Object3D();
this.lookSpeed = 0.005;
this.lookVertical = true;
this.lookHorizontal = true;
this.verticalAngleMap = { srcRange: [ 0, 2 * Math.PI ], dstRange: [ 0, 2 * Math.PI ] };
this.horizontalAngleMap = { srcRange: [ 0, 2 * Math.PI ], dstRange: [ 0, 2 * Math.PI ] };
// internals
this.target = new THREE.Object3D();
this.mouseX = 0;
this.mouseY = 0;
this.lat = 0;
this.lon = 0;
this.phi = 0;
this.theta = 0;
var PI2 = Math.PI * 2;
this.viewHalfX = 0;
this.viewHalfY = 0;
if ( this.domElement !== document ) {
this.domElement.setAttribute( 'tabindex', -1 );
}
// methods
this.handleResize = function () {
if ( this.domElement === document ) {
this.viewHalfX = window.innerWidth / 2;
this.viewHalfY = window.innerHeight / 2;
} else {
this.viewHalfX = this.domElement.offsetWidth / 2;
this.viewHalfY = this.domElement.offsetHeight / 2;
}
};
this.update = function ( delta ) {
var srcRange, dstRange;
if( this.lookHorizontal ) this.lon += this.mouseX * this.lookSpeed * delta;
if( this.lookVertical ) this.lat -= this.mouseY * this.lookSpeed * delta;
this.lon = this.lon;
this.lat = Math.max( - 85, Math.min( 85, this.lat ) );
this.phi = THREE.Math.degToRad( 90 - this.lat );
this.theta = THREE.Math.degToRad( this.lon );
this.phi = normalize_angle_rad( this.phi );
// constrain vertical look angle
srcRange = this.verticalAngleMap.srcRange;
dstRange = this.verticalAngleMap.dstRange;
var tmpPhi = THREE.Math.mapLinear( this.phi, srcRange[ 0 ], srcRange[ 1 ], dstRange[ 0 ], dstRange[ 1 ] );
var tmpPhiFullRange = dstRange[ 1 ] - dstRange[ 0 ];
var tmpPhiNormalized = ( tmpPhi - dstRange[ 0 ] ) / tmpPhiFullRange;
this.phi = QuadraticEaseInOut( tmpPhiNormalized ) * tmpPhiFullRange + dstRange[ 0 ];
// constrain horizontal look angle
srcRange = this.horizontalAngleMap.srcRange;
dstRange = this.horizontalAngleMap.dstRange;
var tmpTheta = THREE.Math.mapLinear( this.theta, srcRange[ 0 ], srcRange[ 1 ], dstRange[ 0 ], dstRange[ 1 ] );
var tmpThetaFullRange = dstRange[ 1 ] - dstRange[ 0 ];
var tmpThetaNormalized = ( tmpTheta - dstRange[ 0 ] ) / tmpThetaFullRange;
this.theta = QuadraticEaseInOut( tmpThetaNormalized ) * tmpThetaFullRange + dstRange[ 0 ];
var targetPosition = this.target.position,
position = this.object.position;
targetPosition.x = 100 * Math.sin( this.phi ) * Math.cos( this.theta );
targetPosition.y = 100 * Math.cos( this.phi );
targetPosition.z = 100 * Math.sin( this.phi ) * Math.sin( this.theta );
for (i=0; i < cc.length; i++){
if (this.waypoints[i]==this.object.position){
//this.object.lookAt( cc[i] );
}
}
alert(this.object.position.z);
};
this.onMouseMove = function ( event ) {
if ( this.domElement === document ) {
this.mouseX = event.pageX - this.viewHalfX;
this.mouseY = event.pageY - this.viewHalfY;
} else {
this.mouseX = event.pageX - this.domElement.offsetLeft - this.viewHalfX;
this.mouseY = event.pageY - this.domElement.offsetTop - this.viewHalfY;
}
};
// utils
function normalize_angle_rad( a ) {
var b = a % PI2;
return b >= 0 ? b : b + PI2;
};
function distance( a, b ) {
var dx = a[ 0 ] - b[ 0 ],
dy = a[ 1 ] - b[ 1 ],
dz = a[ 2 ] - b[ 2 ];
return Math.sqrt( dx * dx + dy * dy + dz * dz );
};
function QuadraticEaseInOut ( k ) {
if ( ( k *= 2 ) < 1 ) return 0.5 * k * k;
return - 0.5 * ( --k * ( k - 2 ) - 1 );
};
function bind( scope, fn ) {
return function () {
fn.apply( scope, arguments );
};
};
function initAnimationPath( parent, spline, name, duration ) {
var animationData = {
name: name,
fps: 0.6,
length: duration,
hierarchy: []
};
var i,
parentAnimation, childAnimation,
path = spline.getControlPointsArray(),
sl = spline.getLength(),
pl = path.length,
t = 0,
first = 0,
last = pl - 1;
parentAnimation = { parent: -1, keys: [] };
parentAnimation.keys[ first ] = { time: 0, pos: path[ first ], rot: [ 0, 0, 0, 1 ], scl: [ 1, 1, 1 ] };
parentAnimation.keys[ last ] = { time: duration, pos: path[ last ], rot: [ 0, 0, 0, 1 ], scl: [ 1, 1, 1 ] };
for ( i = 1; i < pl - 1; i++ ) {
// real distance (approximation via linear segments)
t = duration * sl.chunks[ i ] / sl.total;
// equal distance
//t = duration * ( i / pl );
// linear distance
//t += duration * distance( path[ i ], path[ i - 1 ] ) / sl.total;
parentAnimation.keys[ i ] = { time: t, pos: path[ i ] };
}
animationData.hierarchy[ 0 ] = parentAnimation;
THREE.AnimationHandler.add( animationData );
return new THREE.Animation( parent, name, THREE.AnimationHandler.CATMULLROM_FORWARD, false );
};
function createSplineGeometry( spline, n_sub ) {
var i, index, position,
geometry = new THREE.Geometry();
for ( i = 0; i < spline.points.length * n_sub; i ++ ) {
index = i / ( spline.points.length * n_sub );
position = spline.getPoint( index );
geometry.vertices[ i ] = new THREE.Vector3( position.x, position.y, position.z );
}
return geometry;
};
function createPath( parent, spline, mycam) {
var lineGeo = createSplineGeometry( spline, 10 ),
particleGeo = createSplineGeometry( spline, 10 ),
lineMat = new THREE.LineBasicMaterial( { color: 0xff0000, linewidth: 3 } ),
lineObj = new THREE.Line( lineGeo, lineMat ),
particleObj = new THREE.ParticleSystem( particleGeo, new THREE.ParticleSystemMaterial( { color: 0xffaa00, size: 3 } ) );
lineObj.scale.set( 1, 1, 1 );
parent.add( lineObj );
particleObj.scale.set( 1, 1, 1 );
parent.add( particleObj );
var waypoint,
geo = new THREE.SphereGeometry( 1, 16, 8 ),
mat = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
aa = 0;
var myval;
for ( var i = 0; i < spline.points.length; i ++ ) {
if( i > 0 ) {
var mydirection = new THREE.Vector3(spline.points[i].x - spline.points[i-1].x, spline.points[i].y - spline.points[i-1].y, spline.points[i].z - spline.points[i-1].z);
var planevector = new THREE.Vector3(0,1,0);
var myc = new THREE.Vector3();
myc.crossVectors( mydirection, planevector );
cc[i] = myc;
} else {cc[0] = new THREE.Vector3(0.05,0,-1);}
waypoint = new THREE.Mesh( geo, mat );
waypoint.position.copy( spline.points[ i ] );
parent.add( waypoint );
}
};
this.init = function ( ) {
// constructor
this.spline = new THREE.Spline();
this.spline.initFromArray( this.waypoints );
if ( this.useConstantSpeed ) {
this.spline.reparametrizeByArcLength( this.resamplingCoef );
}
if ( this.createDebugDummy ) {
var dummyParentMaterial = new THREE.MeshLambertMaterial( { color: 0x0077ff } ),
dummyChildMaterial = new THREE.MeshLambertMaterial( { color: 0x00ff00 } ),
dummyParentGeo = new THREE.CubeGeometry( 10, 10, 20 ),
dummyChildGeo = new THREE.CubeGeometry( 2, 2, 10 );
this.animationParent = new THREE.Mesh( dummyParentGeo, dummyParentMaterial );
var dummyChild = new THREE.Mesh( dummyChildGeo, dummyChildMaterial );
dummyChild.position.set( 0, 10, 0 );
this.animation = initAnimationPath( this.animationParent, this.spline, this.id, this.duration );
this.animationParent.add( this.object );
this.animationParent.add( this.target );
this.animationParent.add( dummyChild );
} else {
this.animation = initAnimationPath( this.animationParent, this.spline, this.id, this.duration );
this.animationParent.add( this.target );
this.animationParent.add( this.object );
}
// if ( this.createDebugPath ) {
createPath( this.debugPath, this.spline, this.object );
// }
this.domElement.addEventListener( 'mousemove', bind( this, this.onMouseMove ), false );
};
this.handleResize();
};
THREE.PathControlsIdCounter = 0;
Upvotes: 0
Views: 203
Reputation: 99
seems the solution is
myx = this.object.matrixWorld.getPosition().x; myz = this.object.matrixWorld.getPosition().z;
Upvotes: 1