Currently the quad tree is generated only on loading and remains static. But during runtime the entire map might change which means that another quad tree structure might be more optimal. In general the goal should be to keep the number of triangles per leave low.
The proposed solution would be a "simplify" operation which is applied every frame that has some calculation time left:
Each leave has the following new attributes:
-
positive_points: Is a set of points that consists of newly added polygons. E.g.: when drawing a circle, this would be a point cloud containing random samples of the circle. Because the point cloud should approximate the actual triangles, each point of "positive_points" must have a certain distance to each point of the points set, otherwise area is counted twice, that should not be counted twice.
-
negative_points: Negative points is similarly as "positive_points" for polygons that are being removed.
This is done in order to avoid a costly triangulation and point cloud generation and instead reuse the existing information. Since the point cloud for the operation that acts on the map can either be precomputed or easily generated during runtime.
Now the simplify operation can update the quad tree:
Let x be |points| - |negative_points| + |positive_points|
If x below a certain threshold, this roughly translates to less surface area, and this again translates to that this leave is unnecessary => mark this leave as redundant
If x is above another threshold, this roughly translates to lots of surface area, and this again translates to this leave contains too much information => mark this leave as full
If a parent contains only redundant leaves these leaves must be merged into the parent.
If a leave is marked as full, split it and generate 4 new leaves and mark the original leave as parent. Assign each point (either from the points, negative_points or positive points_set) to the leave it falls into.
Finally the points, negative_points and positive_points must be merged together: Union points and positive_points. From the resulting set remove points as many as there are points in the negative_points set. The resulting set should approximate the density of vertices in the leave.
This would be my proposed solution to tackle quad-tree degeneration. Another way to do this, would be to take a big (what is big though?) chunk, that has been modified. From the triangles that are contained within these chunks, generate the point cloud. Create a new sub quadtree for the current chunk, including the clipping and triangulation. This would take much longer, but the point cloud would be more reliable. If the first approach does not work, this would need to be implemented as a fallback.