private void ProcessMesh(object voxelParameters) { TaskParams voxelParams = (TaskParams) voxelParameters; Vector3 voxelCenter = voxelParams.VoxelCenter; int voxelId = voxelParams.VoxelId; int[] triangles = voxelParams.Triangles; Vector3[] verticesWS = voxelParams.VerticesWS; Vector3[] trianglesNormals = voxelParams.TrianglesNormals; Color[] colors = voxelParams.Colors; Vector2[] uvs = voxelParams.UVs; Vector3 voxelMinPosition = voxelCenter - m_VoxelHalfDimensions; Vector3[] triangleVertices = new Vector3[3]; for (int triangleId = 0; triangleId < triangles.Length; triangleId += 3) { int vertexId1 = triangles[triangleId]; int vertexId2 = triangles[triangleId + 1]; int vertexId3 = triangles[triangleId + 2]; // Triangle vertices with respect to voxel. triangleVertices[0] = verticesWS[vertexId1] - voxelMinPosition; triangleVertices[1] = verticesWS[vertexId2] - voxelMinPosition; triangleVertices[2] = verticesWS[vertexId3] - voxelMinPosition; Vector3 triangleNormal = trianglesNormals[triangleId / 3]; if (MathHelper.CheckAABBAndTriangleIntersection(m_VoxelVertices[0], m_VoxelVertices[7], triangleVertices, m_VoxelVertices, triangleNormal)) { Vector2 uv = Vector2.zero; Color color = Material.Color; // Get mesh properties (color, uv) from first vertex in triangle and set to voxel. if (uvs.Length > 0) { uv = uvs[vertexId1]; } if (colors.Length > 0) { color *= colors[vertexId1]; } VoxelRenderer.Voxel voxel = new VoxelRenderer.Voxel { Center = voxelCenter, Size = m_VoxelSize, Color = new Vector3(color.r, color.g, color.b), UV = uv, }; m_Voxels[voxelId] = voxel; break; } } }
void GenerateVoxels(float voxelSize) { Voxels = new List <VoxelRenderer.Voxel>(); Vector3Int voxelVolumeDimensions = (MaxRange - MinRange); int maxNumberOfVoxels = voxelVolumeDimensions.x * voxelVolumeDimensions.y * voxelVolumeDimensions.z; for (int i = 0; i < maxNumberOfVoxels; i++) { VoxelRenderer.Voxel voxel = new VoxelRenderer.Voxel() { Center = new Vector3(Random.Range(MinRange.x, MaxRange.x), Random.Range(MinRange.y, MaxRange.y) + voxelSize, Random.Range(MinRange.z, MaxRange.z)) * 2 * voxelSize, Size = voxelSize, Color = new Vector3(Random.Range(0.0f, 1.0f), Random.Range(0.0f, 1.0f), Random.Range(0.0f, 1.0f)), UV = Vector2.zero }; // Skip if trying to place a voxel at an occupied position. if (Voxels.FindIndex(v => v.Center == voxel.Center) != -1) { continue; } Voxels.Add(voxel); } Material = new VoxelRenderer.VoxelMaterial() { Color = Color.white, Texture = null }; VoxelsVolumeMin = MinRange; VoxelsVolumeMax = MaxRange; }
public override void GenerateVoxels(float voxelSize) { if (m_MeshRenderer != null && m_MeshFilter != null) { Mesh mesh = m_MeshFilter.sharedMesh; int[] triangles = mesh.triangles; // mesh vertices in World Space Vector3[] verticesWS; Vector3[] trianglesNormals; InitializeVerticesAndNormals(m_MeshRenderer.transform, mesh.vertices, triangles, out verticesWS, out trianglesNormals); Bounds meshBoundsWS = m_MeshRenderer.bounds; Octree.MeshParams meshParams = new Octree.MeshParams() { Triangles = triangles, VerticesWS = verticesWS, TrianglesNormals = trianglesNormals, Colors = mesh.colors, UVs = mesh.uv }; Vector3Int meshDimensionInVoxels = Vector3Int.CeilToInt(meshBoundsWS.size / voxelSize); // In order to keep voxels with uniform size, the max dimension is used as bounds dimension. int maxDimension = Mathf.Max(meshDimensionInVoxels.x, Mathf.Max(meshDimensionInVoxels.y, meshDimensionInVoxels.z)); Vector3 maxPointInVoxelsVolume = meshBoundsWS.min + Vector3.one * maxDimension * voxelSize; m_Octree = new Octree(meshBoundsWS.min, maxPointInVoxelsVolume, voxelSize, meshParams); Queue <Octree.OctreeNode> nodes = new Queue <Octree.OctreeNode>(); if (m_Octree.Root != null) { nodes.Enqueue(m_Octree.Root); } while (nodes.Count > 0) { Octree.OctreeNode currentNode = nodes.Dequeue(); // If node is leaf and has triangles inside it, create a voxel. if (currentNode.IsLeaf && currentNode.Occupied) { Color color = Material.Color * currentNode.Color; VoxelRenderer.Voxel voxel = new VoxelRenderer.Voxel { Center = currentNode.CenterPoint, Size = currentNode.Dimensions.x, Color = new Vector3(color.r, color.g, color.b), UV = currentNode.UV }; Voxels.Add(voxel); } else { if (currentNode.ChildrenNodes != null) { foreach (Octree.OctreeNode octreeNode in currentNode.ChildrenNodes) { if (octreeNode != null) { nodes.Enqueue(octreeNode); } } } } } } }