Reseting Camera After Ending User Input/Adding Interpolation

Hey everyone,

I’m trying to get the camera to reset to its initial position after the user finished interacting with it (orbiting around an object). I tried storing the initial position and rotation/euler angles on initialization and then setting those values at MOUSEUP. When I do this there is no reaction and the camera does not reset and just stays where the user leaves it. The following code is what I’m using to try and achieve this:

On initialize I have this:

this.startPosition = this.entity.getPosition().clone();
this.startRotation = this.entity.getLocalEulerAngles().clone;

Then on mouse up I have this:

this.entity.setLocalPosition(this.startPosition.x, this.startPosition.z, this.startPosition.y);
this.entity.setLocalEulerAngles(this.startRotation);

I tried referencing this thread but I had no luck with the solution: [SOLVED] Reset position after impulse

Here is the link to the project editor: https://playcanvas.com/editor/scene/532716

Thanks,
Diego

That project is private so I get a 404 when I try to open it.

Why are you doing:

this.entity.setLocalPosition(this.startPosition.x, this.startPosition.z, this.startPosition.y);
this.entity.setLocalEulerAngles(this.startRotation);

Instead of:

this.entity.setPosition(this.startPosition);
this.entity.setEulerAngles(this.startRotation);

(And you’re getting local Eulers too. Essentially, I’m asking why you don’t just get/set world space position and rotation).

Hey Will,

I was trying out what you suggested first but it wasn’t working so I just went on to try different methods to see if it would help and the code I posted was the last thing I tried. I made the project public.

The code is in the mouse-input.js

This is happening because your setting of the position and rotation of the camera is being overwritten in the orbit-camera.js script. In mouse-orbit.js, you have:

MouseInput.prototype.initialize = function() {
    this.orbitCamera = this.entity.script.orbitCamera;

This is storing off a reference to the OrbitCamera script on the camera. The MouseInput script then just updates variables on the OrbitCamera script object in response to, say, a pan of the mouse:

MouseInput.prototype.pan = function(screenPoint) {
    var fromWorldPoint = MouseInput.fromWorldPoint;
    var toWorldPoint = MouseInput.toWorldPoint;
    var worldDiff = MouseInput.worldDiff;
    
    // For panning to work at any zoom level, we use screen point to world projection
    // to work out how far we need to pan the pivotEntity in world space 
    var camera = this.entity.camera;
    var distance = this.orbitCamera.distance;
    
    camera.screenToWorld(screenPoint.x, screenPoint.y, distance, fromWorldPoint);
    camera.screenToWorld(this.lastPoint.x, this.lastPoint.y, distance, toWorldPoint);

    worldDiff.sub2(toWorldPoint, fromWorldPoint);
       
    this.orbitCamera.pivotPoint.add(worldDiff);    
};

At the end of that function, the pivotPoint property on the OrbitCamera script is updated. The function doesn’t directly update the position of the camera. That is done in the update function of the OrbitCamera script, called every frame:

OrbitCamera.prototype.update = function(dt) {
    // Add inertia, if any
    var t = this.inertiaFactor === 0 ? 1 : Math.min(dt / this.inertiaFactor, 1);
    this._distance = pc.math.lerp(this._distance, this._targetDistance, t);
    this._yaw = pc.math.lerp(this._yaw, this._targetYaw, t);
    this._pitch = pc.math.lerp(this._pitch, this._targetPitch, t);

    this._updatePosition();
};


OrbitCamera.prototype._updatePosition = function () {
    // Work out the camera position based on the pivot point, pitch, yaw and distance
    this.entity.setLocalPosition(0,0,0);
    this.entity.setLocalEulerAngles(this._pitch, this._yaw, 0);

    var position = this.entity.getPosition();
    position.copy(this.entity.forward);
    position.scale(-this._distance);
    position.add(this.pivotPoint);
    this.entity.setPosition(position);
};

The solution? Store off distance, pivotPoint, pitch, and yaw properties on this.entity.orbitCamera instead and restore those values on the mouse up event.

Thanks will that did the trick.

Hey Will,

Currently I am trying to add some spherical interpolation to my camera when resetting to it’s starting position. I currently have it resetting successfully but I’m not sure how to have it slerp? I understand how to lerp a 3d object like a cube for example but I understand as well that the camera does not need to reset it’s position and rotation values but it’s yaw, pitch, and distance instead. I tried using some of the functions in the orbit-camera and mouse-input scripts but couldn’t find this functionality.

Project: https://playcanvas.com/editor/scene/533551

Thanks,
Diego

There are a couple of ways I can think of doing this:

  • Store the reset pitch, yaw, distance and pivotPoint and lerp the current values towards the reset values yourself in the input script.
  • When you want to reset the camera, change the orbitCamera.inertiaFactor to a value like 0.1 or something similar and change it back to 0 when the user starts interacting again.