WorkInProgress/NanoVDB.Grid.cs
using System.IO;
namespace Sandbox;
public partial class NanoVDB
{
public partial class Grid
{
public string Name { get; private set; } = "";
public uint[] Data { get; private set; }
public GridHeader Header = new();
public static Grid Read( BinaryReader reader, Metadata metadata )
{
var basePos = reader.BaseStream.Position;
Grid grid = new()
{
Name = new string( reader.ReadChars( (int)metadata.NameSize ) ),
Header = GridHeader.Read( reader )
};
// Go back to the start of the grid data
reader.BaseStream.Position = basePos + (int)metadata.NameSize;
grid.Data = new uint[grid.Header.GridSize / sizeof(uint)];
for (int i = 0; i < grid.Data.Length; i++)
{
grid.Data[i] = reader.ReadUInt32();
}
return grid;
}
/// <summary>
///
/// </summary>
public class GridHeader
{
public Magic Magic = 0; // 8 bytes, 0
public ulong Checksum = 0; // 8 bytes, 8
public uint Version = 0; // 4 bytes, 16
public GridFlags Flags = 0; // 4 bytes, 20
public uint GridIndex = 0; // 4 bytes, 24
public uint GridCount = 0; // 4 bytes, 28
public ulong GridSize = 0; // 8 bytes, 32
public string GridName = ""; // 256 bytes, 40 (64 elements)
public byte[] Map = new byte[264]; // 264 bytes, 296
public BBox WorldBBox = new(); // 48 bytes, 560 (6 elements)
public Vector3 VoxelSize = new(); // 24 bytes, 608 (3 elements)
public GridClass Class = 0; // 4 bytes, 632
public GridType Type = 0; // 4 bytes, 636
public long BlindMetadataOffset = 0; // 8 bytes, 640
public uint BlindMetadataCount = 0; // 4 bytes, 648
public uint Data0 = 0; // 4 bytes, 652 (unused)
public ulong Data1 = 0; // 8 bytes, 656 (total value count)
public Magic Data2 = 0; // 8 bytes, 664 (padding to 32 B alignment)
public static GridHeader Read( BinaryReader reader )
{
GridHeader header = new()
{
Magic = (Magic)reader.ReadUInt64(),
Checksum = reader.ReadUInt64(),
Version = reader.ReadUInt32(),
Flags = (GridFlags)reader.ReadUInt32(),
GridIndex = reader.ReadUInt32(),
GridCount = reader.ReadUInt32(),
GridSize = reader.ReadUInt64(),
GridName = new string( reader.ReadChars( 256 ) ),
Map = reader.ReadBytes( 264 ),
WorldBBox = new BBox(
new Vector3( (float)reader.ReadDouble(), (float)reader.ReadDouble(), (float)reader.ReadDouble() ),
new Vector3( (float)reader.ReadDouble(), (float)reader.ReadDouble(), (float)reader.ReadDouble() )
),
VoxelSize = new Vector3( (float)reader.ReadDouble(), (float)reader.ReadDouble(), (float)reader.ReadDouble() ),
Class = (GridClass)reader.ReadUInt32(),
Type = (GridType)reader.ReadUInt32(),
BlindMetadataOffset = reader.ReadInt64(),
BlindMetadataCount = reader.ReadUInt32(),
Data0 = reader.ReadUInt32(),
Data1 = reader.ReadUInt64(),
Data2 = (Magic)reader.ReadUInt64() // NANOVDB_MAGIC_GRID, might change in the future
};
if ( header.Magic != Magic.Grid && header.Magic != Magic.Numb )
throw new Exception( "Invalid NanoVDB grid header" );
if( header.GridSize % 32 != 0 )
throw new Exception( "Grid size must be divisible by 32" );
if( header.Data2 != Magic.Grid )
throw new Exception( "Expected NANOVDB_MAGIC_GRID on Data2" );
return header;
}
}
}
}
/// <summary>
/// When added to a string property, will become a VDB string selector
/// </summary>
[AttributeUsage( AttributeTargets.Property )]
public class NVDBPathAttribute : AssetPathAttribute
{
public override string AssetTypeExtension => "nvdb";
}