Skip to content

Commit 902e316

Browse files
committed
TrackballCamera first version, rotation only
1 parent ce8e05b commit 902e316

File tree

1 file changed

+199
-0
lines changed

1 file changed

+199
-0
lines changed

src/extras/cameras/TrackballCamera.js

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
/**
2+
* @author Eberhard Gräther / http://egraether.com/
3+
4+
* parameters = {
5+
* fov: <float>,
6+
* aspect: <float>,
7+
* near: <float>,
8+
* far: <float>,
9+
* target: <THREE.Object3D>,
10+
11+
* radius: <float>,
12+
13+
* zoomSpeed: <float>,
14+
* panSpeed: <float>,
15+
16+
* noZoom: <bool>,
17+
* noPan: <bool>,
18+
19+
* domElement: <HTMLElement>,
20+
* }
21+
*/
22+
23+
THREE.TrackballCamera = function ( parameters ) {
24+
25+
THREE.Camera.call( this, parameters.fov, parameters.aspect, parameters.near, parameters.far, parameters.target );
26+
27+
this.radius = ( window.innerWidth + window.innerHeight ) / 4;
28+
29+
this.zoomSpeed = 1.0;
30+
this.panSpeed = 1.0;
31+
32+
this.noZoom = false;
33+
this.noPan = false;
34+
35+
this.domElement = document;
36+
37+
if ( parameters ) {
38+
39+
if ( parameters.radius !== undefined ) this.radius = parameters.radius;
40+
41+
if ( parameters.zoomSpeed !== undefined ) this.zoomSpeed = parameters.zoomSpeed;
42+
if ( parameters.panSpeed !== undefined ) this.panSpeed = parameters.panSpeed;
43+
44+
if ( parameters.noZoom !== undefined ) this.noZoom = parameters.noZoom;
45+
if ( parameters.noPan !== undefined ) this.noPan = parameters.noPan;
46+
47+
if ( parameters.domElement !== undefined ) this.domElement = parameters.domElement;
48+
49+
}
50+
51+
this.useTarget = true;
52+
53+
this.mouseDragOn = false;
54+
55+
this.screen = this.getScreenDimensions();
56+
57+
this.start = new THREE.Vector3();
58+
this.end = new THREE.Vector3();
59+
60+
function bind( scope, fn ) {
61+
62+
return function () {
63+
64+
fn.apply( scope, arguments );
65+
66+
};
67+
68+
};
69+
70+
this.domElement.addEventListener( 'mousemove', bind( this, this.mousemove ), false );
71+
this.domElement.addEventListener( 'mousedown', bind( this, this.mousedown ), false );
72+
this.domElement.addEventListener( 'mouseup', bind( this, this.mouseup ), false );
73+
74+
window.addEventListener( 'keydown', bind( this, this.keydown ), false );
75+
window.addEventListener( 'keyup', bind( this, this.keyup ), false );
76+
77+
};
78+
79+
THREE.TrackballCamera.prototype = new THREE.Camera();
80+
THREE.TrackballCamera.prototype.constructor = THREE.TrackballCamera;
81+
THREE.TrackballCamera.prototype.supr = THREE.Camera.prototype;
82+
83+
THREE.TrackballCamera.prototype.handleEvent = function ( event ) {
84+
85+
if ( typeof this[ event.type ] == 'function' ) {
86+
87+
this[ event.type ]( event );
88+
89+
}
90+
91+
};
92+
93+
THREE.TrackballCamera.prototype.keydown = function( event ) {
94+
95+
96+
97+
};
98+
99+
THREE.TrackballCamera.prototype.keyup = function( event ) {
100+
101+
102+
103+
};
104+
105+
THREE.TrackballCamera.prototype.mousedown = function(event) {
106+
107+
event.preventDefault();
108+
event.stopPropagation();
109+
110+
this.mouseDragOn = true;
111+
112+
this.start = this.getMouseProjectionOnBall( event.clientX, event.clientY );
113+
114+
};
115+
116+
THREE.TrackballCamera.prototype.mousemove = function( event ) {
117+
118+
if ( this.mouseDragOn ) {
119+
120+
this.end = this.getMouseProjectionOnBall( event.clientX, event.clientY );
121+
122+
var angle = Math.acos( this.start.dot( this.end ) / this.start.length() / this.end.length() );
123+
124+
if ( angle ) {
125+
126+
var axis = (new THREE.Vector3()).cross( this.end, this.start ).normalize(),
127+
quaternion = new THREE.Quaternion();
128+
129+
quaternion.setFromAxisAngle( axis, angle );
130+
131+
quaternion.multiplyVector3( this.position );
132+
quaternion.multiplyVector3( this.up );
133+
134+
}
135+
136+
}
137+
138+
};
139+
140+
THREE.TrackballCamera.prototype.mouseup = function( event ) {
141+
142+
event.preventDefault();
143+
event.stopPropagation();
144+
145+
this.mouseDragOn = false;
146+
147+
};
148+
149+
THREE.TrackballCamera.prototype.getScreenDimensions = function() {
150+
151+
if ( this.domElement != document ) {
152+
153+
return {
154+
width : this.domElement.offsetWidth,
155+
height : this.domElement.offsetHeight,
156+
offsetLeft : this.domElement.offsetLeft,
157+
offsetTop : this.domElement.offsetTop
158+
};
159+
160+
} else {
161+
162+
return {
163+
width : window.innerWidth,
164+
height : window.innerHeight,
165+
offsetLeft : 0,
166+
offsetTop : 0
167+
};
168+
169+
}
170+
171+
};
172+
173+
THREE.TrackballCamera.prototype.getMouseProjectionOnBall = function( clientX, clientY ) {
174+
175+
var mouse = new THREE.Vector3(
176+
( clientX - this.screen.width * 0.5 - this.screen.offsetLeft ) / this.radius,
177+
( this.screen.height * 0.5 + this.screen.offsetTop - clientY ) / this.radius,
178+
0.0
179+
);
180+
181+
var length = mouse.length();
182+
183+
if ( length > 1.0 ) {
184+
185+
mouse.divideScalar( length );
186+
187+
} else {
188+
189+
mouse.z = Math.sqrt( 1.0 - length * length );
190+
191+
}
192+
193+
var projection = this.up.clone().setLength( mouse.y );
194+
projection.addSelf( this.up.clone().crossSelf( this.position ).setLength( mouse.x ) );
195+
projection.addSelf( this.position.clone().setLength( mouse.z ) );
196+
197+
return projection;
198+
199+
};

0 commit comments

Comments
 (0)