private void Triangulate(DecalProjection projection, MeshBuilder builder, ref List <ClipPointData> polygon) { List <Vector3> vertices = builder.Vertices; int index = polygon[0].index; Vector3 vector = vertices[index]; for (int i = 2; i < polygon.Count; i++) { ClipPointData data2 = polygon[i - 1]; int num3 = data2.index; ClipPointData data3 = polygon[i]; int num4 = data3.index; Vector3 vector2 = vertices[num3]; Vector3 vector3 = vertices[num4]; Ray ray = projection.Ray; Vector3 vector4 = Vector3.Cross(vector - vector2, vector - vector3); if (Vector3.Dot(-ray.direction, vector4.normalized) > 0f) { builder.AddTriangle(index, num3, num4); } else { builder.AddTriangle(index, num4, num3); } } }
private Vector3 GetProjectDirectionAsMiddleNormal(DecalProjection projection, List <int> triangles, List <Vector3> vertices, List <Vector3> normals) { Vector3 zero = Vector3.zero; for (int i = 0; i < triangles.Count; i += 3) { int num2 = triangles[i]; int num3 = triangles[i + 1]; int num4 = triangles[i + 2]; Vector3 vector2 = vertices[num2]; Vector3 vector3 = vertices[num3]; Vector3 vector4 = vertices[num4]; zero += normals[num2] * this.GetTriangleSquare(vector2, vector3, vector4); } return(!zero.Equals(Vector3.zero) ? -zero.normalized : projection.Ray.direction); }
public bool Collect(DecalProjection projection, MeshBuilder meshBuilder) { foreach (Collider collider in this.GetColliders(projection)) { Mesh mesh; if (this.GetMeshByCollider(collider, out mesh)) { Renderer renderer; meshBuilder.ClearWeldHashing(); Transform transform = collider.transform; if (this.TryGetRenderer(collider.gameObject, out renderer) && !renderer.gameObject.CompareTag("IgnoreDecals")) { float[] numArray2; Vector3[] vectorArray3; int[] triangles = this.cache.GetTriangles(mesh); Vector3[] vertices = this.cache.GetVertices(mesh); Vector3[] normals = this.cache.GetNormals(mesh); SurfaceType[] surfaceTypes = this.cache.GetSurfaceTypes(mesh, renderer); this.cache.GetTriangleRadius(mesh, out numArray2, out vectorArray3); Vector3 vector = transform.InverseTransformDirection(projection.Ray.direction); Vector3 vector2 = transform.InverseTransformPoint(projection.ProjectionHit.point); for (int i = 0; i < triangles.Length; i += 3) { int index = i / 3; Vector3 vector3 = vectorArray3[index] - vector2; float sqrMagnitude = vector3.sqrMagnitude; float num5 = numArray2[index] + projection.HalfSize; if (sqrMagnitude <= (num5 * num5)) { int num6 = triangles[i]; if (Vector3.Dot(normals[num6], -vector) >= 0f) { int num8 = triangles[i + 1]; int num9 = triangles[i + 2]; Vector3 vertex = vertices[num6]; Vector3 vector6 = vertices[num8]; Vector3 vector7 = vertices[num9]; num6 = meshBuilder.AddVertexWeldAndTransform((long)num6, new VertexData(vertex, normals[num6], surfaceTypes[num6]), transform); meshBuilder.AddTriangle(num6, meshBuilder.AddVertexWeldAndTransform((long)num8, new VertexData(vector6, normals[num8], surfaceTypes[num8]), transform), meshBuilder.AddVertexWeldAndTransform((long)num9, new VertexData(vector7, normals[num9], surfaceTypes[num9]), transform)); } } } } } } return(meshBuilder.Triangles.Count > 0); }
public void Clip(DecalProjection projection, MeshBuilder sourceBuilder, MeshBuilder destBuilder) { List <int> triangles = sourceBuilder.Triangles; List <Vector3> vertices = sourceBuilder.Vertices; List <Vector3> normals = sourceBuilder.Normals; List <SurfaceType> surfaceTypes = sourceBuilder.SurfaceTypes; Quaternion rotation = Quaternion.LookRotation(-projection.ProjectionHit.normal, projection.Up); Quaternion quaternion2 = Quaternion.Inverse(rotation); ClipEdge2D[] clipPlane = this.CalculateClipPlane(projection.HalfSize, projection.HalfSize); int num = 0; while (num < triangles.Count) { this.polygon.Clear(); int num2 = 0; while (true) { if (num2 >= 3) { if (this.ClipByWidthAndHeight(clipPlane, ref this.polygon) && this.ClipByDepth(clipPlane, projection.HalfSize, ref this.polygon)) { this.AddAllPolygonPointsAndTransformToWorld(destBuilder, ref this.polygon, rotation, projection.ProjectionHit.point); this.Triangulate(projection, destBuilder, ref this.polygon); } num += 3; break; } int num3 = triangles[num + num2]; Vector3 normal = normals[num3]; SurfaceType surfaceType = surfaceTypes[num3]; RaycastHit projectionHit = projection.ProjectionHit; Vector3 vertex = (Vector3)(quaternion2 * (vertices[num3] - projectionHit.point)); this.polygon.Add(new ClipPointData(new VertexData(vertex, normal, surfaceType))); num2++; } } }
public void Project(MeshBuilder builder, DecalProjection projection) { List <Vector3> normals = builder.Normals; List <Vector3> vertices = builder.Vertices; List <int> triangles = builder.Triangles; List <SurfaceType> surfaceTypes = builder.SurfaceTypes; float num = projection.HalfSize * 1.1f; float num2 = (num * 2f) * projection.AtlasHTilesCount; float num3 = (num * 2f) * projection.AtlasVTilesCount; Quaternion quaternion2 = Quaternion.Inverse(Quaternion.LookRotation(this.GetProjectDirectionAsMiddleNormal(projection, triangles, vertices, normals), projection.Up)); for (int i = 0; i < vertices.Count; i++) { int position = projection.SurfaceAtlasPositions[surfaceTypes[i]]; Vector2 vector2 = this.GetAtlasOffset(projection.AtlasHTilesCount, projection.AtlasVTilesCount, position); Vector3 vector3 = vertices[i]; Vector3 vector4 = normals[i]; RaycastHit projectionHit = projection.ProjectionHit; Vector3 vector5 = (Vector3)(quaternion2 * (vector3 - projectionHit.point)); Vector3 vector6 = (Vector3)(quaternion2 * vector4); vector6.x = Mathf.Abs(vector6.x); vector6.y = Mathf.Abs(vector6.y); float num6 = Mathf.Abs(vector5.z) * this.DEPTH_TO_OFFSET_KOEF; float x = vector5.x; float y = vector5.y; if (vector6.x > this.NORMAL_TO_OFFSET_TRESHOLD) { x += (Mathf.Sign(vector5.x) * vector6.x) * num6; } if (vector6.y > this.NORMAL_TO_OFFSET_TRESHOLD) { y += (Mathf.Sign(vector5.y) * vector6.y) * num6; } builder.AddUV(new Vector2(((x / num2) + 0.5f) + vector2.x, ((y / num3) + 0.5f) + vector2.y)); } }
private Collider[] GetColliders(DecalProjection projection) => Physics.OverlapSphere(projection.ProjectionHit.point, projection.HalfSize);