Determine if 3d coordinate is inside frustum - c++

I am trying to implement an overlay for a particular screen saver that I inject my application into.
This screen saver uses 3d objects and a dynamic camera.
I have camera position and direction and the 3d object positions, and the fov value, and I'd like to create an audio based overlay that adds icons to the objects.
I have the 2d overlay in place, and can successfully iterate the objects, however I can't figure how to calculate a frustum with the data I have.
Basically: how can one create a frustrum from the camera direction? Is a world to screen matrix required to create the frustum? I don't have the w2s matrix, so would that make the problem impossible to solve?

There is an excellent resource at http://web.archive.org/web/20120531231005/http://crazyjoke.free.fr/doc/3D/plane%20extraction.pdf which should explain everything you need and outlines how to extract the view frustum using the view and model matrices.
In regards to the world to screen (W2S) matrix you can calculate it on the fly by utilising a variant of the following:
ScreenPosition = (ProjectionMatrix* (ViewMatrix * WorldPosition))
Thast way you can calculate it on the fly as required.
There is also a frustum tutorial at Lighthouse aimed at frustum culling, but explaining the implementation quite nicely.

Related

I want to scale a 3D object so that it always appeats to be the same size, no matter how far from the camera

I have the world, view, and projection matrices. I have an object that is part of the UI and should be the same size no matter how far from the camera it is. I'm using this to create a gizmo similar to the "move" gizmos you see in 3D modelling program.
How can I extract a proper scale to do this from world/view/projection (or from the view frustrum if preferred, I have the six planes).
Bonus question: Using these same matrices, is there a decent way to figure out how much I'd need to move a 3D vector to make it move ONE PIXEL visually?

Drawing a 3d object on a 2D screen plane without angle of view

I have a problem, I need to draw a 3D object in such a way that I can move it along the screen plane and rotate so that the angle of view is as if I always looked at it fixedly from one point.
I use the GLM library for working with matrices. I tried to use glm::ortho, but I can not operate with the z coordinate, respectively, the model does not rotate. if i use glm::perspective, then the model looks like i need only in the center of the screen. I mean, for example, the character model is depicted in the window of a game. How would you not move the window at any point on the screen, you look at the model directly, and not as if looking out of the corner.
I apologize, I do not know how to explain it in normal language, I hope it is understandable.

What are good reasons to enable 2D projection with cocos2d-iphone?

In cocos2d-iphone the default projection type is "3D" projection. But you can also set the projection to "2D" like so:
[[CCDirector sharedDirector] setProjection:CCDirectorProjection2D];
Behind the scenes the 3D projection uses perspective projection whereas 2D projection is the OpenGL orthographic projection. The technical details about these two projection modes can be reviewed here, that's not what I'm interested in.
What are the benefits and drawbacks of 2D projection for cocos2d users? What are good reasons to switch to 2D projection?
Personally I've used 2D projection to be able to use depth buffering for isometric tilemaps. Isometric tilemaps require this for correct z ordering of tiles and objects on the tilemap.
I've also used 2D projection with depth buffering in non-tilemap projects to get complete z order control via the vertexZ property. This project used a pseudo isometric display where the vertexZ of an object is based on its Y coordinate.
That means I've been using 2D projection only to be able to use the vertexZ property, which also requires enabling depth buffering. Are there any other reasons one might want to switch to 2D projection?
Switching to 2D projection is a life saver in the following scenario:
You create a big CCRenderTexture
You draw a bunch of stuff on it, either using [... visit] or OpenGL drawing functions
You add the render texture to your layer, e.g., in order for the things you drew in point 2. to serve as the background for your game.
With 3D projection, the texture will be rendered with vertical and/or horizontal fault lines. See e.g., http://www.cocos2d-x.org/boards/6/topics/16197 which is for cocos2d-x but I have observed the same effect also for cocos2d-iphone and setting the projection to 2D got rid of the problem.
I have switched to 2D projection as the only means to resolve font rendering issues with CClabels, both font file and TTF-based labels. This is not always the cause of a font issue, but it has resolved some problems for me when all else failed.

Here is a Volume Render result, how to interact with other 3D object

I've implemented the volume render using ray-casting in CUDA. Now I need to add other 3D objects (like 3D terrain in my case) in the scene and then make it interact with the volume-render result. For example, when I move the volume-render result overlapping the terrain, I wish to modulate the volume render result such as clipping the overlapping part in the volume render result.
However, the volume render result comes from a ray accumulating color, so it is a 2D picture with no depth. So how to implement the interaction makes me very confuse. Somebody can give me a hint?
First you render your 3D rasterized objects. Then you take the depth buffer and use it as an additional data source in the volume raycaster as additional constraint on the integration limits.
Actually, I think the result of ray-casting is a 2D image, it cannot interact with other 3D objects as the usual way. So my solution is to take the ray-casting 2D image as a texture and blend it in the 3D scene. If I can control the view position and direction, we can map the ray-casting result in the exact place in the 3D scene. I'm still trying to implement this solution, but I think this idea is all right!

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 :)