Skip to content

Commit eca7216

Browse files
authored
feat: cameraControls.lerp position or spherical (#586)
* CameraControls.lerp * return type * undeprecate
1 parent 73db7f8 commit eca7216

File tree

3 files changed

+82
-25
lines changed

3 files changed

+82
-25
lines changed

examples/basic.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@
3838
<button onclick="cameraControls.normalizeRotations().setTarget( 3, 0, -3, true )">look at ( 3, 0, -3 )</button>
3939
<button onclick="cameraControls.normalizeRotations().setLookAt( 1, 2, 3, 1, 1, 0, true )">move to ( 1, 2, 3 ), look at ( 1, 1, 0 )</button>
4040
<br>
41-
<button onclick="cameraControls.normalizeRotations().lerpLookAt( - 2, 0, 0, 1, 1, 0, 0, 2, 5, - 1, 0, 0, Math.random(), true )">move to somewhere between ( -2, 0, 0 ) -> ( 1, 1, 0 ) and ( 0, 2, 5 ) -> ( -1, 0, 0 )</button>
41+
<button onclick="cameraControls.normalizeRotations().lerp( { target: [1, 1, 0], position: [ - 2, 0, 0 ] }, { target: [ -1, 0, 0 ], position: [ 0, 2, 5]}, Math.random(), true )">move to somewhere between position/target: ( -2, 0, 0 ) -> ( 1, 1, 0 ) and ( 0, 2, 5 ) -> ( -1, 0, 0 )</button>
42+
<button onclick="cameraControls.lerp( { target: [ 1, 1, 0 ], spherical: [ 2, 0, -Math.PI/2 ]}, { target: [ -1, 0, 0 ], spherical: [ 7, Math.PI, Math.PI/2 ]}, Math.random(), true )">move to somewhere inside a hemisphere of a radius ∈ [2..7] centered at a point located between ( 1, 1, 0 ) and ( -1, 0, 0 )</button>
4243
<br>
4344
<button onclick="cameraControls.normalizeRotations().reset( true )">reset</button>
4445
<button onclick="cameraControls.saveState()">saveState</button>

src/CameraControls.ts

Lines changed: 72 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
CameraControlsEventMap,
1313
isPerspectiveCamera,
1414
isOrthographicCamera,
15+
CameraControlsLerpState,
1516
} from './types';
1617
import {
1718
PI_2,
@@ -2111,28 +2112,16 @@ export class CameraControls extends EventDispatcher {
21112112
}
21122113

21132114
/**
2114-
* Similar to setLookAt, but it interpolates between two states.
2115-
* @param positionAX
2116-
* @param positionAY
2117-
* @param positionAZ
2118-
* @param targetAX
2119-
* @param targetAY
2120-
* @param targetAZ
2121-
* @param positionBX
2122-
* @param positionBY
2123-
* @param positionBZ
2124-
* @param targetBX
2125-
* @param targetBY
2126-
* @param targetBZ
2115+
* Interpolates between two states.
2116+
* @param stateA
2117+
* @param stateB
21272118
* @param t
21282119
* @param enableTransition
21292120
* @category Methods
21302121
*/
2131-
lerpLookAt(
2132-
positionAX: number, positionAY: number, positionAZ: number,
2133-
targetAX: number, targetAY: number, targetAZ: number,
2134-
positionBX: number, positionBY: number, positionBZ: number,
2135-
targetBX: number, targetBY: number, targetBZ: number,
2122+
lerp(
2123+
stateA: CameraControlsLerpState,
2124+
stateB: CameraControlsLerpState,
21362125
t: number,
21372126
enableTransition: boolean = false,
21382127
): Promise<void> {
@@ -2143,13 +2132,29 @@ export class CameraControls extends EventDispatcher {
21432132
this._lastDollyDirection = DOLLY_DIRECTION.NONE;
21442133
this._changedDolly = 0;
21452134

2146-
const targetA = _v3A.set( targetAX, targetAY, targetAZ );
2147-
const positionA = _v3B.set( positionAX, positionAY, positionAZ );
2148-
_sphericalA.setFromVector3( positionA.sub( targetA ).applyQuaternion( this._yAxisUpSpace ) );
2135+
const targetA = _v3A.set( ...stateA.target );
2136+
if ( 'spherical' in stateA ) {
2137+
2138+
_sphericalA.set( ...stateA.spherical );
2139+
2140+
} else {
2141+
2142+
const positionA = _v3B.set( ...stateA.position );
2143+
_sphericalA.setFromVector3( positionA.sub( targetA ).applyQuaternion( this._yAxisUpSpace ) );
2144+
2145+
}
2146+
2147+
const targetB = _v3C.set( ...stateB.target );
2148+
if ( 'spherical' in stateB ) {
2149+
2150+
_sphericalB.set( ...stateB.spherical );
2151+
2152+
} else {
2153+
2154+
const positionB = _v3B.set( ...stateB.position );
2155+
_sphericalB.setFromVector3( positionB.sub( targetB ).applyQuaternion( this._yAxisUpSpace ) );
21492156

2150-
const targetB = _v3C.set( targetBX, targetBY, targetBZ );
2151-
const positionB = _v3B.set( positionBX, positionBY, positionBZ );
2152-
_sphericalB.setFromVector3( positionB.sub( targetB ).applyQuaternion( this._yAxisUpSpace ) );
2157+
}
21532158

21542159
this._targetEnd.copy( targetA.lerp( targetB, t ) ); // tricky
21552160

@@ -2183,6 +2188,49 @@ export class CameraControls extends EventDispatcher {
21832188

21842189
}
21852190

2191+
/**
2192+
* Similar to setLookAt, but it interpolates between two states.
2193+
* @param positionAX
2194+
* @param positionAY
2195+
* @param positionAZ
2196+
* @param targetAX
2197+
* @param targetAY
2198+
* @param targetAZ
2199+
* @param positionBX
2200+
* @param positionBY
2201+
* @param positionBZ
2202+
* @param targetBX
2203+
* @param targetBY
2204+
* @param targetBZ
2205+
* @param t
2206+
* @param enableTransition
2207+
* @category Methods
2208+
*/
2209+
lerpLookAt(
2210+
positionAX: number, positionAY: number, positionAZ: number,
2211+
targetAX: number, targetAY: number, targetAZ: number,
2212+
positionBX: number, positionBY: number, positionBZ: number,
2213+
targetBX: number, targetBY: number, targetBZ: number,
2214+
t: number,
2215+
enableTransition: boolean = false,
2216+
): Promise<void> {
2217+
2218+
return this.lerp(
2219+
{
2220+
position: [ positionAX, positionAY, positionAZ ],
2221+
target: [ targetAX, targetAY, targetAZ ],
2222+
},
2223+
{
2224+
position: [ positionBX, positionBY, positionBZ ],
2225+
target: [ targetBX, targetBY, targetBZ ],
2226+
},
2227+
t,
2228+
enableTransition,
2229+
2230+
);
2231+
2232+
}
2233+
21862234
/**
21872235
* Set angle and distance by given position.
21882236
* An alias of `setLookAt()`, without target change. Thus keep gazing at the current target

src/types.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,3 +137,11 @@ export function isOrthographicCamera( camera: _THREE.Camera ): camera is _THREE.
137137
return ( camera as _THREE.OrthographicCamera ).isOrthographicCamera;
138138

139139
}
140+
141+
export type CameraControlsLerpState = {
142+
target: [number, number, number]
143+
} & ( {
144+
spherical: Parameters<_THREE.Spherical["set"]>
145+
} | {
146+
position: [number, number, number]
147+
} );

0 commit comments

Comments
 (0)