actually, the artist have barely control over where bulging etc. happens
I've never modelled anything with catmull-clark surfaces -- is the tesselation shape dependent only on the vertex positions and normals, like phong tesselation?
Normals are ignored. The new points are build by averaging neighbouring polygon centers, edge centers, vertices... The different rules for subdivided corner points / edge-, poly-centers are simple, but because the process is recursive, it's difficult to accelerate.
I've done a lot of modeling with catmull clark and also made my own editor because i was not happy with crease options from commercial apps.
For modeling organic shapes catmull clark is the best option. With proper creases it's also a very good alternative to nurbs for things like cars etc., while still easier to understand.
Cons are: You need to avoid triangles and use regular quad grids whenever possible. A good model will end up with mostly quads, some 5 sided and a few 6 sided polygons.
Subdividing a typical triangulated mesh makes no sense - you need to have the original quadbased model to get good results.
The first subdivision step is special, it does the most important work and ends up with a mesh containing quads only.
For a good HW-acceleration it gives sense to do it with its own algorithm, maybe on CPU.
For following steps it could give sense to switch to a more hardware friendly method, like bezier patches.
If anyone has experience with practical HW-acceleration i would like to hear something about it too...
Note that this can be a very good thing, because if you do the skinning with the low res control mesh, you get MUCH better final high res skinning! This also saves some work, as you don't need to skin the subdivided stuff.
Skinning is where difference to other tesselation methods shows up most noticeably. Because the corner vertices get smoothed too, not just the surface around them. Maybe it's hard for a programmer to get the point why they are so good compared th other methods - but with skinning the difference in visual quality is really huge. Trust me
This adds the object to a vector, right? It looks like it replaces the current pointer with a new one, storing only one object at the end. I'm noob with stl and c++11.
The image looks nice (min / max is good way to define axis aligned boxes), but you need to visualize that inside your engine, to proof that its right.
I'd do this: Turn off Z-Test, traverse the entire tree, if a leaf is found, draw its slightly shrinked extends with a transparent color. Build the color from the nodes memory adress, so you can see different nodes better. For each object in the node, draw a line from node center to object center.
Afterwards draw all objects in wireframe. Navigate through the scene, and check if the objects are linked correctly to the nodes. If an object has no line, or the line points to a node far away, you know more.
If still anything looks right, visualize the cameras viewing pyramid (to see that, you need two cameras, one to observe and one for yourself to fly around). While traversing octree, draw nodes extends in white wireframe, if they fail the observeds cameras frustum check.
...that's some work, but you will surely see the bug - from another perspective - and then its easy to find it. And its good for future bugs.
I still believe its a geometirc issue.
Are the missing objects popping depending on camera or do the never appear?
Did you check after the creation, if each object ist at least in one node?
Did you visualize the node extends, maybe one of the 8 cases has a bug?
For occlusion query it's good to draw objects in raw front to back order, even without occ. test that saves pixel shader due to early z-test.
To achieve that you draw objects by traversing the octree bottom down drawing the near child first.
Here the loose octree has advantage too, because front back order is more precise and you draw large objects (good occluders) first.
but its easy to try that after you found the bug...
Some other things you may or may not end up with later, just to keep in mind:
Node extends and position can be calculated dynamically while traversal, no need to store them for each node.
If you align the grid at integer coords, you can use brachless integer bitmath for very fast searching in the tree.
Mostly it's a win to either point to an array of 8 children (some of them may end up unused), or there are no children.
Personally i use it for the same purpose, but i have not made any of those optimisations listed above
But i did it with a software-renderer that used quadtreecompressed lightmaps, so each scanline was clipping a line into the quadtree,
and there i saw a great speedup.
I can't read your code - too much stl :/
But i remember the pitfalls with octrees, so that might be helpful, if you don't know it:
The problem is: What to do with an object that is split by one or more grid planes?
Put it in each node and draw it multiple times?
Put it in one node and missing to draw it whaen the node is clipped? (guessing thats your problem)
Solution: Put each object to the node, where this condition is true:
objects bounding box center is inside node
AND the largest dimenson from the objects bounding box <= the dimenson of the node.
AND the largest dimenson from the objects bounding box > half the dimenson of the node.
... this results in large objects at the top levels, and small objects at the bottom levels of the tree.
While clipping extrude the nodes by one half of its dimension at each side (so it has 4 times its volume).
This is the volume that surely covers all objects.
I guess that is called 'loose octree', but i'm not sure.