Esempio n. 1
0
    private void OnDrawGizmosSelected()
    {
        //foreach(LinearBVHNode node in SceneParser._SceneData._BVHNodeList)
        //{
        //    Gizmos.color = Color.yellow;

        //    Vector3 gizmoCenter = (node.bounds.pMax + node.bounds.pMin) / 2;
        //    Vector3 gizmoDiff = (node.bounds.pMax - node.bounds.pMin);
        //    Gizmos.DrawWireCube(gizmoCenter, gizmoDiff);
        //}


        for (int i = 0; i < level_count; i++)
        {
            LinearBVHNode node = SceneParser._SceneData._BVHNodeList[i];

            Gizmos.color = new Color(1, 0, 0, 0.5f) + new Color(0, 1, 1, 0.5f) / level_count * i;

            if (i == level_count - 1)
            {
                Gizmos.color = Color.yellow;
            }

            Vector3 gizmoCenter = (node.bounds.pMax + node.bounds.pMin) / 2;
            Vector3 gizmoDiff   = (node.bounds.pMax - node.bounds.pMin);
            Gizmos.DrawWireCube(gizmoCenter, gizmoDiff);
        }
    }
Esempio n. 2
0
    //顺序存储BVH
    void FlattenBVH(BVHNode root, int count)
    {
        bvhNodes = new LinearBVHNode[count];
        for (int i = 0; i < count; i++)
        {
            bvhNodes[i] = new LinearBVHNode();
        }

        int offset = 0;

        BuildFlattenBVH(root, ref offset);
    }
Esempio n. 3
0
    void BuildFlattenBVH(BVHNode bvhNode, ref int offset)
    {
        LinearBVHNode linearBVHNode = new LinearBVHNode();

        linearBVHNode.aabb = bvhNode.aabb;
        linearBVHNode.axis = bvhNode.axis;
        if (bvhNode.triangles != null)
        {
            linearBVHNode.triangles = new int[bvhNode.triangles.Length];
            for (int i = 0; i < linearBVHNode.triangles.Length; i++)
            {
                linearBVHNode.triangles[i] = bvhNode.triangles[i];
            }
        }

        bvhNodes[offset] = linearBVHNode;
        if (bvhNode.left == null && bvhNode.right == null)
        {
            offset++;
            linearBVHNode.left  = false;
            linearBVHNode.right = -1;
        }
        else
        {
            if (bvhNode.left != null)
            {
                linearBVHNode.left = true;
                offset++;
                BuildFlattenBVH(bvhNode.left, ref offset);
                linearBVHNode.right = offset;
            }

            if (bvhNode.right != null)
            {
                BuildFlattenBVH(bvhNode.right, ref offset);
            }
        }
    }
Esempio n. 4
0
 private int FlattenBVHTree(Node node, ref int offset)
 {
     if (node == null)
     {
         return -1;
     }
     nodes[offset] = new LinearBVHNode() { bbox = node.Bound };
     var linearNode = nodes[offset];
     int myOffset = (offset)++;
     if (node.nPrims > 0)
     {
         linearNode.primOffset = node.StartOffset;
         linearNode.nPrimitives = (byte)node.nPrims;
     }
     else
     {
         linearNode.axis = (byte)node.SplitAxis;
         linearNode.nPrimitives = 0;
         FlattenBVHTree(node.Left, ref offset);
         linearNode.secondChildOffset = FlattenBVHTree(node.Right, ref offset);
     }
     return myOffset;
 }
Esempio n. 5
0
    // Create MeshData and MeshBoundingBox of the object
    private void ParseSceneMesh(Transform meshObject)
    {
        MeshData newMeshData = new MeshData();

        newMeshData._TriangleIndexStart = _SceneData._SizeOfTriangleList;
        newMeshData._VertexIndexStart   = _SceneData._SizeOfVertexList;
        newMeshData._BVHNodeOffset      = _SceneData._SizeOfBVHNodeList;

        Mesh mesh = meshObject.GetComponent <MeshFilter>().mesh;

        Vector3[] newVertexList = mesh.vertices;

        for (int i = 0; i < newVertexList.Length; i++)
        {
            newVertexList[i] = meshObject.rotation * newVertexList[i];
            newVertexList[i] = meshObject.localScale.x * newVertexList[i];
            newVertexList[i] = meshObject.position + newVertexList[i];
        }

        _SceneData._VertexList.AddRange(newVertexList);
        _SceneData._SizeOfVertexList += mesh.vertexCount;

        List <Triangle>         newMeshTriangles = new List <Triangle>();
        List <BVHPrimitiveInfo> primitiveInfos   = new List <BVHPrimitiveInfo>();

        int iterator = 0;

        while (iterator < mesh.triangles.Length)
        {
            Triangle newTriangle = new Triangle();

            // Set new triangles indices
            newTriangle.indices.x = mesh.triangles[iterator];
            newTriangle.indices.y = mesh.triangles[iterator + 1];
            newTriangle.indices.z = mesh.triangles[iterator + 2];

            Vector3 p0 = newVertexList[(int)newTriangle.indices.x];
            Vector3 p1 = newVertexList[(int)newTriangle.indices.y];
            Vector3 p2 = newVertexList[(int)newTriangle.indices.z];

            // Set new triangles bounds
            Bounds3 triBounds = new Bounds3();
            triBounds.pMax = Vector3.Max(p0, p1);
            triBounds.pMax = Vector3.Max(triBounds.pMax, p2);

            triBounds.pMin = Vector3.Min(p0, p1);
            triBounds.pMin = Vector3.Min(triBounds.pMin, p2);

            BVHPrimitiveInfo newInfo = new BVHPrimitiveInfo(newMeshTriangles.Count, triBounds);
            primitiveInfos.Add(newInfo);

            iterator += 3;
            newMeshTriangles.Add(newTriangle);
        }

        BVHAcc BVHAccObj = new BVHAcc(ref primitiveInfos);

        foreach (LinearBVHNode node in BVHAccObj.LinearBVHArr)
        {
            LinearBVHNode newLinearNode = new LinearBVHNode();
            newLinearNode.bounds            = node.bounds;
            newLinearNode.primitiveOffset   = node.primitiveOffset;
            newLinearNode.secondChildOffset = node.secondChildOffset;
            //Debug.Log("Primitiveoffset: " + node.primitiveOffset);
            //Debug.Log("SecondChildoffset: " + node.secondChildOffset);

            _SceneData._BVHNodeList.Add(newLinearNode);
            _SceneData._SizeOfBVHNodeList++;
        }

        _SceneData._TriangleList.AddRange(newMeshTriangles);

        _SceneData._SizeOfTriangleList = _SceneData._TriangleList.Count;
        newMeshData._TriangleIndexEnd  = _SceneData._SizeOfTriangleList;

        AddMaterialData(meshObject);

        newMeshData._MaterialID = _SceneData._MaterialCount - 1;

        _SceneData._MeshDataList.Add(newMeshData);
        _SceneData._MeshCount++;

        //Debug.Log("Mesh Count: " + _SceneData._MeshCount);
        //Debug.Log("BVHNode Count: " + _SceneData._SizeOfBVHNodeList);
        //Debug.Log("BVHNode offset: " + _SceneData._MeshDataList[0]._BVHNodeOffset);
    }
Esempio n. 6
0
    public override bool RayDetection(Ray ray, RaycastHit hitInfo)
    {
        if (transform != null)
        {
            ray.Transform(transform.worldToLocalMatrix);
        }

        bool[] dirIsNeg = new bool[3] {
            ray.direction.x < 0, ray.direction.y < 0, ray.direction.z < 0
        };
        Stack <int> s = new Stack <int>();

        s.Push(0);
        bool hit = false;

        while (s.Count > 0)
        {
            int           idx           = s.Pop();
            LinearBVHNode linearBVHNode = bvhNodes[idx];
            if (linearBVHNode.aabb.RayDetection(ray))
            {
                if (!linearBVHNode.left && linearBVHNode.right == -1)
                {
                    if (transform != null)
                    {
                        Mesh mesh = transform.GetComponent <MeshFilter>().sharedMesh;
                        for (int i = 0; i < linearBVHNode.triangles.Length; i++)
                        {
                            int triangle = linearBVHNode.triangles[i];
                            hit |= ray.Raycast(mesh.vertices[mesh.triangles[triangle * 3]],
                                               mesh.vertices[mesh.triangles[triangle * 3 + 1]],
                                               mesh.vertices[mesh.triangles[triangle * 3 + 2]]);
                        }
                    }
                    else
                    {
                        hit |= linearBVHNode.aabb.transform.GetComponent <BoxCollider>().box
                               .RayDetection(ray, hitInfo);
                    }
                }

                if (dirIsNeg[linearBVHNode.axis])
                {
                    if (linearBVHNode.left)
                    {
                        s.Push(++idx);
                    }

                    if (linearBVHNode.right != -1)
                    {
                        s.Push(linearBVHNode.right);
                    }
                }
                else
                {
                    if (linearBVHNode.right != -1)
                    {
                        s.Push(linearBVHNode.right);
                    }

                    if (linearBVHNode.left)
                    {
                        s.Push(++idx);
                    }
                }
            }
        }

        if (transform != null)
        {
            ray.Transform(transform.localToWorldMatrix);
            if (hit)
            {
                hitInfo.point     = ray.origin + ray.direction * ray.distance;
                hitInfo.transform = transform;
            }
        }

        return(hit);
    }