Exemplo n.º 1
0
 static void Embed(string inTarget)
 {
     // Embed a package in the Project
     Debug.Log("Embed('" + inTarget + "') called");
     Request = Client.Embed(inTarget);
     EditorApplication.update += Progress;
 }
Exemplo n.º 2
0
    private IEnumerator DeformSurfaceCoroutine()
    {
        while (m_requestQueue.Count > 0)
        {
            // Dequeue
            EmbedRequest request               = m_requestQueue.Dequeue();
            GameObject   marginVolume          = request.marginVolume;
            Vector3      marginFrontPlanePoint = request.centerPointOnFrontPlane;
            Vector3      marginBackPlanePoint  = request.centerPointOnBackPlane;
            GameObject   embedded              = request.embedded;

            // Get the OBB that describes the margin volume we want to create
            BoxCollider obb = marginVolume.GetComponent <BoxCollider>();

            /*
             * Compute a back-plane located directly behind the embedded object.
             * Triangles that intersect with the embedded object's OBB will be
             * projected onto this back plane. The projection formula is:
             *
             *  v' = v - n * (Dot(n, v) + planeToOriginDistance)
             *
             * Where n is the normal pointing toward the spatial mesh and
             * planeToOriginDistance is solved for using the plane equation.
             *
             * We assume the OBB's position is located at the front-facing side of the
             * embedded object rather than in its center.
             */
            Vector3 intoSurface           = marginBackPlanePoint - marginFrontPlanePoint;
            Vector3 intoSurfaceNormal     = Vector3.Normalize(intoSurface);
            float   planeToOriginDistance = 0 - Vector3.Dot(intoSurfaceNormal, marginBackPlanePoint); // Ax+By+Cz+D=0, solving for D here

            // The thickness of the embedded object can easily be obtained from the
            // desired distance between the margin volume's front and back planes
            float requiredMargin = Vector3.Magnitude(intoSurface);

            // Check against each spatial mesh and deform those that intersect the
            // margin volume
            foreach (MeshFilter meshFilter in m_spatialMeshFilters)
            {
                if (meshFilter == null)
                {
                    continue;
                }

                if (request.HasSufficientMargin(meshFilter, requiredMargin))
                {
                    //Debug.Log("Skipping [" + task.plane.GetInstanceID() + "," + meshFilter.GetInstanceID() + "] due to sufficient margin");
                    continue;
                }

                // Detect all triangles that intersect with the margin volume OBB
                Mesh mesh = meshFilter.sharedMesh;
                if (mesh == null)
                {
                    continue;
                }
                Vector3[]   verts   = mesh.vertices; // spatial mesh has vertices and normals, no UVs
                Vector3[]   normals = mesh.normals;
                List <int>  intersectingTriangles = null;
                IEnumerator f = OBBMeshIntersection.FindTrianglesCoroutine((List <int> result) => { intersectingTriangles = result; }, maxSecondsPerFrame, obb, verts, mesh.GetTriangles(0), meshFilter.transform);
                while (f.MoveNext())
                {
                    yield return(f.Current);
                }
                if (intersectingTriangles.Count == 0)
                {
                    //Debug.Log("No intersecting triangles found in: " + meshFilter.gameObject.name);
                    continue;
                }

                // TODO: Use a bit set to keep track of which vertex indices to modify?

                float      t0          = Time.realtimeSinceStartup;
                List <int> vertIndices = intersectingTriangles;

                // Modify spatial mesh by pushing vertices inward onto the back plane of
                // the margin volume
                foreach (int i in vertIndices)
                {
                    Vector3 worldVert    = meshFilter.transform.TransformPoint(verts[i]);
                    float   displacement = Vector3.Dot(intoSurfaceNormal, worldVert) + planeToOriginDistance;
                    worldVert = worldVert - displacement * intoSurfaceNormal;
                    verts[i]  = meshFilter.transform.InverseTransformPoint(worldVert);
                    if (Time.realtimeSinceStartup - t0 >= maxSecondsPerFrame)
                    {
                        yield return(null);

                        t0 = Time.realtimeSinceStartup;
                    }
                }
                mesh.vertices = verts;    // apply changes
                mesh.RecalculateBounds(); // not needed because deformation should be minor
                if (Time.realtimeSinceStartup - t0 >= maxSecondsPerFrame)
                {
                    yield return(null);

                    t0 = Time.realtimeSinceStartup;
                }

                // Update margin depth of this plane/spatial mesh pair
                request.RecordMargin(meshFilter, requiredMargin);
                //Debug.Log("Finished deforming [" + task.plane.GetInstanceID() + "," + meshFilter.GetInstanceID() + "]");
            }

            // Restore embedded object's shared materials (and its render order) now
            // that margin exists in the spatial mesh. Clean up temporary objects.
            // Destroy temporary object
            embedded.GetComponent <SharedMaterialHelper>().RestoreSharedMaterials();
            Object.Destroy(marginVolume.GetComponent <BoxCollider>());
            Object.Destroy(marginVolume);
        }

        m_working = false;
        yield break;
    }
Exemplo n.º 3
0
 private static void Embed(string inTarget)
 {
     Debug.Log("Embed('" + inTarget + "') called");
     eRequest = Client.Embed(inTarget);
     EditorApplication.update += Progress;
 }