-
Notifications
You must be signed in to change notification settings - Fork 290
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Geometric layer management #217
Comments
Yes that's a feature difficult to design to optimize all aspects. About clamp to ground 2D Features:
But it also has its drawbacks such as
|
Concerning global 3D layer, yes I agree that it should be possible to have a different Quadtree than globe elevation one for example. Like 3D Tiles it should be able to incorporate its own pyramidal hierarchy. |
So with this one, we have 5 issues discussing Layer(s):
Clearly a core issue :) |
Quoting myself (from issue #124): A Layer is used to display data sources.
Geometries, textures and colors can be data layers (wmts, geojson, etc) or computed by itowns (tilemesh) Some Layers depends on other Layers (e.g: buildings may depend on globe to get accurate vertical positionning). A |
IMHO a valid solution should cover at least our current and planned use cases:
Am I forgetting something? |
I'll look at this |
|
@peppsac Seems complete to me. I would like to put an emphasis on the fact that we want to be able to handle all these cases without having to modify core files (e.g. Scene.js, TileMesh.js). @gchoqueux Please share your conclusions with us when you're done! |
|
Well, it depends on how it is implemented: if you look at the WFS PR, the features are added inside the TileMesh objects ("content" attribute). They are not in a separated data structure. |
Some suggestions for reflection Design architecture
itowns's instancing
multi-data structure exampleWith 2 independent quadtrees : One solution to optimize is to use a single traverse. We can use the spatial structure of first quadtree to group the nodes of the second. The |
How much do we gain by using the merged quadtree structure? We still have to compute SSE and process all the nodes regardless of the solution we use. I fear that we are adding an extra layer of complexity for very little gain. How do I subdivide quadtree N if quadtree M is lagging behind (because of long request response for instance)? Do I add the new nodes to the content attribute while waiting for M to catch up? Do I need to move these nodes once it has caught up? How do I manage the fact that a single tile from N overlaps multiple tiles from M? Must I process tile A while visiting tile 0 or 2? I agree that this solution is well suited for terrain data since everything is so intertwined. But aside from this specific case, I am not convinced the added complexity is worth the performance gain. |
there 's only one traverse of one quadtree.
We still have to compute SSE and process all the nodes visible (all nodes and theirs contents )
Nothing prevents a content from being refined, if this content is visible
You add new nodes to the children
these nodes B are added to other new nodes A's content
A content may have several nodes
yes |
I'm not that into itowns yet and might make some incorrect assumptions, so bear with my noobiness. So take the following more as questions than complete dismissal. One potential problem I see with your merged quadtree is that... it's not a tree any more. It's becoming a more general graph (among others, it has simple cycles). While it's possible to deal with it, it makes traversal less trivial and more expensive cpu and memory-wise (we need to remember visited nodes, for a start). Whether it will perform better than several quadtrees is possible, but not guaranteed, from my intuition. Also the child-parent relationship was one-to-many (typically 1-to-4 or 1-to-8). It's now many-to-many if I'm not mistaken. This will have consequences memory-wise, although I'm not sure whether or not it will be more than n quadtrees The trees can also be vastly different. There is no guarantee the levels would coincide right? Meaning a level2 tile of tree2 can overlaps dozens of level2 tiles of tree1 or actually none. How do we deal with that? How do you actually calculate that? (I mean, simply and cheaply) But most importantly, we would loose the cool fact that children have one and only one parent. Again, I'm just raising the question: what are the consequences? As far as I can tell, it would break So tl;dr, in my humble opinion, it brings a lot of complexity and we're not sure the perf gain would be there. Also it might be a premature optimization as we are not feature-complete yet. But considering my experience with itowns, please take that with a grain of salt. About @Jeremy-Gaillard proposal : I would do something similar, but instead of having one data structure (tree, grid, whatever) and so one geometry (if I understand correctly) per layer, I would allow a data structure + geometry to have several layers that shares the same geometry. This would limit the numbers of trees to spawn. To summarize, one geometry could have:
That way, when starting itowns, consumers would
These consumers app could define only a plane (for displaying a city for instance), or only a globe, or both (a plane of the size of a city can be placed on our globe without too much errors, right)? Also users can then add octrees for point cloud data too. We could then provide helpers for creating commonly used geometry (eg a Earth geometry, a generic configurable globe that can represents other planets or panoramic pictures if you're inside, a plane, a cube, etc), but users would also be able to define their own. Does that make sense to you? Is this even a viable solution? Please let me know if I missed something and I hope that what I wrote is at least slightly logical ;-) |
Thank you @autra for explaining my concerns better than I could. Concerning the second part of your message, there seems to be a little confusion on what's in a layer. You seem to think that there is one mesh per layer that is refined following a quadtree pattern (similar to Hoppe's progressive mesh). In reality, there's one geometry per node of the quadtree and the combination of these meshes form the terrain. Our layer concept is a bit vague, as you can see in the first posts of this issue. Some layers are directly renderable (e.g. a point cloud layer), while others need to be combined with another layer (e.g. the imagery layers that need a terrain geometry). @gchoqueux I think I understand better what you are trying to do. I think your reasoning is wrong on one point: the performance is not bound to the number of tree traversals but to the number of nodes that are visited. Whether we use my solution or yours, we visit the same number of nodes. Your solution is better only in cases where the refinement/visibility testing are the same for both layers and we need only one visit for several layers (like what is done for the terrain), in other cases there should not be significant difference between the two solutions, apart from the coding complexity. This is what I suggest:
Additionally, we could separate more clearly this notion of shared data structures in the architecture by introducing a container concept: |
The more you traverses the trees the more nodes you visit, isn't? For example (see previous drawing)
In which case it is different?
This concept already exists, |
I rectify, they are potentially visible, in any case there are always fewer visited nodes.
The terrain's nodes have a BBox with contents (building, cloud...)
What are the differences between Container and Layer? |
Specifically answering to #217 (comment)
Beware, your flame chart precisely shows that what is costly in a traversal are not the number of node or the number of levels of your tree, but the function that are called at the bottow of the stack (you see no horizontal shift on the The time is entirely taken by:
And they are all called once or twice for setDisplayed per traversal (apparently on the bottom node?). If my analysis is correct, the tree could have many more levels before it makes any difference. Any optimization that don't aim at removing these calls won't have any effects. More precisely, merging your 2 trees traversal won't remove these calls right? But instead you will probably add expensive computation to just build your merged tree. While I'm at it, how do you plan on building it? It's still very abstract to me 😄 Anyway, is it really the time to discuss optimization ? We don't have a perf problem at the moment. Hell, your tree traversal takes 9ms, which is way less than 60Hz. When I look at the timeline, itowns spends a helluvah time waiting for network answers and user actions, not working on something. Let's remember the 3 rules of optimization and find the right architecture first. We don't even have one that fits our feature needs! We must first design our architecture around these needs, THEN we'll think about optimization, if we need it. And if we did a good job in the first step, chances are we won't even need the second. Any optimization must first come for a clear a good design. If we do so, features would be natural to add and the code will remain efficient. That being said, now that I've made my rants, I don't have more to propose that I have already said. Thank you @Jeremy-Gaillard for clarifying things. Actually I didn't think there was a mesh per layer, I just said that imho we don't need a tree per layer as you suggested in your first comment, but a tree per geometry. Which brings me to
I'm with @gchoqueux on this one: any architectural concept that needs to be called In this particular case, I have the strong feeling that your container is what I call a geometry. What I call a geometry is a globe, which is composed of tiles, subdivided or not). It's actually the geometry that contains its layers. it it is so, I guess we more or less agree. |
To clarify my last comment: I might very well be completely wrong about my perf analysis (I've analysed only a small portion of the execution and perf analysis are hard). My point is: we shouldn't care yet. |
More you traverse trees, more you visit nodes, more you use functions (like
there are perfomance problems :
const processList = [
nodeProcess.occlusion,
nodeProcess.occlusionHorizon,
nodeProcess.SSE,
nodeProcess.refineNode,
];
var updaterQuadtree = new updater(processList);
var quadTree = new QuadTree();
// link updater to quadtree for update
scene.apply(quadTree,updaterQuadtree); We can even imagine a process tree to be applied to each node. The children process will be performed according to the parent process. You can instance a new The format of a process is static function |
we don't know why yet. It could be because of webgl performances, not because of the code or tree traversal, or because of something else entirely.
Then maybe we can start by caring about all the perf warnings we have in the console 😺 : I'm talking about
It's so serious it's reported as errors (mind the last line too, I don't even want to know how many we really have) And then - for instance - we could get rid of things like: function applyFunctionToChildren(func, node) {
for (let i = 0; i < node.children.length; i++) {
func(node.children[i]);
}
} which forces us to create an anonymous function instance for each node we traverse and would certainly prevent any possible JIT loop optimization (seriously, we should never create functions in loops). So of course, we could do better performance-wise, but I still think we should not try to be driven by performance issues in our architecture. There's so many things we have to do for this before trying complicated things. I'm saying that because I had the feeling that performance was the goal of your merged tree idea. Please correct me if I misunderstood. The 3 rules of optimization:
And imho, the 3rd item should be the very last step, a last resort in fact. My opinion is still that we should go for the most natural way of organizing the code and that we would then have naturally good performances. I think a merged tree is not a natural way of expressing our data (but maybe I misunderstood your solution of course) because they are too heterogeneous for one data structure. Anyway, maybe it will be easier to discuss it IRL on January! 😃 |
Regarding the whole quadtree / 2 quadtrees / ... discussions : imho we should focus on not depending on a particular tree structure. The opportunity to merge 2 quadtrees could be nice to have but later. Here is my wish list for iTowns as a framework:
So it's quite close to the current architecture, but with a more strict split between what is the framework and what is Globe-specific. Last but not least: we need to be able to change controls more easily (camera control should not be created in c3dEngine) Last but not least: I don't see the need for |
Yes, quatrees are examples, and can be replaced by any structure
Can you specify?
Yes
yes, something like that.
It needs some factorization too, make generic imagery and elevation
I agree
Yes this must change
Effectively 3D Layer is not really necessary, however more the process to manage layer with Object3D |
Add a child to a |
I close #121 and move content here
Layer and Object3D
|
I close #120 and move content here new functions in Api high level to manage Layer Object3D
Add and remove object in LayerObject3D
|
See issues #217, #124, #40 for related discussion. This massive commit: * unifies layers handling (geometry layers are no longer special citizen) * split processing in smaller units: these units will be more easy to reuse. For example implementing Plane support will be easier because we're now able to share the Tile and LayeredMaterial concepts without being forced to use Globe based concept (e.g horizontalCulling). * limits the duplication of feature between three.js and iTowns: we get the best of three.js and we remove incoherencies (e.g our Node were slightly different) * breaks the Globe|Quadtree centric vision of iTowns to ease the implementation of other types of vizualisaiotn (oriented images, plane mode, pointcloud, etc)
See issues #217, #124, #40 for related discussion. This massive commit: * unifies layers handling (geometry layers are no longer special citizen) * split processing in smaller units: these units will be more easy to reuse. For example implementing Plane support will be easier because we're now able to share the Tile and LayeredMaterial concepts without being forced to use Globe based concept (e.g horizontalCulling). * limits the duplication of feature between three.js and iTowns: we get the best of three.js and we remove incoherencies (e.g our Node were slightly different) * breaks the Globe|Quadtree centric vision of iTowns to ease the implementation of other types of vizualisaiotn (oriented images, plane mode, pointcloud, etc)
See issues #217, #124, #40 for related discussion. This massive commit: * unifies layers handling (geometry layers are no longer special citizen) * split processing in smaller units: these units will be more easy to reuse. For example implementing Plane support will be easier because we're now able to share the Tile and LayeredMaterial concepts without being forced to use Globe based concept (e.g horizontalCulling). * limits the duplication of feature between three.js and iTowns: we get the best of three.js and we remove incoherencies (e.g our Node were slightly different) * breaks the Globe|Quadtree centric vision of iTowns to ease the implementation of other types of vizualisaiotn (oriented images, plane mode, pointcloud, etc)
See issues #217, #124, #40 for related discussion. This massive commit: * unifies layers handling (geometry layers are no longer special citizen) * split processing in smaller units: these units will be more easy to reuse. For example implementing Plane support will be easier because we're now able to share the Tile and LayeredMaterial concepts without being forced to use Globe based concept (e.g horizontalCulling). * limits the duplication of feature between three.js and iTowns: we get the best of three.js and we remove incoherencies (e.g our Node were slightly different) * breaks the Globe|Quadtree centric vision of iTowns to ease the implementation of other types of vizualisaiotn (oriented images, plane mode, pointcloud, etc)
See issues #217, #124, #40 for related discussion. This massive commit: * unifies layers handling (geometry layers are no longer special citizen) * split processing in smaller units: these units will be more easy to reuse. For example implementing Plane support will be easier because we're now able to share the Tile and LayeredMaterial concepts without being forced to use Globe based concept (e.g horizontalCulling). * limits the duplication of feature between three.js and iTowns: we get the best of three.js and we remove incoherencies (e.g our Node were slightly different) * breaks the Globe|Quadtree centric vision of iTowns to ease the implementation of other types of vizualisaiotn (oriented images, plane mode, pointcloud, etc)
See issues #217, #124, #40 for related discussion. This massive commit: * unifies layers handling (geometry layers are no longer special citizen) * split processing in smaller units: these units will be more easy to reuse. For example implementing Plane support will be easier because we're now able to share the Tile and LayeredMaterial concepts without being forced to use Globe based concept (e.g horizontalCulling). * limits the duplication of feature between three.js and iTowns: we get the best of three.js and we remove incoherencies (e.g our Node were slightly different) * breaks the Globe|Quadtree centric vision of iTowns to ease the implementation of other types of vizualisaiotn (oriented images, plane mode, pointcloud, etc)
See issues #217, #124, #40 for related discussion. This massive commit: * unifies layers handling (geometry layers are no longer special citizen) * split processing in smaller units: these units will be more easy to reuse. For example implementing Plane support will be easier because we're now able to share the Tile and LayeredMaterial concepts without being forced to use Globe based concept (e.g horizontalCulling). * limits the duplication of feature between three.js and iTowns: we get the best of three.js and we remove incoherencies (e.g our Node were slightly different) * breaks the Globe|Quadtree centric vision of iTowns to ease the implementation of other types of vizualisaiotn (oriented images, plane mode, pointcloud, etc)
See issues #217, #124, #40 for related discussion. This massive commit: * unifies layers handling (geometry layers are no longer special citizen) * split processing in smaller units: these units will be more easy to reuse. For example implementing Plane support will be easier because we're now able to share the Tile and LayeredMaterial concepts without being forced to use Globe based concept (e.g horizontalCulling). * limits the duplication of feature between three.js and iTowns: we get the best of three.js and we remove incoherencies (e.g our Node were slightly different) * breaks the Globe|Quadtree centric vision of iTowns to ease the implementation of other types of vizualisaiotn (oriented images, plane mode, pointcloud, etc)
See issues #217, #124, #40 for related discussion. This massive commit: * unifies layers handling (geometry layers are no longer special citizen) * split processing in smaller units: these units will be more easy to reuse. For example implementing Plane support will be easier because we're now able to share the Tile and LayeredMaterial concepts without being forced to use Globe based concept (e.g horizontalCulling). * limits the duplication of feature between three.js and iTowns: we get the best of three.js and we remove incoherencies (e.g our Node were slightly different) * breaks the Globe|Quadtree centric vision of iTowns to ease the implementation of other types of vizualisaiotn (oriented images, plane mode, pointcloud, etc)
See issues #217, #124, #40 for related discussion. This massive commit: * unifies layers handling (geometry layers are no longer special citizen) * split processing in smaller units: these units will be more easy to reuse. For example implementing Plane support will be easier because we're now able to share the Tile and LayeredMaterial concepts without being forced to use Globe based concept (e.g horizontalCulling). * limits the duplication of feature between three.js and iTowns: we get the best of three.js and we remove incoherencies (e.g our Node were slightly different) * breaks the Globe|Quadtree centric vision of iTowns to ease the implementation of other types of vizualisaiotn (oriented images, plane mode, pointcloud, etc)
See issues #217, #124, #40 for related discussion. This massive commit: * unifies layers handling (geometry layers are no longer special citizen) * split processing in smaller units: these units will be more easy to reuse. For example implementing Plane support will be easier because we're now able to share the Tile and LayeredMaterial concepts without being forced to use Globe based concept (e.g horizontalCulling). * limits the duplication of feature between three.js and iTowns: we get the best of three.js and we remove incoherencies (e.g our Node were slightly different) * breaks the Globe|Quadtree centric vision of iTowns to ease the implementation of other types of vizualisaiotn (oriented images, plane mode, pointcloud, etc)
See issues #217, #124, #40 for related discussion. This massive commit: * unifies layers handling (geometry layers are no longer special citizen) * split processing in smaller units: these units will be more easy to reuse. For example implementing Plane support will be easier because we're now able to share the Tile and LayeredMaterial concepts without being forced to use Globe based concept (e.g horizontalCulling). * limits the duplication of feature between three.js and iTowns: we get the best of three.js and we remove incoherencies (e.g our Node were slightly different) * breaks the Globe|Quadtree centric vision of iTowns to ease the implementation of other types of vizualisaiotn (oriented images, plane mode, pointcloud, etc)
See issues #217, #124, #40 for related discussion. This massive commit: * unifies layers handling (geometry layers are no longer special citizen) * split processing in smaller units: these units will be more easy to reuse. For example implementing Plane support will be easier because we're now able to share the Tile and LayeredMaterial concepts without being forced to use Globe based concept (e.g horizontalCulling). * limits the duplication of feature between three.js and iTowns: we get the best of three.js and we remove incoherencies (e.g our Node were slightly different) * breaks the Globe|Quadtree centric vision of iTowns to ease the implementation of other types of vizualisaiotn (oriented images, plane mode, pointcloud, etc)
See issues #217, #124, #40 for related discussion. This massive commit: * unifies layers handling (geometry layers are no longer special citizen) * split processing in smaller units: these units will be more easy to reuse. For example implementing Plane support will be easier because we're now able to share the Tile and LayeredMaterial concepts without being forced to use Globe based concept (e.g horizontalCulling). * limits the duplication of feature between three.js and iTowns: we get the best of three.js and we remove incoherencies (e.g our Node were slightly different) * breaks the Globe|Quadtree centric vision of iTowns to ease the implementation of other types of vizualisaiotn (oriented images, plane mode, pointcloud, etc)
See issues iTowns#217, iTowns#124, iTowns#40 for related discussion. This massive commit: * unifies layers handling (geometry layers are no longer special citizen) * split processing in smaller units: these units will be more easy to reuse. For example implementing Plane support will be easier because we're now able to share the Tile and LayeredMaterial concepts without being forced to use Globe based concept (e.g horizontalCulling). * limits the duplication of feature between three.js and iTowns: we get the best of three.js and we remove incoherencies (e.g our Node were slightly different) * breaks the Globe|Quadtree centric vision of iTowns to ease the implementation of other types of vizualisaiotn (oriented images, plane mode, pointcloud, etc)
See issues iTowns#217, iTowns#124, iTowns#40 for related discussion. This massive commit: * unifies layers handling (geometry layers are no longer special citizen) * split processing in smaller units: these units will be more easy to reuse. For example implementing Plane support will be easier because we're now able to share the Tile and LayeredMaterial concepts without being forced to use Globe based concept (e.g horizontalCulling). * limits the duplication of feature between three.js and iTowns: we get the best of three.js and we remove incoherencies (e.g our Node were slightly different) * breaks the Globe|Quadtree centric vision of iTowns to ease the implementation of other types of vizualisaiotn (oriented images, plane mode, pointcloud, etc)
The current architecture has responded to requests. |
There are currently two PRs (#214 and #195) that are adding 3D geometric data to the scene through various protocols.
I am pretty concern by the approach that is being used in both these cases. The favoured solution seems to be shoving every new geometric feature as an attribute in the TileMesh class.
I have several issues with this method:
On my side, I've been adding layers that are totally independent from the globe class (you can see some of my work in the 3DBuildings and 3d-tiles branches). My last PR #213 also aims at enabling this method more easily. Basically, each new layer has its own quadtree (or grid, or BVH, or any other data structure) and nodeProcess, and works on its own.
I realise there are drawbacks to this method:
I think we should discuss here of a unique, "good practice" way of doing these things.
The text was updated successfully, but these errors were encountered: