protected byte calculateOpacity(Voxel[,,] original, uint x, uint y, uint z, float strength) { double opacity = original[x, y, z].averageOpacity(); int minX = Mathf.Max((int)x - blurRadius, 0); int maxX = Mathf.Min((int)x + blurRadius, original.GetLength(0)); int minY = Mathf.Max((int)y - blurRadius, 0); int maxY = Mathf.Min((int)y + blurRadius, original.GetLength(1)); int minZ = Mathf.Max((int)z - blurRadius, 0); int maxZ = Mathf.Min((int)z + blurRadius, original.GetLength(2)); int count = 0; for (int xi = minX; xi < maxX; ++xi) { for (int yi = minY; yi < maxY; ++yi) { for (int zi = minZ; zi < maxZ; ++zi) { ++count; Vector3 diff = new Vector3(x - xi, y - yi, z - zi); float dis = diff.magnitude; Voxel value = original[xi, yi, zi]; if (dis < 0.5f || value == null) continue; float factor = Mathf.Max((1 - dis / blurRadius) * strength * 0.1f, 0); opacity = opacity * (1 - factor) + value.averageOpacity() * factor; } } } return (byte)Mathf.Min((float)opacity, byte.MaxValue); }
/* * MUST BE CALLED BEFORE polygonize!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ public static void setup(float voxelSize, byte isolevel, ref Dictionary<int, object> vertices, ref Dictionary<int, byte> materials, ref Voxel[, ,] voxels, Vector3 offset, Vector3[] meshVerts) { MarchingCubes.isolevel = isolevel; MarchingCubes.vertices = vertices; MarchingCubes.materials = materials; MarchingCubes.voxels = voxels; MarchingCubes.voxelSize = voxelSize; MarchingCubes.offset = offset; MarchingCubes.meshVerts = meshVerts; }
public override Voxel mutate(LocalApplication app, Index p, LocalAction action, Voxel original) { CubeAction cAction = (CubeAction)action; byte newOpacity = (byte)((original.averageOpacity() * (1 - cAction.percentInside) + value.averageOpacity() * (cAction.percentInside))); byte newSubstance = original.averageMaterialType(); if (overwriteSubstance && cAction.percentInside > 0.5) newSubstance = value.averageMaterialType(); if (!overwriteShape) newOpacity = original.averageOpacity(); return new Voxel(newSubstance, newOpacity); }
protected override Voxel mutate(Application app, Index pos, Action action, Voxel original) { BlurApp bApp = (BlurApp)app; BlurAction bAction = (BlurAction)action; float dis = Mathf.Sqrt(bAction.disSqr); float actualStrength = strength * (1 - (dis / bApp.radius)); if (actualStrength <= 0) return original; byte newOpacity = calculateOpacity(bApp.original, pos.x - app.min.x, pos.y - app.min.y, pos.z - app.min.z, actualStrength); return new Voxel(original.averageMaterialType(), newOpacity); }
public CubeModifier(VoxelTree control, Vector3 worldPosition, Vector3 worldDimensions, VoxelHolder value, bool updateMesh) : base(control, updateMesh) { this.value = value.toVoxel(); Vector3 dimensions = worldDimensions / control.voxelSize(); min = control.transform.InverseTransformPoint(worldPosition) / control.voxelSize() - dimensions /2 -Vector3.one *0.5f; max = min + dimensions; setMinMax(min, max); // apply(); }
public override Voxel mutate(LocalApplication app, Index p, LocalAction action, Voxel original) { SphereApp sApp = (SphereApp)app; SphereAction sAction = (SphereAction)action; float dis = Mathf.Sqrt(sAction.disSqr); float percentInside = Mathf.Min((sAction.maxRadius -dis) /(sAction.maxRadius -sAction.minRadius), 1); byte newOpacity = (byte)(original.averageOpacity() * (1 -percentInside) + value.averageOpacity() * percentInside); byte newSubstance = original.averageMaterialType(); if (overwriteSubstance && (dis < sApp.radius || percentInside > 0.5f)) newSubstance = value.averageMaterialType(); if (!overwriteShape) newOpacity = original.averageOpacity(); return new Voxel(newSubstance, newOpacity); }
public override int cleanArtifacts(out Voxel simplified, VoxelHolder head, byte level, byte maxLevel, int x, int y, int z) { simplified = null; if (level < maxLevel) return 0; Voxel[,,] array = new Voxel[3, 3, 3]; head.putInArray(ref array, new Index(level), (uint)x -1, (uint)y -1, (uint)z -1, (uint)x +2, (uint)y +2, (uint)z +2); bool solid = isSolid(); foreach(Voxel vox in array) { if (vox != null && vox.isSolid() != solid) return 0; } simplified = solid? full : empty; return 1; }
public override void putInArray(byte level, ref Voxel[,,] array, int x, int y, int z, int xMin, int yMin, int zMin, int xMax, int yMax, int zMax) { int size = 1 << (VoxelBlock.CHILD_COUNT_POWER *level); int xStart = Mathf.Max(x, xMin); int xEnd = Mathf.Min(x +size, xMax); int yStart = Mathf.Max(y, yMin); int yEnd = Mathf.Min(y +size, yMax); int zStart = Mathf.Max(z, zMin); int zEnd = Mathf.Min(z +size, zMax); for(int xi=xStart; xi<xEnd; ++xi) { for(int yi=yStart; yi<yEnd; ++yi) { for(int zi=zStart; zi<zEnd; ++zi) { array[xi -xMin, yi -yMin, zi -zMin] = this; } } } }
public override Voxel mutate(LocalApplication app, Index p, LocalAction action, Voxel original) { SphereApp sApp = (SphereApp)app; SphereAction sAction = (SphereAction)action; float dis = Mathf.Sqrt(sAction.disSqr); byte newOpacity = (dis <= sAction.minRadius) ? value.averageOpacity() : (byte)((original.averageOpacity() * (dis - sAction.minRadius) + value.averageOpacity() * (sAction.maxRadius - dis)) / 2); byte newSubstance = original.averageMaterialType(); if (newOpacity >= 2 * original.averageOpacity() || (overwriteSubstance && dis < sApp.radius)) newSubstance = value.averageMaterialType(); if (!overwriteShape) newOpacity = original.averageOpacity(); return new Voxel(newSubstance, newOpacity); }
public void set(byte detailLevel, int x, int y, int z, Voxel value, Tree control) { if (detailLevel > 0) { short factor = (short)(1 << (detailLevel - CHILD_COUNT_POWER)); byte xi = (byte)(x / factor); byte yi = (byte)(y / factor); byte zi = (byte)(z / factor); if (detailLevel == CHILD_COUNT_POWER) { children[xi, yi, zi] = value; } else { if (children[xi, yi, zi].GetType() == typeof(Voxel)) { if (children[xi, yi, zi].Equals(value)) { ++skippedSubdivisions; return; } children[xi, yi, zi] = new VoxelBlock((Voxel)children[xi, yi, zi]); } ((VoxelBlock)children[xi, yi, zi]).set((byte)(detailLevel - CHILD_COUNT_POWER), x - xi * factor, y - yi * factor, z - zi * factor, value, control); } } else set(value); }
public override Voxel mutate(LocalApplication app, Index p, LocalAction action, Voxel original) { return child.mutate(((LineApplication)app).childApp, p, action, original); }
public override int canSimplify(out Voxel simplification) { bool canSimplify = true; int count = 0; simplification = null; for (int xi = 0; xi<CHILD_DIMENSION; ++xi) { for (int yi = 0; yi<CHILD_DIMENSION; ++yi) { for (int zi = 0; zi<CHILD_DIMENSION; ++zi) { Voxel child = null; count += children[xi, yi, zi].canSimplify(out child); if (child != null) { children[xi, yi, zi] = child; if (simplification == null) simplification = child; else canSimplify = simplification == child && canSimplify; } else { canSimplify = false; } } } } if (canSimplify) ++count; else simplification = null; return count; }
public void setToHeightmap(byte detailLevel, int x, int y, int z, ref float[,] map, byte[,] mats, OcTree control) { if (detailLevel <= CHILD_COUNT_POWER) { for (int xi = 0; xi < CHILD_DIMENSION; ++xi) { for (int zi = 0; zi < CHILD_DIMENSION; ++zi) { for (int yi = 0; yi < CHILD_DIMENSION; ++yi) { if (yi + y >= map[x + xi, z + zi]) break; else if (yi + y >= map[x + xi, z + zi] - 1) { if (mats[x + xi, z + zi] == byte.MaxValue) children[xi, yi, zi] = Voxel.empty; else children[xi, yi, zi] = new Voxel(mats[x + xi, z + zi], (byte)((map[x + xi, z + zi] - yi - y) * byte.MaxValue)); } else { if (mats[x + xi, z + zi] == byte.MaxValue) children[xi, yi, zi] = Voxel.empty; else children[xi, yi, zi] = new Voxel(mats[x + xi, z + zi], byte.MaxValue); } } } } } else { int multiplier = (1 << (detailLevel - CHILD_COUNT_POWER)); for (int xi = 0; xi < CHILD_DIMENSION; ++xi) { for (int zi = 0; zi < CHILD_DIMENSION; ++zi) { int xMax = x + (xi + 1) * multiplier; int zMax = z + (zi + 1) * multiplier; float yMin = float.MaxValue; float yMax = 0; bool multipleMaterials = false; byte material = mats[x, z]; for (int xPos = x + xi * multiplier; xPos < xMax; ++xPos) { for (int zPos = z + zi * multiplier; zPos < zMax; ++zPos) { if (map[xPos, zPos] < yMin) yMin = map[xPos, zPos]; if (map[xPos, zPos] > yMax) yMax = map[xPos, zPos]; if (mats[xPos, zPos] != material) multipleMaterials = true; } } if (multipleMaterials) yMin = 0; int firstUnsolidBlock = Mathf.Min(((int)(yMin - y)) / multiplier, CHILD_DIMENSION); int lastUnsolidBlock = Mathf.Min(((int)(yMax - y)) / multiplier, CHILD_DIMENSION - 1); int yi = 0; for (; yi < firstUnsolidBlock; ++yi) { if (mats[x + xi * multiplier, z + zi * multiplier] == byte.MaxValue) children[xi, yi, zi] = Voxel.empty; else children[xi, yi, zi] = new Voxel(mats[x + xi * multiplier, z + zi * multiplier], byte.MaxValue); } if (lastUnsolidBlock < 0) continue; for (; yi <= lastUnsolidBlock; ++yi) { VoxelBlock newChild = new VoxelBlock(); newChild.setToHeightmap((byte)(detailLevel - CHILD_COUNT_POWER), x + xi * multiplier, y + yi * multiplier, z + zi * multiplier, ref map, mats, control); children[xi, yi, zi] = newChild; } } } } control.dirty = true; }
public VoxelBlock(Voxel fillValue) { children = new VoxelHolder[CHILD_DIMENSION, CHILD_DIMENSION, CHILD_DIMENSION]; ++blockCount; set(fillValue); }
public void setToHeightmap(byte detailLevel, int x, int y, int z, ref float[,] map, byte material, OcTree control) { if (detailLevel <= CHILD_COUNT_POWER) { for (int xi = 0; xi < CHILD_DIMENSION; ++xi) { for (int zi = 0; zi < CHILD_DIMENSION; ++zi) { for (int yi = 0; yi < CHILD_DIMENSION; ++yi) { if (yi + y >= map[x + xi, z + zi]) break; else if (material == byte.MaxValue) { children[xi, yi, zi] = Voxel.empty; } else { if (yi + y >= map[x + xi, z + zi] - 1) { byte opacity = (byte)((map[x + xi, z + zi] - yi - y) * byte.MaxValue); if (opacity > control.isoLevel || children[xi, yi, zi].averageOpacity() <= opacity) children[xi, yi, zi] = new Voxel(material, opacity); } else { children[xi, yi, zi] = new Voxel(material, byte.MaxValue); } } } } } } else { int multiplier = (1 << (detailLevel - CHILD_COUNT_POWER)); for (int xi = 0; xi < CHILD_DIMENSION; ++xi) { for (int zi = 0; zi < CHILD_DIMENSION; ++zi) { int xMax = x + (xi + 1) * multiplier; int zMax = z + (zi + 1) * multiplier; float yMin = float.MaxValue; float yMax = 0; for (int xPos = x + xi * multiplier; xPos < xMax; ++xPos) { for (int zPos = z + zi * multiplier; zPos < zMax; ++zPos) { if (map[xPos, zPos] < yMin) yMin = map[xPos, zPos]; if (map[xPos, zPos] > yMax) yMax = map[xPos, zPos]; } } int firstUnsolidBlock = Mathf.Min(((int)(yMin - y)) / multiplier, CHILD_DIMENSION); int lastUnsolidBlock = Mathf.Min(((int)(yMax - y)) / multiplier, CHILD_DIMENSION - 1); int yi = 0; for (; yi < firstUnsolidBlock; ++yi) { if (material == byte.MaxValue) children[xi, yi, zi] = Voxel.empty; else children[xi, yi, zi] = new Voxel(material, byte.MaxValue); } if (lastUnsolidBlock < 0) continue; for (; yi <= lastUnsolidBlock; ++yi) { if (children[xi, yi, zi].GetType() == typeof(Voxel)) children[xi, yi, zi] = new VoxelBlock((Voxel)children[xi, yi, zi]); ((VoxelBlock)children[xi, yi, zi]).setToHeightmap((byte)(detailLevel - CHILD_COUNT_POWER), x + xi * multiplier, y + yi * multiplier, z + zi * multiplier, ref map, material, control); } } } } control.dirty = true; }
public void addEdge(VoxelUpdateInfo info, byte x, byte y, byte z) { if (vertices == null) return; bool recalculate = false; Voxel[, ,] voxels = new Voxel[VERTEX_DIMENSION, VERTEX_DIMENSION, VERTEX_DIMENSION]; if (x == 0/* && xExtend == 0*/) { recalculate = true; xExtend = 1; for (byte yi = (byte)(1 - yExtend); yi < yDim; ++yi) { for (byte zi = (byte)(1 - zExtend); zi < zDim; ++zi) { voxels[0, yi, zi] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - xExtend, VOXEL_DIMENSION - 1 + yi, VOXEL_DIMENSION - 1 + zi).toVoxel(); voxels[1, yi, zi] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION, VOXEL_DIMENSION - 1 + yi, VOXEL_DIMENSION - 1 + zi).toVoxel(); } } } else if (x == 2/* && xDim < VERTEX_DIMENSION*/) { recalculate = true; xDim = VERTEX_DIMENSION; for (byte yi = (byte)(1 - yExtend); yi < yDim; ++yi) { for (byte zi = (byte)(1 - zExtend); zi < zDim; ++zi) { voxels[VOXEL_DIMENSION + 1, yi, zi] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION * 2, VOXEL_DIMENSION - 1 + yi, VOXEL_DIMENSION - 1 + zi).toVoxel(); voxels[VOXEL_DIMENSION, yi, zi] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION * 2 - 1, VOXEL_DIMENSION - 1 + yi, VOXEL_DIMENSION - 1 + zi).toVoxel(); } } } else if (y == 0/* && yExtend == 0*/) { recalculate = true; yExtend = 1; for (byte xi = (byte)(1 - xExtend); xi < xDim; ++xi) { for (byte zi = (byte)(1 - zExtend); zi < zDim; ++zi) { voxels[xi, 0, zi] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + xi, VOXEL_DIMENSION - yExtend, VOXEL_DIMENSION - 1 + zi).toVoxel(); voxels[xi, 1, zi] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + xi, VOXEL_DIMENSION, VOXEL_DIMENSION - 1 + zi).toVoxel(); } } } else if (y == 2/* && yDim < VERTEX_DIMENSION*/) { recalculate = true; yDim = VERTEX_DIMENSION; for (byte xi = (byte)(1 - xExtend); xi < xDim; ++xi) { for (byte zi = (byte)(1 - zExtend); zi < zDim; ++zi) { voxels[xi, VOXEL_DIMENSION + 1, zi] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + xi, VOXEL_DIMENSION * 2, VOXEL_DIMENSION - 1 + zi).toVoxel(); voxels[xi, VOXEL_DIMENSION, zi] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + xi, VOXEL_DIMENSION * 2 - 1, VOXEL_DIMENSION - 1 + zi).toVoxel(); } } } else if (z == 0/* && zExtend == 0*/) { recalculate = true; zExtend = 1; for (byte xi = (byte)(1 - xExtend); xi < xDim; ++xi) { for (byte yi = (byte)(1 - yExtend); yi < yDim; ++yi) { voxels[xi, yi, 0] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + xi, VOXEL_DIMENSION - 1 + yi, VOXEL_DIMENSION - zExtend).toVoxel(); voxels[xi, yi, 1] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + xi, VOXEL_DIMENSION - 1 + yi, VOXEL_DIMENSION).toVoxel(); } } } else if (z == 2/* && zDim < VERTEX_DIMENSION*/) { recalculate = true; zDim = VERTEX_DIMENSION; for (byte xi = (byte)(1 - xExtend); xi < xDim; ++xi) { for (byte yi = (byte)(1 - yExtend); yi < yDim; ++yi) { voxels[xi, yi, VOXEL_DIMENSION + 1] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + xi, VOXEL_DIMENSION - 1 + yi, VOXEL_DIMENSION * 2).toVoxel(); voxels[xi, yi, VOXEL_DIMENSION] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + xi, VOXEL_DIMENSION - 1 + yi, VOXEL_DIMENSION * 2 - 1).toVoxel(); } } } if (recalculate) { Queue<int[]> triangleSet = new Queue<int[]>(); MarchingCubes.setup(info.size / VOXEL_DIMENSION, control.isoLevel, ref vertices, ref vertexSubstances, ref voxels, position - new Vector3(0.5f, 0.5f, 0.5f) * size / VOXEL_DIMENSION, VERTS); byte xStart = (byte)(1 - xExtend + (VOXEL_DIMENSION + xExtend - 1) * (x / 2)); byte xEnd = (byte)(2 + (xDim - 2) * ((x + 1) / 2)); byte yStart = (byte)(1 - yExtend + (VOXEL_DIMENSION + yExtend - 1) * (y / 2)); byte yEnd = (byte)(2 + (yDim - 2) * ((y + 1) / 2)); byte zStart = (byte)(1 - zExtend + (VOXEL_DIMENSION + zExtend - 1) * (z / 2)); byte zEnd = (byte)(2 + (zDim - 2) * ((z + 1) / 2)); for (byte xi = xStart, x1 = (byte)(xi + 1); x1 < xEnd; xi = x1++) { for (byte yi = yStart, y1 = (byte)(yi + 1); y1 < yEnd; yi = y1++) { for (byte zi = zStart, z1 = (byte)(zi + 1); z1 < zEnd; zi = z1++) { int[] tris = MarchingCubes.lookupTriangles(xi, yi, zi, x1, y1, z1); if (tris == null) continue; triangleSet.Enqueue(tris); } } } if (vertices.Count < 1) { return; } List<int> newTriangles = new List<int>(TRIS); List<Vector3> newVertices = new List<Vector3>(VERTS); List<Vector3> newNorms = new List<Vector3>(NORMS); int tri = 0; while (triangleSet.Count > 0) { int[] triangleList = triangleSet.Dequeue(); for (int i = 0; i < triangleList.Length; ++i) { if (vertices[triangleList[i]].GetType() == typeof(Vector3)) { newVertices.Add((Vector3)vertices[triangleList[i]]); newNorms.Add(Vector3.zero); vertices[triangleList[i]] = newVertices.Count - 1; } newTriangles.Add((int)vertices[triangleList[i]]); } tri += triangleList.Length; } Vector3[] finalNorms = new Vector3[newNorms.Count]; Array.Copy(NORMS, finalNorms, NORMS.Length); int oldNormCount = NORMS.Length; VERTS = newVertices.ToArray(); TRIS = newTriangles.ToArray(); calcNorms(); Array.Copy(NORMS, oldNormCount, finalNorms, oldNormCount, finalNorms.Length - oldNormCount); NORMS = finalNorms; } alignEdge(info, x, y, z); control.enqueueMeshApply(new ApplyMeshJob(this, info.detailLevel, info.x, info.y, info.z)); }
public CubeMutator(OcTree control, Vector3 worldPosition, Vector3 worldDimensions, VoxelHolder value, bool updateMesh) { this.worldPosition = worldPosition; this.worldDimensions = worldDimensions; this.value = value.toVoxel(); }
protected override Voxel mutate(Application app, Index p, Action action, Voxel original) { return mutate((LocalApplication)app, p, (LocalAction)action, original); }
public abstract void putInArray(ref Voxel[,,] array, Index position, uint xMin, uint yMin, uint zMin, uint xMax, uint yMax, uint zMax);
public abstract int cleanArtifacts(out Voxel simplified, VoxelHolder head, byte level, byte maxLevel, int x, int y, int z);
public abstract int canSimplify(out Voxel simplification);
/* Linearly interpolate the position where an isosurface cuts an edge between two vertices, each with their own scalar value */ public static void stretchVertex(int x1, int y1, int z1, int x2, int y2, int z2, Voxel valp1, Voxel valp2, int vox) { float mu = (isolevel - valp1.opacity) / ((float)(valp2.opacity - valp1.opacity)); //float mu = 0.5f; Vector3 pos = new Vector3(x1 + mu * (x2 - x1), y1 + mu * (y2 - y1), z1 + mu * (z2 - z1)) * voxelSize + offset; if (vertices.ContainsKey(vox) && vertices[vox].GetType() == typeof(int)) meshVerts[(int)vertices[vox]] = pos; else vertices[vox] = pos; if (valp1.opacity > valp2.opacity) materials[vox] = valp1.matType; else materials[vox] = valp2.matType; //vertices[vox] = new Vector3(x1, y1, z1) *voxelSize +offset; //float mu = (valp1) / ((float)(byte.MaxValue)); //vertices[vox] = new Vector3(x1 + mu * (x2 - x1), y1 + mu * (y2 - y1), z1 + mu * (z2 - z1)) * voxelSize; }
public override int canSimplify(out Voxel simplification) { simplification = this; return 0; }
public SphereMutator(Vector3 worldPosition, float worldRadius, Voxel value) { this.value = value; this.worldPosition = worldPosition; this.worldRadius = worldRadius; }
public abstract Voxel mutate(LocalApplication app, Index p, LocalAction action, Voxel original);
public override int cleanArtifacts(out Voxel simplified, VoxelHolder head, byte level, byte maxLevel, int x, int y, int z) { int size = 1 << (CHILD_COUNT_POWER *level -CHILD_COUNT_POWER); int count = 0; for (int xi = 0; xi<CHILD_DIMENSION; ++xi) { for (int yi = 0; yi<CHILD_DIMENSION; ++yi) { for (int zi = 0; zi<CHILD_DIMENSION; ++zi) { Voxel newChild = null; count += children[xi, yi, zi].cleanArtifacts(out newChild, head, (byte)(level +CHILD_COUNT_POWER), maxLevel, x +xi *size, y +yi *size, z +zi *size); if (newChild != null) children[xi, yi, zi] = newChild; } } } simplified = null; return count; }
//private static int getX(int index, int dimension) { // return (y * VERTEX_DIMENSION + z) * VERTEX_DIMENSION + x; //} //private static int getY(int index, int dimension) { // return ((VERTEX_DIMENSION + x) * VERTEX_DIMENSION + z) * VERTEX_DIMENSION + y; //} //private static int getZ(int index, int dimension) { // return ((VERTEX_DIMENSION * 2 + x) * VERTEX_DIMENSION + y) * VERTEX_DIMENSION + z; //} //private static int getDimension(int index) { // return index / (VERTEX_DIMENSION * VERTEX_DIMENSION * VERTEX_DIMENSION); //} private Voxel[, ,] createVoxelArray(VoxelUpdateInfo info) { setDimensions(info); Voxel[, ,] voxels = new Voxel[VERTEX_DIMENSION, VERTEX_DIMENSION, VERTEX_DIMENSION]; for (byte y = (byte)(1 - yExtend); y < yDim; ++y) { for (byte z = (byte)(1 - zExtend); z < zDim; ++z) { voxels[1 - xExtend, y, z] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - xExtend, VOXEL_DIMENSION - 1 + y, VOXEL_DIMENSION - 1 + z).toVoxel(); } } for (byte x = (byte)(2 - xExtend); x < xDim; ++x) { for (byte z = (byte)(1 - zExtend); z < zDim; ++z) { voxels[x, 1 - yExtend, z] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + x, VOXEL_DIMENSION - yExtend, VOXEL_DIMENSION - 1 + z).toVoxel(); } } for (byte x = (byte)(2 - xExtend); x < xDim; ++x) { for (byte y = (byte)(2 - yExtend); y < yDim; ++y) { voxels[x, y, 1 - zExtend] = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION - 1 + x, VOXEL_DIMENSION - 1 + y, VOXEL_DIMENSION - zExtend).toVoxel(); } } return voxels; }
public override void putInArray(ref Voxel[,,] array, Index position, uint xMin, uint yMin, uint zMin, uint xMax, uint yMax, uint zMax) { uint size = 1u << (CHILD_COUNT_POWER *position.depth -CHILD_COUNT_POWER); for(uint xi=0; xi<CHILD_DIMENSION; ++xi) { uint xPos = position.x +xi *size; if (xPos > xMax || xPos +size < xMin) continue; for (uint yi=0; yi<CHILD_DIMENSION; ++yi) { uint yPos = position.y +yi *size; if (yPos > yMax || yPos +size < yMin) continue; for (uint zi=0; zi<CHILD_DIMENSION; ++zi) { uint zPos = position.z +zi *size; if (zPos > zMax || zPos +size < zMin) continue; children[xi, yi, zi].putInArray(ref array, new Index((byte)(position.depth -1), xPos, yPos, zPos), xMin, yMin, zMin, xMax, yMax, zMax); } } } }
public Voxel(Voxel other) { this.matType = other.matType; this.opacity = other.opacity; }
public void set(Voxel fillValue) { for (byte xi = 0; xi < CHILD_DIMENSION; ++xi) for (byte yi = 0; yi < CHILD_DIMENSION; ++yi) for (byte zi = 0; zi < CHILD_DIMENSION; ++zi) children[xi, yi, zi] = fillValue; }