Skip to content

Commit

Permalink
Added damping support for camera orbit control
Browse files Browse the repository at this point in the history
  • Loading branch information
jnsmalm committed Feb 5, 2023
1 parent b18d13a commit 2b89923
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Added `renderSortOrder` to `Sprite3D`.
- Added `lerp` to `Point3D`.
- Added damping (inertia) support for `CameraOrbitControl`.

## [2.1.1] - 2022-12-23
### Fixed
Expand Down
1 change: 1 addition & 0 deletions serve/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ let app = new PIXI.Application({
document.body.appendChild(app.view)

let control = new PIXI3D.CameraOrbitControl(app.view)
control.enableDamping = true

app.loader.add("assets/chromatic/diffuse.cubemap")
app.loader.add("assets/chromatic/specular.cubemap")
Expand Down
24 changes: 21 additions & 3 deletions src/camera/camera-orbit-control.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,13 @@ import { Compatibility } from "../compatibility/compatibility"
* Allows the user to control the camera by orbiting the target.
*/
export class CameraOrbitControl {
private _distance = 5
private _grabbed = false

private _dampingAngles = new ObservablePoint(() => { }, undefined, 0, 180)

private _distance = 5
private _dampingDistance = 5

private _angles = new ObservablePoint(() => {
this._angles.x = Math.min(Math.max(-85, this._angles.x), 85)
}, undefined, 0, 180)
Expand All @@ -24,6 +28,12 @@ export class CameraOrbitControl {
return this._angles
}

/** Value indicating if damping (inertia) is enabled, which can be used to give a sense of weight to the controls. Default is false. */
enableDamping = false

/** The damping inertia used if enableDamping is true. Default is 0.1. */
dampingFactor = 0.1

/** Target position (x, y, z) to orbit. */
target = { x: 0, y: 0, z: 0 }

Expand All @@ -38,6 +48,11 @@ export class CameraOrbitControl {
*/
constructor(element: HTMLElement, public camera = Camera.main) {
this.camera.renderer.on("prerender", () => {
if (this.enableDamping) {
this._dampingAngles.x = this._dampingAngles.x + (this._angles.x - this._dampingAngles.x) * this.dampingFactor
this._dampingAngles.y = this._dampingAngles.y + (this._angles.y - this._dampingAngles.y) * this.dampingFactor
this._dampingDistance = this._dampingDistance + (this._distance - this._dampingDistance) * this.dampingFactor
}
this.updateCamera()
})
let interaction = Compatibility.getInteractionPlugin(this.camera.renderer)
Expand Down Expand Up @@ -72,11 +87,14 @@ export class CameraOrbitControl {
* Updates the position and rotation of the camera.
*/
updateCamera() {
let rot = Quat.fromEuler(this._angles.x, this._angles.y, 0, new Float32Array(4))
let angles = this.enableDamping ? this._dampingAngles : this._angles
let distance = this.enableDamping ? this._dampingDistance : this._distance

let rot = Quat.fromEuler(angles.x, angles.y, 0, new Float32Array(4))
let dir = Vec3.transformQuat(
Vec3.set(0, 0, 1, new Float32Array(3)), rot, new Float32Array(3))
let pos = Vec3.subtract(
Vec3.set(this.target.x, this.target.y, this.target.z, new Float32Array(3)), Vec3.scale(dir, this.distance, new Float32Array(3)), new Float32Array(3))
Vec3.set(this.target.x, this.target.y, this.target.z, new Float32Array(3)), Vec3.scale(dir, distance, new Float32Array(3)), new Float32Array(3))

this.camera.position.set(pos[0], pos[1], pos[2])
this.camera.rotationQuaternion.set(rot[0], rot[1], rot[2], rot[3])
Expand Down

0 comments on commit 2b89923

Please sign in to comment.