public static void BuildDecalForObject(DecalGenerator generator, Transform decal, Transform affectedObject) { Mesh affectedMesh = affectedObject.GetComponent<MeshFilter>().sharedMesh; if (affectedMesh == null) return; float maxAngle = generator.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.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, generator.sprite); }
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 int ClipMesh() { int totalVertices = 0; if (clippedPolygons == null) { clippedPolygons = new List <DecalPolygon>(); } else { clippedPolygons.Clear(); } for (int i = 0, c = startPolygons.Count; i < c; i++) { DecalPolygon face = startPolygons[i]; DecalPolygon tempFace = DecalPolygon.ClipPolygonAgainstPlane(face, frontPlane); if (tempFace == null) { continue; } tempFace = DecalPolygon.ClipPolygonAgainstPlane(tempFace, backPlane); if (tempFace == null) { continue; } tempFace = DecalPolygon.ClipPolygonAgainstPlane(tempFace, rightPlane); if (tempFace == null) { continue; } tempFace = DecalPolygon.ClipPolygonAgainstPlane(tempFace, leftPlane); if (tempFace == null) { continue; } tempFace = DecalPolygon.ClipPolygonAgainstPlane(tempFace, bottomPlane); if (tempFace == null) { continue; } tempFace = DecalPolygon.ClipPolygonAgainstPlane(tempFace, topPlane); if (tempFace == null) { continue; } totalVertices += tempFace.vertexCount; clippedPolygons.Add(tempFace); } return(totalVertices); }
public static DecalPolygon ClipPolygon (DecalPolygon poly, Plane plane) { bool[] positive = new bool[9]; int positiveCount = 0; // Iterate through every vertex of the polygon <poly>. for (int i = 0; i < poly.vertices.Count; i++) { // Set if the current vertex is in the positive side of the plane. positive[i] = !plane.GetSide(poly.vertices[i]); if (positive[i]) positiveCount++; } // If there are no vertices on the positive side of the plane, then // return null and cancel out the whole triangle polygon. if (positiveCount == 0) return null; // If all the vertices of the this triangle polygon are on the positive // side of the plane, just return the polygon as is. Nothing needs to be clipped. if (positiveCount == poly.vertices.Count) return poly; DecalPolygon tempPoly = new DecalPolygon(); for (int i = 0; i < poly.vertices.Count; i++) { // <next> will start from the last vertex index and move towards the starting index. int next = i + 1; next %= poly.vertices.Count; // If the current vertex is within the positive side of the plane, then no clipping is needed. // So we just add it back to <tempPoly>. if (positive[i]) tempPoly.vertices.Add(poly.vertices[i]); // If the current vertex and the next vertex are on oposite sides of the plane, then clipe them // so the plane and add the new clipped vertex. if (positive[i] != positive[next]) { Vector3 v1 = poly.vertices[next]; Vector3 v2 = poly.vertices[i]; ///Vector3 v = DecalBuilder.LineCast(plane, v1, v2); Vector3 v = DecalBuilder.LineCast(plane, v1, v2); // Add the new clipped vertex to <tempPoly>. tempPoly.vertices.Add(v); } } return tempPoly; }
private void AddPolygon(DecalPolygon polygon, Vector3 normal) { int triangle = CalculateVertex(polygon.vertices[0], normal); for (int i = 1; i < polygon.vertices.Count - 1; i++) { triangles.Add(triangle); triangles.Add(CalculateVertex(polygon.vertices[i], normal)); triangles.Add(CalculateVertex(polygon.vertices[i + 1], normal)); } }
private void AddPolygon(DecalPolygon poly, Vector3 normal) { int ind1 = AddVertex(poly.vertices[0], normal); for (int i = 1; i < poly.vertices.Count - 1; i++) { int ind2 = AddVertex(poly.vertices[i], normal); int ind3 = AddVertex(poly.vertices[i + 1], normal); bufIndices.Add(ind1); bufIndices.Add(ind2); bufIndices.Add(ind3); } }
public static DecalPolygon ClipPolygon(DecalPolygon polygon, Plane plane) { positive = new bool[9]; positiveCount = 0; for (int i = 0; i < polygon.vertices.Count; i++) { positive[i] = !plane.GetSide(polygon.vertices[i]); if (positive[i]) { positiveCount++; } } if (positiveCount == 0) { return(null); } if (positiveCount == polygon.vertices.Count) { return(polygon); } DecalPolygon tempPolygon = new DecalPolygon(); for (int i = 0; i < polygon.vertices.Count; i++) { int next = i + 1; next %= polygon.vertices.Count; if (positive[i]) { tempPolygon.vertices.Add(polygon.vertices[i]); } if (positive[i] != positive[next]) { Vector3 v1 = polygon.vertices[next]; Vector3 v2 = polygon.vertices[i]; float dist = 0f; Ray ray = new Ray(v1, v2 - v1); plane.Raycast(ray, out dist); tempPolygon.vertices.Add(ray.GetPoint(dist)); } } return(tempPolygon); }
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); }
public static DecalPolygon ClipPolygon(DecalPolygon polygon, Plane plane) { bool[] positive = new bool[9]; int positiveCount = 0; for (int i = 0; i < polygon.vertices.Count; i++) { positive[i] = !plane.GetSide(polygon.vertices[i]); if (positive[i]) { positiveCount++; } } if (positiveCount == 0) { return(null); // полностью за плоскостью } if (positiveCount == polygon.vertices.Count) { return(polygon); // полностью перед плоскостью } DecalPolygon tempPolygon = new DecalPolygon(); for (int i = 0; i < polygon.vertices.Count; i++) { int next = i + 1; next %= polygon.vertices.Count; if (positive[i]) { tempPolygon.vertices.Add(polygon.vertices[i]); } if (positive[i] != positive[next]) { Vector3 v1 = polygon.vertices[next]; Vector3 v2 = polygon.vertices[i]; Vector3 v = LineCast(plane, v1, v2); tempPolygon.vertices.Add(v); } } return(tempPolygon); }
public static bool ClipPolygon(ref DecalPolygon polygon, Plane plane) { ResetPositive(); int positiveCount = 0; for (int i = 0; i < polygon.vertices.Count; i++) { positive[i] = !plane.GetSide(polygon.vertices[i]); if (positive[i]) { positiveCount++; } } if (positiveCount == 0) { return(false); } if (positiveCount == polygon.vertices.Count) { return(true); } tempPolygon.Clear(); for (int i = 0; i < polygon.vertices.Count; i++) { int next = i + 1; next %= polygon.vertices.Count; if (positive[i]) { tempPolygon.vertices.Add(polygon.vertices[i]); } if (positive[i] != positive[next]) { Vector3 v1 = polygon.vertices[next]; Vector3 v2 = polygon.vertices[i]; Vector3 v = LineCast(plane, v1, v2); tempPolygon.vertices.Add(v); } } polygon.CopyFrom(tempPolygon); return(true); }
private static void AddPolygon(DecalPolygon poly, Vector3 normal) { // Get the index for the first index, which will be a constant). int index1 = AddVertex(poly.vertices[0], normal); for (int i = 1; i < poly.vertices.Count - 1; i++) { // Get the other indexes for the proceding vertices. int index2 = AddVertex(poly.vertices[i], normal); int index3 = AddVertex(poly.vertices[i + 1], normal); // Add all the collected triangle polygon indices. bufIndices.Add(index1); bufIndices.Add(index2); bufIndices.Add(index3); } }
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 static DecalPolygon ClipPolygon(DecalPolygon polygon, Plane plane) { bool[] positive = new bool[9]; int positiveCount = 0; for (int i = 0; i < polygon.vertices.Count; i++) { positive[i] = !plane.GetSide(polygon.vertices[i]); if (positive[i]) positiveCount++; } if (positiveCount == 0) return null; // полностью за плоскостью if (positiveCount == polygon.vertices.Count) return polygon; // полностью перед плоскостью DecalPolygon tempPolygon = new DecalPolygon(); for (int i = 0; i < polygon.vertices.Count; i++) { int next = i + 1; next %= polygon.vertices.Count; if (positive[i]) { tempPolygon.vertices.Add(polygon.vertices[i]); } if (positive[i] != positive[next]) { Vector3 v1 = polygon.vertices[next]; Vector3 v2 = polygon.vertices[i]; Vector3 v = LineCast(plane, v1, v2); tempPolygon.vertices.Add(v); } } return tempPolygon; }
static public DecalPolygon ClipPolygonAgainstPlane(DecalPolygon polygon, Vector4 plane) { bool[] neg = new bool[10]; int negCount = 0; Vector3 n = new Vector3(plane.x, plane.y, plane.z); for (int i = 0; i < polygon.verticeCount; i++) { neg[i] = (Vector3.Dot(polygon.vertice[i], n) + plane.w) < 0.0f; if (neg[i]) { negCount++; } } if (negCount == polygon.verticeCount) { return(null); } if (negCount == 0) { return(polygon); } DecalPolygon tempPolygon = new DecalPolygon(); tempPolygon.verticeCount = 0; Vector3 v1, v2, dir; float t; for (int i = 0; i < polygon.verticeCount; i++) { int b = (i == 0) ? polygon.verticeCount - 1 : i - 1; if (neg[i]) { if (!neg[b]) { v1 = polygon.vertice[i]; v2 = polygon.vertice[b]; dir = (v2 - v1).normalized; t = -(Vector3.Dot(n, v1) + plane.w) / Vector3.Dot(n, dir); tempPolygon.tangent[tempPolygon.verticeCount] = polygon.tangent[i] + ((polygon.tangent[b] - polygon.tangent[i]).normalized * t); tempPolygon.vertice[tempPolygon.verticeCount] = v1 + ((v2 - v1).normalized * t); tempPolygon.normal[tempPolygon.verticeCount] = polygon.normal[i] + ((polygon.normal[b] - polygon.normal[i]).normalized * t); tempPolygon.verticeCount++; } } else { if (neg[b]) { v1 = polygon.vertice[b]; v2 = polygon.vertice[i]; dir = (v2 - v1).normalized; t = -(Vector3.Dot(n, v1) + plane.w) / Vector3.Dot(n, dir); tempPolygon.tangent[tempPolygon.verticeCount] = polygon.tangent[b] + ((polygon.tangent[i] - polygon.tangent[b]).normalized * t); tempPolygon.vertice[tempPolygon.verticeCount] = v1 + ((v2 - v1).normalized * t); tempPolygon.normal[tempPolygon.verticeCount] = polygon.normal[b] + ((polygon.normal[i] - polygon.normal[b]).normalized * t); tempPolygon.verticeCount++; } tempPolygon.tangent[tempPolygon.verticeCount] = polygon.tangent[i]; tempPolygon.vertice[tempPolygon.verticeCount] = polygon.vertice[i]; tempPolygon.normal[tempPolygon.verticeCount] = polygon.normal[i]; tempPolygon.verticeCount++; } } return(tempPolygon); }
public void CalculateObjectDecal(GameObject obj, Matrix4x4 cTransform) { Mesh m = null; if(decalMode == DecalMode.MESH_COLLIDER) { if(obj.GetComponent<MeshCollider>() != null) { m = obj.GetComponent<MeshCollider>().sharedMesh; } else { m = null; } } if(m == null || decalMode == DecalMode.MESH_FILTER) { if(obj.GetComponent<MeshFilter>() == null) return; m = obj.GetComponent<MeshFilter>().sharedMesh; } if(m == null || m.name.ToLower().Contains("combined")) { return; } decalNormal = obj.transform.InverseTransformDirection(transform.forward); decalCenter = obj.transform.InverseTransformPoint(transform.position); decalTangent = obj.transform.InverseTransformDirection(transform.right); decalBinormal = obj.transform.InverseTransformDirection(transform.up); decalSize = new Vector3(transform.lossyScale.x / obj.transform.lossyScale.x, transform.lossyScale.y / obj.transform.lossyScale.y, transform.lossyScale.z / obj.transform.lossyScale.z);//transf.MultiplyPoint(transform.lossyScale); bottomPlane = new Vector4(-decalBinormal.x, -decalBinormal.y, -decalBinormal.z, (decalSize.y * 0.5f) + Vector3.Dot(decalCenter, decalBinormal)); topPlane = new Vector4(decalBinormal.x, decalBinormal.y, decalBinormal.z, (decalSize.y * 0.5f) - Vector3.Dot(decalCenter, decalBinormal)); rightPlane = new Vector4(-decalTangent.x, -decalTangent.y, -decalTangent.z, (decalSize.x * 0.5f) + Vector3.Dot(decalCenter, decalTangent)); leftPlane = new Vector4(decalTangent.x, decalTangent.y, decalTangent.z, (decalSize.x * 0.5f) - Vector3.Dot(decalCenter, decalTangent)); frontPlane = new Vector4(decalNormal.x, decalNormal.y, decalNormal.z, (decalSize.z * 0.5f) - Vector3.Dot(decalCenter, decalNormal)); backPlane = new Vector4(-decalNormal.x, -decalNormal.y, -decalNormal.z, (decalSize.z * 0.5f) + Vector3.Dot(decalCenter, decalNormal)); int[] triangles = m.triangles; Vector3[] vertices = m.vertices; Vector3[] normals = m.normals; Vector4[] tangents = m.tangents; float dot; int i1, i2, i3; Vector3 v1, v2, v3; Vector3 n1; Vector3 t1, t2, t3; DecalPolygon t; startPolygons = new List<DecalPolygon>(); for(int i = 0; i < triangles.Length; i += 3) { i1 = triangles[i]; i2 = triangles[i+1]; i3 = triangles[i+2]; v1 = vertices[i1]; v2 = vertices[i2]; v3 = vertices[i3]; n1 = normals[i1]; dot = Vector3.Dot(n1, -decalNormal); if(dot <= angleCosine) continue; t1 = tangents[i1]; t2 = tangents[i2]; t3 = tangents[i3]; t = new DecalPolygon(); t.verticeCount = 3; t.vertice[0] = v1; t.vertice[1] = v2; t.vertice[2] = v3; t.normal[0] = n1; t.normal[1] = n1; t.normal[2] = n1; t.tangent[0] = t1; t.tangent[1] = t2; t.tangent[2] = t3; startPolygons.Add(t); } Mesh aux = CreateMesh(ClipMesh(), obj.transform); if(aux != null) { MeshCombineUtility.MeshInstance instance = new MeshCombineUtility.MeshInstance(); instance.mesh = aux; instance.subMeshIndex = 0; instance.transform = transform.worldToLocalMatrix * obj.transform.localToWorldMatrix; instancesList.Add(instance); } aux = null; startPolygons.Clear(); startPolygons = null; clippedPolygons.Clear(); clippedPolygons = null; triangles = null; normals = null; vertices = null; tangents = null; System.GC.Collect(); }
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); }
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(); }
private static void AddPolygon(DecalPolygon poly, Vector3 normal) { int ind1 = AddVertex(poly.vertices[0], normal); for (int i = 1; i < poly.vertices.Count - 1; i++) { int ind2 = AddVertex(poly.vertices[i], normal); int ind3 = AddVertex(poly.vertices[i + 1], normal); bufIndices.Add(ind1); bufIndices.Add(ind2); bufIndices.Add(ind3); } }
static public DecalPolygon ClipPolygonAgainstPlane (DecalPolygon polygon, Vector4 plane) { bool[] neg = new bool[10]; int negCount = 0; Vector3 n = new Vector3(plane.x, plane.y, plane.z); for(int i = 0; i < polygon.verticeCount; i++) { neg[i] = (Vector3.Dot(polygon.vertice[i], n) + plane.w) < 0.0f; if(neg[i]) negCount++; } if(negCount == polygon.verticeCount) return null; if(negCount == 0) return polygon; DecalPolygon tempPolygon = new DecalPolygon(); tempPolygon.verticeCount = 0; Vector3 v1, v2, dir; float t; for(int i = 0; i < polygon.verticeCount; i++) { int b = (i == 0) ? polygon.verticeCount - 1 : i -1; if(neg[i]) { if(!neg[b]) { v1 = polygon.vertice[i]; v2 = polygon.vertice[b]; dir = (v2 - v1).normalized; t = -(Vector3.Dot(n, v1) + plane.w) / Vector3.Dot(n, dir); tempPolygon.tangent[tempPolygon.verticeCount] = polygon.tangent[i] + ((polygon.tangent[b] - polygon.tangent[i]).normalized * t); tempPolygon.vertice[tempPolygon.verticeCount] = v1 + ((v2 - v1).normalized * t); tempPolygon.normal[tempPolygon.verticeCount] = polygon.normal[i] + ((polygon.normal[b] - polygon.normal[i]).normalized * t); tempPolygon.verticeCount++; } } else { if(neg[b]) { v1 = polygon.vertice[b]; v2 = polygon.vertice[i]; dir = (v2 - v1).normalized; t = -(Vector3.Dot(n, v1) + plane.w) / Vector3.Dot(n, dir); tempPolygon.tangent[tempPolygon.verticeCount] = polygon.tangent[b] + ((polygon.tangent[i] - polygon.tangent[b]).normalized * t); tempPolygon.vertice[tempPolygon.verticeCount] = v1 + ((v2 - v1).normalized * t); tempPolygon.normal[tempPolygon.verticeCount] = polygon.normal[b] + ((polygon.normal[i] - polygon.normal[b]).normalized * t); tempPolygon.verticeCount++; } tempPolygon.tangent[tempPolygon.verticeCount] = polygon.tangent[i]; tempPolygon.vertice[tempPolygon.verticeCount] = polygon.vertice[i]; tempPolygon.normal[tempPolygon.verticeCount] = polygon.normal[i]; tempPolygon.verticeCount++; } } return tempPolygon; }
private void CalculateObjectDecal(GameObject obj) { MeshFilter mf = obj.GetComponent <MeshFilter>(); if (!mf) { return; } Mesh mesh = mf.sharedMesh; if (!mesh || mesh.name.ToLower().Contains("combined") || mesh.tangents.Length == 0) { return; } decalNormal = obj.transform.InverseTransformDirection(transform.forward); decalCenter = obj.transform.InverseTransformPoint(transform.position); decalTangent = obj.transform.InverseTransformDirection(transform.right); decalBinormal = obj.transform.InverseTransformDirection(transform.up); Vector3 lossyScale = obj.transform.lossyScale; Vector3 scale = transform.lossyScale; decalSize = new Vector3(scale.x / lossyScale.x, scale.y / lossyScale.y, scale.z / lossyScale.z); bottomPlane = new Vector4(-decalBinormal.x, -decalBinormal.y, -decalBinormal.z, (decalSize.y * 0.5f) + Vector3.Dot(decalCenter, decalBinormal)); topPlane = new Vector4(decalBinormal.x, decalBinormal.y, decalBinormal.z, (decalSize.y * 0.5f) - Vector3.Dot(decalCenter, decalBinormal)); rightPlane = new Vector4(-decalTangent.x, -decalTangent.y, -decalTangent.z, (decalSize.x * 0.5f) + Vector3.Dot(decalCenter, decalTangent)); leftPlane = new Vector4(decalTangent.x, decalTangent.y, decalTangent.z, (decalSize.x * 0.5f) - Vector3.Dot(decalCenter, decalTangent)); frontPlane = new Vector4(decalNormal.x, decalNormal.y, decalNormal.z, (decalSize.z * 0.5f) - Vector3.Dot(decalCenter, decalNormal)); backPlane = new Vector4(-decalNormal.x, -decalNormal.y, -decalNormal.z, (decalSize.z * 0.5f) + Vector3.Dot(decalCenter, decalNormal)); int[] triangles = mesh.triangles; Vector3[] vertices = mesh.vertices; Vector3[] normals = mesh.normals; Vector4[] tangents = mesh.tangents; startPolygons = new List <DecalPolygon>(); 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 = vertices[i1]; Vector3 v2 = vertices[i2]; Vector3 v3 = vertices[i3]; Vector3 n1 = normals[i1]; float dot = Vector3.Dot(n1, -decalNormal); if (dot <= angleCosine) { continue; } Vector3 t1 = tangents[i1]; Vector3 t2 = tangents[i2]; Vector3 t3 = tangents[i3]; DecalPolygon decalPolygon = new DecalPolygon { vertexCount = 3, vertex = { [0] = v1, [1] = v2, [2] = v3 }, normal = { [0] = n1, [1] = n1, [2] = n1 }, tangent = { [0] = t1, [1] = t2, [2] = t3 } }; startPolygons.Add(decalPolygon); } Mesh aux = CreateMesh(ClipMesh()); if (aux) { MeshInstance instance = new MeshInstance { mesh = aux, subMeshIndex = 0, transform = transform.worldToLocalMatrix * obj.transform.localToWorldMatrix }; m_InstancesList.Add(instance); } startPolygons.Clear(); startPolygons = null; clippedPolygons.Clear(); clippedPolygons = null; }
public void CalculateObjectDecal(GameObject obj, Matrix4x4 cTransform) { Mesh m = null; if (decalMode == DecalMode.MESH_COLLIDER) { if (obj.GetComponent <MeshCollider>() != null) { m = obj.GetComponent <MeshCollider>().sharedMesh; } else { m = null; } } if (m == null || decalMode == DecalMode.MESH_FILTER) { if (obj.GetComponent <MeshFilter>() == null) { return; } m = obj.GetComponent <MeshFilter>().sharedMesh; } if (m == null || m.name.ToLower().Contains("combined")) { return; } decalNormal = obj.transform.InverseTransformDirection(transform.forward); decalCenter = obj.transform.InverseTransformPoint(transform.position); decalTangent = obj.transform.InverseTransformDirection(transform.right); decalBinormal = obj.transform.InverseTransformDirection(transform.up); decalSize = new Vector3(transform.lossyScale.x / obj.transform.lossyScale.x, transform.lossyScale.y / obj.transform.lossyScale.y, transform.lossyScale.z / obj.transform.lossyScale.z); //transf.MultiplyPoint(transform.lossyScale); bottomPlane = new Vector4(-decalBinormal.x, -decalBinormal.y, -decalBinormal.z, (decalSize.y * 0.5f) + Vector3.Dot(decalCenter, decalBinormal)); topPlane = new Vector4(decalBinormal.x, decalBinormal.y, decalBinormal.z, (decalSize.y * 0.5f) - Vector3.Dot(decalCenter, decalBinormal)); rightPlane = new Vector4(-decalTangent.x, -decalTangent.y, -decalTangent.z, (decalSize.x * 0.5f) + Vector3.Dot(decalCenter, decalTangent)); leftPlane = new Vector4(decalTangent.x, decalTangent.y, decalTangent.z, (decalSize.x * 0.5f) - Vector3.Dot(decalCenter, decalTangent)); frontPlane = new Vector4(decalNormal.x, decalNormal.y, decalNormal.z, (decalSize.z * 0.5f) - Vector3.Dot(decalCenter, decalNormal)); backPlane = new Vector4(-decalNormal.x, -decalNormal.y, -decalNormal.z, (decalSize.z * 0.5f) + Vector3.Dot(decalCenter, decalNormal)); int[] triangles = m.triangles; Vector3[] vertices = m.vertices; Vector3[] normals = m.normals; Vector4[] tangents = m.tangents; float dot; int i1, i2, i3; Vector3 v1, v2, v3; Vector3 n1; Vector3 t1, t2, t3; DecalPolygon t; startPolygons = new List <DecalPolygon>(); for (int i = 0; i < triangles.Length; i += 3) { i1 = triangles[i]; i2 = triangles[i + 1]; i3 = triangles[i + 2]; v1 = vertices[i1]; v2 = vertices[i2]; v3 = vertices[i3]; n1 = normals[i1]; dot = Vector3.Dot(n1, -decalNormal); if (dot <= angleCosine) { continue; } t1 = tangents[i1]; t2 = tangents[i2]; t3 = tangents[i3]; t = new DecalPolygon(); t.verticeCount = 3; t.vertice[0] = v1; t.vertice[1] = v2; t.vertice[2] = v3; t.normal[0] = n1; t.normal[1] = n1; t.normal[2] = n1; t.tangent[0] = t1; t.tangent[1] = t2; t.tangent[2] = t3; startPolygons.Add(t); } Mesh aux = CreateMesh(ClipMesh(), obj.transform); if (aux != null) { MeshCombineUtility.MeshInstance instance = new MeshCombineUtility.MeshInstance(); instance.mesh = aux; instance.subMeshIndex = 0; instance.transform = transform.worldToLocalMatrix * obj.transform.localToWorldMatrix; instancesList.Add(instance); } aux = null; startPolygons.Clear(); startPolygons = null; clippedPolygons.Clear(); clippedPolygons = null; triangles = null; normals = null; vertices = null; tangents = null; System.GC.Collect(); }
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 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); }
public void CopyFrom(DecalPolygon value) { Clear(); vertices.AddRange(value.vertices); }
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); } }
public static void BuildDecalForObject(Decal decal, CLIPSHAPE_TYPE eShapeType, float fAngle, GameObject affectedObject) { Mesh affectedMesh = null; MeshCollider mc = affectedObject.GetComponent <MeshCollider>(); if (mc != null) { affectedMesh = mc.sharedMesh; } else { MeshFilter mf = affectedObject.GetComponent <MeshFilter>(); if (mf != null) { affectedMesh = mf.sharedMesh; } } if (affectedMesh == null || affectedMesh.isReadable == false) { return; } float maxSlopeAngle = decal.maxSlopeAngle; 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.up, normal) >= maxSlopeAngle) { continue; } if (eShapeType == CLIPSHAPE_TYPE.CST_SQUARE) { DecalPolygon poly = ClipPolygonBySquare(v1, v2, v3); if (poly != null) { AddPolygon(poly, normal); } } else if (eShapeType == CLIPSHAPE_TYPE.CST_SECTOR) { if (fAngle <= 0f && fAngle >= 360f) { LogMgr.UnityError("Sector angle beyond Range! Must limit it greater than 0 degree and less than 360 degree."); continue; } if (fAngle <= 180f) { DecalPolygon poly = ClipPolygonByConvexSector(fAngle, v1, v2, v3); if (poly != null) { AddPolygon(poly, normal); } } else { DecalPolygon poly = ClipPolygonByNonConvexSector(fAngle, v1, v2, v3, false); if (poly != null) { AddPolygon(poly, normal); } DecalPolygon polySec = ClipPolygonByNonConvexSector(fAngle, v1, v2, v3, true); if (polySec != null) { AddPolygon(polySec, normal); } } } } //GenerateTexCoords(startVertexCount, decal.sprite); GenerateTexCoords(startVertexCount, decal); }