public void clear() { // lock (this) { //MonoBehaviour.print("Deleted Renderer"); if (control != null) { lock (control) { control.renderers.Remove(index); if (control.getHead() != null) { VoxelHolder block = control.getHead().get(index); if (block.GetType() == typeof(VoxelBlock) && ((VoxelBlock)block).renderer == this) { ((VoxelBlock)block).renderer = null; } } } } removePolyCount(); if (obs != null) { foreach (GameObject ob in obs) { GameObject.DestroyImmediate(ob); } } // if (collider != null) // GameObject.DestroyImmediate(collider); // } }
public void relinkRenderers(Dictionary <VoxelIndex, List <GameObject> > meshes) { lock (this) { //print("Start Renderers: " + renderers.Count); foreach (VoxelIndex index in meshes.Keys) { List <GameObject> objects = meshes[index]; //print("Mesh object count: " + objects.Count); VoxelRenderer rend; renderers.TryGetValue(index, out rend); if (rend == null) { rend = new VoxelRenderer(index, this); renderers[index] = rend; //} else { // print("already had renderer"); } VoxelHolder block = head.get(index); if (block is VoxelBlock) { //print("linking"); ((VoxelBlock)block).renderer = rend; //} else { // print("NOT BLOCK!"); } rend.obs = objects.ToArray(); } //print("End Renderers: " + renderers.Count); } }
protected override VoxelHolder modifyVoxel(VoxelHolder original, int x, int y, int z) { double percentInside = 1; percentInside *= percentOverlapping(x, min.x); percentInside *= percentOverlapping(y, min.y); percentInside *= percentOverlapping(z, min.z); percentInside *= percentOverlapping(-x, -max.x); percentInside *= percentOverlapping(-y, -max.y); percentInside *= percentOverlapping(-z, -max.z); if (percentInside <= 0.001) { return(original); } if (percentInside >= 0.999) { return(new Voxel(value.averageMaterialType(), overwriteShape? value.averageOpacity(): original.averageOpacity())); } byte newOpacity = (byte)((original.averageOpacity() * (1 - percentInside) + value.averageOpacity() * (percentInside))); byte newSubstance = original.averageMaterialType(); if (newOpacity >= 2 * original.averageOpacity() || (overwriteSubstance && percentInside > 0.5)) { newSubstance = value.averageMaterialType(); } if (!overwriteShape) { newOpacity = original.averageOpacity(); } return(new Voxel(newSubstance, newOpacity)); }
protected override VoxelHolder modifyVoxel(VoxelHolder original, int x, int y, int z) { float dis = (center - new Vector3(x, y, z)).magnitude; if (dis > maxDis) { return(original); } if (dis < minDis) { return(new Voxel(value.averageMaterialType(), overwriteShape? value.averageOpacity(): original.averageOpacity())); } byte newOpacity = (byte)((original.averageOpacity() * (dis - minDis) + value.averageOpacity() * (maxDis - dis)) / 2); byte newSubstance = value.averageMaterialType(); if (newOpacity >= 2 * original.averageOpacity() || (overwriteSubstance && dis < radius)) { newSubstance = value.averageMaterialType(); } if (!overwriteShape) { newOpacity = original.averageOpacity(); } return(new Voxel(newSubstance, newOpacity)); }
public CubeModifier(VoxelTree control, Vector3 worldPosition, Vector3 worldDimensions, VoxelHolder value, bool updateMesh) : base(control, updateMesh) { this.value = value; Vector3 dimensions = worldDimensions / control.voxelSize(); min = control.transform.InverseTransformPoint(worldPosition) / control.voxelSize() - dimensions /2 - Vector3.one * (control.voxelSize() / 2); max = min + dimensions; apply(); }
public SphereModifier(VoxelTree control, Vector3 worldPosition, float worldRadius, VoxelHolder value, bool updateMesh) : base(control, updateMesh) { this.value = value; Vector3 radiusCube = new Vector3(worldRadius, worldRadius, worldRadius) / control.voxelSize(); min = control.transform.InverseTransformPoint(worldPosition) / control.voxelSize() - radiusCube - Vector3.one * (control.voxelSize() / 2); max = min + radiusCube * 2; apply(); }
protected override VoxelHolder modifyVoxel(VoxelHolder original, int x, int y, int z) { float dis = (center - new Vector3(x, y, z)).magnitude; float actualStrength = strength * (1 - (dis / radius)); if (actualStrength <= 0) { return(original); } byte newOpacity = calculateOpacity(x - minX, y - minY, z - minZ, actualStrength); return(new Voxel(original.averageMaterialType(), newOpacity)); }
public SphereModifier(VoxelTree control, Vector3 worldPosition, float worldRadius, VoxelHolder value, bool updateMesh) : base(control, updateMesh) { this.value = value; Vector3 radiusCube = new Vector3(worldRadius, worldRadius, worldRadius) / control.voxelSize(); Vector3 min = control.transform.InverseTransformPoint(worldPosition) / control.voxelSize() - radiusCube -Vector3.one *0.5f; Vector3 max = min + radiusCube * 2; center = (min + max) / 2; radius = center.x - min.x; minDis = (radius - 1); maxDis = (radius + 1); setMinMax(min, max); // apply(); }
public VoxelBlock(BinaryReader reader) { children = new VoxelHolder[CHILD_DIMENSION, CHILD_DIMENSION, CHILD_DIMENSION]; ++blockCount; 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] = VoxelHolder.deserialize(reader); } } } }
public VoxelUpdateInfo(float size, VoxelHolder main, Tree control) : this() { this.size = size; this.detailLevel = 0; this.control = control; x = y = z = 0; for (byte xi = 0; xi < DIMENSION; ++xi) { for (byte yi = 0; yi < DIMENSION; ++yi) { for (byte zi = 0; zi < DIMENSION; ++zi) { blocks[xi, yi, zi] = Voxel.empty; } } } blocks[1, 1, 1] = main; }
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 SphereModifier(VoxelTree control, Vector3 worldPosition, float worldRadius, VoxelHolder value, bool updateMesh) : base(control, updateMesh) { this.value = value; Vector3 radiusCube = new Vector3(worldRadius, worldRadius, worldRadius) / control.voxelSize(); Vector3 min = control.transform.InverseTransformPoint(worldPosition) / control.voxelSize() - radiusCube - Vector3.one * 0.5f; Vector3 max = min + radiusCube * 2; center = (min + max) / 2; radius = center.x - min.x; minDis = (radius - 1); maxDis = (radius + 1); setMinMax(min, max); // apply(); }
public static VoxelHolder setSphere(VoxelHolder original, int x, int y, int z, Vector3 min, Vector3 max, VoxelHolder val) { Vector3 center = (min + max) / 2; float radius = center.x - min.x; float minDis = (radius - 1); float maxDis = (radius + 1); float dis = (center - new Vector3(x, y, z)).magnitude; if (dis > maxDis) return original; if (dis < minDis) return val; byte newOpacity = (byte)((original.averageOpacity() * (dis - minDis) + val.averageOpacity() * (maxDis - dis)) /2); if ((dis - minDis) > 0.5f) return new Voxel(val.averageMaterialType(), newOpacity); return new Voxel(original.averageMaterialType(), newOpacity); }
protected override VoxelHolder modifyVoxel(VoxelHolder original, int x, int y, int z) { float dis = (center - new Vector3(x, y, z)).magnitude; if (dis > maxDis) return original; if (dis < minDis) return new Voxel(value.averageMaterialType(), overwriteShape? value.averageOpacity(): original.averageOpacity()); byte newOpacity = (byte)((original.averageOpacity() * (dis - minDis) + value.averageOpacity() * (maxDis - dis)) / 2); byte newSubstance = value.averageMaterialType(); if (newOpacity >= 2 *original.averageOpacity() || (overwriteSubstance && dis < radius)) newSubstance = value.averageMaterialType(); if (!overwriteShape) newOpacity = original.averageOpacity(); return new Voxel(newSubstance, newOpacity); }
protected override VoxelHolder modifyVoxel(VoxelHolder original, int x, int y, int z) { Vector3 center = (min + max) / 2; float radius = center.x - min.x; float minDis = (radius - 1); float maxDis = (radius + 1); float dis = (center - new Vector3(x, y, z)).magnitude; if (dis > maxDis) return original; if (dis < minDis) return value; byte newOpacity = (byte)((original.averageOpacity() * (dis - minDis) + value.averageOpacity() * (maxDis - dis)) / 2); if (newOpacity >= 2 *original.averageOpacity() || (overwriteSubstance && dis < radius)) return new Voxel(value.averageMaterialType(), newOpacity); return new Voxel(original.averageMaterialType(), newOpacity); }
public void OnAfterDeserialize() { // clearRenderers(); //print("Deserializing"); lock (this) { if (voxelData.Length > 0) { MemoryStream stream = new MemoryStream(voxelData); BinaryReader reader = new BinaryReader(stream); head = (VoxelBlock)VoxelHolder.deserialize(reader); stream.Close(); } // relink renderers //relinkRenderers(); enqueueJob(new LinkRenderersJob(this)); } }
public VoxelUpdateInfo(float size, VoxelHolder main, VoxelTree control) : this() { this.size = size; this.detailLevel = 0; this.control = control; x = y = z = 0; for (byte xi = 0; xi < DIMENSION; ++xi) { for (byte yi = 0; yi < DIMENSION; ++yi) { for (byte zi = 0; zi < DIMENSION; ++zi) { blocks[xi, yi, zi] = Voxel.empty; } } } blocks[1, 1, 1] = main; }
public bool import(string fileName) { clearRenderers(); Stream stream = File.OpenRead(fileName); BinaryReader reader = new BinaryReader(stream); ulong fileFormatVersion = reader.ReadUInt64(); if (fileFormatVersion != FILE_FORMAT_VERSION) { stream.Close(); print("Wrong voxel file format version: " + fileFormatVersion + ", should be " + FILE_FORMAT_VERSION); return(false); } else { head = (VoxelBlock)VoxelHolder.deserialize(reader); dirty = true; stream.Close(); return(true); } }
protected override VoxelHolder modifyVoxel(VoxelHolder original, int x, int y, int z) { double percentInside = 1; percentInside *= percentOverlapping(x, min.x); percentInside *= percentOverlapping(y, min.y); percentInside *= percentOverlapping(z, min.z); percentInside *= percentOverlapping(-x, -max.x); percentInside *= percentOverlapping(-y, -max.y); percentInside *= percentOverlapping(-z, -max.z); if (percentInside <= 0.001) return original; if (percentInside >= 0.999) return new Voxel(value.averageMaterialType(), overwriteShape? value.averageOpacity(): original.averageOpacity()); byte newOpacity = (byte)((original.averageOpacity() * (1 -percentInside) + value.averageOpacity() * (percentInside))); byte newSubstance = original.averageMaterialType(); if (newOpacity >= 2 *original.averageOpacity() || (overwriteSubstance && percentInside > 0.5)) newSubstance = value.averageMaterialType(); if (!overwriteShape) newOpacity = original.averageOpacity(); return new Voxel(newSubstance, newOpacity); }
public static VoxelHolder setSphere(VoxelHolder original, int x, int y, int z, Vector3 min, Vector3 max, VoxelHolder val) { Vector3 center = (min + max) / 2; float radius = center.x - min.x; float minDis = (radius - 1); float maxDis = (radius + 1); float dis = (center - new Vector3(x, y, z)).magnitude; if (dis > maxDis) { return(original); } if (dis < minDis) { return(val); } byte newOpacity = (byte)((original.averageOpacity() * (dis - minDis) + val.averageOpacity() * (maxDis - dis)) / 2); if ((dis - minDis) > 0.5f) { return(new Voxel(val.averageMaterialType(), newOpacity)); } return(new Voxel(original.averageMaterialType(), newOpacity)); }
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; }
protected abstract VoxelHolder modifyVoxel(VoxelHolder original, int x, int y, int z);
public void genMesh(VoxelUpdateInfo info) { if (control == null) { return; } size = info.size; Queue <int[]> triangleSet = new Queue <int[]>(); vertices = new Dictionary <int, object>(); vertexSubstances = new Dictionary <int, byte>(); Voxel[, ,] voxels = createVoxelArray(info); 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, null); int totalTris = 0; for (byte x = (byte)(1 - xExtend), x1 = (byte)(x + 1); x1 < xDim; x = x1++) { for (byte y = (byte)(1 - yExtend), y1 = (byte)(y + 1); y1 < yDim; y = y1++) { for (byte z = (byte)(1 - zExtend), z1 = (byte)(z + 1); z1 < zDim; z = z1++) { lock (control) { VoxelHolder block = info.getSub(VOXEL_COUNT_POWER, VOXEL_DIMENSION + x, VOXEL_DIMENSION + y, VOXEL_DIMENSION + z); voxels[x1, y1, z1] = block.toVoxel(); int[] tris = MarchingCubes.lookupTriangles(x, y, z, x1, y1, z1); if (tris == null) { continue; } triangleSet.Enqueue(tris); totalTris += tris.Length; } } } } if (vertices.Count < 1) { applied = true; return; } List <int> triangles = new List <int>(); List <Vector3> finalVertices = new List <Vector3>(vertices.Count); //List<byte> finalMats = new List<byte>(vertices.Count); while (triangleSet.Count > 0) { int[] triangleList = triangleSet.Dequeue(); for (int i = 0; i < triangleList.Length; ++i) { if (vertices[triangleList[i]].GetType() == typeof(Vector3)) { finalVertices.Add((Vector3)vertices[triangleList[i]]); //finalMats.Add(vertexSubstances[triangleList[i]]); vertices[triangleList[i]] = finalVertices.Count - 1; } triangles.Add((int)vertices[triangleList[i]]); } } VERTS = finalVertices.ToArray(); TRIS = triangles.ToArray(); //MATS = finalMats.ToArray(); calcNorms(); alignEdge(info, 0, 1, 1); alignEdge(info, 2, 1, 1); alignEdge(info, 1, 0, 1); alignEdge(info, 1, 2, 1); alignEdge(info, 1, 1, 0); alignEdge(info, 1, 1, 2); lock (control) { control.enqueueJob(new ApplyMeshJob(this, info.detailLevel, info.x, info.y, info.z)); } }
public CubeMutator(Tree control, Vector3 worldPosition, Vector3 worldDimensions, VoxelHolder value, bool updateMesh) { this.worldPosition = worldPosition; this.worldDimensions = worldDimensions; this.value = value.toVoxel(); }
protected override VoxelHolder modifyVoxel(VoxelHolder original, int x, int y, int z) { return new Voxel(value.toVoxel()); }
public CubeMutator(OcTree control, Vector3 worldPosition, Vector3 worldDimensions, VoxelHolder value, bool updateMesh) { this.worldPosition = worldPosition; this.worldDimensions = worldDimensions; this.value = value.toVoxel(); }
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 abstract int cleanArtifacts(out Voxel simplified, VoxelHolder head, byte level, byte maxLevel, int x, int y, int z);