Skip to content
This repository was archived by the owner on Sep 16, 2019. It is now read-only.

Commit 1041ba5

Browse files
committed
Decal rendering #2: Clipping
1 parent beb0315 commit 1041ba5

File tree

1 file changed

+63
-7
lines changed

1 file changed

+63
-7
lines changed

Sledge.DataStructures/MapObjects/Entity.cs

+63-7
Original file line numberDiff line numberDiff line change
@@ -137,11 +137,12 @@ public void CalculateDecalGeometry()
137137
// Get the faces that intersect with the decal's radius
138138
var faces = root.GetAllNodesIntersectingWith(box).OfType<Solid>()
139139
.SelectMany(x => x.Faces).Where(x => x.IntersectsWithBox(box));
140+
var idg = new IDGenerator(); // Dummy generator
140141
foreach (var face in faces)
141142
{
142143
// Project the decal onto the face
143144
var center = face.Plane.Project(Origin);
144-
var decalFace = new Face(int.MinValue) // Use a dummy ID
145+
var decalFace = new Face(idg.GetNextFaceID())
145146
{
146147
Colour = Colour,
147148
IsSelected = IsSelected,
@@ -160,20 +161,75 @@ public void CalculateDecalGeometry()
160161
}
161162
};
162163
// Re-project the vertices in case the texture axes are not on the face plane
163-
// Also add a tiny bit to the normal axis to ensure the decal is rendered in front of the face
164-
var normalAdd = face.Plane.Normal * 0.2m;
165164
var xShift = face.Texture.UAxis * face.Texture.XScale * Decal.Width / 2;
166165
var yShift = face.Texture.VAxis * face.Texture.YScale * Decal.Height / 2;
167-
decalFace.Vertices.Add(new Vertex(face.Plane.Project(center + xShift - yShift) + normalAdd, decalFace)); // Bottom Right
168-
decalFace.Vertices.Add(new Vertex(face.Plane.Project(center + xShift + yShift) + normalAdd, decalFace)); // Top Right
169-
decalFace.Vertices.Add(new Vertex(face.Plane.Project(center - xShift + yShift) + normalAdd, decalFace)); // Top Left
170-
decalFace.Vertices.Add(new Vertex(face.Plane.Project(center - xShift - yShift) + normalAdd, decalFace)); // Bottom Left
166+
decalFace.Vertices.Add(new Vertex(face.Plane.Project(center + xShift - yShift), decalFace)); // Bottom Right
167+
decalFace.Vertices.Add(new Vertex(face.Plane.Project(center + xShift + yShift), decalFace)); // Top Right
168+
decalFace.Vertices.Add(new Vertex(face.Plane.Project(center - xShift + yShift), decalFace)); // Top Left
169+
decalFace.Vertices.Add(new Vertex(face.Plane.Project(center - xShift - yShift), decalFace)); // Bottom Left
170+
decalFace.UpdateBoundingBox();
171171
// TODO: verify this covers all situations and I don't have to manually calculate the texture coordinates
172172
decalFace.FitTextureToPointCloud(new Cloud(decalFace.Vertices.Select(x => x.Location)));
173+
174+
// Next, the decal geometry needs to be clipped to the face so it doesn't spill into the void
175+
// Create a fake solid out of the decal geometry and clip it against all the brush planes
176+
var fake = CreateFakeDecalSolid(decalFace);
177+
foreach (var f in face.Parent.Faces.Except(new[] { face }))
178+
{
179+
Solid back, front;
180+
fake.Split(f.Plane, out back, out front, idg);
181+
fake = back ?? fake;
182+
}
183+
184+
// Extract out the original face
185+
decalFace = fake.Faces.First(x => x.Plane.EquivalentTo(face.Plane));
186+
187+
// Add a tiny bit to the normal axis to ensure the decal is rendered in front of the face
188+
var normalAdd = face.Plane.Normal * 0.2m;
189+
decalFace.Transform(new UnitTranslate(normalAdd));
190+
173191
_decalGeometry.Add(decalFace);
174192
}
175193
}
176194

195+
private static Solid CreateFakeDecalSolid(Face face)
196+
{
197+
var s = new Solid(0)
198+
{
199+
Colour = face.Colour,
200+
IsVisgroupHidden = face.IsHidden,
201+
IsSelected = face.IsSelected
202+
};
203+
s.Faces.Add(face);
204+
var p = face.BoundingBox.Center - face.Plane.Normal * 10; // create a new point underneath the face
205+
var p1 = face.Vertices[0].Location;
206+
var p2 = face.Vertices[1].Location;
207+
var p3 = face.Vertices[2].Location;
208+
var p4 = face.Vertices[3].Location;
209+
var faces = new[]
210+
{
211+
new[] { p2, p1, p},
212+
new[] { p3, p2, p},
213+
new[] { p4, p3, p},
214+
new[] { p1, p4, p}
215+
};
216+
foreach (var ff in faces)
217+
{
218+
var f = new Face(-1)
219+
{
220+
Colour = face.Colour,
221+
IsSelected = face.IsSelected,
222+
IsHidden = face.IsHidden,
223+
Plane = new Plane(ff[0], ff[1], ff[2])
224+
};
225+
f.Vertices.AddRange(ff.Select(x => new Vertex(x, f)));
226+
f.UpdateBoundingBox();
227+
s.Faces.Add(f);
228+
}
229+
s.UpdateBoundingBox(false);
230+
return s;
231+
}
232+
177233
public override void Transform(IUnitTransformation transform)
178234
{
179235
Origin = transform.Transform(Origin);

0 commit comments

Comments
 (0)