Camera Issues

    This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

    • Camera Issues

      I am having a problem with my camera working for a little bit and then the sign of the pitch will flip and reverse the angle change (it actually becomes aligned with the z axis...that is if I am looking along the + Z the pitch is ok / - Z pitch is reversed...initially I can look anywhere is pitch is good). Has anyone experienced this? I checked my angle validation code(+ - 2pi) and it looks good, so I'm not sure why this would happen.

      I also noticed that there is a slight glitch right before it happens...I guess this would indicate some sort of data corruption?
    • It's hard to tell without some code, could you post some to take a look at?

      Without looking at it and not knowing how it is coded, is your value rolling over it's limit? ie. if it was int: +/- 2147483647
      PC - Custom Built
      CPU: 3rd Gen. Intel i7 3770 3.4Ghz
      GPU: ATI Radeon HD 7959 3GB
      RAM: 16GB

      Laptop - Alienware M17x
      CPU: 3rd Gen. Intel i7 - Ivy Bridge
      GPU: NVIDIA GeForce GTX 660M - 2GB GDDR5
      RAM: 8GB Dual Channel DDR3 @ 1600mhz

      The post was edited 1 time, last by mholley519 ().

    • RE: Camera Issues

      It sounds to me like you have something incorrect in your transformation matrix.

      First - a few troubleshooting questions:

      1. How do you go about calculating the transform matrix of the camera?

      2. Where is the camera positioned in your world, and does the odd behavior you mention depend on this position?

      3. When you are ready to render the screen, how to do calculate the world-view-projection matrix?

      Answer those questions and I'm sure we'll see the problem.
      Mr.Mike
      Author, Programmer, Brewer, Patriot
    • Background Info:
      - I have one vertex buffer at the moment which contains the terrain and sky vertices
      - The shader process is: apply world transform(identity matrix), apply view transform(calculated in camera function), apply projection transform(perspectiveLH matrix). Then do the texture mapping.
      - Global Accum Vars: pitch, yaw, roll radians and x,y,z position
      - New values are set in winProc (raw input) and stored globally
      - Camera is at the origin looking down the z axis to start

      Calculating the View Matrix (pitch, yaw, roll, w, s, a, d)
      - Apply scalar to PYR and add to accum PYR vars
      - Create XMMatrixRotationYPR from accum PYR
      - Use new yaw to correct XZ position change
      - Accum XYZ positions
      - Create Translation from accum vars
      - Use MatrixMultiply(T,R) and store in global view matrix

      Then I launch a thread for rendering if its time to render. I have my render set for 30fps and the input is updated 20fps

      The way that I am trying to do this is to move the env (sky_terrain data) to the origin based on the translation matrix where the camera is (pointed down the z axis) and then rotate the env to the direction I should be looking based on the rotation matrix. The odd behavior starts as soon as I look away from the z axis. If I look 90d right, pitch becomes roll and so on.
    • Ok I think I see a potential source of the problem.

      In most games, the camera is initialized with PYR, but it typically isn't retained as the source from which a world transform matrix is calculated.

      Instead, a world transform is, well, transformed by other orientation and position movements...such as:

      1. W is pressed, signifying a desire to move the camera forward.
      2. Camera forward vector (a unit vector) is grabbed directly from the camera's world transform matrix.
      3. The desired movement delta along the camera forward vector is added to the current camera transform matrix.

      You could of course make your solution work - but it is probably having trouble at a 90 degree rotation because of gimbal lock - although it typically happens about the "up" axis of games, your system might be set up differently, causing the lock about the "Right" axis. It could also be something as simple as one of your orientations "wrapping" or "reflecting" around zero, but I'd have to see a video of the problem to be sure....

      This could be caused by a lot of things - such as how you've defined your 3D axes (typically X is right, Y is up, and Z is forward) - if you've defined them otherwise you might have problems with stock rotation transformations.

      These problems can be maddening to solve, because they could have worked themselves throughout your code, as you adjusted things here and there to make things look right in a particular case, but were actually just patching over a deeper seated problem elsewhere. Rez and I were fighting this at the end of GCC4's code production - our teapots weren't targeting each other properly and were rotating in opposite directions to what we expected. To fix the problem I had to tweak code in 3-4 different places!

      I wish I had better news for you and an easy solution. Here's what I'd do:
      1. Start with a very simple case, just an immobile camera at the origin and a single object, , like your terrain grid, or even a single polygon, and make sure that it can move and rotate on each axis properly (especially check the direction of rotation!!!! Think of the Unit circle and you'll get it). Fix any bugs that you find with your basic transformations.
      2. Then, open up the ability for your camera to translate, using transform matrix concatenation instead of sourcing it from YPR+position. Check in all three axes.
      3. Then, check camera rotations in exactly the same way. All three axes, all the way around the circle.

      Breaking this problem down into simple measurable components should really help.

      Sorry I didn't have a silver bullet for you.


      2.
      Mr.Mike
      Author, Programmer, Brewer, Patriot
    • Thanks for the tips. I got the camera to work by creating a rotation matrix doing the rotations in YPR order, rather than RPY. The way I have it now there is no gimbal lock problem, at least it hasn't surfaced yet.

      I am also having studdering problems with the movements when a key is pressed. There isn't a smooth transition, and diagonal movement is only possible when the two keys are pressed at the same time. Is this a Raw Input problem? When I print the keypresses out to a file everything looks fine.
    • The camera jitter problem usually happens as a result of something going wrong in your main game loop or input processing, most typically in the following spots:
      1. Rendering more than once per game loop with two different camera positions.
      2. Reading input more than once, with sightly different outcomes causing a jumpy camera.
      3. Processing input or updating the camera position in a manner that looses precision, causing discontinuous movement.

      You might just need a filter between your input processor and the camera update. Teapot Wars does this naturally by using input as a way to alter the forces acting on the teapot, with the physics system smoothly moving the teapots around.

      In the GCC4 editor code, there's a great example on how to just move a camera around with a mouse and keyboard. Take a look at the MovementController class in GCC4\Graphics3D\MovementController.cpp, especially the OnUpdate() method.
      Mr.Mike
      Author, Programmer, Brewer, Patriot
    • I have my render thread controlled with a flag so only one thread can run at a time. I also tried experimenting with double/float to cut back on drift and that helped a little.

      I went back to my RawInput test program, which uses GetRawInputData, and noticed that it only picks up one keyboard event at a time. Could this be the problem?

      Should I be using GetRawInputBuffer instead? I am using the previous method because the buffer version always return zero buffer size and zero elements for some reason. Does the buffered version grab the states of every key on the keyboard at once?
    • TeapotWars uses WM_KEYDOWN and WM_KEYUP messages as the source of a typical WASD controller, and they will work with any number of keys pressed simultaneously. Also, they are trivial to use.

      Also - your base unit might not be small enough, perhaps? The jitter problem might be a lack of precision in your final position calculation or in your position delta calculation.

      I tend to use 1.0 game units = 1 meter. It's a good compromise between precision on the tiny side and range of movement on the "how big can my levels get" side.
      Mr.Mike
      Author, Programmer, Brewer, Patriot
    • I tried capturing WM_KEYUP/DOWN, and if I hold down WSAD at the same time only one or two will actually show up as being pressed. Inidividual keys work fine though.

      The GetKeyboardState seems to work, I just need to figure out which indexes I need to check.

      Is there an advantage to using GetKeyboardState rather than GetAsyncKeyState? Are there any speed issues using these?

      Thanks for the tips.

      The post was edited 6 times, last by Roster ().

    • I modified my app to catch WM_KEYUP/DOWN and then use GetAsyncKeyStates for WSAD keys. This will capture upto 3 simultaneous key presses. If I press all four only three will show up. I am also still having the gittering problem. It looks to me like the frames are freezing for a sec and then rresuming. It also has problems when changing the WSAD kays a lot. Sometimes it will just drop a key and not pick it back up until it is released and pressed again.

      I also tried printing out the time it takes to render each frame and there are a few frames that take substantially longer to render. The vast majority of the frames take 15ms to render and then every 20-30 frames there will be a one or two frames that take around 300ms surrounded by a few 30ms frames.

      The post was edited 2 times, last by Roster ().

    • Ya know, I've had cheap keyboards that wouldn't register more than a couple of key presses. I wonder if that's what's happening here....

      Anyway, in terms of speed, things have changed so much in the last several years that I honestly don't know anymore. I would set up a test and profile it. There used to be speed issues with GetAsyncKeyState() WM_KEYDOWN when compared to DirectInput, but now that DirectInput is officially deprecated, I'm guessing performance isn't as big of an issue anymore.

      As for long frames, you'll have to do some profiling to figure out what's happening. Spikes like that are fairly common in games during development and are a pain to nail down. Trust me, we had a lot in the AI systems of The Sims Medieval before we ran through and fixed them.

      -Rez
    • camera movement:

      I am also using '1' as my WSAD movements, but that is converted to the scale of my world, which is [-1,1] for all axes. I am uing 2.5ft as a step forward which converts to something like .0013 world units. Of course I am also converting the deltas again based on the yaw direction, and then to top it off I am using double for those calculations which is converted to float for D3D.

      spikes:

      I used PIX to check where the time spike is occuring and it looks like its a problem with D3D. I used the start times and durations to calculate the time spent in the APP and it seems that the between draws time is always 2395ns, which seems a little strange. I wouldn't expect there to be such a consistent time occurance. Is there a way to check where the time is spent during each render?

      The post was edited 2 times, last by Roster ().

    • 0.0013 seems small to me. Maybe you're running into float precision issues? Try cranking this up to a larger value, like 0.13. Your character will move much faster than intended, but it may remove the stuttering. Unless of course the stutter is happening once every second or so, in which case the framerate spike is the likely culprit.

      Without an in-depth analysis of your render code, I'd only be guessing as to what could cause the spike. It sounds like you took the difference in the timings PIX gave you and the total app time, which implies that you have the D3D timings. Where was it spending its time?

      -Rez
    • A typical scale would set the world as 1.0 = 1 meter, so that would mean 2.5 ft = 0.762 meters, which plays nicely with most game simulations in the human being scale. Your scale is really big, which will lead to the jitter problems you are experiencing...
      Mr.Mike
      Author, Programmer, Brewer, Patriot
    • Ok, what I am trying to do is make all my object based on a standard of [-1,1] and then just scale everything up or down. The problem is that I was trying to use the objects (sky / terrain) as is. Instead of applying a scalar to them with the world matrix I just scaled the movements. I was only going to do this until I have a stable graphics engine to do testing on for all the other d3d stuff.

      I applied a scalar and switched to using movements of +-1 and it is smoother but there is still a problem with discontinuous movement. The issues is when I change direction, such as holding down the forward key and then pressing the strafe right key. When I do this there will be a pause, or movement will stop entirely.

      The input configurations that I have tried are (the vars that they are updating are independent of the calc also):

      WM_KEYUP/DOWN with a switch case for each key

      RawInput with a switch case for each key

      RawInput for Mouse + WM_KEYUP/DOWN for keyboard:

      the the WM is used to pickup the key press and then if WSAD int vars are == 0 or != 0 it goes through if statements that uses GetAsync to get and set the vars. This way no matter what key was pressed it checks the keys that might need to be updated.

      There are no problems at all with the mouse input and camera direction changes.

      I also tried putting timers in each function and the msg loop & setviewmatrix = 0ms, render = 0-16ms, but when I use the timer for an entire game loop every 20 or so frames there is a loop around 200ms.

      The post was edited 5 times, last by Roster ().