private void OnDrawGizmos() { if (kDopTree != null) { Gizmos.matrix = mf.transform.localToWorldMatrix; List <KDopNode> nodes = kDopTree.nodes; int leafCount = 0; for (int nodeIndex = 0; nodeIndex < nodes.Count; ++nodeIndex) { if (leafCount == depth) { break; } KDopNode node = kDopTree.nodes[nodeIndex]; if (node.isLeaf) { ++leafCount; KDopBounds bounds = node.boundingVolumes; Gizmos.color = colors[nodeIndex % colors.Length]; Gizmos.DrawWireCube(bounds.Center, bounds.Size); } } } Gizmos.matrix = Matrix4x4.identity; Gizmos.color = Color.white; Gizmos.DrawLine(linep0.position, linep1.position); if (kDopTree != null) { check.Init(linep0.position, linep1.position, mf.transform.worldToLocalMatrix); kDopTree.LineCheck(check); if (check.HitResult.isHit) { KDopTriangle tri = kDopTree.triangles[check.HitResult.hitTriangle]; Vector3 hitPoint = check.LocalStart + check.HitResult.hitTime * check.LocalDir; Gizmos.matrix = mf.transform.localToWorldMatrix; Gizmos.color = Color.red; Gizmos.DrawLine(tri.v0, tri.v1); Gizmos.DrawLine(tri.v1, tri.v2); Gizmos.DrawLine(tri.v2, tri.v0); Gizmos.DrawSphere(hitPoint, 0.01f); Gizmos.DrawLine(hitPoint, hitPoint + tri.GetNormal() * 0.3f); } } }
public void Build(Mesh mesh) { if (mesh == null || !mesh.isReadable) { return; } if (nodes != null) { nodes.Clear(); } nodes = new List <KDopNode>(); BuildTriangles(mesh); KDopNode rootNode = new KDopNode(); nodes.Add(rootNode); rootNode.SplitTriangleList(0, triangles.Count, this); nodes[0] = rootNode; }
public KDopBounds SplitTriangleList(int startIndex, int numTriangles, KDopTree kDopTree) { if (numTriangles > 4) { isLeaf = false; int BestPlane = -1; float BestMean = 0.0f; float BestVariance = 0.0f; for (int nPlane = 0; nPlane < KDopTree.NUM_PLANES; nPlane++) { float Mean = 0.0f; float Variance = 0.0f; for (int nTriangle = startIndex; nTriangle < startIndex + numTriangles; nTriangle++) { Mean += kDopTree.triangles[nTriangle].GetCentroid()[nPlane]; } Mean /= (float)numTriangles; for (int nTriangle = startIndex; nTriangle < startIndex + numTriangles; nTriangle++) { float Dot = kDopTree.triangles[nTriangle].GetCentroid()[nPlane]; Variance += (Dot - Mean) * (Dot - Mean); } Variance /= (float)numTriangles; if (Variance >= BestVariance) { BestPlane = nPlane; BestVariance = Variance; BestMean = Mean; } } int Left = startIndex - 1; int Right = startIndex + numTriangles; while (Left < Right) { float Dot; do { Dot = kDopTree.triangles[++Left].GetCentroid()[BestPlane]; }while (Dot < BestMean && Left < Right); do { Dot = kDopTree.triangles[--Right].GetCentroid()[BestPlane]; }while (Dot >= BestMean && Right > 0 && Left < Right); if (Left < Right) { KDopTriangle Temp = kDopTree.triangles[Left]; kDopTree.triangles[Left] = kDopTree.triangles[Right]; kDopTree.triangles[Right] = Temp; } } if (Left == startIndex + numTriangles || Right == startIndex) { Left = startIndex + (numTriangles / 2); } KDopNode leftNode = new KDopNode(); int leftNodeIndex = kDopTree.nodes.Count; kDopTree.nodes.Add(leftNode); data.leftNode = leftNodeIndex; KDopNode rightNode = new KDopNode(); int rightNodeIndex = kDopTree.nodes.Count; kDopTree.nodes.Add(rightNode); data.rightNode = rightNodeIndex; KDopBounds leftBoundingVolume = leftNode.SplitTriangleList(startIndex, Left - startIndex, kDopTree); KDopBounds rightBoundingVolume = rightNode.SplitTriangleList(Left, startIndex + numTriangles - Left, kDopTree); boundingVolumes.Encapsulate(leftBoundingVolume); boundingVolumes.Encapsulate(rightBoundingVolume); kDopTree.nodes[leftNodeIndex] = leftNode; kDopTree.nodes[rightNodeIndex] = rightNode; } else { isLeaf = true; data.startIndex = startIndex; data.numTriangles = numTriangles; for (int triIndex = data.startIndex; triIndex < data.startIndex + numTriangles; ++triIndex) { KDopTriangle tri = kDopTree.triangles[triIndex]; boundingVolumes.Encapsulate(tri.v0); boundingVolumes.Encapsulate(tri.v1); boundingVolumes.Encapsulate(tri.v2); } } return(boundingVolumes); }