예제 #1
0
		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);
		}
        public void genMesh(Voxel[,,] voxels)
        {
            if (control == null)
                return;

            size = control.sizes[index.depth];

            Queue<int[]> triangleSet = new Queue<int[]>();
            Dictionary<int, Vector3> actualVertices = new Dictionary<int, Vector3>();
            vertexSubstances = new Dictionary<int, byte>();
            lock (control) {
                MarchingCubes.setup(size / VOXEL_DIMENSION, control.isoLevel, ref actualVertices, ref vertexSubstances, ref voxels, position + new Vector3(0.5f, 0.5f, 0.5f) * size / VOXEL_DIMENSION);
                int totalTris = 0;
                uint xDim = (uint)voxels.GetLength(0) -1;
                uint yDim = (uint)voxels.GetLength(1) -1;
                uint zDim = (uint)voxels.GetLength(2) -1;

                for (int x = 0; x < xDim; ++x) {
                    for (int y = 0; y < yDim; ++y) {
                        for (int z = 0; z < zDim; ++z) {
                            int[] tris = MarchingCubes.lookupTriangles(x, y, z, x+1, y+1, z+1);
                            if (tris == null) continue;
                            triangleSet.Enqueue(tris);
                            totalTris += tris.Length;
                        }
                    }
                }
            }

            if (actualVertices.Count < 1) {
                applied = true;
                return;
            }

            System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
            watch.Start();

            List<int> triangles = new List<int>();
            List<Vector3> finalVertices = new List<Vector3>(actualVertices.Count);
            vertices.Clear();
            while (triangleSet.Count > 0) {
                int[] triangleList = triangleSet.Dequeue();
                for (int i = 0; i < triangleList.Length; ++i) {
                    if (!vertices.ContainsKey(triangleList[i])) {
                        finalVertices.Add(actualVertices[triangleList[i]]);
                        vertices[triangleList[i]] = finalVertices.Count - 1;
                    }
                    triangles.Add(vertices[triangleList[i]]);
                }
            }
            VERTS = finalVertices.ToArray();
            TRIS = triangles.ToArray();
            calcNorms();

            alignEdge(0, 1, 1);
            alignEdge(1, 0, 1);
            alignEdge(1, 1, 0);
            lock (control) {
                control.enqueueJob(new ApplyMeshJob(this));
            }

            watch.Stop();
            control.meshGenArrayTime += watch.Elapsed.TotalSeconds;
        }