@@ -70,10 +70,34 @@ def _get_node_coords_and_layers_map(
70
70
return node_coords , dict (zip (node_ids , node_layers ))
71
71
72
72
73
- def _normalize_coordinates (coords , layer , bfs_depth , max_layer ):
74
- node_depth = max_layer - layer
75
- depth_diff = node_depth - bfs_depth
76
- return coords // 2 ** depth_diff
73
+ def sort_octree_row (coords ):
74
+ """
75
+ Sort children by their morton code.
76
+ """
77
+ coords = np .array (coords , dtype = int , copy = False )
78
+ if coords .size == 0 :
79
+ return empty_1d
80
+
81
+ def z_order (x , y , z ):
82
+ result = 0
83
+ for i in range (10 ):
84
+ result |= (
85
+ ((x & (1 << i )) << (2 * i ))
86
+ | ((y & (1 << i )) << ((2 * i ) + 1 ))
87
+ | ((z & (1 << i )) << ((2 * i ) + 2 ))
88
+ )
89
+ return result
90
+
91
+ x_coords = coords [:, 0 ]
92
+ y_coords = coords [:, 1 ]
93
+ z_coords = coords [:, 2 ]
94
+ z_order_values = np .array (
95
+ [z_order (x , y , z ) for x , y , z in zip (x_coords , y_coords , z_coords )],
96
+ dtype = np .uint32 ,
97
+ )
98
+
99
+ sorted_indices = np .argsort (z_order_values )
100
+ return sorted_indices
77
101
78
102
79
103
def build_octree (
@@ -91,7 +115,7 @@ def build_octree(
91
115
requested/rendered.
92
116
"""
93
117
node_ids = np .fromiter (mesh_fragments .keys (), dtype = NODE_ID )
94
- node_coords_d , node_layers_d = _get_node_coords_and_layers_map (cg , node_children )
118
+ node_coords_d , _ = _get_node_coords_and_layers_map (cg , node_children )
95
119
skipped , leaves = _get_skipped_and_missing_leaf_nodes (node_children , mesh_fragments )
96
120
97
121
OCTREE_NODE_SIZE = 5
@@ -105,24 +129,15 @@ def build_octree(
105
129
106
130
que = deque ()
107
131
rows_used = 1
108
- que .append (( node_id , 0 ) )
132
+ que .append (node_id )
109
133
110
134
while len (que ) > 0 :
111
135
row_counter -= 1
112
- current_node , depth = que .popleft ()
136
+ current_node = que .popleft ()
113
137
children = node_children [current_node ]
114
- node_layer = node_layers_d [current_node ]
115
138
node_coords = node_coords_d [current_node ]
116
139
117
- # node_coords = _normalize_coordinates(
118
- # coords=node_coords,
119
- # layer=node_layer,
120
- # bfs_depth=depth,
121
- # max_layer=cg.meta.layer_count,
122
- # )
123
-
124
140
x , y , z = node_coords
125
- # x, y, z = node_coords * np.array(cg.meta.graph_config.CHUNK_SIZE, dtype=int)
126
141
offset = OCTREE_NODE_SIZE * row_counter
127
142
octree [offset + 0 ] = x
128
143
octree [offset + 1 ] = y
@@ -138,17 +153,22 @@ def build_octree(
138
153
octree_node_ids [row_counter ] = current_node
139
154
try :
140
155
if children .size == 1 :
141
- # map to child fragment
142
- # octree_fragments[row_counter] = mesh_fragments[children[0]]
156
+ # mark node virtual
143
157
octree [offset + 3 ] |= 1 << 31
144
158
else :
145
159
octree_fragments [row_counter ] = mesh_fragments [current_node ]
146
160
except KeyError :
147
161
# no mesh, mark node empty
148
162
octree [offset + 4 ] |= 1 << 31
149
163
164
+ children_coords = []
165
+ for child in children :
166
+ children_coords .append (cg .get_chunk_coordinates (child ))
167
+
168
+ indices = sort_octree_row (children_coords )
169
+ children = children [indices ]
150
170
for child in children :
151
- que .append (( child , depth + 1 ) )
171
+ que .append (child )
152
172
return octree , octree_node_ids , octree_fragments
153
173
154
174
0 commit comments