# solved Camera Inertia Angle

## Recommended Posts

Hi there,

Is there a way for me to get the ArcRotateCamera's rotation angle led by its inertia?

I have pointerDown and pointerUp events to calculate how many angles I rotates during pointerEvent, but if I make a quick slide, the camera doesn't stop immediately after pointerUp, it will rotate for some angles due to inertia.

Thanks!

##### Share on other sites

I do not think that anything built in could provide the diff, but in your case if you prefer to have the full control yourself, you could stop inertia by putting to 0.

Hope that helps.

##### Share on other sites
3 minutes ago, Sebavan said:

I do not think that anything built in could provide the diff, but in your case if you prefer to have the full control yourself, you could stop inertia by putting to 0.

Hope that helps.

Thanks Sebavan, yes, putting the inertia to 0 could help. But the rotation would be so slow and would affect the UE, So I'm trying to calculate the inertia angle, it maybe something like camera inertia * pointerMove length. aha, just my imagination..Hope @Deltakosh and @Wingnut could support me any idea~

##### Share on other sites

You could rely on speed to make the camera faster independently of inertia.

Else about the formula  it is exactly computed like this:

if (this.inertialAlphaOffset !== 0 || this.inertialBetaOffset !== 0 || this.inertialRadiusOffset !== 0) {
let inertialAlphaOffset = this.inertialAlphaOffset;
if (this.beta <= 0) inertialAlphaOffset *= -1;
if (this.getScene().useRightHandedSystem) inertialAlphaOffset *= -1;
if (this.parent && this.parent._getWorldMatrixDeterminant() < 0) inertialAlphaOffset *= -1;
this.alpha += inertialAlphaOffset;

this.beta += this.inertialBetaOffset;

this.inertialAlphaOffset *= this.inertia;
this.inertialBetaOffset *= this.inertia;
if (Math.abs(this.inertialAlphaOffset) < Epsilon)
this.inertialAlphaOffset = 0;
if (Math.abs(this.inertialBetaOffset) < Epsilon)
this.inertialBetaOffset = 0;
if (Math.abs(this.inertialRadiusOffset) < this.speed * Epsilon)
}

where offset are computed from the pointers in this way:
if (pointA && pointB === null && cacheSoloPointer) {
if (this.panningSensibility !== 0 &&
((evt.ctrlKey && this.camera._useCtrlForPanning) || this._isPanClick)) {
this.camera.inertialPanningX += -(evt.clientX - cacheSoloPointer.x) / this.panningSensibility;
this.camera.inertialPanningY += (evt.clientY - cacheSoloPointer.y) / this.panningSensibility;
} else {
var offsetX = evt.clientX - cacheSoloPointer.x;
var offsetY = evt.clientY - cacheSoloPointer.y;
this.camera.inertialAlphaOffset -= offsetX / this.angularSensibilityX;
this.camera.inertialBetaOffset -= offsetY / this.angularSensibilityY;
}

cacheSoloPointer.x = evt.clientX;
cacheSoloPointer.y = evt.clientY;
}

Hope this might help.

##### Share on other sites

Hi guys!  Interesting challenge.

Lary... after a click happens, CAN you pre-calculate the needed amount of camera.alpha change... to make the camera point-at the clicked point?  Maybe you could make a testing playground... and then we will try to find a formula to calculate that value.

IF you can, then perhaps animate the camera.alpha to the new angle.  Perhaps put the below function (untested) at the top of your code, which will add an ease-out camera.spin() function to all your created arcRotateCameras.  We are attaching a little animation motor to camera.alpha.

BABYLON.ArcRotateCamera.prototype.spin = function (radians, speed) {
var ease = new BABYLON.CubicEase();
ease.setEasingMode(BABYLON.EasingFunction.EASINGMODE_EASEOUT);
BABYLON.Animation.CreateAndStartAnimation('myanim', this, 'alpha', speed, 120, this.alpha, this.alpha+radians, 0, ease);
}

Reminder... I didn't test it.    This playground has a bunch of little animation motors at the top of the code... added to abstractMesh.  They could work on cameras, too, after some adjusting.  You could make your animation be:    spin(amountOfChange)     ...or spinTo(newRadianValue).

EASEINOUT is also an option.

Just some Wingnut thoughts.  Might help.  Probably not.

##### Share on other sites
``````var createScene = function () {

// This creates a basic Babylon Scene object (non-mesh)
var scene = new BABYLON.Scene(engine);

// This creates and positions a free camera (non-mesh)
var camera = new BABYLON.ArcRotateCamera("arcRotateCamera", 0, 0, 15, new BABYLON.Vector3(0, 0, 0), scene)
camera.beta = Math.PI / 3;

// This targets the camera to scene origin
camera.setTarget(BABYLON.Vector3.Zero());

// This attaches the camera to the canvas
camera.attachControl(canvas, true);

// This creates a light, aiming 0,1,0 - to the sky (non-mesh)
var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene);

// Default intensity is 1. Let's dim the light a small amount
light.intensity = 0.7;

// Our built-in 'sphere' shape. Params: name, subdivs, size, scene
var sphere = BABYLON.Mesh.CreateSphere("sphere1", 16, 2, scene);

// Move the sphere upward 1/2 its height
sphere.position.y = 1;

// Our built-in 'ground' shape. Params: name, width, depth, subdivs, scene
var ground = BABYLON.Mesh.CreateGround("ground1", 6, 6, 2, scene);

//Camera rotation Detection
let oriAlpha = 0;
let oriBeta = 0;
let oriDirAlpha = 0;
let oriDirBeta = 0;

let turnAlpha = 0;
let turnBeta = 0;

let infoAlpha = [];
let infoBeta = [];
//
// let camera = scene.activeCamera;

let timeStart = null;

oriAlpha = turnAlpha = camera.alpha;
// console.log(oriAlpha)
oriBeta = turnBeta = camera.beta;
oriDirAlpha = 0;
oriDirBeta = 0;
infoAlpha = [];
infoBeta = [];
timeStart = new Date().getTime();
}, 1)
infoAlpha.push({
dir: (camera.alpha - turnAlpha) > 0 ? 1 : -1,
angle: camera.alpha - turnAlpha
})

if (infoAlpha.length === 1) {
if (infoAlpha[0].angle === 0) {
console.log("click")
} else {
var direction = infoAlpha[0].dir < 0 ? "Right：" : "Left:"

console.log(direction + Math.abs(infoAlpha[0].angle * 180 / Math.PI).toFixed(0) + "°")
}
} else {

var turns = infoAlpha.length;
var turnInfo = "";

for (var i = 0; i < turns; i++) {
var direction = infoAlpha[i].dir < 0 ? "Right：" : "Left:";
turnInfo += (direction + Math.abs(infoAlpha[i].angle * 180 / Math.PI).toFixed(0) + "°" + "\n")
}
console.log(turnInfo)
}

console.log("Duration:" + (new Date().getTime() - timeStart) / 1000 + "秒");
}, 2)
let alphaDif = camera.alpha - oriAlpha;
let betaDif = camera.beta - oriBeta;

oriAlpha = camera.alpha;
oriBeta = camera.beta;

let dir = alphaDif > 0 ? 1 : -1;

if (!oriDirAlpha) {
oriDirAlpha = dir;
//   console.log(ariDirAlpha)
} else {
//   console.log("turn:"+turnAlpha)

if (oriDirAlpha !== dir) {
infoAlpha.push({
dir: oriDirAlpha,
angle: camera.alpha - turnAlpha
})
oriDirAlpha = dir;
turnAlpha = camera.alpha;
}
}
}

})

return scene;

};``````

Hi all, I paste my code here, coz I wonder if what happens that I can't save a PG for your information.

##### Share on other sites

Your code had a few non-standard characters in it... and the json parser in the SAVE... was getting indigestion.

Now the forum friends can do some studying and thinking.  Thx for the PG/code, Lary.

##### Share on other sites
23 minutes ago, Wingnut said:

Your code had a few non-standard characters in it... and the json parser in the SAVE... was getting indigestion.

Now the forum friends can do some studying and thinking.  Thx for the PG/code, Lary.

Thank you for correction. Wingnut. and all BJSers

##### Share on other sites

If all you're wanting is the additional angle that the camera will rotate due to inertia after the pointerup event, you can calculate it in radians as:

``const additionalAngle = camera.inertialAlphaOffset / (1 - camera.inertia);``

which follows from the implementation posted by Sebavan above.

##### Share on other sites
5 hours ago, sable said:

If all you're wanting is the additional angle that the camera will rotate due to inertia after the pointerup event, you can calculate it in radians as:

```
`const additionalAngle = camera.inertialAlphaOffset / (1 - camera.inertia)﻿;````

which follows from the implementation posted by Sebavan above.﻿﻿

Greeeeet! Thank you so sosososoos much Sable! It really saved me! I tested the values, and it is correct!!!!!

## Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

×   Pasted as rich text.   Paste as plain text instead

Only 75 emoji are allowed.

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.