//using System.Collections; //using System.Collections.Generic; //using UnityEngine; //using MeshCombineStudio; //using System; //namespace MeshCombineStudio //{ // static public class Voxelize // { // static readonly byte[] bits = new byte[] { 1, 2, 4, 8, 16, 32, 64, 128 }; // static Dictionary voxelizedLookup = new Dictionary(); // static List intersectList = new List(); // const byte insideVoxel = 1; // const byte outsideVoxel = 2; // public class VoxelizedMesh // { // public byte[,,] volume; // public Bounds bounds; // public Int3 voxels; // } // static VoxelizedMesh VoxelizeMesh(Transform t, float voxelResolution, int voxelizeLayer) // { // // TODO ray cast from right/left and top/down // MeshRenderer mr = t.GetComponent(); // if (mr == null) return null; // MeshFilter mf = t.GetComponent(); // if (mf == null) return null; // Mesh mesh = mf.sharedMesh; // if (mesh == null) return null; // VoxelizedMesh vm = new VoxelizedMesh(); // voxelizedLookup.Add(mesh, vm); // Transform oldParent = t.parent; // Vector3 oldPos = t.position; // Quaternion oldRot = t.rotation; // Vector3 oldScale = t.localScale; // t.parent = null; // t.position = Vector3.zero; // t.rotation = Quaternion.identity; // t.localScale = Vector3.one; // int oldLayer = t.gameObject.layer; // t.gameObject.layer = voxelizeLayer; // LayerMask voxelizeLayerMask = 1 << voxelizeLayer; // Bounds bounds = mr.bounds; // Vector3 size = bounds.size; // Int3 voxels = new Int3(Mathf.CeilToInt(size.x / voxelResolution), Mathf.CeilToInt(size.y / voxelResolution), Mathf.CeilToInt(size.z / voxelResolution)); // voxels += new Int3(2, 2, 2); // int voxelsX = Mathf.CeilToInt(voxels.x / 8f); // vm.voxels = voxels; // size = new Vector3(voxels.x * voxelResolution, voxels.y * voxelResolution, voxels.z * voxelResolution); // bounds.size = size; // vm.bounds = bounds; // byte[,,] volume = new byte[voxelsX, voxels.y, voxels.z]; // Ray ray = new Ray(); // Ray ray2 = new Ray(); // ray.direction = Vector3.forward; // ray2.direction = Vector3.back; // Vector3 pos = bounds.min; // Vector3 pos2 = pos; // pos2.z = bounds.max.z; // // Debug.Log(PrintVector3(mr.bounds.size) + " new size " + PrintVector3(size) + " voxels " + voxels); // int voxelCount = 0; // Vector3 halfVoxel = Vector3.one * voxelResolution * 0.5f; // Vector3 minBoundsVoxel = pos + halfVoxel; // try // { // for (int x = 0; x < voxels.x; x++) // { // int xGrid = x / 8; // byte bit = bits[x - (xGrid * 8)]; // for (int y = 0; y < voxels.y; y++) // { // Vector3 origin = pos + new Vector3((x + 0.5f) * voxelResolution, (y + 0.5f) * voxelResolution, 0); // ray.origin = origin; // origin.z = pos2.z; // ray2.origin = origin; // intersectList.Clear(); // MultiCast(ray, intersectList, 0.001f, size.z, voxelizeLayerMask); // MultiCast(ray2, intersectList, -0.001f, size.z, voxelizeLayerMask); // intersectList.Sort(); // float half = (float)intersectList.Count / 2; // if (half != (int)half) { continue; } // // Debug.Log(hitInfos.Length +" " + hitInfos2.Length +" " + list.Count); // for (int i = 0; i < intersectList.Count; i += 2) // { // int z1 = Mathf.RoundToInt((intersectList[i] - pos.z) / voxelResolution); // int z2 = Mathf.RoundToInt((intersectList[i + 1] - pos.z) / voxelResolution); // for (int z = z1; z < z2; z++) // { // Vector3 voxelPos = new Vector3(x * voxelResolution, y * voxelResolution, z * voxelResolution) + minBoundsVoxel; // voxelPos = t.TransformPoint(voxelPos); // // volume[xGrid, y, z] |= bit; // // if (!Physics.CheckBox(voxelPos, halfVoxel, Quaternion.identity, voxelizeLayerMask)) // { // volume[xGrid, y, z] |= bit; // ++voxelCount; // } // } // } // } // } // } // catch (Exception e) // { // Debug.LogError(e.ToString()); // } // // Debug.Log(t.name + " voxels " + voxelCount); // vm.volume = volume; // t.gameObject.layer = oldLayer; // t.parent = oldParent; // t.position = oldPos; // t.rotation = oldRot; // t.localScale = oldScale; // return vm; // } // static string PrintVector3(Vector3 v) // { // return "(" + v.x + ", " + v.y + ", " + v.z + ")"; // } // static void MultiCast(Ray ray, List points, float hitOffset, float maxDistance, LayerMask voxelizeLayerMask) // { // RaycastHit hitInfo; // while (Physics.Raycast(ray, out hitInfo, maxDistance, voxelizeLayerMask)) // { // points.Add(hitInfo.point.z); // Vector3 origin = ray.origin; // ray.origin = new Vector3(origin.x, origin.y, hitInfo.point.z + hitOffset); // } // } // static void Report(VoxelizedMesh vm, float voxelResolution) // { // int voxelResolutionX = (int)voxelResolution / 8; // for (int x = 0; x < voxelResolutionX; x++) // { // for (int y = 0; y < voxelResolution; y++) // { // for (int z = 0; z < voxelResolution; z++) // { // Debug.Log(vm.volume[x, y, z]); // } // } // } // } // static public void RemoveOverlap(Transform t, MeshCombineJobManager.MeshCombineJob meshCombineJob, MeshCache.SubMeshCache newMeshCache, ref byte[] vertexIsInsideVoxels) // { // if (vertexIsInsideVoxels == null) vertexIsInsideVoxels = new byte[65534]; // float voxelResolution = meshCombineJob.meshCombiner.voxelResolution; // int voxelizeLayer = meshCombineJob.meshCombiner.voxelizeLayer; // Vector3[] newVertices = newMeshCache.vertices; // int[] newTriangles = newMeshCache.triangles; // List meshObjects = meshCombineJob.meshObjectsHolder.meshObjects; // int startIndex = meshCombineJob.startIndex; // int endIndex = meshCombineJob.endIndex; // for (int a = startIndex; a < endIndex; a++) // { // MeshObject meshObject = meshObjects[a]; // CachedGameObject cachedGO = meshObject.cachedGO; // // Get array of intersections // // Bounds bounds = cachedGO.mr.bounds; // Collider[] colliders = null;//!! Physics.OverlapBox(bounds.center, bounds.extents, Quaternion.identity, meshCombineJob.meshCombiner.overlapLayerMask); // if (colliders.Length == 0) // { // // Debug.Log("No overlap " + cachedGO.go.name); // continue; // } // // Debug.Log("Overlaps " + colliders.Length); // Transform[] colliderTs = new Transform[colliders.Length]; // VoxelizedMesh[] colliderVms = new VoxelizedMesh[colliders.Length]; // for (int i = 0; i < colliderVms.Length; i++) // { // colliderTs[i] = colliders[i].transform; // if (colliderTs[i] == cachedGO.t) continue; // MeshFilter mf = colliderTs[i].GetComponent(); // if (mf == null) continue; // Mesh mesh = mf.sharedMesh; // if (mesh == null) continue; // voxelizedLookup.TryGetValue(mesh, out colliderVms[i]); // if (colliderVms[i] == null) colliderVms[i] = VoxelizeMesh(colliderTs[i], voxelResolution, voxelizeLayer); // // Debug.LogError("Couldn't find voxelized mesh for " + mo.m + " " + child.name); // } // float invVoxelResolution = 1 / voxelResolution; // int startTriangleIndex = meshObject.startNewTriangleIndex; // int endTriangleIndex = meshObject.newTriangleCount + startTriangleIndex; // // Debug.Log("start " + startTriangleIndex + " end " + endTriangleIndex); // for (int i = startTriangleIndex; i < endTriangleIndex; i += 3) // { // bool insideAllVoxels = true; // for (int k = 0; k < 3; k++) // { // int vertexIndex = newTriangles[i + k]; // if (vertexIndex == -1) continue; // byte isInsideVoxel = vertexIsInsideVoxels[vertexIndex]; // if (isInsideVoxel == 0) // { // bool inside = false; // for (int j = 0; j < colliders.Length; j++) // { // Transform colliderT = colliderTs[j]; // VoxelizedMesh colliderVm = colliderVms[j]; // if (colliderVm == null) continue; // Vector3 boundsMin = colliderVm.bounds.min; // Vector3 vertPos = t.TransformPoint(newVertices[vertexIndex]); // Vector3 pos = colliderT.InverseTransformPoint(vertPos) - boundsMin; // Vector3 grid = new Vector3(pos.x * invVoxelResolution, pos.y * invVoxelResolution, pos.z * invVoxelResolution); // if (grid.x < 0 || grid.x >= colliderVm.voxels.x || grid.y < 0 || grid.y >= colliderVm.voxels.y || grid.z < 0 || grid.z >= colliderVm.voxels.z) continue; // int xGrid = (int)grid.x; // int xxGrid = xGrid / 8; // byte bit = bits[(xGrid - (xxGrid * 8))]; // if ((colliderVm.volume[xxGrid, (int)grid.y, (int)grid.z] & bit) == 0) continue; // inside = true; // break; // } // vertexIsInsideVoxels[vertexIndex] = isInsideVoxel = (inside ? insideVoxel : outsideVoxel); // } // if (isInsideVoxel == outsideVoxel) // { // insideAllVoxels = false; // break; // } // } // if (insideAllVoxels) // { // meshCombineJob.trianglesRemoved += 3; // newTriangles[i] = -1; // } // } // } // Array.Clear(vertexIsInsideVoxels, 0, newMeshCache.vertexCount); // // Debug.Log("Removed " + meshCombineJob.trianglesRemoved); // newMeshCache.triangles = newTriangles; // } // static public void DrawGizmos(GameObject go, float voxelResolution) // { // Transform[] ts = go.GetComponentsInChildren(); // Gizmos.color = Color.red; // for (int i = 0; i < ts.Length; i++) DrawVolume(ts[i], voxelResolution); // Gizmos.color = Color.white; // } // static public void DrawVolume(Transform t, float voxelResolution) // { // MeshRenderer mr = t.GetComponent(); // if (mr == null) return; // MeshFilter mf = t.GetComponent(); // if (mf == null) return; // Mesh m = mf.sharedMesh; // if (m == null) return; // VoxelizedMesh vm; // voxelizedLookup.TryGetValue(m, out vm); // if (vm == null) return; // byte[,,] volume = vm.volume; // if (volume == null) return; // Vector3 pos = vm.bounds.min; // Vector3 voxel = t.lossyScale * voxelResolution; // Vector3 halfVoxel = Vector3.one * voxelResolution * 0.5f; // Int3 voxels = vm.voxels; // // Debug.Log(voxels); // // Debug.Log(volume.Length); // Gizmos.DrawWireCube(mr.bounds.center, mr.bounds.size); // for (int x = 0; x < voxels.x; x++) // { // int xGrid = x / 8; // int bit = x - (xGrid * 8); // for (int y = 0; y < voxels.y; y++) // { // for (int z = 0; z < voxels.z; z++) // { // if ((volume[xGrid, y, z] & bits[bit]) > 0) // { // Vector3 localPos = new Vector3(pos.x + (x * voxelResolution), pos.y + (y * voxelResolution), pos.z + (z * voxelResolution)) + halfVoxel; // Gizmos.DrawWireCube(t.TransformPoint(localPos), voxel); // } // } // } // } // } // } //}