Phuein Posted September 16, 2018 Share Posted September 16, 2018 I'm working on a camera that behaves as if tracking a spaceship. The Z axis rotation shouldn't affect looking up/down and right/left, as if I'm the pilot in the cockpit of the ship in space, up is always my local up. I tried the FollowCamera, but it only lets me rotate the target mesh so the camera yaws, but doesn't roll or pitch. I tried the Free/Universal cameras, but rotating the camera to roll skews the yaw and pitch, as if they're in global dimensions - instead of local. I couldn't find a local/global rotation option, or figure out using quaternions/matrices with it, no matter how much I read about those and tweaked the code. I know I could make this spaceship camera from scratch, using an empty/mesh as a pivot, but I don't want to miss on using the quality code that comes with the engine already. Any suggestions? coolroar 1 Quote Link to comment Share on other sites More sharing options...
coolroar Posted September 16, 2018 Share Posted September 16, 2018 Hi Phuein, I also believe BJS should have a "flying" camera. Here is a thread that led to my solution: I used it in ZOOM my "flying through space" game. And here I added flight simulator functionality: ))))))))))))))))))))))))))))))))))))))) Best luck to ya! ☘️ ✅ Phuein and trevordev 2 Quote Link to comment Share on other sites More sharing options...
Phuein Posted September 16, 2018 Author Share Posted September 16, 2018 1 hour ago, coolroar said: Hi Phuein, I also believe BJS should have a "flying" camera. Here is a thread that led to my solution: I like the colors in your flight demo . Can you show a PG with your addYawPitchRollFunction function with roll upside down and around to make sure right stays right, left stays left, up is up, and so on? The flight example doesn't let me move that much around, so it's hard to tell. Quote Link to comment Share on other sites More sharing options...
coolroar Posted September 16, 2018 Share Posted September 16, 2018 Hi Phuein, Before I made addYawPitchRollFunction I did it like this: https://www.babylonjs-playground.com/index.html#2UFUC3 Otherwise to keep left left, right right, & up up, you will need a manual roll control for your space craft. Imagine heading North, then applying up pitch. As you pass straight up, down & up will reverse. But remember, in real space there is no UNIVERSAL up, left, etc. Try my zoom game to as an example where you can move around a lot! https://jounce.space/zoom?deep=5 Quote Link to comment Share on other sites More sharing options...
Phuein Posted September 16, 2018 Author Share Posted September 16, 2018 Neither example has roll, to freely test all directions. It would be awesome if you link a PG example with free movement in all directions including yaw. To clarify, in real space, when you're the pilot, yaw and pitch are ALWAYS local to you. You never fly to your right and it's not your right. Quote Link to comment Share on other sites More sharing options...
coolroar Posted September 16, 2018 Share Posted September 16, 2018 (edited) Ok, try this: https://www.babylonjs-playground.com/index.html#Q1RH6C Edit: add playground instructions: ///// Mouse point to desired yaw pitch ///// Left-right arrow keys for roll. ///// ✨ ✈️ Edited September 16, 2018 by coolroar add playground instructions Phuein 1 Quote Link to comment Share on other sites More sharing options...
Phuein Posted September 17, 2018 Author Share Posted September 17, 2018 Cool, seems to work fine in this trippy example. Instructions definitely needed! So, in your experience that function works fine? Test plenty? If so, it looks like a solution. I'd say this should be applied to the Universal camera, so it can move in 3D freely out-of-the-box. Have you considered pulling this into the engine? Say at https://github.com/BabylonJS/Babylon.js/blob/master/src/Cameras/Inputs/babylon.freeCameraMouseInput.ts#L122 Quote Link to comment Share on other sites More sharing options...
coolroar Posted September 17, 2018 Share Posted September 17, 2018 Tested only in examples referred to in this topic and at ZOOM. Agree "this should be applied to the Universal camera, so it can move in 3D freely out-of-the-box". I don't know how to merge to the code-base, and I don't care to learn it at this time. But I'd be happy if someone else were to do that. Here it is with both yawPitchRoll() and autoBank(), plus clearYawPitchRoll(). function addYawPitchRollFunction(ob, gravity) { ob.rotationQuaternion = new BABYLON.Quaternion(); ob.rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(ob.rotation.y, ob.rotation.x, ob.rotation.z); ob.myGrav = gravity; ob.yawPitchRoll = function(yaw, pitch, roll) { var axis = new BABYLON.Vector3(0, 0, -1); var partRotQuat = new BABYLON.Quaternion(); BABYLON.Quaternion.RotationAxisToRef(axis, roll, partRotQuat); this.rotationQuaternion.multiplyInPlace(partRotQuat); BABYLON.Quaternion.RotationAxisToRef(axis.set(-1, 0, 0), pitch, partRotQuat); this.rotationQuaternion.multiplyInPlace(partRotQuat); BABYLON.Quaternion.RotationAxisToRef(axis.set(0, 1, 0), yaw, partRotQuat); this.rotationQuaternion.multiplyInPlace(partRotQuat); this.rotationQuaternion.toEulerAnglesToRef(this.rotation); } ob.autoBank = function(yaw, pitch, speed) { var axis = new BABYLON.Vector3(0, 0, -1); var partRotQuat = new BABYLON.Quaternion(); var roll = Math.atan2(-yaw*222*speed, this.myGrav); this.rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(this.rotation.y, this.rotation.x, roll); BABYLON.Quaternion.RotationAxisToRef(axis.set(-1, 0, 0), pitch, partRotQuat); this.rotationQuaternion.multiplyInPlace(partRotQuat); BABYLON.Quaternion.RotationAxisToRef(axis.set(0, 1, 0), yaw, partRotQuat); this.rotationQuaternion.multiplyInPlace(partRotQuat); this.rotationQuaternion.toEulerAnglesToRef(this.rotation); } ob.clearYawPitchRoll = function() { this.rotationQuaternion.set(0, 0, 0, 1); this.rotation.set(0,0,0); } } Cheers -- ? ✅ ✨! Quote Link to comment Share on other sites More sharing options...
Phuein Posted September 18, 2018 Author Share Posted September 18, 2018 Please add comments to the functions. Isn't clear [for me] what autoBank does, what's expected. Looks good. Quote Link to comment Share on other sites More sharing options...
coolroar Posted September 18, 2018 Share Posted September 18, 2018 Sorry my code is so obscure & cryptic, but I'm not inclined to add anything except that you can see autoBank() in use here: https://www.babylonjs-playground.com/#UL7W2M Good luck with your projects. Quote Link to comment Share on other sites More sharing options...
Phuein Posted September 18, 2018 Author Share Posted September 18, 2018 I saw the demo, but I'm still not clear on what it does. The 222 multiplier, and why RotationAxisToRef twice? Also, how does the yawPitchRoll function work, in regards to calling RotationAxisToRef three times? Seems mysterious without some explanation. Quote Link to comment Share on other sites More sharing options...
coolroar Posted September 18, 2018 Share Posted September 18, 2018 Ok. fine. sheesh. function addYawPitchRollFunction(ob, gravity) { ob.rotationQuaternion = new BABYLON.Quaternion(); ob.rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(ob.rotation.y, ob.rotation.x, ob.rotation.z);// Initialize to current rotation. ob.myGrav = gravity; // Set some gravity for autoBank() function. ob.yawPitchRoll = function(yaw, pitch, roll) { var axis = new BABYLON.Vector3(0, 0, -1); // Set an axis to 'z' (roll). var partRotQuat = new BABYLON.Quaternion(); // A var to hold partial rotation. BABYLON.Quaternion.RotationAxisToRef(axis, roll, partRotQuat); // put roll in partRotQuat this.rotationQuaternion.multiplyInPlace(partRotQuat); // Apply roll to rotationQuaternion. // Set axis to '-x' (pitch) and put pitch in partRotQuat. BABYLON.Quaternion.RotationAxisToRef(axis.set(-1, 0, 0), pitch, partRotQuat); this.rotationQuaternion.multiplyInPlace(partRotQuat); // Apply pitch to rotationQuaternion. // Set axis to 'y' (yaw) and put yaw in partRotQuat. BABYLON.Quaternion.RotationAxisToRef(axis.set(0, 1, 0), yaw, partRotQuat); this.rotationQuaternion.multiplyInPlace(partRotQuat); // Apply yaw to rotationQuaternion. this.rotationQuaternion.toEulerAnglesToRef(this.rotation); // Apply rotationQuaternion to (camera.rotation) } ob.autoBank = function(yaw, pitch, speed) { var axis = new BABYLON.Vector3(0, 0, -1); // Set an axis to 'z' (roll). var partRotQuat = new BABYLON.Quaternion(); // A var to hold partial rotation. var fudge = 222; // Whatever, change to make bank angle seem appropriate. var roll = Math.atan2(-yaw*fudge*speed, this.myGrav);// Roll (bank) based on speed, turn rate, & gravity. // get current camera.rotation, substitute roll for camera.rotation.z. this.rotationQuaternion = BABYLON.Quaternion.RotationYawPitchRoll(this.rotation.y, this.rotation.x, roll); // Set axis to '-x' (pitch) and put pitch in partRotQuat. BABYLON.Quaternion.RotationAxisToRef(axis.set(-1, 0, 0), pitch, partRotQuat); this.rotationQuaternion.multiplyInPlace(partRotQuat); // Apply pitch to rotationQuaternion. // Set axis to 'y' (yaw) and put yaw in partRotQuat. BABYLON.Quaternion.RotationAxisToRef(axis.set(0, 1, 0), yaw, partRotQuat); this.rotationQuaternion.multiplyInPlace(partRotQuat); // Apply yaw to rotationQuaternion. this.rotationQuaternion.toEulerAnglesToRef(this.rotation);// Apply rotationQuaternion to (camera.rotation) } ob.clearYawPitchRoll = function() { this.rotationQuaternion.set(0, 0, 0, 1); this.rotation.set(0,0,0); } } ? Phuein 1 Quote Link to comment Share on other sites More sharing options...
SvenFrankson Posted September 18, 2018 Share Posted September 18, 2018 In case it help, I did some camera for flying spaceship for this demo Here is the script about the flying camera following the spaceship : https://github.com/SvenFrankson/space-scout/blob/master/scripts/SpaceShipCamera.ts Line 55, there's an update loop for the camera. Main idea is that I keep an empty mesh at a fixed position relatively to the spaceship (it's the vector named _targetPosition), and lerp to it each frame with a smoothness factor. It makes the camera go to a point with some delay, so when spaceship accelerates you feel it a little more because it goes further. A Slerp make the camera rotationQuaternion go to the spaceship rotationQuaternion, so barrel rolls are smoothed too. For the most part it's inspired from the Galactic StarFighter mode of Star Wars The Old Republic. Hope it helps, good luck ! trevordev and coolroar 2 Quote Link to comment Share on other sites More sharing options...
Phuein Posted September 19, 2018 Author Share Posted September 19, 2018 Thanks! Now the code makes full sense. I'm sure others will enjoy it, too. Cool space example, Sven. Thanks for sharing. Could you add comments to the code? I'm not entirely sure how you chose your logic there. What's focalLength() about? And focalPlane? Why _checkInputs() checks on the ship's worldMatrix? I do generally get that you basically used a rotationQuaternion like coolroar's example, which seems like what's missing from the FreeCamera/UniversalCamera. Quote Link to comment Share on other sites More sharing options...
Phuein Posted September 26, 2018 Author Share Posted September 26, 2018 Say coolroar, did you notice that your rotation method loses the straight angle when it goes over a certain degree? When implementing your method, I noticed that I get an issue with the camera slowly rolling, when I rotate the camera on X and Y. It doesn't happen in your example - but that's not a free rolling camera either - but it does show when changing the angle enough. Quote Link to comment Share on other sites More sharing options...
coolroar Posted September 27, 2018 Share Posted September 27, 2018 Does "...loses the straight angle..." mean "...the screen point for zero attitude change..."? I think I noticed that once. If true, I don't know why. Work-a-round: periodic re-center: https://www.babylonjs-playground.com/index.html#Q1RH6C#1 "...camera slowly rolling..." I'm not sure what you mean. You know of course that you will get roll as you yaw when pitch != 0. ☘️ ? Quote Link to comment Share on other sites More sharing options...
Phuein Posted September 27, 2018 Author Share Posted September 27, 2018 "Loses the straight angle" means it has an unwanted roll. Why do you get a roll from yaw and pitch? You can take an object and yaw and pitch it without any roll. Quote Link to comment Share on other sites More sharing options...
coolroar Posted September 27, 2018 Share Posted September 27, 2018 Clarification of my previous post: "... you will get roll as you yaw when pitch != 0" should be: " the horizon will tilt (relative to your craft) as you yaw when pitch != 0". The tilted horizon makes you think your craft rolled. (Since at computer we lack the physical sensations of yaw, pitch, & roll). Imagine: You are heading North, straight and level. Then you pitch to straight up. Then you yaw PI/2 to the left. What is your heading? Describe the horizon as seen looking straight ahead. You are headed West, the horizon appears vertical with the ground out the left window. With no craft roll! Pitch(PI/2), Yaw(PI/2) = Roll(PI/2), Pitch(PI/2) = Yaw(PI/2), Roll(PI/2) A series of yaws and pitches can equal a roll: Roll(PI/2) = Pitch(PI/2), Yaw(PI/2), Pitch(-PI/2). (Check my work? ?) I hope I'm not blathering stuff you already know. ? For the benefit of others, I'll also post this to Quote Link to comment Share on other sites More sharing options...
Phuein Posted September 28, 2018 Author Share Posted September 28, 2018 I'll mark this topic as solved, and direct any followup to the other topic, which builds on this. ? 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.