예제 #1
0
        public VxlReader(Stream s)
        {
            if (!s.ReadASCII(16).StartsWith("Voxel Animation"))
            {
                throw new InvalidDataException("Invalid vxl header");
            }

            s.ReadUInt32();
            LimbCount = s.ReadUInt32();
            s.ReadUInt32();
            BodySize = s.ReadUInt32();
            s.Seek(770, SeekOrigin.Current);

            // Read Limb headers
            Limbs = new VxlLimb[LimbCount];
            for (var i = 0; i < LimbCount; i++)
            {
                Limbs[i]      = new VxlLimb();
                Limbs[i].Name = s.ReadASCII(16);
                s.Seek(12, SeekOrigin.Current);
            }

            // Skip to the Limb footers
            s.Seek(802 + 28 * LimbCount + BodySize, SeekOrigin.Begin);

            var LimbDataOffset = new uint[LimbCount];

            for (var i = 0; i < LimbCount; i++)
            {
                LimbDataOffset[i] = s.ReadUInt32();
                s.Seek(8, SeekOrigin.Current);
                Limbs[i].Scale = s.ReadFloat();
                s.Seek(48, SeekOrigin.Current);

                Limbs[i].Bounds = new float[6];
                for (var j = 0; j < 6; j++)
                {
                    Limbs[i].Bounds[j] = s.ReadFloat();
                }
                Limbs[i].Size = s.ReadBytes(3);
                Limbs[i].Type = (NormalType)s.ReadByte();
            }

            for (var i = 0; i < LimbCount; i++)
            {
                s.Seek(802 + 28 * LimbCount + LimbDataOffset[i], SeekOrigin.Begin);
                ReadVoxelData(s, Limbs[i]);
            }
        }
예제 #2
0
        public VxlReader(Stream s)
        {
            if (!s.ReadASCII(16).StartsWith("Voxel Animation"))
                throw new InvalidDataException("Invalid vxl header");

            s.ReadUInt32();
            LimbCount = s.ReadUInt32();
            s.ReadUInt32();
            BodySize = s.ReadUInt32();
            s.Seek(770, SeekOrigin.Current);

            // Read Limb headers
            Limbs = new VxlLimb[LimbCount];
            for (var i = 0; i < LimbCount; i++)
            {
                Limbs[i] = new VxlLimb();
                Limbs[i].Name = s.ReadASCII(16);
                s.Seek(12, SeekOrigin.Current);
            }

            // Skip to the Limb footers
            s.Seek(802 + 28*LimbCount + BodySize, SeekOrigin.Begin);

            var LimbDataOffset = new uint[LimbCount];
            for (var i = 0; i < LimbCount; i++)
            {
                LimbDataOffset[i] = s.ReadUInt32();
                s.Seek(8, SeekOrigin.Current);
                Limbs[i].Scale = s.ReadFloat();
                s.Seek(48, SeekOrigin.Current);

                Limbs[i].Bounds = new float[6];
                for (var j = 0; j < 6; j++)
                    Limbs[i].Bounds[j] = s.ReadFloat();
                Limbs[i].Size = s.ReadBytes(3);
                Limbs[i].Type = (NormalType)s.ReadByte();
            }

            for (var i = 0; i < LimbCount; i++)
            {
                s.Seek(802 + 28*LimbCount + LimbDataOffset[i], SeekOrigin.Begin);
                ReadVoxelData(s, Limbs[i]);
            }
        }
예제 #3
0
        static void ReadVoxelData(Stream s, VxlLimb l)
        {
            var baseSize = l.Size[0] * l.Size[1];
            var colStart = new int[baseSize];

            for (var i = 0; i < baseSize; i++)
            {
                colStart[i] = s.ReadInt32();
            }
            s.Seek(4 * baseSize, SeekOrigin.Current);
            var dataStart = s.Position;

            // Count the voxels in this limb
            l.VoxelCount = 0;
            for (var i = 0; i < baseSize; i++)
            {
                // Empty column
                if (colStart[i] == -1)
                {
                    continue;
                }

                s.Seek(dataStart + colStart[i], SeekOrigin.Begin);
                var z = 0;
                do
                {
                    z += s.ReadUInt8();
                    var count = s.ReadUInt8();
                    z            += count;
                    l.VoxelCount += count;
                    s.Seek(2 * count + 1, SeekOrigin.Current);
                } while (z < l.Size[2]);
            }

            // Read the data
            l.VoxelMap = new Dictionary <byte, VxlElement> [l.Size[0], l.Size[1]];
            for (var i = 0; i < baseSize; i++)
            {
                // Empty column
                if (colStart[i] == -1)
                {
                    continue;
                }

                s.Seek(dataStart + colStart[i], SeekOrigin.Begin);

                var  x = (byte)(i % l.Size[0]);
                var  y = (byte)(i / l.Size[0]);
                byte z = 0;
                l.VoxelMap[x, y] = new Dictionary <byte, VxlElement>();
                do
                {
                    z += s.ReadUInt8();
                    var count = s.ReadUInt8();
                    for (var j = 0; j < count; j++)
                    {
                        var v = new VxlElement();
                        v.Color  = s.ReadUInt8();
                        v.Normal = s.ReadUInt8();

                        l.VoxelMap[x, y].Add(z, v);
                        z++;
                    }
                    // Skip duplicate count
                    s.ReadUInt8();
                } while (z < l.Size[2]);
            }
        }
예제 #4
0
        void ReadVoxelData(Stream s, VxlLimb l)
        {
            var baseSize = l.Size[0]*l.Size[1];
            var colStart = new int[baseSize];
            for (var i = 0; i < baseSize; i++)
                colStart[i] = s.ReadInt32();
            s.Seek(4*baseSize, SeekOrigin.Current);
            var dataStart = s.Position;

            // Count the voxels in this limb
            l.VoxelCount = 0;
            for (var i = 0; i < baseSize; i++)
            {
                // Empty column
                if (colStart[i] == -1)
                    continue;

                s.Seek(dataStart + colStart[i], SeekOrigin.Begin);
                var z = 0;
                do
                {
                    z += s.ReadUInt8();
                    var count = s.ReadUInt8();
                    z += count;
                    l.VoxelCount += count;
                    s.Seek(2*count + 1, SeekOrigin.Current);
                } while (z < l.Size[2]);
            }

            // Read the data
            l.VoxelMap = new Dictionary<byte, VxlElement>[l.Size[0],l.Size[1]];
            for (var i = 0; i < baseSize; i++)
            {
                // Empty column
                if (colStart[i] == -1)
                    continue;

                s.Seek(dataStart + colStart[i], SeekOrigin.Begin);

                byte x = (byte)(i % l.Size[0]);
                byte y = (byte)(i / l.Size[0]);
                byte z = 0;
                l.VoxelMap[x,y] = new Dictionary<byte, VxlElement>();
                do
                {
                    z += s.ReadUInt8();
                    var count = s.ReadUInt8();
                    for (var j = 0; j < count; j++)
                    {
                        var v = new VxlElement();
                        v.Color = s.ReadUInt8();
                        v.Normal = s.ReadUInt8();

                        l.VoxelMap[x,y].Add(z, v);
                        z++;
                    }
                    // Skip duplicate count
                    s.ReadUInt8();
                } while (z < l.Size[2]);
            }
        }
예제 #5
0
        public VoxelRenderData GenerateRenderData(VxlLimb l)
        {
            Vertex[] v;
            try
            {
                v = GenerateSlicePlanes(l).SelectMany(x => x).ToArray();
            }
            catch (SheetOverflowException)
            {
                // Sheet overflow - allocate a new sheet and try once more
                Log.Write("debug", "Voxel sheet overflow! Generating new sheet");
                sheetBuilder = CreateSheetBuilder();
                v = GenerateSlicePlanes(l).SelectMany(x => x).ToArray();
            }

            vertices.Add(v);

            var start = totalVertexCount;
            var count = v.Length;
            totalVertexCount += count;
            return new VoxelRenderData(start, count, sheetBuilder.Current);
        }
예제 #6
0
        IEnumerable<Vertex[]> GenerateSlicePlanes(VxlLimb l)
        {
            Func<int,int,int,VxlElement> get = (x,y,z) =>
            {
                if (x < 0 || y < 0 || z < 0)
                    return null;

                if (x >= l.Size[0] || y >= l.Size[1] || z >= l.Size[2])
                    return null;

                var v = l.VoxelMap[(byte)x,(byte)y];
                if (v == null || !v.ContainsKey((byte)z))
                    return null;

                return l.VoxelMap[(byte)x,(byte)y][(byte)z];
            };

            // Cull slices without any visible faces
            var xPlanes = new bool[l.Size[0]+1];
            var yPlanes = new bool[l.Size[1]+1];
            var zPlanes = new bool[l.Size[2]+1];
            for (var x = 0; x < l.Size[0]; x++)
            {
                for (var y = 0; y < l.Size[1]; y++)
                {
                    for (var z = 0; z < l.Size[2]; z++)
                    {
                        if (get(x,y,z) == null)
                            continue;

                        // Only generate a plane if it is actually visible
                        if (!xPlanes[x] && get(x-1,y,z) == null)
                            xPlanes[x] = true;
                        if (!xPlanes[x+1] && get(x+1,y,z) == null)
                            xPlanes[x+1] = true;

                        if (!yPlanes[y] && get(x,y-1,z) == null)
                            yPlanes[y] = true;
                        if (!yPlanes[y+1] && get(x,y+1,z) == null)
                            yPlanes[y+1] = true;

                        if (!zPlanes[z] && get(x,y,z-1) == null)
                            zPlanes[z] = true;
                        if (!zPlanes[z+1] && get(x,y,z+1) == null)
                            zPlanes[z+1] = true;
                    }
                }
            }

            for (var x = 0; x <= l.Size[0]; x++)
                if (xPlanes[x])
                    yield return GenerateSlicePlane(l.Size[1], l.Size[2],
                        (u,v) => get(x, u, v),
                        (u,v) => get(x - 1, u, v),
                        (u,v) => new float[] {x, u, v});

            for (var y = 0; y <= l.Size[1]; y++)
                if (yPlanes[y])
                    yield return GenerateSlicePlane(l.Size[0], l.Size[2],
                        (u,v) => get(u, y, v),
                        (u,v) => get(u, y - 1, v),
                        (u,v) => new float[] {u, y, v});

            for (var z = 0; z <= l.Size[2]; z++)
                if (zPlanes[z])
                    yield return GenerateSlicePlane(l.Size[0], l.Size[1],
                        (u,v) => get(u, v, z),
                        (u,v) => get(u, v, z - 1),
                        (u,v) => new float[] {u, v, z});
        }