Lary Posted August 13, 2018 Share Posted August 13, 2018 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! Quote Link to comment Share on other sites More sharing options...
Sebavan Posted August 13, 2018 Share Posted August 13, 2018 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. Quote Link to comment Share on other sites More sharing options...
Lary Posted August 13, 2018 Author Share Posted August 13, 2018 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~ Quote Link to comment Share on other sites More sharing options...
Sebavan Posted August 13, 2018 Share Posted August 13, 2018 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.radius -= this.inertialRadiusOffset; this.inertialAlphaOffset *= this.inertia; this.inertialBetaOffset *= this.inertia; this.inertialRadiusOffset *= 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) this.inertialRadiusOffset = 0; } 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. Lary and Wingnut 2 Quote Link to comment Share on other sites More sharing options...
Wingnut Posted August 13, 2018 Share Posted August 13, 2018 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. Quote Link to comment Share on other sites More sharing options...
Lary Posted August 13, 2018 Author Share Posted August 13, 2018 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; scene.onPointerObservable.add(() => { oriAlpha = turnAlpha = camera.alpha; // console.log(oriAlpha) oriBeta = turnBeta = camera.beta; oriDirAlpha = 0; oriDirBeta = 0; infoAlpha = []; infoBeta = []; timeStart = new Date().getTime(); }, 1) scene.onPointerObservable.add(() => { 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) camera.onViewMatrixChangedObservable.add(() => { let alphaDif = camera.alpha - oriAlpha; let betaDif = camera.beta - oriBeta; // console.log(alphaDif) oriAlpha = camera.alpha; oriBeta = camera.beta; if (alphaDif) { 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. @Wingnut Quote Link to comment Share on other sites More sharing options...
Wingnut Posted August 13, 2018 Share Posted August 13, 2018 http://playground.babylonjs.com/#A22EAV 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. Quote Link to comment Share on other sites More sharing options...
Lary Posted August 13, 2018 Author Share Posted August 13, 2018 23 minutes ago, Wingnut said: http://playground.babylonjs.com/#A22EAV 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 Wingnut 1 Quote Link to comment Share on other sites More sharing options...
sable Posted August 13, 2018 Share Posted August 13, 2018 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. http://playground.babylonjs.com/#PCMNE0#1 Sebavan and Lary 2 Quote Link to comment Share on other sites More sharing options...
Lary Posted August 14, 2018 Author Share Posted August 14, 2018 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. http://playground.babylonjs.com/#PCMNE0#1 Greeeeet! Thank you so sosososoos much Sable! It really saved me! I tested the values, and it is correct!!!!! Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.