public static void DrawGizmos(TRS trs) { NativeArray <Edge> unitCubeEdges; NativeArray <Plane> unitCubePlanes; UnitCube.GenerateStructures(out unitCubeEdges, out unitCubePlanes); foreach (var e in unitCubeEdges) { GizmoLine(e, trs); } Gizmos.color = Color.green; GizmoLine(UnitCube.Edge0, trs); GizmoLine(UnitCube.Edge1, trs); GizmoLine(UnitCube.Edge2, trs); GizmoLine(UnitCube.Edge3, trs); float4 extrapolate0 = GizmoLineExtrapolate(UnitCube.Edge0.Vertex0, trs); float4 extrapolate1 = GizmoLineExtrapolate(UnitCube.Edge1.Vertex0, trs); float4 extrapolate2 = GizmoLineExtrapolate(UnitCube.Edge2.Vertex0, trs); float4 extrapolate3 = GizmoLineExtrapolate(UnitCube.Edge3.Vertex0, trs); GizmoLine(extrapolate0, extrapolate1, trs); GizmoLine(extrapolate1, extrapolate2, trs); GizmoLine(extrapolate2, extrapolate3, trs); GizmoLine(extrapolate3, extrapolate0, trs); unitCubeEdges.Dispose(); unitCubePlanes.Dispose(); }
static float4 GizmoLineExtrapolate(float4 v, TRS trs) { float4 extrapolatedV = v + (math.normalize(v) * 0.2f); GizmoLine(v, extrapolatedV, trs); return(extrapolatedV); }
public Triangle WorldToLocal(TRS trs) { Triangle t = Triangle.zero; t.SetFrom( trs.WorldToLocal(Vertex0), trs.WorldToLocal(Vertex1), trs.WorldToLocal(Vertex2) ); return(t); }
public Triangle LocalToWorld(TRS trs) { Triangle t = Triangle.zero; t.SetFrom( trs.LocalToWorld(Vertex0), trs.LocalToWorld(Vertex1), trs.LocalToWorld(Vertex2) ); return(t); }
// Scan for MeshRenderers that overlap the projector, and collect all of their triangles to be clipped // into the projector int GatherTriangles(NativeArray <Triangle> sourceTriangleArray) { TRS meshTRS = new TRS(); int sourceTriangles = 0; float4 up = new float4(0f, 1f, 0f, 0f); foreach (var meshFilter in FindObjectsOfType <MeshFilter>()) { // Filter out object by layer mask int mask = 1 << meshFilter.gameObject.layer; if ((mask & m_layerMask) != mask) { continue; } // Filter out objects that are themselves decal projectors if (meshFilter.GetComponent <DecalProjector>() != null) { continue; } // Filter out objects by render bounds Renderer r = meshFilter.GetComponent <Renderer>(); if (!r.bounds.Intersects(m_bounds)) { continue; } // Filter out objects with no mesh Mesh m = meshFilter.sharedMesh; if (m == null) { continue; } Transform meshTransform = meshFilter.transform; meshTRS.Update(meshTransform.worldToLocalMatrix, meshTransform.localToWorldMatrix, meshTransform.position.ToFloat4()); Vector3[] meshVertices = m.vertices; // Iterate over the submeshes for (int submeshIndex = 0; submeshIndex < m.subMeshCount; submeshIndex++) { // Iterate over every group of 3 indices that form triangles int[] meshIndices = m.GetIndices(submeshIndex); for (int meshIndex = 0; meshIndex < meshIndices.Length; meshIndex += 3) { // TODO, make triangle Transform modify the triangle instead of making a new one Triangle tInMeshLocal = Triangle.zero; tInMeshLocal.SetFrom( meshVertices[meshIndices[meshIndex]].ToFloat4(), meshVertices[meshIndices[meshIndex + 1]].ToFloat4(), meshVertices[meshIndices[meshIndex + 2]].ToFloat4()); Triangle tInWorld = tInMeshLocal.LocalToWorld(meshTRS); if (m_cullBackfaces) { if (math.dot(tInWorld.Normal, up) < 0f) { continue; } } // If the bounds of the individual triangle don't intersect with the unit cube bounds, we can // ignore it Bounds triangleBounds = BoundsFromTriangle(tInWorld); if (!triangleBounds.Intersects(m_bounds)) { continue; } Triangle tInProjectorLocal = tInWorld.WorldToLocal(m_TRS); sourceTriangleArray[sourceTriangles++] = tInProjectorLocal; if (sourceTriangles >= MaxDecalTriangles) { Debug.LogError($"Decal triangles exceeds max trianges {MaxDecalTriangles}."); return(sourceTriangles); } } } } return(sourceTriangles); }
static void GizmoLine(float4 a, float4 b, TRS trs) { Gizmos.DrawLine( trs.LocalToWorld(a).xyz, trs.LocalToWorld(b).xyz ); }
static void GizmoLine(Edge e, TRS trs) { GizmoLine(e.Vertex0, e.Vertex1, trs); }