|
@@ -77,6 +77,7 @@ class Sculpt {
|
|
|
this._dragDir = [ 0, 0, 0 ];
|
|
this._dragDir = [ 0, 0, 0 ];
|
|
|
this._scalePrevX = 0;
|
|
this._scalePrevX = 0;
|
|
|
this._scaleDelta = 0;
|
|
this._scaleDelta = 0;
|
|
|
|
|
+ this._cachedRect = null;
|
|
|
|
|
|
|
|
// Bind event handlers
|
|
// Bind event handlers
|
|
|
this._onPointerDown = this._onPointerDown.bind( this );
|
|
this._onPointerDown = this._onPointerDown.bind( this );
|
|
@@ -99,9 +100,21 @@ class Sculpt {
|
|
|
|
|
|
|
|
// ---- Picking ----
|
|
// ---- Picking ----
|
|
|
|
|
|
|
|
|
|
+ _getRect() {
|
|
|
|
|
+
|
|
|
|
|
+ if ( this._cachedRect === null ) {
|
|
|
|
|
+
|
|
|
|
|
+ this._cachedRect = this._domElement.getBoundingClientRect();
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return this._cachedRect;
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
_unproject( mouseX, mouseY, z ) {
|
|
_unproject( mouseX, mouseY, z ) {
|
|
|
|
|
|
|
|
- const rect = this._domElement.getBoundingClientRect();
|
|
|
|
|
|
|
+ const rect = this._getRect();
|
|
|
const x = ( ( mouseX - rect.left ) / rect.width ) * 2 - 1;
|
|
const x = ( ( mouseX - rect.left ) / rect.width ) * 2 - 1;
|
|
|
const y = - ( ( mouseY - rect.top ) / rect.height ) * 2 + 1;
|
|
const y = - ( ( mouseY - rect.top ) / rect.height ) * 2 + 1;
|
|
|
_v3Temp.set( x, y, z ).unproject( this._camera );
|
|
_v3Temp.set( x, y, z ).unproject( this._camera );
|
|
@@ -112,7 +125,7 @@ class Sculpt {
|
|
|
_project( point ) {
|
|
_project( point ) {
|
|
|
|
|
|
|
|
_v3Temp.set( point[ 0 ], point[ 1 ], point[ 2 ] ).project( this._camera );
|
|
_v3Temp.set( point[ 0 ], point[ 1 ], point[ 2 ] ).project( this._camera );
|
|
|
- const rect = this._domElement.getBoundingClientRect();
|
|
|
|
|
|
|
+ const rect = this._getRect();
|
|
|
return [
|
|
return [
|
|
|
( _v3Temp.x * 0.5 + 0.5 ) * rect.width + rect.left,
|
|
( _v3Temp.x * 0.5 + 0.5 ) * rect.width + rect.left,
|
|
|
( - _v3Temp.y * 0.5 + 0.5 ) * rect.height + rect.top,
|
|
( - _v3Temp.y * 0.5 + 0.5 ) * rect.height + rect.top,
|
|
@@ -540,41 +553,29 @@ class Sculpt {
|
|
|
|
|
|
|
|
if ( event.button !== 0 ) return;
|
|
if ( event.button !== 0 ) return;
|
|
|
|
|
|
|
|
|
|
+ this._cachedRect = null;
|
|
|
|
|
+
|
|
|
const mouseX = event.clientX;
|
|
const mouseX = event.clientX;
|
|
|
const mouseY = event.clientY;
|
|
const mouseY = event.clientY;
|
|
|
|
|
|
|
|
- if ( this.tool === 'drag' ) {
|
|
|
|
|
-
|
|
|
|
|
- if ( ! this._intersectionRayMesh( mouseX, mouseY ) ) return;
|
|
|
|
|
- this._sculpting = true;
|
|
|
|
|
- this._lastMouseX = mouseX;
|
|
|
|
|
- this._lastMouseY = mouseY;
|
|
|
|
|
- try { this._domElement.setPointerCapture( event.pointerId ); } catch ( e ) { /* synthetic events */ }
|
|
|
|
|
- return;
|
|
|
|
|
|
|
+ if ( ! this._intersectionRayMesh( mouseX, mouseY ) ) return;
|
|
|
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ this._sculpting = true;
|
|
|
|
|
+ this._lastMouseX = mouseX;
|
|
|
|
|
+ this._lastMouseY = mouseY;
|
|
|
|
|
+ try { this._domElement.setPointerCapture( event.pointerId ); } catch ( e ) { /* synthetic events */ }
|
|
|
|
|
|
|
|
if ( this.tool === 'scale' ) {
|
|
if ( this.tool === 'scale' ) {
|
|
|
|
|
|
|
|
- if ( ! this._intersectionRayMesh( mouseX, mouseY ) ) return;
|
|
|
|
|
- this._sculpting = true;
|
|
|
|
|
this._scalePrevX = mouseX;
|
|
this._scalePrevX = mouseX;
|
|
|
- this._lastMouseX = mouseX;
|
|
|
|
|
- this._lastMouseY = mouseY;
|
|
|
|
|
- try { this._domElement.setPointerCapture( event.pointerId ); } catch ( e ) { /* synthetic events */ }
|
|
|
|
|
- return;
|
|
|
|
|
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ } else if ( this.tool !== 'drag' ) {
|
|
|
|
|
|
|
|
- if ( ! this._intersectionRayMesh( mouseX, mouseY ) ) return;
|
|
|
|
|
- this._sculpting = true;
|
|
|
|
|
- this._lastMouseX = mouseX;
|
|
|
|
|
- this._lastMouseY = mouseY;
|
|
|
|
|
- try { this._domElement.setPointerCapture( event.pointerId ); } catch ( e ) { /* synthetic events */ }
|
|
|
|
|
|
|
+ // Do first stroke immediately
|
|
|
|
|
+ this._makeStroke( mouseX, mouseY );
|
|
|
|
|
+ this._syncGeometry();
|
|
|
|
|
|
|
|
- // Do first stroke immediately
|
|
|
|
|
- this._makeStroke( mouseX, mouseY );
|
|
|
|
|
- this._syncGeometry();
|
|
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -582,6 +583,8 @@ class Sculpt {
|
|
|
|
|
|
|
|
if ( ! this._sculpting ) return;
|
|
if ( ! this._sculpting ) return;
|
|
|
|
|
|
|
|
|
|
+ this._cachedRect = null;
|
|
|
|
|
+
|
|
|
const mouseX = event.clientX;
|
|
const mouseX = event.clientX;
|
|
|
const mouseY = event.clientY;
|
|
const mouseY = event.clientY;
|
|
|
|
|
|
|
@@ -624,6 +627,22 @@ class Sculpt {
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ get hitNormal() {
|
|
|
|
|
+
|
|
|
|
|
+ return this._pickedNormal;
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ pickFromMouse( mouseX, mouseY ) {
|
|
|
|
|
+
|
|
|
|
|
+ this._cachedRect = null;
|
|
|
|
|
+
|
|
|
|
|
+ if ( ! this._intersectionRayMesh( mouseX, mouseY ) ) return false;
|
|
|
|
|
+ this._computePickedNormal();
|
|
|
|
|
+ return true;
|
|
|
|
|
+
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
export { Sculpt };
|
|
export { Sculpt };
|