I have been converting a bunch of demos to the November CTP of WPF and I came upon an interesting problem. The LookAtPoint property of PerspectiveCamera was changed to LookDirection. So I happily renamed it, compiled and ran, but nothing appeared inside of the Viewport3D. I asked Tim Sneath if there was anything that might cause this. He pointed out that LookDirection is a Vector3D instead of a Point3D. My LookDirection was set to (0,0,0). This worked great for LookAtPoint because (0,0,0) is a valid 3D point to look at, but (0,0,0) doesn’t work for LookDirection.
When I asked Jordan Parker of the WPF team for an explanation of what was happening he explained that the definition of LookDirection is LookAtPoint – Position. You will end up with a zero length vector if LookAtPoint = Poisiton. A zero vector is not a viable direction. Ok so that explains why I don’t see anything, now how do I fix it?
This diagram shows how cameras worked with LookAtPoint and how they work with LookDirection. I have done this in 2D to make explanation easier. On the left I have two cameras marked with blue arrows. They both have a LookAtPoint set to (1,1) so regardless of what there position is they will look at the green dot. On the right I have two cameras marked with red arrows showing how things work with LookDirection. The red camera in the lower left at position (-2,-2) is pointing at the green dot because it’s LookDirection is set to (1,1), but the other red camera at position (2,2) is not facing the green dot because it too has a LookDirection set to (1,1). Note that the reason that the camera a position (2,2) can’t see the green dot is because of the direction it’s facing. To get the red camera at position (2,2) to look towards the green dot we would need to set the LookDirection to (-1,-1), which would cause the camera to face directly towards the green dot, because of the camera’s position. Something to note here is that a camera doesn’t actually look at a single point it looks at all the points in the direction it’s facing. Also the LookDirection is normalized so there is no difference between setting the LookDirection to (1,1) or (100,100), they would both result in the camera facing in the same direction.
In the demo I am porting the camera is looking at a box and rotating the camera around the box. I could just rotate the box. Instead I used Jordan’s definition of LookDirection and subtracted the position I wanted to look at from the camera position. This gives me the direction I should apply to LookDirection. If I wanted to look at (0,0,0) I would do something like the following every time I updated my camera position.
PerspectiveCamera pc = (PerspectiveCamera)this.Camera;
Point3D objectPosition = new Point3D(0,0,0);
pc.LookDirection = new Vector3D(objectPosition.X – pc.Position.X, objectPosition.Y – pc.Position.Y, objectPosition.Z – pc.Position.Z);