Пример #1
0
    private static DecalPolygon ClipPolygonByConvexSector(float fAngle, Vector3 v1, Vector3 v2, Vector3 v3)
    {
        if (fAngle <= 0f && fAngle > 180f)
        {
            LogMgr.UnityError("Convex sector angle beyond Range! Must limit it greater than 0 degree and less than or equal to 180 degree.");
            return(null);
        }

        DecalPolygon poly = ClipPolygonBySquare(v1, v2, v3);

        if (poly == null)
        {
            return(null);
        }

        Plane start = new Plane(new Vector3(-Mathf.Sin(fAngle * Mathf.Deg2Rad / 2.0f), 0, Mathf.Cos(fAngle * Mathf.Deg2Rad / 2.0f)), Vector3.zero);
        Plane end   = new Plane(new Vector3(-Mathf.Sin(fAngle * Mathf.Deg2Rad / 2.0f), 0, -Mathf.Cos(fAngle * Mathf.Deg2Rad / 2.0f)), Vector3.zero);

        poly = DecalPolygon.ClipPolygon(poly, start);
        if (poly == null)
        {
            return(null);
        }
        poly = DecalPolygon.ClipPolygon(poly, end);
        if (poly == null)
        {
            return(null);
        }

        return(poly);
    }
Пример #2
0
    private static DecalPolygon ClipPolygonBySquare(Vector3 v1, Vector3 v2, Vector3 v3)
    {
        DecalPolygon poly = new DecalPolygon(v1, v2, v3);

        Plane top    = new Plane(Vector3.up, Vector3.up / 2f);
        Plane bottom = new Plane(-Vector3.up, -Vector3.up / 2f);

        poly = DecalPolygon.ClipPolygon(poly, top);
        if (poly == null)
        {
            return(null);
        }
        poly = DecalPolygon.ClipPolygon(poly, bottom);
        if (poly == null)
        {
            return(null);
        }

        Plane right = new Plane(Vector3.right, Vector3.right / 2f);
        Plane left  = new Plane(-Vector3.right, -Vector3.right / 2f);

        Plane front = new Plane(Vector3.forward, Vector3.forward / 2f);
        Plane back  = new Plane(-Vector3.forward, -Vector3.forward / 2f);

        poly = DecalPolygon.ClipPolygon(poly, right);
        if (poly == null)
        {
            return(null);
        }
        poly = DecalPolygon.ClipPolygon(poly, left);
        if (poly == null)
        {
            return(null);
        }

        poly = DecalPolygon.ClipPolygon(poly, front);
        if (poly == null)
        {
            return(null);
        }
        poly = DecalPolygon.ClipPolygon(poly, back);
        if (poly == null)
        {
            return(null);
        }

        return(poly);
    }
Пример #3
0
    private static DecalPolygon ClipPolygonByNonConvexSector(float fAngle, Vector3 v1, Vector3 v2, Vector3 v3, bool bSecondBlock)
    {
        if (fAngle <= 180f && fAngle >= 360f)
        {
            LogMgr.UnityError("Non-convex sector angle beyond Range! Must limit it greater than 180 degree and less than 360 degree.");
            return(null);
        }

        DecalPolygon poly = ClipPolygonBySquare(v1, v2, v3);

        if (poly == null)
        {
            return(null);
        }

        Plane start = new Plane(new Vector3(-Mathf.Sin(fAngle * Mathf.Deg2Rad / 2.0f), 0, Mathf.Cos(fAngle * Mathf.Deg2Rad / 2.0f)), Vector3.zero);
        Plane end   = new Plane(new Vector3(-Mathf.Sin(fAngle * Mathf.Deg2Rad / 2.0f), 0, -Mathf.Cos(fAngle * Mathf.Deg2Rad / 2.0f)), Vector3.zero);

        if (bSecondBlock == false)
        {
            Plane startInverse = new Plane(-start.normal, Vector3.zero);
            poly = DecalPolygon.ClipPolygon(poly, startInverse);
            if (poly == null)
            {
                return(null);
            }
            poly = DecalPolygon.ClipPolygon(poly, end);
            if (poly == null)
            {
                return(null);
            }
        }
        else
        {
            poly = DecalPolygon.ClipPolygon(poly, start);
            if (poly == null)
            {
                return(null);
            }
        }

        return(poly);
    }
    public void BuildDecalForObject(GameObject affectedObject)
    {
        bufVertices.Clear();
        bufNormals.Clear();
        bufTexCoords.Clear();
        bufIndices.Clear();
        Mesh affectedMesh = affectedObject.GetComponent <MeshFilter>().sharedMesh;

        if (affectedMesh == null)
        {
            return;
        }

        Plane right = new Plane(Vector3.right, Vector3.right / 2f);
        Plane left  = new Plane(-Vector3.right, -Vector3.right / 2f);

        Plane top    = new Plane(Vector3.up, Vector3.up / 2f);
        Plane bottom = new Plane(-Vector3.up, -Vector3.up / 2f);

        Plane front = new Plane(Vector3.forward, Vector3.forward / 2f);
        Plane back  = new Plane(-Vector3.forward, -Vector3.forward / 2f);

        Vector3[] vertices  = affectedMesh.vertices;
        int[]     triangles = affectedMesh.triangles;
        startVertexCount = bufVertices.Count;

        Matrix4x4 matrix = transform.worldToLocalMatrix * affectedObject.transform.localToWorldMatrix;

        for (int i = 0; i < triangles.Length; i += 3)
        {
            int i1 = triangles[i];
            int i2 = triangles[i + 1];
            int i3 = triangles[i + 2];

            Vector3 v1 = matrix.MultiplyPoint(vertices[i1]);
            Vector3 v2 = matrix.MultiplyPoint(vertices[i2]);
            Vector3 v3 = matrix.MultiplyPoint(vertices[i3]);

            Vector3 side1  = v2 - v1;
            Vector3 side2  = v3 - v1;
            Vector3 normal = Vector3.Cross(side1, side2).normalized;

            if (Vector3.Angle(-Vector3.forward, normal) >= maxAngle)
            {
                continue;
            }


            DecalPolygon poly = new DecalPolygon(v1, v2, v3);

            poly = DecalPolygon.ClipPolygon(poly, right);
            if (poly == null)
            {
                continue;
            }
            poly = DecalPolygon.ClipPolygon(poly, left);
            if (poly == null)
            {
                continue;
            }

            poly = DecalPolygon.ClipPolygon(poly, top);
            if (poly == null)
            {
                continue;
            }
            poly = DecalPolygon.ClipPolygon(poly, bottom);
            if (poly == null)
            {
                continue;
            }

            poly = DecalPolygon.ClipPolygon(poly, front);
            if (poly == null)
            {
                continue;
            }
            poly = DecalPolygon.ClipPolygon(poly, back);
            if (poly == null)
            {
                continue;
            }

            AddPolygon(poly, normal);
        }

        GenerateTexCoords(startVertexCount);
    }
Пример #5
0
    public static void BuildDecalForObject(GameObject decal, GameObject affectedObject, Texture2D texture)
    {
        Mesh         affectedMesh = null;
        MeshCollider mc           = affectedObject.GetComponent <MeshCollider>();

        if (mc != null)
        {
            affectedMesh = mc.sharedMesh;
        }
        if (affectedMesh == null)
        {
            affectedMesh = GenarateTerrainMesh(affectedObject);
        }

        if (affectedMesh == null)
        {
            MeshFilter mf = affectedObject.GetComponent <MeshFilter>();
            if (mf)
            {
                affectedMesh = mf.sharedMesh;
            }
        }
        if (affectedMesh == null)
        {
            return;
        }

        float maxAngle = /*decal.maxAngle*/ 90.0f;

        Vector3[] vertices         = affectedMesh.vertices;
        int[]     triangles        = affectedMesh.triangles;
        int       startVertexCount = bufVertices.Count;

        Matrix4x4 matrix = decal.transform.worldToLocalMatrix * affectedObject.transform.localToWorldMatrix;

        for (int i = 0; i < triangles.Length; i += 3)
        {
            int i1 = triangles[i];
            int i2 = triangles[i + 1];
            int i3 = triangles[i + 2];

            Vector3 v1 = matrix.MultiplyPoint(vertices[i1]);
            Vector3 v2 = matrix.MultiplyPoint(vertices[i2]);
            Vector3 v3 = matrix.MultiplyPoint(vertices[i3]);

            Vector3 side1  = v2 - v1;
            Vector3 side2  = v3 - v1;
            Vector3 normal = Vector3.Cross(side1, side2).normalized;

            if (Vector3.Angle(-Vector3.forward, normal) >= maxAngle)
            {
                continue;
            }

            poly.Clear();
            poly.SetVts(v1, v2, v3);

            //DecalPolygon poly = new DecalPolygon();
            //poly.SetVts(v1, v2, v3);

            if (!DecalPolygon.ClipPolygon(ref poly, right))
            {
                continue;
            }
            if (!DecalPolygon.ClipPolygon(ref poly, left))
            {
                continue;
            }

            if (!DecalPolygon.ClipPolygon(ref poly, top))
            {
                continue;
            }
            if (!DecalPolygon.ClipPolygon(ref poly, bottom))
            {
                continue;
            }

            if (!DecalPolygon.ClipPolygon(ref poly, front))
            {
                continue;
            }
            if (!DecalPolygon.ClipPolygon(ref poly, back))
            {
                continue;
            }
            AddPolygon(poly, normal);
        }
        GenerateTexCoords(startVertexCount, texture);
    }
    public static void BuildObjectDecal(Decal decal, GameObject affectedObject)
    {
        Mesh affectedMesh = affectedObject.GetComponent <MeshFilter>().sharedMesh;

        // If there is not mesh for <affectedObject>, just return.
        if (affectedMesh == null)
        {
            return;
        }

        Vector3[] vertices  = affectedMesh.vertices;
        int[]     triangles = affectedMesh.triangles;

        // TODO: Perform a linecast from the affectedobject to all other objects based on their
        // bounds and return new vertices on the edges of the linecast.

        Plane right = new Plane(Vector3.right, Vector3.right / 2f);
        Plane left  = new Plane(-Vector3.right, -Vector3.right / 2f);

        Plane top    = new Plane(Vector3.up, Vector3.up / 2f);
        Plane bottom = new Plane(-Vector3.up, -Vector3.up / 2f);

        Plane front = new Plane(Vector3.forward, Vector3.forward / 2f);
        Plane back  = new Plane(-Vector3.forward, -Vector3.forward / 2f);

        Matrix4x4 matrix = decal.transform.worldToLocalMatrix * affectedObject.transform.localToWorldMatrix;

        // Used to keep track of our vertex count when dealing with multiple GameObjects.
        // NO NEED FOR THIS, SINCE IT WILL ALWAYS START AT 0 WHEN WE SEPERATE THE GENERATED MESHES (MAYBE)
        int startVertexCount = bufVertices.Count;

        // Iterate through all the triangles in the <affectedMesh>.
        for (int i = 0; i < triangles.Length; i += 3)
        {
            // Get all the vertices based on their respective triangle indices.
            // TODO: Figure out what MultiplyPoint() does.
            Vector3 v1 = matrix.MultiplyPoint(vertices[triangles[i]]);
            Vector3 v2 = matrix.MultiplyPoint(vertices[triangles[i + 1]]);
            Vector3 v3 = matrix.MultiplyPoint(vertices[triangles[i + 2]]);

            // Calculate the normal for this triangle.
            Vector3 normal = Vector3.Cross(v2 - v1, v3 - v1).normalized;

            // Create a new polygon based on the vertices from the current triangle.
            DecalPolygon poly = new DecalPolygon(v1, v2, v3);

            // Clip the current polygon (triangle) using the Sutherland-Hodgman clipping algorithm
            // applied using the Devide and Conquer simplification method.

            if ((poly = DecalPolygon.ClipPolygon(poly, right)) == null)
            {
                continue;
            }

            if ((poly = DecalPolygon.ClipPolygon(poly, left)) == null)
            {
                continue;
            }

            if ((poly = DecalPolygon.ClipPolygon(poly, top)) == null)
            {
                continue;
            }

            if ((poly = DecalPolygon.ClipPolygon(poly, bottom)) == null)
            {
                continue;
            }

            if ((poly = DecalPolygon.ClipPolygon(poly, front)) == null)
            {
                continue;
            }

            if ((poly = DecalPolygon.ClipPolygon(poly, back)) == null)
            {
                continue;
            }

            // Add the information from this modified triangle polygon to their respective buffers.
            AddPolygon(poly, normal);
        }

        GenerateUVCoords(startVertexCount);
    }
Пример #7
0
    private void BuildDecalGeometry(GameObject affectedObject)
    {
        MeshFilter affectedMesh = affectedObject.GetComponent <MeshFilter>();

        if (affectedMesh == null)
        {
            return;
        }

        if (!affectedMesh.sharedMesh.isReadable)
        {
            return;
        }

        Plane leftPlane  = new Plane(-Vector3.right, -Vector3.right * 0.5f);
        Plane rightPlane = new Plane(Vector3.right, Vector3.right * 0.5f);

        Plane topPlane    = new Plane(Vector3.up, Vector3.up * 0.5f);
        Plane bottomPlane = new Plane(-Vector3.up, -Vector3.up * 0.5f);

        Plane frontPlane = new Plane(Vector3.forward, Vector3.forward * 0.5f);
        Plane backPlane  = new Plane(-Vector3.forward, -Vector3.forward * 0.5f);

        targetVerts = affectedMesh.sharedMesh.vertices;
        targetTris  = affectedMesh.sharedMesh.triangles;
        int startIndex = vertices.Count;

        Matrix4x4 matrix = tr.worldToLocalMatrix * affectedObject.transform.localToWorldMatrix;

        for (int i = 0; i < targetTris.Length; i += 3)
        {
            Vector3 v1 = matrix.MultiplyPoint(targetVerts[targetTris[i]]);
            Vector3 v2 = matrix.MultiplyPoint(targetVerts[targetTris[i + 1]]);
            Vector3 v3 = matrix.MultiplyPoint(targetVerts[targetTris[i + 2]]);

            Vector3 normal = Vector3.Cross(v2 - v1, v3 - v1).normalized;

            if (Vector3.Angle(-Vector3.forward, normal) >= maxAngle - 0.01f)
            {
                continue;
            }

            DecalPolygon poly = new DecalPolygon(v1, v2, v3);

            poly = DecalPolygon.ClipPolygon(poly, leftPlane);
            if (poly == null)
            {
                continue;
            }
            poly = DecalPolygon.ClipPolygon(poly, rightPlane);
            if (poly == null)
            {
                continue;
            }

            poly = DecalPolygon.ClipPolygon(poly, topPlane);
            if (poly == null)
            {
                continue;
            }
            poly = DecalPolygon.ClipPolygon(poly, bottomPlane);
            if (poly == null)
            {
                continue;
            }

            if (!optimized)
            {
                poly = DecalPolygon.ClipPolygon(poly, frontPlane);
                if (poly == null)
                {
                    continue;
                }
                poly = DecalPolygon.ClipPolygon(poly, backPlane);
                if (poly == null)
                {
                    continue;
                }
            }

            AddPolygon(poly, normal);
        }

        CalculateUVs(startIndex);

        if (pushOffset > 0f)
        {
            Push(pushOffset);
        }

        GenerateDecalMesh();
    }
Пример #8
0
    public static void BuildDecalForObject(Decal decal, GameObject affectedObject)
    {
        Mesh affectedMesh = affectedObject.GetComponent <MeshFilter>().sharedMesh;

        if (affectedMesh == null)
        {
            return;
        }

        float maxAngle = decal.maxAngle;

        Plane right = new Plane(Vector3.right, Vector3.right / 2f);
        Plane left  = new Plane(-Vector3.right, -Vector3.right / 2f);

        Plane top    = new Plane(Vector3.up, Vector3.up / 2f);
        Plane bottom = new Plane(-Vector3.up, -Vector3.up / 2f);

        Plane front = new Plane(Vector3.forward, Vector3.forward / 2f);
        Plane back  = new Plane(-Vector3.forward, -Vector3.forward / 2f);

        Vector3[] vertices         = affectedMesh.vertices;
        int[]     triangles        = affectedMesh.triangles;
        int       startVertexCount = bufVertices.Count;

        Matrix4x4 matrix = decal.transform.worldToLocalMatrix * affectedObject.transform.localToWorldMatrix;

        for (int i = 0; i < triangles.Length; i += 3)
        {
            int i1 = triangles[i];
            int i2 = triangles[i + 1];
            int i3 = triangles[i + 2];

            Vector3 v1 = matrix.MultiplyPoint(vertices[i1]);
            Vector3 v2 = matrix.MultiplyPoint(vertices[i2]);
            Vector3 v3 = matrix.MultiplyPoint(vertices[i3]);

            Vector3 side1  = v2 - v1;
            Vector3 side2  = v3 - v1;
            Vector3 normal = Vector3.Cross(side1, side2).normalized;

            if (Vector3.Angle(-Vector3.forward, normal) >= maxAngle)
            {
                continue;
            }


            DecalPolygon poly = new DecalPolygon(v1, v2, v3);

            poly = DecalPolygon.ClipPolygon(poly, right);
            if (poly == null)
            {
                continue;
            }
            poly = DecalPolygon.ClipPolygon(poly, left);
            if (poly == null)
            {
                continue;
            }

            poly = DecalPolygon.ClipPolygon(poly, top);
            if (poly == null)
            {
                continue;
            }
            poly = DecalPolygon.ClipPolygon(poly, bottom);
            if (poly == null)
            {
                continue;
            }

            poly = DecalPolygon.ClipPolygon(poly, front);
            if (poly == null)
            {
                continue;
            }
            poly = DecalPolygon.ClipPolygon(poly, back);
            if (poly == null)
            {
                continue;
            }

            AddPolygon(poly, normal);
        }

        if (decal.sprite)
        {
            GenerateTexCoords(startVertexCount, decal.sprite);
        }
        else
        {
            Sprite    fakeSprite    = new Sprite();
            int       textureWidth  = decal.material.mainTexture.width;
            int       textureHeight = decal.material.mainTexture.height;
            Texture2D textureData   = new Texture2D(textureWidth, textureHeight);
            fakeSprite = Sprite.Create(textureData, new Rect(0, 0, textureWidth, textureHeight), new Vector2(textureWidth / 2, textureHeight / 2));
            GenerateTexCoords(startVertexCount, decal.sprite);
        }
    }