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); }
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); }
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); }
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); }
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(); }
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); } }