opengl ray tracing and mesh - c++

I was able to get a starter code for a ray tracer online and the starter code has two "Geometries":
class sphere
class triangle
I understand the triangle since the code creates a mesh using triangles and gets the intersection between triangles and ray from each pixel. But how does sphere come into play?
So I've done some online researching and a lot of them discuss about triangle intersection and sphere intersection. but how do we use sphere in mesh?

A mesh is a collection of triangles and to render that object using ray tracing, you have to solve lots of ray tracing equations with all the triangles. However, a sphere has a closed form implicit function for which solving the ray intersection is very easy. These two sample object are coming from the fact that we have two ways of representing objects in computer graphics, implicit objects for which we have a closed form implicit functions and polygonal mesh representation for which we have a collection of triangles. Usually, in ray tracing, we have objects such as sphere, cylinder, plane (triangle), and torus for which we have a closed form function and we can find their intersection with rays. For complicated objects like bunny, ray is casted and intersected with a collection of planes (triangles).

Related

Mesh and cone intersection algorithm

I am looking for an efficient algorithm for mesh (set of triangles) and cone (given by origin, direction and angle from that direction) intersection. More precisely I want to find intersection point which is closest to the cone's origin. For now all what I can think about is to intersect a mesh with several rays from the cone origin and get the closest point. (Of course some spatial structure will be constructed for mesh to reject unnecessary intersections)
Also I found the following algo with brief description:
"Cone to mesh intersection is computed on the GPU by drawing the cone geometry with the mesh and reading the minimum depth value marking the intersection point".
Unfortunately it's implementation isn't obvious for me.
So can anyone suggest something more efficient than I have or explain in more details how it can be done on GPU using OpenGL?
on GPU I would do it like this:
set view
to cones origin
directing outwards
covering the bigest circle slice
for infinite cone use max Z value of mesh vertexes in view coordinate system
clear buffers
draw mesh
but in fragment shader draw only pixels intersecting cone
|fragment.xyz-screen_middle|=tan(cone_ang/2)*fragment.z
read z-buffer
read fragments and from valid (filled) select the closest one to cones origin
[notes]
if your gfx engine can handle also output values from your fragment shader
then you can skip bullet 4 and do the min distance search inside bullet 3 instead of rendering ...
that will speed up the process considerably (need just single xyz vector)

Find the vertices on the outline of a 3d model

I have found a lot of materials on how to draw outline around a model with the help of a stencil buffer, like https://www.opengl.org/archives/resources/code/samples/mjktips/StenciledHaloEffect.html
However, this time I need to locate the vertices on the outline, to get their coordinates, but haven't found an elegant way to do so.
I once came across a method that can solve my problem for simple models like cube or sphere. It suggests to check the two triangles that share an edge, if the normals of the two triangles pointing in opposite directions with respect to the camera direction, than the edge they share is on the outline.
The above method works for simple models like sphere or cube, but not for complex models because it might also picked up those edges that inside the outline from the view of the camera.
In conclusion, my objective is to find the coordinates of the vertices on the outline, for example, vertices on the red line in the image which you can find at https://gamedev.stackexchange.com/questions/59361/opengl-get-the-outline-of-multiple-overlapping-objects.
BTW, I am doing this using Ogre.

calculating normals for quad mesh

I have a struct QUAD that stores 4 pointers to 4 VECTOR3D (which contains 3 floats) so that I can draw the quad mesh.
From what I understand is whenever I draw a mesh, I need normal as well to properly light/shade a mesh and it's relatively easy when it's a mesh laying on a plain, using normal per face.
When I have 2 by 2 quad meshes laying on XZ coordinate and tried to raise it's centre (0,0,0) by a certain point, say (0, 4, 0) it would start to form real 3D shapes, then I need to calculate normals again. I'm having hard time understanding how and what is to be to calculated normals. As expected, the 3D shape shades like it's still a flat mesh, so it does not represent real shape. One of the explanation says I need to calculate normals per vertex instead of per face.
Does it mean I need to calculate normals for all corners of mesh? once i have normals what would i do? I was still using old glBegin glEnd methods but now I feel like i need to use DrawArray method. I'm deeply confused and I'm pretty sure I don't make much sound but i'd much appreciate your help.
If you need flat looking surface then your normals will be normals to the quad plane. If you need "soft looking" surface you need to blend(read this and watch this cool simple video) normals - that will add sort of gradient.

Terrain collision with .X file

I have been looking for example of terrain collision that is in C++ but i haven't found anything. I found one example that uses .RAW file it is in toymaker.info so don't mention it.
How do you detect collision between object can terrain against every triangle. I know it will be slow. How you detect collision between terrain and .X file?
Here is one method:
Draw a line from the origin through the center of a sphere you wish to test collision of. Now do a ray triangle intersection using the line, or ray, you have just created. You now know if the ray has passed through the triangle or not. If it has passed through the triangle then get the point it intersected the triangle and do a simple distance check with the sphere's center. If the distance is greater than the radius of the sphere a collision has not occurred. If it less then the sphere is intersecting the triangle.
Its also worth checking which side of the triangle the sphere's center is on. This is a simple dot product between the triangle's face normal and the sphere's center. a value of 0 indicate the sphere's center lies in the triangle and a positive result indicates its on one side and negative, the other.
You can also perform this calculation for a range of times. So if you know you are simulating a second and you know the velocity the sphere is moving at, then you can calculate the point in that second that the sphere intersected the triangle. This is pretty simple to calculate. If at the start the sphere is 4 units from the triangle and after a second it is 1 unit through the triangle. So in 1 second it has travelled 5 unit. Therefore the intersection must have happened 0.8 seconds into the movement. This way you can react to collisions of particles even when they are travelling so fast they would otherwise pass straight through the item they are colliding with.
If your .X file means DirectX format file, use DirectX Library to load .X meshes. Collision methods are also provided like D3DXIntersect.
Additional information : http://msdn.microsoft.com/en-us/library/windows/desktop/bb172882(v=vs.85).aspx

How can I compute the picking ray with multiple model view matrixes?

I'd like to compute the intersection between a ray and the models the user sees on the screen of my app. I'm following the OpenGL guide but I have many models in the scene that I draw independently and dynamically in a push-pop context applying a translate to the current modelview matrix (ie for each model I do a
glPushMatrix,
glTranslatef,
draw the model,
glPopMatrix
).
Do I need to compute also different rays, one for each object (for testing later if it intersects with the model's bounding sphere)?
Maybe some concept about ray picking is not so clear to me yet. Any link, guide, etc will be very appreciated ^^
The picking ray has nothing to do with the model matrix. If the objects in your scene move (i.e. the model matrices change), the ray itself won't move.
Which method do you plan to use between those proposed in the link ? GL_SELECTION, rendering with a special color, home-made intersections ?
I'll edit this answer accordingly
EDIT : let's go for the home-made one then
First, you need to generate a ray. You usually want to express it in world space (i.e. "my ray starts at the same pos than my camera, and its dir is (xyz) ). You have two methods to do that, which are pretty well explained in the openGL Faq (One way to generate a pick ray... Another method...). Just copy 'n paste the code.
If the mouse is in the middle of the screen, you should have your ray pointing towards the same direction than your camera. You can check that with your arguments to gluLookAt.
Now, what you want to do is intersect your ray with your meshes' triangles, but you have a problem, because the triangles are not expressed in the same system than the ray.
So you have to express the ray in the triangle's system.
triangles system : the model system ; ray system : the world system. Fortunately, you have a matrix to go from model to world (the Model matrix, the one you set after your glPushMatrix). So inverse(ModelMatrix) is the matrix from world to matrix.
ray = Ray(cam_pos, dir);
foreach (mesh)
ModelMatrix = whatever you want
InverseModelMatrix = inverse(ModelMatrix)
rayInModelSpace = Ray(InverseModelMatrix x ray.pos, InverseModelMatrix x ray.dir)
Intersect(rayInModelSpace, mesh)
Your Intersect method could look like this :
foreach (triangle in mesh )
if ray.intersect(triangle) return true
triangle-ray intersection code can be found at geometrictools.com
This will be quite slow, but it will work. There are several ways to improve the preformance, but the easiest is to compute the AABB of each mesh, and first intersect the ray with the AABB. No intersection with the AABB => no intersection with the mesh
Code can be found on geometrictools too.
I'll be away for a few days, so good luck :)