Quaternion Camera Representation in 6DOF - fending off inherent rolling - camera

first question on SO although I've been here many times through Google. I have read quite a lot on the topic of using quaternions to represent rotation as well as finding people who have similar problems. I have yet to find a good solution, or one that I could understand.. so I'm giving a shot at asking a clear enough question to generate solid answers.
I am currently using a quaternion (specifically, a Qt 4.7 quaternion/C++) to represent the orientation of my camera. At each step of the program I check for mouse movement and do a fromAxisAndAngle(xaxis, x_mouse_movement) and fromAxisAndAngle(yaxis, y_mouse_movement). I take these two quaternions and multiply them (yaxis * xaxis). For the initialization I have a unit quaternion (w,x,y,z -> 1,0,0,0) to multiply with. I keep accumulating the rotation over these fromAxisAndAngle multiplications with the current orientation. This produces a roll, known as the Lie Group Problem (I think) that if you apply pitch and yaw continuously you can generate a pure roll, and this is what I have in my current implementation (which is correct for my procedure as far as I can tell).
I have implemented another method where pitch,yaw,roll are incremented and the quaternion is built fromAxisAndAngle from scratch each time from these values. This produces a correct FPS style camera, but it suffers from gimbal lock. My goal is to keep the pure quaternion representation, while eliminating (or compensating for) the rolling effect produced from only pitches and yaws so I can use this general 6DOF camera as an FPS camera or a space ship style camera. I'm looking for suggestions (specific routines) for correcting this roll, or an alternative representation that can fit my needs. Sorry for the wall of text, but I wanted to be very clear. Thanks for your time and happy hacking!

It's not completely clear what you're trying to accomplish. Consider:
Begin in the canonical orientation (+x is right, +y is up, -z is forward)
Pitch down by 90°. (-z is up, -y is forward)
Yaw right by 90°. (+y is right, +x is forward)
Pitch up 90°. (-x is up, -z is forward)
You are now facing the canonical forward again, but rolled 90° to the left.
What do you want to happen instead? This is normal behavior if you always define pitch and yaw to be with respect to the camera/body frame of reference. If, instead, you want 'yaw' to always rotate around the world's y-axis and 'pitch' to always rotate around the camera/body's x-axis (so that the camera's x-axis is always parallel to the ground plane), then, if you were pitched down by 90°, the yaw movement would visually appear to be roll (you're looking down and turning in a circle). A quaternion that maintains that property will always have a 'z' component of zero. You could simply enforce that constraint on your quaternion (being sure to always re-normalize).
However, your method of simply keeping track of pitch and yaw separately should work fine for that case. Gimbal lock isn't a problem if you're only using two axes in the first place. You just need to be sure that you apply the pitch and then the yaw.

Related

How to apply depth test to diffuse lighting?

I've been fiddling my way through vulkan, and have tried out some basic diffuse lighting, which only takes into account the surface normals. On the side of the model facing the light, things look fine -
On the opposite side of the model though, there's a part of the model which is shaded like it is illuminated even though it shouldn't be-
I know this happens because I'm only considering the surface normals and the shader doesn't care where the vertex is as long as its normal is towards the light, but how do I fix it? I feel like I need a way to do a depth test to figure out whether a part of the model should be lighted or not. How would I go about doing this if that is the case? What should I be doing if otherwise?
Sounds like you want to implement shadows.
A standard way is shadow mapping. You render the scene from the point of the light and only keep the depth buffer. You then pass that depth buffer as a texture to the fragment shader and sample that based on where the point is in the world and compare the sampled depth with the distance to the light.
However there are various caveats with this technique. Most common ones being shadow acne where quantization error leads to fragments self shadowing resulting in speckled lighting, you can fix that by adding a small offset to the depth. The next one is peter panning, where that offset you added previously leads to light bleedthrough where a thin wall meets a floor, you fix that by not having walls thin enough that the offset goes through them.

setup requirement of stereo camera

In the stereo camera system, two cameras are needed and should be mounted side by side. I see someone just glues two cameras to a wooden board. However One mobile phone manufacture claimed that the two lens of dual camera modules on their phone are parallel within 0.3 degree. Why do two lens on mobile phones need such high precise assembly? Does this will bring any benefit?
I have not worked on stereo setup, but would like to answer from what I have studied during my course. Camera setup which are not parallel are usually called converged/toe-in setup.
Stereo camera setup which are parallel does provide some advantages over toe-in setup. But the advantage is not absolute and dependent on what is required.
In toe-in setup there is a problem of keystoning. Keystoning is when two images(Left and Right) are kept side by side, the images are aligned at the meeting point but they tilt as you go further towards the edge. This leads to depth plane curvature and it shows as though farther objects are curved. This can be corrected in post processing and its called keystone correction. There is no keystone problem in parallel setup. Below image shows image distortion towards edges. If your requirement is not to have keystone effect, then it is an advantage ;)
In parallel setup you can decide the image convergence in post processing by slightly shifting the images horizontally(Horizontal image translation HIT). In toe-in you need to decide the convergence area during the shoot. Convergence is the region of the image which is same in both Left and Right. As you can imagine, in parallel setup, there is no convergence and you get stereo effect for the whole image. This is good right ? Depends. Because, in stereo, we have zero place, near plane and far place. Zero plane is when the image is perceived as to be formed on the screen(screen on which image is projected in the theatre).Near field is near the viewer(imagine popping out of the screen towards the viewer). Far field is farther from the viewer. Therefore, since there is no convergence in parallel setup the whole screen has stereo effect(that is near or far field, see figure below) and convergence is at infinity. Now imagine sky which is very deep in real, i.e the sky which is at infinity. But since in parallel setup sky converges as it is at infinity and appears to be formed on the screen. But a person who is near to the viewer seems to be floating in stereo space, which messes up the brain. Therefore usually people prefer slight convergence angle to avoid this or use HIT such that the convergence point appears on the zero field. Hope this helps :) I will try to rephrase this tomorrow as I wrote this in one go.

How to avoid Gimbal lock when converting from Quaternion to Roll Pitch Yaw

I have a IMU sensor that gives me orientation in terms of Quaternion and I would like to change it to readable RPY angles.
I found the formula to convert them intrinsically from Wiki
for a quaternion q= qr+qi+qj+qk
roll=atan2(2(qr*qi+qj*qk),1-2(qi^2+qj^2))
pitch=arcsin(2(qr*qj-qk*qi))
yaw=atan2(2(qr*qk+qi*qj),1-2(qj^2+qk^2))
I understand there can be gimbal lock problem when representing in RPY. How could I avoid this when pitch approaches +/- 90 degrees
P.S. I am coding in LabVIEW
Nekomatic is right, the gimbal lock is a fundemental problem with Euler angles. Either stick with Quaternions (which I would advise), a free downloadable LabView library can be found here: https://www.winemantech.com/blog/quaternions-for-rotations-in-native-labview, the labview robotics toolbox also supports quaternions but is paid.
Otherwise keep track of when you approach a singularity (gimbal lock). In the singularity angles may flip instantaneously from 90 to -90 degrees, since in the real world you know this cannot happen you can code around it. Examples how to do this can be found here: http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/

How is ray coherence used to improve raytracing speed while still looking realistic?

I'm considering exploiting ray coherence in my software per-pixel realtime raycaster.
AFAICT, using a uniform grid, if I assign ray coherence to patches of say 4x4 pixels (where at present I have one raycast per pixel), given 16 parallel rays with different start (and end) point, how does this work out to a coherent scene? What I foresee is:
There is a distance within which the ray march would be exactly the same for adjacent/similar rays. Within that distance, I am saving on processing. (How do I know what that distance is?)
I will end up with a slightly to seriously incorrect image, due to the fact that some rays didn't diverge at the right times.
Given that my rays are cast from a single point rather than a plane, I guess I will need some sort of splitting function according to distance traversed, such that the set of all rays forms a tree as it move outward. My concern here is that finer detail will be lost when closer to the viewer.
I guess I'm just not grasping how this is meant to be used.
If done correctly, ray coherence shouldn't affect the final image. Because the rays are very close together, there's a good change that they'll all take similar paths when traversing the acceleration structure (kd-tree, aabb tree, etc). You have to go down each branch that any of the rays could hit, but hopefully this doesn't increase the number of branches much, and it saves on memory access.
The other advantage is that you can use SIMD (e.g. SSE) to accelerate some of your tests, both in the acceleration structure and against the triangles.

Detect Collision point between a mesh and a sphere?

I am writing a physics simulation using Ogre and MOC.
I have a sphere that I shoot from the camera's position and it travels in the direction the camera is facing by using the camera's forward vector.
I would like to know how I can detect the point of collision between my sphere and another mesh.
How would I be able to check for a collision point between the two meshes using MOC or OGRE?
Update: Should have mentioned this earlier. I am unable to use a 3rd party physics library as we I need to develop this myself (uni project).
The accepted solution here flat out doesn't work. It will only even sort of work if the mesh density is generally high enough that no two points on the mesh are farther apart than the diameter of your collision sphere. Imagine a tiny sphere launched at short range on a random vector at a huuuge cube mesh. The cube mesh only has 8 verts. What are the odds that the cube is actually going to hit one of those 8 verts?
This really needs to be done with per-polygon collision. You need to be able to check intersection of polygon and a sphere (and additionally a cylinder if you want to avoid tunneling like reinier mentioned). There are quite a few resources for this online and in book form, but http://www.realtimerendering.com/intersections.html might be a useful starting point.
The comments about optimization are good. Early out opportunities (perhaps a quick check against a bounding sphere or an axis aligned bounding volume for the mesh) are essential. Even once you've determined that you're inside a bounding volume, it would probably be a good idea to be able to weed out unlikely polygons (too far away, facing the wrong direction, etc.) from the list of potential candidates.
I think the best would be to use a specialized physics library.
That said. If I think about this problem, I would suspect that it's not that hard:
The sphere has a midpoint and a radius. For every point in the mesh do the following:
check if the point lies inside the sphere.
if it does check if it is closer to the center than the previously found point(if any)
if it does... store this point as the collision point
Of course, this routine will be fairly slow.
A few things to speed it up:
for a first trivial reject, first see if the bounding sphere of the mesh collides
don't calc the squareroots when checking distances... use the squared lengths instead.(much faster)
Instead of comparing every point of the mesh, use a dimensional space division algorithm (quadtree / BSP)for the mesh to quickly rule out groups of points
Ah... and this routine only works if the sphere doesn't travel too fast (relative to the mesh). If it would travel very fast, and you sample it X times per second, chances are the sphere would have flown right through the mesh without every colliding. To overcome this, you must use 'swept volumes' which basically makes your sphere into a tube. Making the math exponentially complicated.