public Task Convert(BufferBuilder builder, MapDocument document, IMapObject obj, ResourceCollector resourceCollector) { var c = GetCordon(document); if (!c.Enabled) { return(Task.FromResult(0)); } // It's always a box, these numbers are known const uint numVertices = 4 * 6; const uint numWireframeIndices = numVertices * 2; var points = new VertexStandard[numVertices]; var indices = new uint[numWireframeIndices]; var colour = new Vector4(1, 0, 0, 1); var vi = 0u; var wi = 0u; foreach (var face in c.Box.GetBoxFaces()) { var offs = vi; var normal = new Plane(face[0], face[1], face[2]).Normal; foreach (var v in face) { points[vi++] = new VertexStandard { Position = v, Colour = colour, Normal = normal, Texture = Vector2.Zero, Tint = Vector4.One }; } // Lines - [0 1] ... [n-1 n] [n 0] for (uint i = 0; i < 4; i++) { indices[wi++] = offs + i; indices[wi++] = offs + (i == 4 - 1 ? 0 : i + 1); } } var groups = new[] { new BufferGroup(PipelineType.Wireframe, CameraType.Both, 0, numWireframeIndices) }; builder.Append(points, indices, groups); return(Task.FromResult(0)); }
public override void Render(MapDocument document, BufferBuilder builder) { if (ShouldDrawBox()) { // Draw a box around the point var c = new Box(State.Start, State.End); const uint numVertices = 4 * 6; const uint numWireframeIndices = numVertices * 2; var points = new VertexStandard[numVertices]; var indices = new uint[numWireframeIndices]; var col = GetRenderBoxColour(); var colour = new Vector4(col.R, col.G, col.B, 255) / 255; var vi = 0u; var wi = 0u; foreach (var face in c.GetBoxFaces()) { var offs = vi; foreach (var v in face) { points[vi++] = new VertexStandard { Position = v, Colour = colour, Tint = Vector4.One }; } // Lines - [0 1] ... [n-1 n] [n 0] for (uint i = 0; i < 4; i++) { indices[wi++] = offs + i; indices[wi++] = offs + (i == 4 - 1 ? 0 : i + 1); } } var groups = new[] { new BufferGroup(PipelineType.Wireframe, CameraType.Perspective, 0, numWireframeIndices) }; builder.Append(points, indices, groups); } }
// Rendering protected override void Render(MapDocument document, BufferBuilder builder, ResourceCollector resourceCollector) { if (_state != EntityState.None) { var vec = _location; var high = 1024f * 1024f; var low = -high; // Draw a box around the point var c = new Box(vec - Vector3.One * 10, vec + Vector3.One * 10); const uint numVertices = 4 * 6 + 6; const uint numWireframeIndices = numVertices * 2; var points = new VertexStandard[numVertices]; var indices = new uint[numWireframeIndices]; var colour = new Vector4(0, 1, 0, 1); var vi = 0u; var wi = 0u; foreach (var face in c.GetBoxFaces()) { var offs = vi; foreach (var v in face) { points[vi++] = new VertexStandard { Position = v, Colour = colour, Tint = Vector4.One }; } // Lines - [0 1] ... [n-1 n] [n 0] for (uint i = 0; i < 4; i++) { indices[wi++] = offs + i; indices[wi++] = offs + (i == 4 - 1 ? 0 : i + 1); } } // Draw 3 lines pinpointing the point var lineOffset = vi; points[vi++] = new VertexStandard { Position = new Vector3(low, vec.Y, vec.Z), Colour = colour, Tint = Vector4.One }; points[vi++] = new VertexStandard { Position = new Vector3(high, vec.Y, vec.Z), Colour = colour, Tint = Vector4.One }; points[vi++] = new VertexStandard { Position = new Vector3(vec.X, low, vec.Z), Colour = colour, Tint = Vector4.One }; points[vi++] = new VertexStandard { Position = new Vector3(vec.X, high, vec.Z), Colour = colour, Tint = Vector4.One }; points[vi++] = new VertexStandard { Position = new Vector3(vec.X, vec.Y, low), Colour = colour, Tint = Vector4.One }; points[vi++] = new VertexStandard { Position = new Vector3(vec.X, vec.Y, high), Colour = colour, Tint = Vector4.One }; indices[wi++] = lineOffset++; indices[wi++] = lineOffset++; indices[wi++] = lineOffset++; indices[wi++] = lineOffset++; indices[wi++] = lineOffset++; indices[wi++] = lineOffset++; var groups = new[] { new BufferGroup(PipelineType.Wireframe, CameraType.Both, 0, numWireframeIndices) }; builder.Append(points, indices, groups); } base.Render(document, builder, resourceCollector); }
internal static Task ConvertBox(BufferBuilder builder, IMapObject obj, Box box) { // It's always a box, these numbers are known const uint numVertices = 4 * 6; // Pack the indices like this [ solid1 ... solidn ] [ wireframe1 ... wireframe n ] const uint numSolidIndices = 36; const uint numWireframeIndices = numVertices * 2; var points = new VertexStandard[numVertices]; var indices = new uint[numSolidIndices + numWireframeIndices]; var c = obj.IsSelected ? Color.Red : obj.Data.GetOne <ObjectColor>()?.Color ?? Color.Magenta; var colour = new Vector4(c.R, c.G, c.B, c.A) / 255f; var flags = obj.IsSelected ? VertexFlags.SelectiveTransformed : VertexFlags.None; var vi = 0u; var si = 0u; var wi = numSolidIndices; foreach (var face in box.GetBoxFaces()) { var offs = vi; var normal = new Plane(face[0], face[1], face[2]).Normal; foreach (var v in face) { points[vi++] = new VertexStandard { Position = v, Colour = colour, Normal = normal, Texture = Vector2.Zero, Tint = Vector4.One, Flags = flags | VertexFlags.FlatColour }; } // Triangles - [0 1 2] ... [0 n-1 n] for (uint i = 2; i < 4; i++) { indices[si++] = offs; indices[si++] = offs + i - 1; indices[si++] = offs + i; } // Lines - [0 1] ... [n-1 n] [n 0] for (uint i = 0; i < 4; i++) { indices[wi++] = offs + i; indices[wi++] = offs + (i == 4 - 1 ? 0 : i + 1); } } var origin = obj.Data.GetOne <Origin>()?.Location ?? box.Center; var groups = new List <BufferGroup>(); if (!obj.Data.OfType <IContentsReplaced>().Any(x => x.ContentsReplaced)) { groups.Add(new BufferGroup(PipelineType.TexturedOpaque, CameraType.Perspective, 0, numSolidIndices)); } groups.Add(new BufferGroup(PipelineType.Wireframe, obj.IsSelected ? CameraType.Both : CameraType.Orthographic, numSolidIndices, numWireframeIndices)); builder.Append(points, indices, groups); // Also push the untransformed wireframe when selected if (obj.IsSelected) { for (var i = 0; i < points.Length; i++) { points[i].Flags = VertexFlags.None; } var untransformedIndices = indices.Skip((int)numSolidIndices); builder.Append(points, untransformedIndices, new[] { new BufferGroup(PipelineType.Wireframe, CameraType.Both, 0, numWireframeIndices) }); } return(Task.FromResult(0)); }
internal static async Task ConvertFaces(BufferBuilder builder, MapDocument document, IMapObject obj, List <Face> faces, ResourceCollector resourceCollector) { faces = faces.Where(x => x.Vertices.Count > 2).ToList(); var displayFlags = document.Map.Data.GetOne <DisplayFlags>(); var hideNull = displayFlags?.HideNullTextures == true; // Pack the vertices like this [ f1v1 ... f1vn ] ... [ fnv1 ... fnvn ] var numVertices = (uint)faces.Sum(x => x.Vertices.Count); // Pack the indices like this [ solid1 ... solidn ] [ wireframe1 ... wireframe n ] var numSolidIndices = (uint)faces.Sum(x => (x.Vertices.Count - 2) * 3); var numWireframeIndices = numVertices * 2; var points = new VertexStandard[numVertices]; var indices = new uint[numSolidIndices + numWireframeIndices]; var colour = (obj.IsSelected ? Color.Red : obj.Data.GetOne <ObjectColor>()?.Color ?? Color.White).ToVector4(); //var c = obj.IsSelected ? Color.FromArgb(255, 128, 128) : Color.White; //var tint = new Vector4(c.R, c.G, c.B, c.A) / 255f; var tint = Vector4.One; var tc = await document.Environment.GetTextureCollection(); var pipeline = PipelineType.TexturedOpaque; var entityHasTransparency = false; var flags = obj.IsSelected ? VertexFlags.SelectiveTransformed : VertexFlags.None; // try and find the parent entity for render flags // TODO: this code is extremely specific to Goldsource and should be abstracted away var parentEntity = obj.FindClosestParent(x => x is Entity) as Entity; if (parentEntity?.EntityData != null) { const int renderModeColor = 1; const int renderModeTexture = 2; const int renderModeGlow = 3; // same as texture for brushes const int renderModeSolid = 4; const int renderModeAdditive = 5; var rendermode = parentEntity.EntityData.Get("rendermode", 0); var renderamt = parentEntity.EntityData.Get("renderamt", 255f) / 255; entityHasTransparency = renderamt < 0.99; switch (rendermode) { case renderModeColor: // Flat colour, use render colour and force it to run through the alpha tested pipeline var rendercolor = parentEntity.EntityData.GetVector3("rendercolor") / 255f ?? Vector3.One; tint = new Vector4(rendercolor, renderamt); flags |= VertexFlags.FlatColour | VertexFlags.AlphaTested; pipeline = PipelineType.TexturedAlpha; entityHasTransparency = true; break; case renderModeTexture: case renderModeGlow: // Texture is alpha tested and can be transparent tint = new Vector4(1, 1, 1, renderamt); flags |= VertexFlags.AlphaTested; if (entityHasTransparency) { pipeline = PipelineType.TexturedAlpha; } break; case renderModeSolid: // Texture is alpha tested only flags |= VertexFlags.AlphaTested; entityHasTransparency = false; break; case renderModeAdditive: // Texture is alpha tested and transparent, force through the additive pipeline tint = new Vector4(renderamt, renderamt, renderamt, 1); pipeline = PipelineType.TexturedAdditive; entityHasTransparency = true; break; default: entityHasTransparency = false; break; } } if (obj.IsSelected) { tint *= new Vector4(1, 0.5f, 0.5f, 1); } var vi = 0u; var si = 0u; var wi = numSolidIndices; foreach (var face in faces) { var opacity = tc.GetOpacity(face.Texture.Name); var t = await tc.GetTextureItem(face.Texture.Name); var w = t?.Width ?? 0; var h = t?.Height ?? 0; var tintModifier = new Vector4(1, 1, 1, opacity); var extraFlags = t == null ? VertexFlags.FlatColour : VertexFlags.None; var offs = vi; var numFaceVerts = (uint)face.Vertices.Count; var textureCoords = face.GetTextureCoordinates(w, h).ToList(); var normal = face.Plane.Normal; for (var i = 0; i < face.Vertices.Count; i++) { var v = face.Vertices[i]; points[vi++] = new VertexStandard { Position = v, Colour = colour, Normal = normal, Texture = new Vector2(textureCoords[i].Item2, textureCoords[i].Item3), Tint = tint * tintModifier, Flags = flags | extraFlags }; } // Triangles - [0 1 2] ... [0 n-1 n] for (uint i = 2; i < numFaceVerts; i++) { indices[si++] = offs; indices[si++] = offs + i - 1; indices[si++] = offs + i; } // Lines - [0 1] ... [n-1 n] [n 0] for (uint i = 0; i < numFaceVerts; i++) { indices[wi++] = offs + i; indices[wi++] = offs + (i == numFaceVerts - 1 ? 0 : i + 1); } } var groups = new List <BufferGroup>(); uint texOffset = 0; foreach (var f in faces) { var texInd = (uint)(f.Vertices.Count - 2) * 3; if (hideNull && tc.IsNullTexture(f.Texture.Name)) { texOffset += texInd; continue; } var opacity = tc.GetOpacity(f.Texture.Name); var t = await tc.GetTextureItem(f.Texture.Name); var transparent = entityHasTransparency || opacity < 0.95f || t?.Flags.HasFlag(TextureFlags.Transparent) == true; var texture = t == null ? string.Empty : $"{document.Environment.ID}::{f.Texture.Name}"; var group = new BufferGroup( pipeline == PipelineType.TexturedOpaque && transparent ? PipelineType.TexturedAlpha : pipeline, CameraType.Perspective, transparent, f.Origin, texture, texOffset, texInd ); groups.Add(group); texOffset += texInd; if (t != null) { resourceCollector.RequireTexture(t.Name); } } groups.Add(new BufferGroup(PipelineType.Wireframe, obj.IsSelected ? CameraType.Both : CameraType.Orthographic, numSolidIndices, numWireframeIndices)); builder.Append(points, indices, groups); // Also push the untransformed wireframe when selected if (obj.IsSelected) { for (var i = 0; i < points.Length; i++) { points[i].Flags = VertexFlags.None; } var untransformedIndices = indices.Skip((int)numSolidIndices); builder.Append(points, untransformedIndices, new[] { new BufferGroup(PipelineType.Wireframe, CameraType.Both, 0, numWireframeIndices) }); } }
private async Task Convert(BufferBuilder builder, MapDocument document, IMapObject obj, ResourceCollector resourceCollector) { var solid = (Solid)obj; var faces = solid.Faces.Where(x => x.Vertices.Count > 2).ToList(); // Pack the vertices like this [ f1v1 ... f1vn ] ... [ fnv1 ... fnvn ] var numVertices = (uint)faces.Sum(x => x.Vertices.Count); // Pack the indices like this [ solid1 ... solidn ] [ wireframe1 ... wireframe n ] var numSolidIndices = (uint)faces.Sum(x => (x.Vertices.Count - 2) * 3); var numWireframeIndices = numVertices * 2; var points = new VertexStandard[numVertices]; var indices = new uint[numSolidIndices + numWireframeIndices]; var c = Color.Turquoise; var colour = new Vector4(c.R, c.G, c.B, c.A) / 255f; c = Color.FromArgb(192, Color.Turquoise); var tint = new Vector4(c.R, c.G, c.B, c.A) / 255f; var tc = await document.Environment.GetTextureCollection(); var vi = 0u; var si = 0u; var wi = numSolidIndices; foreach (var face in faces) { var t = await tc.GetTextureItem(face.Texture.Name); var w = t?.Width ?? 0; var h = t?.Height ?? 0; var offs = vi; var numFaceVerts = (uint)face.Vertices.Count; var textureCoords = face.GetTextureCoordinates(w, h).ToList(); var normal = face.Plane.Normal; for (var i = 0; i < face.Vertices.Count; i++) { var v = face.Vertices[i]; points[vi++] = new VertexStandard { Position = v, Colour = colour, Normal = normal, Texture = new Vector2(textureCoords[i].Item2, textureCoords[i].Item3), Tint = tint, Flags = t == null ? VertexFlags.FlatColour : VertexFlags.None }; } // Triangles - [0 1 2] ... [0 n-1 n] for (uint i = 2; i < numFaceVerts; i++) { indices[si++] = offs; indices[si++] = offs + i - 1; indices[si++] = offs + i; } // Lines - [0 1] ... [n-1 n] [n 0] for (uint i = 0; i < numFaceVerts; i++) { indices[wi++] = offs + i; indices[wi++] = offs + (i == numFaceVerts - 1 ? 0 : i + 1); } } var groups = new List <BufferGroup>(); uint texOffset = 0; foreach (var f in faces) { var texInd = (uint)(f.Vertices.Count - 2) * 3; var opacity = tc.GetOpacity(f.Texture.Name); var t = await tc.GetTextureItem(f.Texture.Name); var transparent = opacity < 0.95f || t?.Flags.HasFlag(TextureFlags.Transparent) == true; var texture = t == null ? string.Empty : $"{document.Environment.ID}::{f.Texture.Name}"; groups.Add(transparent ? new BufferGroup(PipelineType.TexturedAlpha, CameraType.Perspective, f.Origin, texture, texOffset, texInd) : new BufferGroup(PipelineType.TexturedOpaque, CameraType.Perspective, texture, texOffset, texInd) ); texOffset += texInd; if (t != null) { resourceCollector.RequireTexture(t.Name); } } groups.Add(new BufferGroup(PipelineType.Wireframe, solid.IsSelected ? CameraType.Both : CameraType.Orthographic, numSolidIndices, numWireframeIndices)); builder.Append(points, indices, groups); }
private async Task Convert(BufferBuilder builder, MapDocument document, MutableSolid solid, ResourceCollector resourceCollector) { var displayFlags = document.Map.Data.GetOne <DisplayFlags>(); var hideNull = displayFlags?.HideNullTextures == true; var faces = solid.Faces.Where(x => x.Vertices.Count > 2).ToList(); // Pack the vertices like this [ f1v1 ... f1vn ] ... [ fnv1 ... fnvn ] var numVertices = (uint)faces.Sum(x => x.Vertices.Count); // Pack the indices like this [ solid1 ... solidn ] [ wireframe1 ... wireframe n ] var numSolidIndices = (uint)faces.Sum(x => (x.Vertices.Count - 2) * 3); var numWireframeIndices = numVertices * 2; var points = new VertexStandard[numVertices]; var indices = new uint[numSolidIndices + numWireframeIndices]; var tint = Color.FromArgb(128, 255, 128).ToVector4(); var tc = await document.Environment.GetTextureCollection(); var vi = 0u; var si = 0u; var wi = numSolidIndices; foreach (var face in faces) { var opacity = tc.GetOpacity(face.Texture.Name); var t = await tc.GetTextureItem(face.Texture.Name); var w = t?.Width ?? 0; var h = t?.Height ?? 0; var tintModifier = new Vector4(1, 1, 1, opacity); var offs = vi; var numFaceVerts = (uint)face.Vertices.Count; var textureCoords = face.GetTextureCoordinates(w, h).ToList(); var normal = face.Plane.Normal; for (var i = 0; i < face.Vertices.Count; i++) { var v = face.Vertices[i]; points[vi++] = new VertexStandard { Position = v.Position, Colour = Vector4.One, Normal = normal, Texture = new Vector2(textureCoords[i].Item2, textureCoords[i].Item3), Tint = tint * tintModifier, Flags = VertexFlags.None }; } // Triangles - [0 1 2] ... [0 n-1 n] for (uint i = 2; i < numFaceVerts; i++) { indices[si++] = offs; indices[si++] = offs + i - 1; indices[si++] = offs + i; } // Lines - [0 1] ... [n-1 n] [n 0] for (uint i = 0; i < numFaceVerts; i++) { indices[wi++] = offs + i; indices[wi++] = offs + (i == numFaceVerts - 1 ? 0 : i + 1); } } var groups = new List <BufferGroup>(); uint texOffset = 0; foreach (var f in faces) { var texInd = (uint)(f.Vertices.Count - 2) * 3; if (hideNull && tc.IsNullTexture(f.Texture.Name)) { texOffset += texInd; continue; } var opacity = tc.GetOpacity(f.Texture.Name); var t = await tc.GetTextureItem(f.Texture.Name); var transparent = opacity < 0.95f || t?.Flags.HasFlag(TextureFlags.Transparent) == true; var texture = t == null ? string.Empty : $"{document.Environment.ID}::{f.Texture.Name}"; groups.Add(transparent ? new BufferGroup(PipelineType.TexturedAlpha, CameraType.Perspective, f.Origin, texture, texOffset, texInd) : new BufferGroup(PipelineType.TexturedOpaque, CameraType.Perspective, texture, texOffset, texInd) ); texOffset += texInd; if (t != null) { resourceCollector.RequireTexture(t.Name); } } groups.Add(new BufferGroup(PipelineType.Wireframe, CameraType.Both, numSolidIndices, numWireframeIndices)); builder.Append(points, indices, groups); }