I do have troubles understanding the rendering of a voxel object - c++

Lets say I have an array[3][3][3]. This array is filled with 0s and 1s, where 1 means draw and 0 - ignore. For the sake of simplicity lets assume I want to draw a cube (3 * 3 * 3). My understanding:
loop through the array using 3 nested for loops. (I do understand that is the worst way of implementing it and it has complexity O(n^3). However, I want to understand stupidest way of implementing it and then move to more complex algorithms).
check if an element of array is one.
create 36 vertices (vec3) 6 per each face of a cube and then assign x, y, z coordinates. (Again I do understand I do not need to create all vectices and show all faces of voxels. As doing so is just a waste of memory).
My problem is in step 3. I do not understand how to assign position to vertices of a voxel. For cube it is simple and I have seen people doing it manually but I need an algorithm that will work also for more complex objects which may contain thousands of voxels.

Related

Choosing an appropriate data structure for point-intersection detecting

I have some kind of shapes (rectangles, triangles, circles, etc.) that are given by points in space (coordinates). For example, for a rectangle - [0,0] and [5,5] - opposite corners.
There will be a lot of such shapes. My task is to find all shapes that contain a given point in themselves or on their edges.
Coordinates are always integers.
The total size of the coordinate plane can reach more than 2,000,000 x 2,000,000 points.
I'm trying to choose an appropriate data structure for this task. I was thinking about the Point Quadtree, and adding each point of the given shape to the tree. However, after thinking a little, I realized that if the maximum size of the shape is given, then I will end up with more than 2,000,000 x 2,000,000 nodes, which will be equivalent to a two-dimensional array with a size of 2,000,000 x 2,000,000. And that's exactly what I'm trying to avoid.
Which data structure would suit me best?

What is the best way for rendering a huge voxel object?

I am trying to display 3d model of a human in opengl. The human object is represented by a 3D array[n][n][n] (height, width and depth), where n = 300. Each element of array has value either 1 or 0. If element is 0 then it should be ignored else drawn.
Problem: due to the fact that I have to iterate through 3D array using 3 nested for loops and then create vertices for each individual voxel it takes a lot of time.
My idea of how to solve the problem: write another program that would iterate through array, create vertices and write them to the file. And then whenever I need to render I would read vertices from the file.
Question: What is the best way to render such an object? Would be great if you could suggest any algorithm or technic.
Many years ago I made a school project where I did something similar.
I had a 3D volume representation with 0s and 1s which represents a room. 0 means the cube is empty, 1 means the cube is full. It's the same problem you are facing but flipping the normal of the quads.
So I made an algorithm that turns the cube of bits into the minimum number of quads.
I've been digging in my old code repository and found the function that does that. I feel a bit ashamed of the code I wrote back then, but hopefully you can grab some inspiration from it.
I'm going to try to give a brief explanation of what the algorithm does.
We slice the volume with planes in each direction X, Y and Z.
For each plane we check all the cells it touches on each side.
If both sides have the same number (both 0, or both 1), we do nothing.
Otherwise (we have a different number on each side), we generate a quad in that position, and the normal of that quad will depend on the order of the numbers (01 or 10).
Ignore the colorCount variable, I think it's just a color ID I used for debugging.
My program called this algorithm when it first loads, and whenever you make a change in the scene (it was a live-editor). I didn't notice any slowdowns when editing the scene and the computer I was using back then was not very fast.

c++, Generate diamond or triangular holes in uniform distribution in a 2D space

How to generate particles in 2D space using uniform random distribution such that there are triangular or diamond shaped holes within?
Acceptance/Rejection - define your cutout areas, generate points uniformly over the 2-d space, and if the result lands in a cutout reject it and try again. Probability of acceptance will be p(accept) = 1 - Area(cutouts) / Area(2-d_generating_space), and the expected number of attempts to generate will be the inverse of that. For example, if the holes make up 80% of your space then p(accept) = 0.2 for a given trial and on average it will take 5 attempts to get an acceptable point.
I would start off with the triangle case, since the diamond case is really the same as having two triangles.
Here is another explanation of pjs' algorithm:
Define your 2-d space in terms of x-min, x-max, y-min, y-max.
Define your a set of triangles you are cutting from in terms of triangle1[point1, point2, point3] ... triangle_n[point1, point2, point3].
Pick how many points you want to generate, call this numberOfPoints.
Iterate over the numberOfPoints.
Pick a random value within your x-range (from x-min to x-max)
Pick a random value within your y-range (from y-min to y-max).
This is your x,y position for your new random point.
Check to see if this fits within any of your cutting triangles (you will have another loop here) and can use this, or another containment test.
If it is within one of the cutting triangles, throw it away and do not increment your counter. Otherwise, you have successfully added a point.
There are ways to do this more efficiently, than checking every single point against every single cutting triangle. This is an OK first approach for not too many triangles.

3D Math - Only keeping positions within a certain amount of yards

I'm trying to determine from a large set of positions how to narrow my list down significantly.
Right now I have around 3000 positions (x, y, z) and I want to basically keep the positions that are furthest apart from each other (I don't need to keep 100 positions that are all within a 2 yard radius from each other).
Besides doing a brute force method and literally doing 3000^2 comparisons, does anyone have any ideas how I can narrow this list down further?
I'm a bit confused on how I should approach this from a math perspective.
Well, I can't remember the name for this algorithm, but I'll tell you a fun technique for handling this. I'll assume that there is a semi-random scattering of points in a 3D environment.
Simple Version: Divide and Conquer
Divide your space into a 3D grid of cubes. Each cube will be X yards on each side.
Declare a multi-dimensional array [x,y,z] such that you have an element for each cube in your grid.
Every element of the array should either be a vertex or reference to a vertex (x,y,z) structure, and each should default to NULL
Iterate through each vertex in your dataset, determine which cube the vertex falls in.
How? Well, you might assume that the (5.5, 8.2, 9.1) vertex belongs in MyCubes[5,8,9], assuming X (cube-side-length) is of size 1. Note: I just truncated the decimals/floats to determine which cube.
Check to see if that relevant cube is already taken by a vertex. Check: If MyCubes[5,8,9] == NULL then (inject my vertex) else (do nothing, toss it out! spot taken, buddy)
Let's save some memory
This will give you a nicely simplified dataset in one pass, but at the cost of a potentially large amount of memory.
So, how do you do it without using too much memory?
I'd use a hashtable such that my key is the Grid-Cube coordinate (5,8,9) in my sample above.
If MyHashTable.contains({5,8,9}) then DoNothing else InsertCurrentVertex(...)
Now, you will have a one-pass solution with minimal memory usage (no gigantic array with a potentially large number of empty cubes. What is the cost? Well, the programming time to setup your structure/class so that you can perform the .contains action in a HashTable (or your language-equivalent)
Hey, my results are chunky!
That's right, because we took the first result that fit in any cube. On average, we will have achieved X-separation between vertices, but as you can figure out by now, some vertices will still be close to one another (at the edges of the cubes).
So, how do we handle it? Well, let's go back to the array method at the top (memory-intensive!).
Instead of ONLY checking to see if a vertex is already in the cube-in-question, also perform this other check:
If Not ThisCubeIsTaken()
For each SurroundingCube
If not Is_Your_Vertex_Sufficiently_Far_Away_From_Me()
exit_loop_and_outer_if_statement()
end if
Next
//Ok, we got here, we can add the vertex to the current cube because the cube is not only available, but the neighbors are far enough away from me
End If
I think you can probably see the beauty of this, as it is really easy to get neighboring cubes if you have a 3D array.
If you do some smoothing like this, you can probably enforce a 'don't add if it's with 0.25X' policy or something. You won't have to be too strict to achieve a noticeable smoothing effect.
Still too chunky, I want it smooth
In this variation, we will change the qualifying action for whether a vertex is permitted to take residence in a cube.
If TheCube is empty OR if ThisVertex is closer to the center of TheCube than the Cube's current vertex
InsertVertex (overwrite any existing vertex in the cube
End If
Note, we don't have to perform neighbor detection for this one. We just optimize towards the center of each cube.
If you like, you can merge this variation with the previous variation.
Cheat Mode
For some people in this situation, you can simply take a 10% random selection of your dataset and that will be a good-enough simplification. However, it will be very chunky with some points very close together. On the bright side, it takes a few minutes max. I don't recommend it unless you are prototyping.

See what "block" the player is looking at

I'm creating a game where the world is formed out of cubes (like in Minecraft), but there's just one small problem I can't put my finger on. I've created the world, the player, the camera movement and rotation (glRotatef and glTranslatef). Now I'm stuck at finding out what block the player is looking at.
EDIT: In case I didn't make my question clear enough, I don't understand how to cast the ray to check for collision with the blocks. All the blocks that I'm drawing are stored in a 3D array, containing the block id (I know I need to use octrees, but I just want the algorithm to work, optimization comes along the way)
OpenGL is a drawing/rendering API, not some kind of game/graphics engine. You tell it to draw stuff, and that's what it does.
Tests like the one you intend are not covered by OpenGL, you've to implement them either yourself or use some library designed for this. In your case you want to test the world against the viewing frustum. The exact block the player looks on can be found by doing a ray geometry intersection test, i.e. you cast a ray from your player position into the direction the player looks and test which objects intersect with that ray. Using a spatial subdivision structure helps speeding things up. In the case of a world made of cubes the most easy and efficient structure is a octree, i.e. one large cube that gets subdivided into 8 sub-cubes of half the containing cube's edge length. Then those subcubes are divided and so on.
Traversing such a structure is easily implemented by recursive functions – don't worry about stack overflow, since already as litte as 10 subdivisions would yield 2^10^3 = 2^30 sub-sub-...-sub-cubes, with a requirement of at leat 8GB of data to build a full detailed mesh from them. But 10 function recursion levels are not very deep.
First imagine a vector from your eye point in the direction of the camera with a length equal to the player's "reach". If I remember correctly the reach in Minecraft is about 4 blocks (or 4 meters). For every block in your world that could intersect that vector (which can be as simple as a 3D loop over a cube of blocks bounded by the min/max x/y/z values for your reach vector) cast a ray at the cube (if it's not air) to see if you hit it. Raycasting at an AABB (axis aligned bounding box) is pretty straightforward and you can Google that algorithm. Now sort the results by distance and return the block that hit the ray first.