@@ -119,33 +119,53 @@ p5.prototype.orbitControl = function(sensitivityX, sensitivityY, sensitivityZ) {
119119 sensitivityY * ( this . mouseY - this . pmouseY ) / scaleFactor ;
120120 this . _renderer . _curCamera . _orbit ( deltaTheta , deltaPhi , 0 ) ;
121121 } else if ( this . mouseButton === this . RIGHT ) {
122- // PANNING BEHAVIOR along X/Z camera axes and restricted to X/Z plane
123- // in world space
122+ // Translate the camera so that the entire object moves
123+ // perpendicular to the line of sight when the mouse is moved
124124 const local = cam . _getLocalAxes ( ) ;
125125
126- // normalize portions along X/Z axes
127- const xmag = Math . sqrt ( local . x [ 0 ] * local . x [ 0 ] + local . x [ 2 ] * local . x [ 2 ] ) ;
128- if ( xmag !== 0 ) {
129- local . x [ 0 ] /= xmag ;
130- local . x [ 2 ] /= xmag ;
126+ // Calculate the z coordinate in the view coordinates of
127+ // the center, that is, the distance to the view point.
128+ const diffX = cam . eyeX - cam . centerX ;
129+ const diffY = cam . eyeY - cam . centerY ;
130+ const diffZ = cam . eyeZ - cam . centerZ ;
131+ const viewZ = Math . sqrt ( diffX * diffX + diffY * diffY + diffZ * diffZ ) ;
132+
133+ // position vector of the center
134+ let cv = createVector ( cam . centerX , cam . centerY , cam . centerZ ) ;
135+
136+ // Calculate the normalized device coordinates of the center
137+ cv = cam . cameraMatrix . multiplyPoint ( cv ) ;
138+ cv = this . _renderer . uPMatrix . multiplyAndNormalizePoint ( cv ) ;
139+
140+ // Normalize mouse movement distance
141+ const ndcX = ( this . mouseX - this . pmouseX ) * 2 / this . width ;
142+ const ndcY = - ( this . mouseY - this . pmouseY ) * 2 / this . height ;
143+
144+ // Move the center by this distance
145+ // in the normalized device coordinate system
146+ cv . x -= ndcX ;
147+ cv . y -= ndcY ;
148+
149+ // Calculate the translation vector
150+ // in the direction perpendicular to the line of sight of center
151+ let dx , dy ;
152+ const uP = this . _renderer . uPMatrix . mat4 ;
153+ // When calculating the view coordinates, the calculation method is
154+ // different depending on whether ortho() or not, so separate the cases.
155+ // uP[15] is non-zero only for ortho().
156+ if ( uP [ 15 ] === 0 ) {
157+ dx = ( ( uP [ 8 ] + cv . x ) / uP [ 0 ] ) * viewZ ;
158+ dy = ( ( uP [ 9 ] + cv . y ) / uP [ 5 ] ) * viewZ ;
159+ } else {
160+ dx = ( cv . x - uP [ 12 ] ) / uP [ 0 ] ;
161+ dy = ( cv . y - uP [ 13 ] ) / uP [ 5 ] ;
131162 }
132163
133- // normalize portions along X/Z axes
134- const ymag = Math . sqrt ( local . y [ 0 ] * local . y [ 0 ] + local . y [ 2 ] * local . y [ 2 ] ) ;
135- if ( ymag !== 0 ) {
136- local . y [ 0 ] /= ymag ;
137- local . y [ 2 ] /= ymag ;
138- }
139-
140- // move along those vectors by amount controlled by mouseX, pmouseY
141- const dx = - 1 * sensitivityX * ( this . mouseX - this . pmouseX ) ;
142- const dz = - 1 * sensitivityY * ( this . mouseY - this . pmouseY ) ;
143-
144- // restrict movement to XZ plane in world space
164+ // translate the camera
145165 cam . setPosition (
146- cam . eyeX + dx * local . x [ 0 ] + dz * local . z [ 0 ] ,
147- cam . eyeY ,
148- cam . eyeZ + dx * local . x [ 2 ] + dz * local . z [ 2 ]
166+ cam . eyeX + dx * local . x [ 0 ] + dy * local . y [ 0 ] ,
167+ cam . eyeY + dx * local . x [ 1 ] + dy * local . y [ 1 ] ,
168+ cam . eyeZ + dx * local . x [ 2 ] + dy * local . y [ 2 ]
149169 ) ;
150170 }
151171 }
0 commit comments