For my game, I have added "Brushes" which are 3D boxes that will be used to create level geometry. I wanted to add the ability to flip the brushes inside out, so the exterior becomes the interior, etc. I’m pretty sure I know how to do this, but I wanted to make sure this is actually standard practice. First of all, here’s a picture of my BrushVolume in engine:

I generate this BrushVolume via the following code:

`public void Rebuild() { /** * No faces are present; empty the StaticBrushVolume */ if (this.FaceVisibility == BrushVolumeFaceVisibility.None) { if (_bufferBinding.Buffer != null) { _bufferBinding.Buffer.Dispose(); } this.FaceCount = 0; _drawCount = 0; return; } this.FaceCount = CountVisibleFaces(this.FaceVisibility); Vertex[] vertices = new Vertex[this.FaceCount * 6]; float width = this.Width; float height = this.Height; float depth = this.Depth; float uvX = width / (float)this.DiffuseMaterial.Width; float uvY = height / (float)this.DiffuseMaterial.Height; float uvZ = depth / (float)this.DiffuseMaterial.Width; // Generate Front Face int index = 0; if (this.FaceVisibility.HasFlag(BrushVolumeFaceVisibility.Front)) { Vector3 normal = new Vector3(0, 0, -1); vertices[index++] = new Vertex(new Vector3(-width, height, -depth), new Vector2(uvX, 0), normal); vertices[index++] = new Vertex(new Vector3(width, height, -depth), new Vector2(0, 0), normal); vertices[index++] = new Vertex(new Vector3(width, -height, -depth), new Vector2(0, uvY), normal); vertices[index++] = new Vertex(new Vector3(-width, height, -depth), new Vector2(uvX, 0), normal); vertices[index++] = new Vertex(new Vector3(-width, -height, -depth), new Vector2(uvX, uvY), normal); vertices[index++] = new Vertex(new Vector3(width, -height, -depth), new Vector2(0, uvY), normal); } // Generate East Face if (this.FaceVisibility.HasFlag(BrushVolumeFaceVisibility.Left)) { Vector3 normal = new Vector3(1, 0, 0); vertices[index++] = new Vertex(new Vector3(width, -height, depth), new Vector2(0, uvY), normal); vertices[index++] = new Vertex(new Vector3(width, -height, -depth), new Vector2(uvZ, uvY), normal); vertices[index++] = new Vertex(new Vector3(width, height, -depth), new Vector2(uvZ, 0), normal); vertices[index++] = new Vertex(new Vector3(width, height, -depth), new Vector2(uvZ, 0), normal); vertices[index++] = new Vertex(new Vector3(width, height, depth), new Vector2(0, 0), normal); vertices[index++] = new Vertex(new Vector3(width, -height, depth), new Vector2(0, uvY), normal); } // Generate South Face if (this.FaceVisibility.HasFlag(BrushVolumeFaceVisibility.Back)) { Vector3 normal = new Vector3(0, 0, 1); vertices[index++] = new Vertex(new Vector3(width, height, depth), new Vector2(uvX, 0), normal); vertices[index++] = new Vertex(new Vector3(-width, height, depth), new Vector2(0, 0), normal); vertices[index++] = new Vertex(new Vector3(-width, -height, depth), new Vector2(0, uvY), normal); vertices[index++] = new Vertex(new Vector3(-width, -height, depth), new Vector2(0, uvY), normal); vertices[index++] = new Vertex(new Vector3(width, -height, depth), new Vector2(uvX, uvY), normal); vertices[index++] = new Vertex(new Vector3(width, height, depth), new Vector2(uvX, 0), normal); } // Generate West Face if (this.FaceVisibility.HasFlag(BrushVolumeFaceVisibility.Right)) { Vector3 normal = new Vector3(-1, 0, 0); // Clockwise vertices[index++] = new Vertex(new Vector3(-width, height, depth), new Vector2(uvZ, 0), normal); vertices[index++] = new Vertex(new Vector3(-width, -height, depth), new Vector2(uvZ, uvY), normal); vertices[index++] = new Vertex(new Vector3(-width, -height, -depth), new Vector2(0, uvY), normal); vertices[index++] = new Vertex(new Vector3(-width, -height, -depth), new Vector2(0, uvY), normal); vertices[index++] = new Vertex(new Vector3(-width, height, -depth), new Vector2(0, 0), normal); vertices[index++] = new Vertex(new Vector3(-width, height, depth), new Vector2(uvZ, 0), normal); // Counter Clockwise //vertices[index++] = new Vertex(new Vector3(-width, -height, -depth), new Vector2(0, uvY), normal); //vertices[index++] = new Vertex(new Vector3(-width, -height, depth), new Vector2(uvZ, uvY), normal); //vertices[index++] = new Vertex(new Vector3(-width, height, depth), new Vector2(uvZ, 0), normal); //vertices[index++] = new Vertex(new Vector3(-width, height, depth), new Vector2(uvZ, 0), normal); //vertices[index++] = new Vertex(new Vector3(-width, height, -depth), new Vector2(0, 0), normal); //vertices[index++] = new Vertex(new Vector3(-width, -height, -depth), new Vector2(0, uvY), normal); } // Generate Top Face if (this.FaceVisibility.HasFlag(BrushVolumeFaceVisibility.Top)) { Vector3 normal = new Vector3(0, 1, 0); vertices[index++] = new Vertex(new Vector3(width, height, depth), new Vector2(uvX, uvZ), normal); vertices[index++] = new Vertex(new Vector3(-width, height, depth), new Vector2(0, uvZ), normal); vertices[index++] = new Vertex(new Vector3(-width, height, -depth), new Vector2(0, 0), normal); vertices[index++] = new Vertex(new Vector3(-width, height, -depth), new Vector2(0, 0), normal); vertices[index++] = new Vertex(new Vector3(width, height, -depth), new Vector2(uvX, 0), normal); vertices[index++] = new Vertex(new Vector3(width, height, depth), new Vector2(uvX, uvZ), normal); } // Generate Bottom Face if (this.FaceVisibility.HasFlag(BrushVolumeFaceVisibility.Bottom)) { Vector3 normal = new Vector3(0, -1, 0); vertices[index++] = new Vertex(new Vector3(-width, -height, depth), new Vector2(uvX, uvZ), normal); vertices[index++] = new Vertex(new Vector3(width, -height, depth), new Vector2(0, uvZ), normal); vertices[index++] = new Vertex(new Vector3(width, -height, -depth), new Vector2(0, 0), normal); vertices[index++] = new Vertex(new Vector3(-width, -height, depth), new Vector2(uvX, uvZ), normal); vertices[index++] = new Vertex(new Vector3(-width, -height, -depth), new Vector2(uvX, 0), normal); vertices[index++] = new Vertex(new Vector3(width, -height, -depth), new Vector2(0, 0), normal); } if (this._bufferBinding.Buffer != null) { this._bufferBinding.Buffer.Dispose(); } this._drawCount = vertices.Length; Buffer vertexBuffer = Buffer.Create(Device, BindFlags.VertexBuffer, vertices); this._bufferBinding = new VertexBufferBinding(vertexBuffer, 32, 0); // 32 is Vertex Size In Bytes } `

I left a note in there showing my current thinking on how to flip a face from interior to exterior. Quite simply, I was thinking to just invert the winding order. My engine uses clockwise winding by default, so if I were to invert the winding for each face to be counter clockwise, it would appear as an interior in engine. This works, too. However, and it may be a stupid question. But is this standard? I tried Googling how Blender implements "Recalculate Inside", but I can’t find anything online discussing the actual implementation details.

Does anyone know if the standard practice for flipping a face from exterior to interior is as simple as reversing the winding order?