@@ -7,6 +7,7 @@ use half::f16;
77use rav1e:: {
88 config:: SpeedSettings , prelude:: v_frame, Config , Context , EncoderConfig , EncoderStatus ,
99} ;
10+ use rav1d_safe:: src:: managed:: { Decoder , Planes } ;
1011use smooth_bevy_cameras:: { controllers:: unreal:: * , LookTransformPlugin } ;
1112use vdb_rs:: VdbReader ;
1213
@@ -52,7 +53,7 @@ fn setup(mut commands: Commands, mut color_options_map: ResMut<CuboidMaterialMap
5253 let mut vdb_reader = VdbReader :: new ( BufReader :: new ( f) ) . unwrap ( ) ;
5354 let grid_names = vdb_reader. available_grids ( ) ;
5455
55- let grid_to_load = std:: env:: args ( ) . nth ( 2 ) . unwrap_or_else ( || {
56+ let _grid_to_load = std:: env:: args ( ) . nth ( 2 ) . unwrap_or_else ( || {
5657 println ! (
5758 "Grid name not specified, defaulting to first available grid.\n Available grids: {:?}" ,
5859 grid_names
@@ -68,9 +69,9 @@ fn setup(mut commands: Commands, mut color_options_map: ResMut<CuboidMaterialMap
6869 . unwrap ( ) ;
6970 let extent = max_aabb - min_aabb + 1 ;
7071
71- info ! ( "Extent : {}" , extent) ;
72+ info ! ( "min_aabb : {}, max_aabb: {}, extent: {}" , min_aabb , max_aabb , extent) ;
7273
73- // MY GLORIOUS COMPRESSION
74+ // ENCODE: VDB -> AV1/IVF
7475 {
7576 let grid = vdb_reader
7677 . read_grid :: < half:: f16 > ( & grid_names. first ( ) . unwrap ( ) )
@@ -85,7 +86,8 @@ fn setup(mut commands: Commands, mut color_options_map: ResMut<CuboidMaterialMap
8586 dbg ! ( "Error pos: {}" , pos) ;
8687 }
8788 let actual_index =
88- ( pos + Vec3 :: new ( x as f32 , y as f32 , z as f32 ) ) . as_uvec3 ( ) ;
89+ ( pos + Vec3 :: new ( x as f32 , y as f32 , z as f32 ) ) . as_uvec3 ( )
90+ - min_aabb. as_uvec3 ( ) ;
8991 let id = actual_index. x
9092 + actual_index. y * extent. x as u32
9193 + actual_index. z * extent. x as u32 * extent. y as u32 ;
@@ -130,23 +132,17 @@ fn setup(mut commands: Commands, mut color_options_map: ResMut<CuboidMaterialMap
130132 }
131133 Err ( EncoderStatus :: Encoded ) => ( ) ,
132134 Err ( EncoderStatus :: LimitReached ) => {
133- ctx. flush ( ) ;
134135 break ;
135136 }
136137 Err ( EncoderStatus :: NeedMoreData ) => {
137- info ! ( "Requesting more data" ) ;
138- frame_idx += 1 ;
139138 if frame_idx >= slices {
140139 ctx. flush ( ) ;
141-
142- // we need to continue the loop here to receive more packets
143140 continue ;
144141 }
145142 info ! ( "Writing frame {} out of {}" , frame_idx, slices) ;
146143
147144 let mut frame = f. clone ( ) ;
148145 for ( plane_idx, plane) in frame. planes . iter_mut ( ) . enumerate ( ) {
149- info ! ( "Plane idx: {}" , plane_idx) ;
150146 if plane_idx != 0 {
151147 continue ;
152148 }
@@ -159,39 +155,13 @@ fn setup(mut commands: Commands, mut color_options_map: ResMut<CuboidMaterialMap
159155 for ( col, dst) in dst_row. iter_mut ( ) . take ( width) . enumerate ( ) {
160156 let multiplier = ( ( 1 << 8 ) - 1 ) as f32 ;
161157 let id = col + row_idx * width + frame_idx * width * height;
162- if voxel_grid[ id] != f16:: ZERO {
163- // dbg!(
164- // col,
165- // row_idx,
166- // frame_idx,
167- // id,
168- // voxel_grid[id],
169- // voxel_grid[id].to_f32() * multiplier
170- // );
171- }
172- match plane_idx {
173- 0 => {
174- * dst = ( voxel_grid[ id] . to_f32 ( ) * multiplier * 10.0 )
175- . clamp ( 0.0 , 255.0 )
176- as u16
177- }
178- 1 => {
179- * dst = ( voxel_grid[ id] . to_f32 ( ) * multiplier * 10.0 )
180- . clamp ( 0.0 , 255.0 )
181- as u16
182- }
183- 2 => {
184- * dst = ( voxel_grid[ id] . to_f32 ( ) * multiplier * 10.0 )
185- . clamp ( 0.0 , 255.0 )
186- as u16
187- }
188- _ => { }
189- }
158+ * dst = ( voxel_grid[ id] . to_f32 ( ) * multiplier * 10.0 )
159+ . clamp ( 0.0 , 255.0 )
160+ as u16 ;
190161 }
191162 }
192163 }
193164
194- info ! ( "Sending frame" ) ;
195165 match ctx. send_frame ( frame) {
196166 Ok ( _) => { }
197167 Err ( EncoderStatus :: EnoughData ) => {
@@ -201,23 +171,123 @@ fn setup(mut commands: Commands, mut color_options_map: ResMut<CuboidMaterialMap
201171 panic ! ( "Unable to send frame {frame_idx}: {e:?}" ) ;
202172 }
203173 }
174+ frame_idx += 1 ;
204175 }
205176 _ => { }
206177 }
207178 }
208179 }
209180
210- let grid = vdb_reader. read_grid :: < half:: f16 > ( & grid_to_load) . unwrap ( ) ;
211- let instances: Vec < Cuboid > = grid
212- . iter ( )
213- . map ( |( pos, voxel, level) | {
214- Cuboid :: new (
215- pos * 0.1 ,
216- ( pos + level. scale ( ) ) * 0.1 ,
217- u32:: from_le_bytes ( f32:: to_le_bytes ( voxel. to_f32 ( ) ) ) ,
218- )
219- } )
220- . collect ( ) ;
181+ // DECODE: IVF/AV1 -> voxel grid
182+ let decoded_voxels = {
183+ let mut ivf_file =
184+ BufReader :: new ( std:: fs:: File :: open ( "out.ivf" ) . expect ( "Failed to open out.ivf" ) ) ;
185+
186+ let header = ivf:: read_header ( & mut ivf_file) . expect ( "Failed to read IVF header" ) ;
187+ let width = header. w as usize ;
188+ let height = header. h as usize ;
189+ let slices = extent. z as usize ;
190+
191+ info ! (
192+ "Decoding IVF: {}x{}, expecting {} slices" ,
193+ width, height, slices
194+ ) ;
195+
196+ let mut decoder = Decoder :: new ( ) . expect ( "Failed to create rav1d decoder" ) ;
197+
198+ let mut decoded_grid = vec ! [ f16:: ZERO ; width * height * slices] ;
199+ let mut frames_decoded = 0usize ;
200+
201+ // Read all IVF packets
202+ let mut packets = Vec :: new ( ) ;
203+ loop {
204+ match ivf:: read_packet ( & mut ivf_file) {
205+ Ok ( pkt) => packets. push ( pkt) ,
206+ Err ( _) => break ,
207+ }
208+ }
209+ info ! ( "Read {} packets from IVF" , packets. len( ) ) ;
210+
211+ for pkt in & packets {
212+ match decoder. decode ( & pkt. data ) {
213+ Ok ( Some ( frame) ) => {
214+ decode_frame_to_grid ( & frame, & mut decoded_grid, width, height, slices, frames_decoded) ;
215+ frames_decoded += 1 ;
216+ info ! ( "Decoded frame {} / {}" , frames_decoded, slices) ;
217+ }
218+ Ok ( None ) => { }
219+ Err ( e) => panic ! ( "Decode error: {e}" ) ,
220+ }
221+
222+ // Drain any buffered frames
223+ loop {
224+ match decoder. get_frame ( ) {
225+ Ok ( Some ( frame) ) => {
226+ decode_frame_to_grid ( & frame, & mut decoded_grid, width, height, slices, frames_decoded) ;
227+ frames_decoded += 1 ;
228+ info ! ( "Decoded frame {} / {}" , frames_decoded, slices) ;
229+ }
230+ Ok ( None ) => break ,
231+ Err ( e) => panic ! ( "Decode error draining: {e}" ) ,
232+ }
233+ }
234+ }
235+
236+ // Flush remaining frames
237+ match decoder. flush ( ) {
238+ Ok ( remaining_frames) => {
239+ for frame in & remaining_frames {
240+ decode_frame_to_grid ( frame, & mut decoded_grid, width, height, slices, frames_decoded) ;
241+ frames_decoded += 1 ;
242+ info ! ( "Decoded frame {} / {} (flushed)" , frames_decoded, slices) ;
243+ }
244+ }
245+ Err ( e) => info ! ( "Flush completed with: {e}" ) ,
246+ }
247+
248+ info ! (
249+ "Decoding complete: {} frames decoded, grid size: {}" ,
250+ frames_decoded,
251+ decoded_grid. len( )
252+ ) ;
253+
254+ decoded_grid
255+ } ;
256+
257+ // Visualize the decoded voxels
258+ let width = extent. x as usize ;
259+ let height = extent. y as usize ;
260+ let slices = extent. z as usize ;
261+
262+ // Use a threshold to filter out AV1 lossy compression artifacts.
263+ // AV1 at speed 9 creates ringing at boundaries; pixel values of ~5-15
264+ // are common artifacts, which decode to 0.002-0.006. Use 0.005 to be safe.
265+ let artifact_threshold = 0.008 ;
266+
267+ let mut instances: Vec < Cuboid > = Vec :: new ( ) ;
268+ for z in 0 ..slices {
269+ for y in 0 ..height {
270+ for x in 0 ..width {
271+ let id = x + y * width + z * width * height;
272+ let voxel = decoded_voxels[ id] ;
273+ if voxel. to_f32 ( ) > artifact_threshold {
274+ let pos = Vec3 :: new (
275+ x as f32 + min_aabb. x as f32 ,
276+ y as f32 + min_aabb. y as f32 ,
277+ z as f32 + min_aabb. z as f32 ,
278+ ) ;
279+ instances. push ( Cuboid :: new (
280+ pos * 0.1 ,
281+ ( pos + 1.0 ) * 0.1 ,
282+ u32:: from_le_bytes ( f32:: to_le_bytes ( voxel. to_f32 ( ) ) ) ,
283+ ) ) ;
284+ }
285+ }
286+ }
287+ }
288+
289+ info ! ( "Rendering {} decoded voxels" , instances. len( ) ) ;
290+
221291 let cuboids = Cuboids :: new ( instances) ;
222292 let aabb = cuboids. aabb ( ) ;
223293 commands
@@ -243,3 +313,47 @@ fn setup(mut commands: Commands, mut color_options_map: ResMut<CuboidMaterialMap
243313 Vec3 :: Y ,
244314 ) ) ;
245315}
316+
317+ fn decode_frame_to_grid (
318+ frame : & rav1d_safe:: src:: managed:: Frame ,
319+ decoded_grid : & mut [ f16 ] ,
320+ width : usize ,
321+ height : usize ,
322+ slices : usize ,
323+ frame_idx : usize ,
324+ ) {
325+ if frame_idx >= slices {
326+ return ;
327+ }
328+
329+ let multiplier = ( ( 1 << 8 ) - 1 ) as f32 ;
330+
331+ match frame. planes ( ) {
332+ Planes :: Depth8 ( planes) => {
333+ let y_plane = planes. y ( ) ;
334+ for row in 0 ..y_plane. height ( ) . min ( height) {
335+ let row_data = y_plane. row ( row) ;
336+ for col in 0 ..row_data. len ( ) . min ( width) {
337+ let pixel = row_data[ col] ;
338+ // Reverse the encoding: encoded = (f16 * 255.0 * 10.0).clamp(0, 255)
339+ // So: f16 = pixel / 255.0 / 10.0
340+ let value = pixel as f32 / multiplier / 10.0 ;
341+ let id = col + row * width + frame_idx * width * height;
342+ decoded_grid[ id] = f16:: from_f32 ( value) ;
343+ }
344+ }
345+ }
346+ Planes :: Depth16 ( planes) => {
347+ let y_plane = planes. y ( ) ;
348+ for row in 0 ..y_plane. height ( ) . min ( height) {
349+ let row_data = y_plane. row ( row) ;
350+ for col in 0 ..row_data. len ( ) . min ( width) {
351+ let pixel = row_data[ col] ;
352+ let value = pixel as f32 / multiplier / 10.0 ;
353+ let id = col + row * width + frame_idx * width * height;
354+ decoded_grid[ id] = f16:: from_f32 ( value) ;
355+ }
356+ }
357+ }
358+ }
359+ }
0 commit comments