Darkbouncer4689 114 Report post Posted July 25, 2011 Hey all, I've implemented a 3rd person camera by following the tutorial located here [url="http://msdn.microsoft.com/en-us/library/bb203909(v=xnagamestudio.20).aspx#Y208"]http://msdn.microsoft.com/en-us/library/bb203909(v=xnagamestudio.20).aspx#Y208[/url] The camera works fine but when I try to allow the user to adjust the camera position I'm running into some problems. First I have an offset vector (x, y, z) Then I create a yRotation matrix based on my avatars modelMatrix I multiply the offset vector and rotation matrix. I calculate the cameras position as the transformed camera offset vector plus the avatars position. Then construct a new view matrix using a lookAt function. So if I have an offset vector of (0, 50, -50) I get a camera that is behind and above the player by 45 degrees, looking like a traditional 3rd person camera. However, I would like to have a fully adjustable camera (such as the WoW camera, which orbits around the player and also allows rotation along the x axis). I believe that I can achieve this by changing my values of the offset vector. For example, incrementing the x value of the offset vector does start to move my camera around the player in an "orbiting" fashion, however the larger the x value gets the more the camera starts to move further away from the player (and can never exceed a 90 degree rotation). I believe that changing the x and z values at the same time could give me the "orbiting" camera I am trying to achieve. For example [0, 50, 50] puts my camera in front of the player (instead of behind as before). The problem is that I have no idea what type of mathematical relation the x and z values should have in order to be able to give me camera a full 360 degree rotation around the player. Any help is greatly appreciated! 0 Share this post Link to post Share on other sites
Darkbouncer4689 114 Report post Posted July 25, 2011 With some additional thought the fact that the avatars world position is the lookat point for the lookat function means that as x increases in the offset vector it would make sense that camera moves further out from the avatar. [0, 0, 50] gives me a camera in front (north) of and facing the avatar [0, 0, 50] gives me a camera behind (south) and facing the avatar [50, 0, 0] gives me a camera on the left side (west) and facing the avatar [-50, 0, 0] gives me a camera on the right side (east) and facing the avatar So now the problem is down to how can I smoothly interpolate these values to implement a full 360 degree rotation around the avatar? The unit sphere comes to mind, I think this problem may be solvable with the correct use of sin and cos on the x and z values. Thanks! 0 Share this post Link to post Share on other sites
haegarr 7372 Report post Posted July 25, 2011 Orbiting means that the location of the camera is sticking to the surface of a sphere. If you look at the [url="http://en.wikipedia.org/wiki/Spherical_coordinate_system#Coordinate_system_conversions"]spherical co-ordinate system[/url] and keep a constant radius, and further enforces the camera to always look at the sphere's center, then you have orbiting. Mathematically the relation is that of the lengths of the legs of a rectangular triangle with the condition of a constant length hypothenuse. Perhaps the easiest approach is to rotate the camera by its heading and pitching (which are under user control), to position it then onto the look-at target point, and to translate it along its negated forward vector (i.e. moving it backwards) by the "viewing distance". The resulting matrix is complete w.r.t. user control, avatar attachment, and look-at. 2 Share this post Link to post Share on other sites
Darkbouncer4689 114 Report post Posted July 25, 2011 Thanks haegarr. I'm going to try that right now =) 0 Share this post Link to post Share on other sites
Darkbouncer4689 114 Report post Posted July 25, 2011 I have managed to get an orbiting camera by using my offset vector (xPos, yPos, zPos) and the following relations xPos = Math.sin(degToRad(cameraYaw)) * (distance); yPos = Math.sin(degToRad(cameraPitch)) * (distance); zPos = (Math.cos(degToRad(cameraYaw))) * (Math.cos(degToRad(cameraPitch))) * (distance); where distance is the zoom factor. I then let the user change the cameraYaw and cameraPitch values and I get an orbiting camera. However there is one slight problem. When the camera is positioned at the 4 key points of a unit sphere (north, south, east, west) the rotation gets really qwerky and hard to work with. Any suggestions on how to smooth it out? Thanks! 0 Share this post Link to post Share on other sites
haegarr 7372 Report post Posted July 25, 2011 [quote name='Darkbouncer4689' timestamp='1311586449' post='4839916'] xPos = Math.sin(degToRad(cameraYaw)) * (distance); yPos = Math.sin(degToRad(cameraPitch)) * (distance); zPos = (Math.cos(degToRad(cameraYaw))) * (Math.cos(degToRad(cameraPitch))) * (distance); [/quote] These formulas cannot be correct. If y denotes the up direction, then a [i]structure[/i] more like [code] xPos = distance * Math.sin(degToRad(cameraPitch)) * Math.sin(degToRad(cameraYaw)) yPos = distance * Math.cos(degToRad(cameraPitch)) zPos = distance * Math.sin(degToRad(cameraPitch)) * Math.cos(degToRad(cameraYaw)) [/code] should be correct. However, the details depend on whether x or z denotes the forward direction, and where zero angles point to. (Those aspects may introduce angle offsets that allow to switch sine and cosine and signs, therefore I wrote "the structure" should be ...). As mentioned in my previous post, it may be easier to concatenate rotation matrices. It may be at least a way to determine the correct formulas. 1 Share this post Link to post Share on other sites
Darkbouncer4689 114 Report post Posted July 25, 2011 Thanks again haegarr. I'll keep working on it! 0 Share this post Link to post Share on other sites