Example #1
0
    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);
            }
        }
    }
Example #2
0
    public void Encapsulate(KDopBounds otherBounds)
    {
        if (isValid && otherBounds.isValid)
        {
            min.x = Mathf.Min(min.x, otherBounds.min.x);
            min.y = Mathf.Min(min.y, otherBounds.min.y);
            min.z = Mathf.Min(min.z, otherBounds.min.z);

            max.x = Mathf.Max(max.x, otherBounds.max.x);
            max.y = Mathf.Max(max.y, otherBounds.max.y);
            max.z = Mathf.Max(max.z, otherBounds.max.z);
        }
        else if (otherBounds.isValid)
        {
            min     = otherBounds.min;
            max     = otherBounds.max;
            isValid = true;
        }
        else
        {
            // Do nothing
        }
    }
Example #3
0
    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);
    }