AlexB Posted August 8, 2014 Share Posted August 8, 2014 Hey guys, I thought I'd post this for anyone to use. I wrote this function for Away3D, and I just ported it to TypeScript to see if it would work with Babylon. Basically, you run the moveCamera function in your render loop. It takes a FreeCamera and a target mesh and follows the object around using easing. Mostly like the ArcRotate camera but it doesn't have a set distance. It sets a "goal" for (x,y,z) and eases to it. So you can use this to follow a character around or a ball, etc. Anyway, here's the code in TS. If this is useful to anyone I can take the time to create a fork and submit a PR?module cameras {export class CameraFollow {public radius:number = 12;public CAMERA_SPEED = 0.05;public MAX_CAMERA_SPEED:number = 20;public orbit:number = 0;public height:number=3;constructor() {}private getRadians (degrees):number {return degrees * Math.PI / 180;}public moveCamera(camera:BABYLON.FreeCamera, cameraTarget:BABYLON.AbstractMesh) {if (!cameraTarget)return;if (!camera)return;var radians:number = this.getRadians(cameraTarget.rotation.y - this.orbit);var targetX:number = cameraTarget.position.x + Math.sin(radians) * this.radius;var targetZ:number = cameraTarget.position.z + Math.cos(radians) * this.radius;var dx:number = targetX - camera.position.x;var dy:number = (cameraTarget.position.y + this.height) - camera.position.y;var dz:number = (targetZ) - camera.position.z;var vx:number = dx * this.CAMERA_SPEED * 2;//this is set to .05var vy:number = dy * this.CAMERA_SPEED;var vz:number = dz * this.CAMERA_SPEED * 2;if (vx > this.MAX_CAMERA_SPEED || vx < -this.MAX_CAMERA_SPEED) {vx = vx < 1 ? -this.MAX_CAMERA_SPEED : this.MAX_CAMERA_SPEED; //max speed is 40}if (vy > this.MAX_CAMERA_SPEED || vy < -this.MAX_CAMERA_SPEED) {vy = vy < 1 ? -this.MAX_CAMERA_SPEED : this.MAX_CAMERA_SPEED;}if (vz > this.MAX_CAMERA_SPEED || vz < -this.MAX_CAMERA_SPEED) {vz = vz < 1 ? -this.MAX_CAMERA_SPEED : this.MAX_CAMERA_SPEED;}camera.position = new BABYLON.Vector3(camera.position.x + vx, camera.position.y + vy, camera.position.z + vz);camera.setTarget(cameraTarget.position);}}} Quote Link to comment Share on other sites More sharing options...
AlexB Posted August 8, 2014 Author Share Posted August 8, 2014 I added this. https://github.com/jumpkick-studios/Babylon.js/blob/master/Babylon/Cameras/babylon.followCamera.ts Usage is really simple://adjust the paramsscene.activeCamera.heightOffset=4; //height above the objectscene.activeCamera.rotationOffset=180; // follow from the rearscene.activeCamera.radius=12; // how far from the objectscene.activeCamera.cameraAcceleration=0.05 // how fast to movescene.activeCamera.maxCameraSpeed=20 // speed limit//follow the objectengine.runRenderLoop(function() { scene.render(); var car=scene.getMeshByName("car"); scene.activeCamera.follow(car);}); Dad72 1 Quote Link to comment Share on other sites More sharing options...
Dad72 Posted August 9, 2014 Share Posted August 9, 2014 This feature is interesting. I tested it. Currently I use an ArcRotateCamera that follows a character. Is it works with all cameras? (free, rotate...) Thanks for the feature. Quote Link to comment Share on other sites More sharing options...
AlexB Posted August 9, 2014 Author Share Posted August 9, 2014 Right now it's just extending the FreeCamera. I was thinking that the problem with the ArcRotate is that it sets a certain distance from the object and sticks to it, so there's no easing. So if you were making a car game, you wouldn't want to just lock to the car or else your view would be jerky. The first example above used a composition but I was thinking it would be better as its own camera type and extending the basic free camera. I think to use with the ArcRotate you'd have to override some of the positioning anyway so I'm not sure how useful it would be there. Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted August 9, 2014 Share Posted August 9, 2014 The only ask I can make is: keep it simple and remove the follow function. by default the camera._checkInputs function is called on every frame Other question: are you using collisions mecanism from freeCamera? if no, I would prefer creating a brand new camera (but using collisions can be interesting tough:)) Quote Link to comment Share on other sites More sharing options...
AlexB Posted August 9, 2014 Author Share Posted August 9, 2014 Hi Deltakosh, let me look at the code a little more closely tomorrow. I'm not using the collisions, I only subclassed the freeCamera because I thought it was the right one to use. I'm happy to adjust, but can you explain the request about the follow function? Should I move the follow invocation into the _checkInputs call? Perhaps it should use the target property you already have? Again, I'll take a look, but any guidance you have would be great! Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted August 9, 2014 Share Posted August 9, 2014 First of all thank you for your submission Yes please move the code from follow to _checkInputs so that user should not have to call it (I always try to reduce the number of line of code that the user must have to use) Also using the target property could be better Quote Link to comment Share on other sites More sharing options...
AlexB Posted August 9, 2014 Author Share Posted August 9, 2014 Great, and you're welcome. This library is just phenomenal! So I should have an update soon. I took out the follow command and made the camera subclass BABYLON.Camera, removing superfluous code. Now it won't check inputs anymore at all, which really it shouldn't. If it's just trying to follow a car, then you use inputs to move the car, not the camera, right? I also added a "target" property so the user can use it like this:camera.target=myCharacter;Then the camera just locks onto that mesh's position and rotation from that point on. I just need to do some more testing and clean up the code. One question, though: I copied a lot of the code from the freeCamera class, so now the code isn't as DRY as it should be. Should there be some sort of other class we create that extends Camera, that both freeCamera and followCamera could extend? Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted August 9, 2014 Share Posted August 9, 2014 We should If there is a lot of shared code this is definitely what we have to do What about BABYLON.BasicCamera as name ? Quote Link to comment Share on other sites More sharing options...
AlexB Posted August 9, 2014 Author Share Posted August 9, 2014 I think that works, although I'm not sure it's very descriptive. Would you like me to integrate this? Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted August 9, 2014 Share Posted August 9, 2014 As you wish This is your idea so feel free to integrate it But if we can keep the inheritance from freeCamera it would be even simpler. You should just have to deal with collisions right? Quote Link to comment Share on other sites More sharing options...
AlexB Posted August 9, 2014 Author Share Posted August 9, 2014 I wasn't planning on dealing with collisions at all. Actually, I'm not so sure how to accomplish this. So maybe I take it as far as I can and if someone wants to work with collisions they can use my version as a base? Either way, I can do the DRY stuff and then I'll submit a new PR. Quote Link to comment Share on other sites More sharing options...
GameMonetize Posted August 9, 2014 Share Posted August 9, 2014 So no problem just create a new root camera with two children: freeCamera and followCamera that is perfect to me Quote Link to comment Share on other sites More sharing options...
Dad72 Posted August 9, 2014 Share Posted August 9, 2014 That would be really good if the collision could work also for the use I want to do (for test). see this topic: http://www.html5gamedevs.com/topic/8144-camerarotative-with-collisions/?p=48719 Quote Link to comment Share on other sites More sharing options...
AlexB Posted August 9, 2014 Author Share Posted August 9, 2014 Ok, I think I have it working, but I'm running into issues testing. I'm using PHPStorm (not Visual Studio) and if I add the two new camera files manually it works, but if I build the code using Gulp, I get some strange errors. I'm totally lost in VS2013 (installing now) but I may need some help integrating. Stay tuned. Quote Link to comment Share on other sites More sharing options...
AlexB Posted August 13, 2014 Author Share Posted August 13, 2014 Code is in, if anyone wants to test https://github.com/BabylonJS/Babylon.js/blob/master/Babylon/Cameras/babylon.followCamera.ts Quote Link to comment Share on other sites More sharing options...
Dad72 Posted August 14, 2014 Share Posted August 14, 2014 You have some explanation and example on FollowCamera and TargetCamera. What are their differences? Support it the Anaglyph as the freeCamera or the ArcRotateCamera? consider it you? This would be very useful. Thanks for these new camera. Quote Link to comment Share on other sites More sharing options...
AlexB Posted August 14, 2014 Author Share Posted August 14, 2014 targetCamera is really just a base class to avoid writing code twice. freeCamera usage has not changed. followCamera works like this. var camera = new BABYLON.FollowCamera("FollowCamera", new BABYLON.Vector3(0,0,0), scene); camera.heightOffset = 8; //how high up from the object to place the camera camera.radius = 30; // how far from the object to follow camera.rotationOffset = 180; //rotate around the object (if it's imported strangely or you want to follow from the front) camera.target = myMeshObject; //any mesh or object with a "position" Vector3 scene.activeCamera = camera; //set the active camera Dad72 1 Quote Link to comment Share on other sites More sharing options...
Dad72 Posted August 16, 2014 Share Posted August 16, 2014 Thanks AlexB. It works, but one thing does not work well, or I miss something with rotationOffset. The camera does not turn around the object http://www.babylonjs.com/playground/#1CC7UC#4 Quote Link to comment Share on other sites More sharing options...
AlexB Posted August 16, 2014 Author Share Posted August 16, 2014 It's doing exactly what it should. The rotationOffset is the angle at which it should orient itself as the "goal" rotation. So try adding some keyboard controls to move your model. Make a left/right key turn your model and change its direction. The camera should swing smoothly around and continue following, still from the back. It's the easing that helps this work nicely. ETA: Maybe there's a bug here. Doing some testing... Quote Link to comment Share on other sites More sharing options...
Dad72 Posted August 16, 2014 Share Posted August 16, 2014 Ah ok, I see, I thought that it was the mouse that controlled the camera AlexB 1 Quote Link to comment Share on other sites More sharing options...
AlexB Posted August 17, 2014 Author Share Posted August 17, 2014 I fixed the bug and submitted a pull request. I didn't realize that Babylon rotations were already in radians, so my conversion formula was not correctly following the mesh. To fix, change this line:var radians = this.getRadians(cameraTarget.rotation.y - this.rotationOffset);To:var radians = this.getRadians(this.rotationOffset)+cameraTarget.rotation.y;Now, if you rotate your model, the camera should follow correctly. Quote Link to comment Share on other sites More sharing options...
Wingnut Posted August 17, 2014 Share Posted August 17, 2014 Hey Alex... thanks for the new camera! (And thanks for showing us how to use it, too!) Umm... I have some concerns. I'm not much of a coder, but, 'easing' seems like it COULD be complicated. There's linear, and log, and ease-in and ease-out, etc. There could be lots of properties to give the user flexibility in 'easing types'. Is there potential for CPU slowdown while easings are finishing? Are the easings on forked threads? (Just being funny. I don't think we have forking in JS.) FollowCam is a great tool/idea, and I'd love to see it code-tight and feature-fleshed (whatever the hell THAT means). Now I'll ask something seriously uninformed. Can it be done without creating a new class called TargetCamera? Maybe it CAN be done that way, but it shouldn't? Again, pardon my lack of programming experience, especially when it comes to inheritence. All you JS Gods probably have all these things totally under control. I'm just trying to figure out if TargetCamera should be included in our cameras tutorial, or if it is a special tool used (only) for FollowCamera (and thus maybe NOT included in our tutorials). *shrug* FollowCamera is DEFINITELY going into our camera tutorial. It rocks! (Well, it probably only rocks when its target is a physics-active box that is bouncing around on a rubber-room floor.) I bet THAT would wear-out the gimbal bearings on the FollowCamera rather quickly. Quote Link to comment Share on other sites More sharing options...
AlexB Posted August 17, 2014 Author Share Posted August 17, 2014 Hey Alex... thanks for the new camera! (And thanks for showing us how to use it, too!) Umm... I have some concerns. I'm not much of a coder, but, 'easing' seems like it COULD be complicated. There's linear, and log, and ease-in and ease-out, etc. Is there potential for CPU slowdown while easings are finishing? Are the easings on forked threads? (Just being funny. I don't think we have forking in JS.) FollowCam is a great tool/idea, and I'd love to see it code-tight and feature-fleshed (whatever the hell THAT means). Now I'll ask something seriously uninformed. Can it be done without creating a new class called TargetCamera? Maybe it CAN be done that way, but it shouldn't? Again, pardon my lack of programming experience, especially when it comes to inheritence. All you JS Gods probably have all these things totally under control. I'm just trying to figure out if TargetCamera should be included in our cameras tutorial, or if its a special tool used (only) for FollowCamera. *shrug* I included many other dumb comments just because I was curious. Hi Wingnut, I'm 100% sure the code can be tightened up. I've been really busy and honestly rushed it out a bit. But to answer your questions: Easing can definitely slow things down. I'm doing some basic trig functions to calculate the x and z position of the camera, based on the angle of the object. If you know the angle/hypotenuse of a triangle, then the opposite and adjacent are easy to figure. The only thing I can think of to optimize this is to only do these calculations where the "goal" position is within a threshold of the actual position. Maybe store the previous vector and compare before doing further calculations? I just don't know if this will make it better or worse :-) So, why create the subclass? I'm using a lot of the code from the freeCamera, and Deltakosh correctly noticed that a lot of that code wasn't being used, which is a bad idea. So I guess we can do two things. a) we can write a new class that duplicates some code from freeCamera (bad idea since then we have the same code in two places, which means any bug fix happens twice or creates new bugs) or we make a subclass. I'm sure there are other approaches too, but I'm not comfortable enough with the code base to get too radical :-) Always open to suggestions! Also, I *think* TargetCamera should not be included in a tutorial, since it really is just a common library of code for both freeCamera and followCamera. I take it you don't have an entry on the basic camera? Quote Link to comment Share on other sites More sharing options...
Wingnut Posted August 17, 2014 Share Posted August 17, 2014 Wow, thanks Alex... good information. Correct, the basic camera isn't mentioned in the cameras tutorial. I won't plan on adding TargetCamera to the tutorial, but I am not the only tutorial editor or decision maker regarding such things. And you are certainly welcome to add things to the cameras tutorial yourself, too, at any time. Also, just because the FollowCamera goes into the tutorial, does not mean you/we can't add features and make changes, so please don't feel handcuffed or rushed by anything. It's very kind of you to be open to suggestions, and thanks again for ALL your good coding work and information... well done. I don't know if you follow the Tutorial Talk thread, but we have been learning about the FollowCam with the help of some playground scenes... starting around here in the thread. Most of MY talking there... happened before I discovered THIS thread... which answers many of my questions. I should learn to read more... before talking, eh? 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.