@@ -137,11 +137,12 @@ public void CalculateDecalGeometry()
137
137
// Get the faces that intersect with the decal's radius
138
138
var faces = root . GetAllNodesIntersectingWith ( box ) . OfType < Solid > ( )
139
139
. SelectMany ( x => x . Faces ) . Where ( x => x . IntersectsWithBox ( box ) ) ;
140
+ var idg = new IDGenerator ( ) ; // Dummy generator
140
141
foreach ( var face in faces )
141
142
{
142
143
// Project the decal onto the face
143
144
var center = face . Plane . Project ( Origin ) ;
144
- var decalFace = new Face ( int . MinValue ) // Use a dummy ID
145
+ var decalFace = new Face ( idg . GetNextFaceID ( ) )
145
146
{
146
147
Colour = Colour ,
147
148
IsSelected = IsSelected ,
@@ -160,20 +161,75 @@ public void CalculateDecalGeometry()
160
161
}
161
162
} ;
162
163
// 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 ;
165
164
var xShift = face . Texture . UAxis * face . Texture . XScale * Decal . Width / 2 ;
166
165
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 ( ) ;
171
171
// TODO: verify this covers all situations and I don't have to manually calculate the texture coordinates
172
172
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
+
173
191
_decalGeometry . Add ( decalFace ) ;
174
192
}
175
193
}
176
194
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
+
177
233
public override void Transform ( IUnitTransformation transform )
178
234
{
179
235
Origin = transform . Transform ( Origin ) ;
0 commit comments