예제 #1
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));
        }
예제 #2
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 }));
                }
            }
        }