@@ -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