public void ShouldCompactBufferToLowerLimit() { int bufferLength = BufferBuilder.INITIAL_CAPACITY / 2; byte[] buffer = new byte[bufferLength]; UnsafeBuffer srcBuffer = new UnsafeBuffer(buffer); BufferBuilder bufferBuilder = new BufferBuilder(); const int bufferCount = 5; for (int i = 0; i < bufferCount; i++) { bufferBuilder.Append(srcBuffer, 0, buffer.Length); } int expectedLimit = buffer.Length * bufferCount; Assert.That(bufferBuilder.Limit(), Is.EqualTo(expectedLimit)); int expandedCapacity = bufferBuilder.Capacity(); Assert.That(expandedCapacity, Is.GreaterThan(expectedLimit)); bufferBuilder.Reset(); bufferBuilder.Append(srcBuffer, 0, buffer.Length); bufferBuilder.Append(srcBuffer, 0, buffer.Length); bufferBuilder.Append(srcBuffer, 0, buffer.Length); bufferBuilder.Compact(); Assert.That(bufferBuilder.Limit(), Is.EqualTo(buffer.Length * 3)); Assert.That(bufferBuilder.Capacity(), Is.LessThan(expandedCapacity)); }
public override string GetDebugName() { BufferBuilder dbgName = new BufferBuilder(); dbgName.Append("<xsl:attribute-set name=\""); dbgName.Append(Name.QualifiedName); dbgName.Append("\">"); return(dbgName.ToString()); }
internal void WriteHeader(string name, string value, bool allowUnicode) { ArgumentNullException.ThrowIfNull(name); ArgumentNullException.ThrowIfNull(value); if (_isInContent) { throw new InvalidOperationException(SR.MailWriterIsInContent); } CheckBoundary(); _bufferBuilder.Append(name); _bufferBuilder.Append(": "); WriteAndFold(value, name.Length + 2, allowUnicode); _bufferBuilder.Append("\r\n" u8); }
protected override void Render(MapDocument document, BufferBuilder builder, ResourceCollector resourceCollector) { if (_mouseMovePoint.HasValue && _mouseDown != CircleType.None) { var axis = Vector3.One; var c = Color.White; switch (_mouseDown) { case CircleType.X: axis = Vector3.UnitX; c = Color.Red; break; case CircleType.Y: axis = Vector3.UnitY; c = Color.Lime; break; case CircleType.Z: axis = Vector3.UnitZ; c = Color.Blue; break; case CircleType.Outer: if (ActiveViewport == null || !(ActiveViewport.Viewport.Camera is PerspectiveCamera pc)) { return; } axis = pc.Direction; c = Color.White; break; } var start = _pivotPoint - axis * 1024 * 1024; var end = _pivotPoint + axis * 1024 * 1024; var col = new Vector4(c.R, c.G, c.B, c.A) / 255; builder.Append( new[] { new VertexStandard { Position = start, Colour = col, Tint = Vector4.One }, new VertexStandard { Position = end, Colour = col, Tint = Vector4.One }, }, new uint[] { 0, 1 }, new[] { new BufferGroup(PipelineType.Wireframe, CameraType.Perspective, 0, 2) } ); } base.Render(document, builder, resourceCollector); }
private Pop3Command(SecureString password) { this.type = Pop3CommandType.Pass; BufferBuilder bufferBuilder = new BufferBuilder(Pop3Command.PassBytes.Length + password.Length + Pop3Command.CrLfBytes.Length); bufferBuilder.Append(Pop3Command.PassBytes); try { bufferBuilder.Append(password); } catch (ArgumentException innerException) { throw new Pop3InvalidCommandException("All characters in the string must be in the range 0x00 - 0xff.", innerException); } bufferBuilder.Append(Pop3Command.CrLfBytes); this.commandBytes = bufferBuilder.GetBuffer(); }
internal string InternalReadContentAsString() { var value = ""; BufferBuilder sb = null; do { switch (this.NodeType) { case XmlNodeType.Attribute: return(this.Value); case XmlNodeType.Text: case XmlNodeType.Whitespace: case XmlNodeType.SignificantWhitespace: case XmlNodeType.CDATA: // merge text content if (value.Length == 0) { value = this.Value; } else { if (sb == null) { sb = new BufferBuilder(); sb.Append(value); } sb.Append(this.Value); } break; case XmlNodeType.ProcessingInstruction: case XmlNodeType.Comment: case XmlNodeType.EndEntity: // skip comments, pis and end entity nodes break; case XmlNodeType.EntityReference: if (this.CanResolveEntity) { this.ResolveEntity(); break; } goto default; case XmlNodeType.EndElement: default: goto ReturnContent; } } while ((this.AttributeCount != 0) ? this.ReadAttributeValue() : this.Read()); ReturnContent: return((sb == null) ? value : sb.ToString()); }
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)); }
internal void CopyTo(int valueOffset, BufferBuilder sb) { if (_value == null) { Debug.Assert(_valueStartPos != -1); Debug.Assert(_chars != null); sb.Append(_chars, _valueStartPos + valueOffset, _valueLength - valueOffset); } else { if (valueOffset <= 0) { sb.Append(_value); } else { sb.Append(_value, valueOffset, _value.Length - valueOffset); } } }
public void ShouldAppendTwoBuffersAndResize() { const int bufferLength = 128; byte[] buffer = new byte[bufferLength]; int firstLength = buffer.Length / 4; int secondLength = buffer.Length / 2; Arrays.Fill(buffer, 0, firstLength + secondLength, (byte)7); UnsafeBuffer srcBuffer = new UnsafeBuffer(buffer); BufferBuilder bufferBuilder = new BufferBuilder(bufferLength / 2); bufferBuilder.Append(srcBuffer, 0, firstLength); bufferBuilder.Append(srcBuffer, firstLength, secondLength); byte[] temp = new byte[buffer.Length]; bufferBuilder.Buffer().GetBytes(0, temp, 0, secondLength + firstLength); Assert.That(bufferBuilder.Limit(), Is.EqualTo(firstLength + secondLength)); Assert.That(bufferBuilder.Capacity(), Is.EqualTo(bufferLength)); Assert.That(temp, Is.EqualTo(buffer)); }
public string GetDebugName() { BufferBuilder dbgName = new BufferBuilder(); dbgName.Append("<xsl:key name=\""); dbgName.Append(Name.QualifiedName); dbgName.Append('"'); if (Match != null) { dbgName.Append(" match=\""); dbgName.Append(Match); dbgName.Append('"'); } if (Use != null) { dbgName.Append(" use=\""); dbgName.Append(Use); dbgName.Append('"'); } dbgName.Append('>'); return(dbgName.ToString()); }
public Task Convert(BufferBuilder builder, MapDocument document, IMapObject obj, ResourceCollector resourceCollector) { var pointfile = GetPointfile(document); if (pointfile == null) { return(Task.FromResult(0)); } var r = 1f; var g = 0.5f; var b = 0.5f; var change = 0.5f / pointfile.Lines.Count; var verts = new List <VertexStandard>(); var index = new List <uint>(); for (var i = 0; i < pointfile.Lines.Count; i++) { var line = pointfile.Lines[i]; index.Add((uint)index.Count + 0); index.Add((uint)index.Count + 1); verts.Add(new VertexStandard { Position = line.Start, Colour = new Vector4(r, g, b, 1), Tint = Vector4.One }); verts.Add(new VertexStandard { Position = line.End, Colour = new Vector4(r, g, b, 1), Tint = Vector4.One }); r = 1f - (change * i); b = 0.5f + (change * i); } builder.Append(verts, index, new [] { new BufferGroup(PipelineType.Wireframe, CameraType.Both, 0, (uint)index.Count) }); 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); } }
private Pop3Command(Pop3CommandType commandType, bool listings, string commandText) { this.type = commandType; BufferBuilder bufferBuilder = new BufferBuilder(commandText.Length); try { bufferBuilder.Append(commandText); } catch (ArgumentException innerException) { throw new Pop3InvalidCommandException("All characters in the string must be in the range 0x00 - 0xff.", innerException); } this.commandBytes = bufferBuilder.GetBuffer(); this.listings = listings; }
public Task Convert(BufferBuilder builder, MapDocument document, IEnumerable <IMapObject> objects, ResourceCollector resourceCollector) { if (!_drawCenterHandles) { return(Task.CompletedTask); } var objs = ( from mo in objects where mo is Solid || (mo is Entity && !mo.Hierarchy.HasChildren) where !mo.Data.OfType <IObjectVisibility>().Any(x => x.IsHidden) select mo ).ToList(); var verts = ( // Current centers from mo in objs let color = mo.IsSelected ? Color.Red : mo.Data.GetOne <ObjectColor>()?.Color ?? Color.White select new VertexStandard { Position = mo.Data.GetOne <Origin>()?.Location ?? mo.BoundingBox.Center, Normal = new Vector3(9, 9, 0), Colour = color.ToVector4(), Tint = Vector4.One } ).Union( // Selective transformed centers from mo in objs where mo.IsSelected let color = Color.Red select new VertexStandard { Position = mo.Data.GetOne <Origin>()?.Location ?? mo.BoundingBox.Center, Normal = new Vector3(9, 9, 0), Colour = color.ToVector4(), Tint = Vector4.One, Flags = VertexFlags.SelectiveTransformed } ).ToList(); builder.Append(verts, Enumerable.Range(0, verts.Count).Select(x => (uint)x), new[] { new BufferGroup(PipelineType.BillboardOpaque, CameraType.Orthographic, CenterHandleTextureDataSource.Name, 0, (uint)verts.Count) }); return(Task.CompletedTask); }
public async Task Convert(BufferBuilder builder, MapDocument document, IMapObject obj, ResourceCollector resourceCollector) { var entity = (Entity)obj; var tc = await document.Environment.GetTextureCollection(); var sd = GetSpriteData(entity); if (sd == null || !sd.ContentsReplaced) { return; } var name = sd.Name; var scale = sd.Scale; var width = entity.BoundingBox.Width; var height = entity.BoundingBox.Height; var t = await tc.GetTextureItem(name); var texture = $"{document.Environment.ID}::{name}"; if (t != null) { resourceCollector.RequireTexture(t.Name); } var tint = sd.Color.ToVector4(); var flags = VertexFlags.None; if (entity.IsSelected) { flags |= VertexFlags.SelectiveTransformed; } builder.Append( new [] { new VertexStandard { Position = entity.Origin, Normal = new Vector3(width, height, 0), Colour = Vector4.One, Tint = tint, Flags = flags } }, new [] { 0u }, new [] { new BufferGroup(PipelineType.BillboardAlpha, CameraType.Perspective, entity.BoundingBox.Center, texture, 0, 1) } ); }
public void ShouldResizeWhenBufferJustDoesNotFit() { const int bufferLength = 128; byte[] buffer = new byte[bufferLength + 1]; Arrays.Fill(buffer, (byte)7); UnsafeBuffer srcBuffer = new UnsafeBuffer(buffer); BufferBuilder bufferBuilder = new BufferBuilder(bufferLength); bufferBuilder.Append(srcBuffer, 0, buffer.Length); byte[] temp = new byte[buffer.Length]; bufferBuilder.Buffer().GetBytes(0, temp, 0, buffer.Length); Assert.That(bufferBuilder.Limit(), Is.EqualTo(buffer.Length)); Assert.That(bufferBuilder.Capacity(), Is.GreaterThan(bufferLength)); Assert.That(temp, Is.EqualTo(buffer)); }
internal void WriteHeader(string name, string value, bool allowUnicode) { if (name == null) { throw new ArgumentNullException(nameof(name)); } if (value == null) { throw new ArgumentNullException(nameof(value)); } if (_isInContent) { throw new InvalidOperationException(SR.MailWriterIsInContent); } CheckBoundary(); _bufferBuilder.Append(name); _bufferBuilder.Append(": "); WriteAndFold(value, name.Length + 2, allowUnicode); _bufferBuilder.Append(s_crlf); }
public void ShouldFillBufferWithoutResizing() { const int bufferLength = 128; byte[] buffer = new byte[bufferLength]; Arrays.Fill(buffer, (byte)7); UnsafeBuffer srcBuffer = new UnsafeBuffer(buffer); BufferBuilder bufferBuilder = new BufferBuilder(bufferLength); bufferBuilder.Append(srcBuffer, 0, bufferLength); byte[] temp = new byte[bufferLength]; bufferBuilder.Buffer().GetBytes(0, temp, 0, bufferLength); Assert.That(bufferBuilder.Limit(), Is.EqualTo(bufferLength)); Assert.That(bufferBuilder.Capacity(), Is.EqualTo(bufferLength)); Assert.That(temp, Is.EqualTo(buffer)); }
public ControlledFragmentHandlerAction OnFragment(IDirectBuffer buffer, int offset, int length, Header header) { ControlledFragmentHandlerAction action = ControlledFragmentHandlerAction.CONTINUE; byte flags = header.Flags; if ((flags & UNFRAGMENTED) == UNFRAGMENTED) { action = OnMessage(buffer, offset, length, header); } else { if ((flags & BEGIN_FRAG_FLAG) == BEGIN_FRAG_FLAG) { builder.Reset().Append(buffer, offset, length); } else { int limit = builder.Limit(); if (limit > 0) { builder.Append(buffer, offset, length); if ((flags & END_FRAG_FLAG) == END_FRAG_FLAG) { action = OnMessage(builder.Buffer(), 0, builder.Limit(), header); if (ControlledFragmentHandlerAction.ABORT == action) { builder.Limit(limit); } else { builder.Reset(); } } } } } return(action); }
public Task Convert(BufferBuilder builder, MapDocument document, IMapObject obj, ResourceCollector resourceCollector) { var points = new[] { // X axis - red new VertexStandard { Position = Vector3.Zero, Colour = Vector4.UnitX + Vector4.UnitW }, new VertexStandard { Position = Vector3.UnitX * 100, Colour = Vector4.UnitX + Vector4.UnitW }, // Y axis - green new VertexStandard { Position = Vector3.Zero, Colour = Vector4.UnitY + Vector4.UnitW }, new VertexStandard { Position = Vector3.UnitY * 100, Colour = Vector4.UnitY + Vector4.UnitW }, // Z axis - blue new VertexStandard { Position = Vector3.Zero, Colour = Vector4.UnitZ + Vector4.UnitW }, new VertexStandard { Position = Vector3.UnitZ * 100, Colour = Vector4.UnitZ + Vector4.UnitW }, }; var indices = new uint[] { 0, 1, 2, 3, 4, 5 }; builder.Append(points, indices, new [] { new BufferGroup(PipelineType.Wireframe, CameraType.Perspective, 0, (uint)indices.Length) }); return(Task.FromResult(0)); }
public override void Render(BufferBuilder builder, ResourceCollector resourceCollector) { base.Render(builder, resourceCollector); var verts = new List <VertexStandard>(); var indices = new List <int>(); var groups = new List <BufferGroup>(); var col = Vector4.One; var tintCol = Color.FromArgb(128, Color.OrangeRed).ToVector4(); foreach (var face in _selectedFaces) { var vo = verts.Count; var io = indices.Count; verts.AddRange(face.Face.Vertices.Select(x => new VertexStandard { Position = x.Position, Colour = col, Tint = tintCol, Flags = VertexFlags.FlatColour })); for (var i = 2; i < face.Face.Vertices.Count; i++) { indices.Add(vo); indices.Add(vo + i - 1); indices.Add(vo + i); } groups.Add(new BufferGroup(PipelineType.TexturedAlpha, CameraType.Perspective, face.Face.Origin, (uint)io, (uint)(indices.Count - io))); } builder.Append(verts, indices.Select(x => (uint)x), 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); }
internal string InternalReadContentAsString() { string value = string.Empty; BufferBuilder sb = null; do { switch (this.NodeType) { case XmlNodeType.Attribute: return this.Value; case XmlNodeType.Text: case XmlNodeType.Whitespace: case XmlNodeType.SignificantWhitespace: case XmlNodeType.CDATA: // merge text content if (value.Length == 0) { value = this.Value; } else { if (sb == null) { sb = new BufferBuilder(); sb.Append(value); } sb.Append(this.Value); } break; case XmlNodeType.ProcessingInstruction: case XmlNodeType.Comment: case XmlNodeType.EndEntity: // skip comments, pis and end entity nodes break; case XmlNodeType.EntityReference: if (this.CanResolveEntity) { this.ResolveEntity(); break; } goto default; case XmlNodeType.EndElement: default: goto ReturnContent; } } while ((this.AttributeCount != 0) ? this.ReadAttributeValue() : this.Read()); ReturnContent: return (sb == null) ? value : sb.ToString(); }
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) }); } }
public override string GetDebugName() { BufferBuilder dbgName = new BufferBuilder(); dbgName.Append("<xsl:template"); if (Match != null) { dbgName.Append(" match=\""); dbgName.Append(Match); dbgName.Append('"'); } if (Name != null) { dbgName.Append(" name=\""); dbgName.Append(Name.QualifiedName); dbgName.Append('"'); } if (!double.IsNaN(Priority)) { dbgName.Append(" priority=\""); dbgName.Append(Priority.ToString(CultureInfo.InvariantCulture)); dbgName.Append('"'); } if (Mode.LocalName.Length != 0) { dbgName.Append(" mode=\""); dbgName.Append(Mode.QualifiedName); dbgName.Append('"'); } dbgName.Append('>'); return(dbgName.ToString()); }
// Parses named character entity reference (& ' < > "). // Returns -1 if the reference is not a character entity reference. // Returns -2 if more data is needed in the buffer // Otherwise // - replaces the last character of the entity reference (';') with the referenced character (if expand == true) // - returns position of the end of the character reference, that is of the character next to the original ';' private int ParseNamedCharRefInline( int startPos, bool expand, BufferBuilder internalSubsetBuilder ) { Debug.Assert( startPos < ps.charsUsed ); Debug.Assert( ps.chars[startPos] == '&' ); Debug.Assert( ps.chars[startPos + 1] != '#' ); int pos = startPos + 1; char[] chars = ps.chars; char ch; switch ( chars[pos] ) { // ' or & case 'a': pos++; // & if ( chars[pos] == 'm' ) { if ( ps.charsUsed - pos >= 3 ) { if ( chars[pos+1] == 'p' && chars[pos+2] == ';' ) { pos += 3; ch = '&'; goto FoundCharRef; } else { return -1; } } } // ' else if ( chars[pos] == 'p' ) { if ( ps.charsUsed - pos >= 4 ) { if ( chars[pos+1] == 'o' && chars[pos+2] == 's' && chars[pos+3] == ';' ) { pos += 4; ch = '\''; goto FoundCharRef; } else { return -1; } } } else if ( pos < ps.charsUsed ) { return -1; } break; // &guot; case 'q': if ( ps.charsUsed - pos >= 5 ) { if ( chars[pos+1] == 'u' && chars[pos+2] == 'o' && chars[pos+3] == 't' && chars[pos+4] == ';' ) { pos += 5; ch = '"'; goto FoundCharRef; } else { return -1; } } break; // < case 'l': if ( ps.charsUsed - pos >= 3 ) { if ( chars[pos+1] == 't' && chars[pos+2] == ';' ) { pos += 3; ch = '<'; goto FoundCharRef; } else { return -1; } } break; // > case 'g': if ( ps.charsUsed - pos >= 3 ) { if ( chars[pos+1] == 't' && chars[pos+2] == ';' ) { pos += 3; ch = '>'; goto FoundCharRef; } else { return -1; } } break; default: return -1; } // need more data in the buffer return -2; FoundCharRef: Debug.Assert( pos > 0 ); if ( expand ) { if ( internalSubsetBuilder != null ) { internalSubsetBuilder.Append( ps.chars, ps.charPos, pos - ps.charPos ); } ps.chars[pos-1] = ch; } return pos; }
// Parses numeric character entity reference (e.g.    ). // Returns -2 if more data is needed in the buffer // Otherwise // - replaces the last one or two character of the entity reference (';' and the character before) with the referenced // character or surrogates pair (if expand == true) // - returns position of the end of the character reference, that is of the character next to the original ';' private int ParseNumericCharRefInline( int startPos, bool expand, BufferBuilder internalSubsetBuilder, out int charCount, out EntityType entityType ) { Debug.Assert( ps.chars[startPos] == '&' && ps.chars[startPos + 1] == '#' ); int val; int pos; char[] chars; val = 0; string badDigitExceptionString = null; chars = ps.chars; pos = startPos + 2; charCount = 0; if ( chars[pos] == 'x' ) { pos++; badDigitExceptionString = Res.Xml_BadHexEntity; for (;;) { char ch = chars[pos]; if ( ch >= '0' && ch <= '9' ) val = val * 16 + ch - '0'; else if ( ch >= 'a' && ch <= 'f' ) val = val * 16 + 10 + ch - 'a'; else if ( ch >= 'A' && ch <= 'F' ) val = val * 16 + 10 + ch - 'A'; else break; pos++; } entityType = EntityType.CharacterHex; } else if ( pos < ps.charsUsed ) { badDigitExceptionString = Res.Xml_BadDecimalEntity; while ( chars[pos] >= '0' && chars[pos] <= '9' ) { val = val * 10 + chars[pos] - '0'; pos++; } entityType = EntityType.CharacterDec; } else { // need more data in the buffer entityType = EntityType.Unexpanded; return -2; } if ( chars[pos] != ';' ) { if ( pos == ps.charsUsed ) { // need more data in the buffer return -2; } else { Throw( pos, badDigitExceptionString ); } } // simple character if ( val <= char.MaxValue ) { char ch = (char)val; if ( ( !xmlCharType.IsCharData(ch) || ( ch >= SurLowStart && ch <= 0xdeff ) ) && ( ( v1Compat && normalize ) || (!v1Compat && checkCharacters ) ) ) { ThrowInvalidChar( (ps.chars[ps.charPos + 2] == 'x') ? ps.charPos + 3 : ps.charPos + 2, ch ); } if ( expand ) { if ( internalSubsetBuilder != null ) { internalSubsetBuilder.Append( ps.chars, ps.charPos, pos - ps.charPos + 1 ); } chars[pos] = ch; } charCount = 1; return pos + 1; } // surrogate else { int v = val - 0x10000; int low = SurLowStart + v % 1024; int high = SurHighStart + v / 1024; if ( normalize ) { char ch = (char)high; if ( ch >= SurHighStart && ch <= SurHighEnd ) { ch = (char)low; if ( ch >=SurLowStart && ch <= SurLowEnd ) { goto Return; } } ThrowInvalidChar( (ps.chars[ps.charPos + 2] == 'x') ? ps.charPos + 3 : ps.charPos + 2, (char)val ); } Return: Debug.Assert( pos > 0 ); if ( expand ) { if ( internalSubsetBuilder != null ) { internalSubsetBuilder.Append( ps.chars, ps.charPos, pos - ps.charPos + 1 ); } chars[pos-1] = (char)high; chars[pos] = (char)low; } charCount = 2; return pos + 1; } }
private int EatWhitespaces( BufferBuilder sb ) { int pos = ps.charPos; int wsCount = 0; char[] chars = ps.chars; for (;;) { for (;;) { switch ( chars[pos] ) { case (char)0xA: pos++; OnNewLine( pos ); continue; case (char)0xD: if ( chars[pos+1] == (char)0xA ) { int tmp1 = pos - ps.charPos; if ( sb != null && !ps.eolNormalized ) { if ( tmp1 > 0 ) { sb.Append( chars, ps.charPos, tmp1 ); wsCount += tmp1; } ps.charPos = pos + 1; } pos += 2; } else if ( pos+1 < ps.charsUsed || ps.isEof ) { if ( !ps.eolNormalized ) { chars[pos] = (char)0xA; // EOL normalization of 0xD } pos++; } else { goto ReadData; } OnNewLine( pos ); continue; case (char)0x9: case (char)0x20: pos++; continue; default: if ( pos == ps.charsUsed ) { goto ReadData; } else { int tmp2 = pos - ps.charPos; if ( tmp2 > 0 ) { if ( sb != null ) { sb.Append( ps.chars, ps.charPos, tmp2 ); } ps.charPos = pos; wsCount += tmp2; } return wsCount; } } } ReadData: int tmp3 = pos - ps.charPos; if ( tmp3 > 0 ) { if ( sb != null ) { sb.Append( ps.chars, ps.charPos, tmp3 ); } ps.charPos = pos; wsCount += tmp3; } if ( ReadData() == 0 ) { if ( ps.charsUsed - ps.charPos == 0 ) { return wsCount; } if ( ps.chars[ps.charPos] != (char)0xD ) { Debug.Assert( false, "We should never get to this point." ); Throw( Res.Xml_UnexpectedEOF1 ); } Debug.Assert( ps.isEof ); } pos = ps.charPos; chars = ps.chars; } }
// Parses processing instruction; if piInDtdStringBuilder != null, the processing instruction is in DTD and // it will be saved in the passed string builder (target, whitespace & value). private bool ParsePI( BufferBuilder piInDtdStringBuilder ) { if ( parsingMode == ParsingMode.Full ) { curNode.SetLineInfo( ps.LineNo, ps.LinePos ); } Debug.Assert( stringBuilder.Length == 0 ); // parse target name int nameEndPos = ParseName(); string target = nameTable.Add( ps.chars, ps.charPos, nameEndPos - ps.charPos ); if ( string.Compare( target, "xml", StringComparison.OrdinalIgnoreCase ) == 0 ) { Throw( target.Equals( "xml" ) ? Res.Xml_XmlDeclNotFirst : Res.Xml_InvalidPIName, target ); } ps.charPos = nameEndPos; if ( piInDtdStringBuilder == null ) { if ( !ignorePIs && parsingMode == ParsingMode.Full ) { curNode.SetNamedNode( XmlNodeType.ProcessingInstruction, target ); } } else { piInDtdStringBuilder.Append( target ); } // check mandatory whitespace char ch = ps.chars[ps.charPos]; Debug.Assert( ps.charPos < ps.charsUsed ); if ( EatWhitespaces( piInDtdStringBuilder ) == 0 ) { if ( ps.charsUsed - ps.charPos < 2 ) { ReadData(); } if ( ch != '?' || ps.chars[ps.charPos+1] != '>' ) { Throw( Res.Xml_BadNameChar, XmlException.BuildCharExceptionStr( ch ) ); } } // scan processing instruction value int startPos, endPos; if ( ParsePIValue( out startPos, out endPos ) ) { if ( piInDtdStringBuilder == null ) { if ( ignorePIs ) { return false; } if ( parsingMode == ParsingMode.Full ) { curNode.SetValue( ps.chars, startPos, endPos - startPos ); } } else { piInDtdStringBuilder.Append( ps.chars, startPos, endPos - startPos ); } } else { BufferBuilder sb; if ( piInDtdStringBuilder == null ) { if ( ignorePIs || parsingMode != ParsingMode.Full ) { while ( !ParsePIValue( out startPos, out endPos ) ); return false; } sb = stringBuilder; Debug.Assert( stringBuilder.Length == 0 ); } else { sb = piInDtdStringBuilder; } do { sb.Append( ps.chars, startPos, endPos - startPos ); } while ( !ParsePIValue( out startPos, out endPos ) ); sb.Append( ps.chars, startPos, endPos - startPos ); if ( piInDtdStringBuilder == null ) { curNode.SetValue( stringBuilder.ToString() ); stringBuilder.Length = 0; } } return true; }
internal void CopyTo(int valueOffset, BufferBuilder sb) { if (value == null) { Debug.Assert(valueStartPos != -1); Debug.Assert(chars != null); sb.Append(chars, valueStartPos + valueOffset, valueLength - valueOffset); } else { if (valueOffset <= 0) { sb.Append(value); } else { sb.Append(value, valueOffset, value.Length - valueOffset); } } }
protected override void Render(MapDocument document, BufferBuilder builder, ResourceCollector resourceCollector) { base.Render(document, builder, resourceCollector); var sel = GetSelection(document); if (sel.IsEmpty) { return; } var verts = new List <VertexStandard>(); var indices = new List <int>(); var groups = new List <BufferGroup>(); var hideFaceMask = ShouldHideFaceMask; var selectionColour = Color.FromArgb(32, Color.Red).ToVector4(); // Add selection highlights if (!hideFaceMask) { foreach (var face in sel) { var indOffs = indices.Count; var offs = verts.Count; verts.AddRange(face.Vertices.Select(x => new VertexStandard { Position = x, Colour = Vector4.One, Tint = selectionColour, Flags = VertexFlags.FlatColour })); for (var i = 2; i < face.Vertices.Count; i++) { indices.Add(offs); indices.Add(offs + i - 1); indices.Add(offs + i); } groups.Add(new BufferGroup(PipelineType.TexturedAlpha, CameraType.Perspective, face.Origin, (uint)indOffs, (uint)(indices.Count - indOffs))); } builder.Append(verts, indices.Select(x => (uint)x), groups); } // Add wireframes - selection outlines and texture axes var lineColour = Color.Yellow.ToVector4(); var uAxisColour = Color.Yellow.ToVector4(); var vAxisColour = Color.Lime.ToVector4(); var wfIndOffs = indices.Count; foreach (var face in sel) { var offs = verts.Count; // outlines verts.AddRange(face.Vertices.Select(x => new VertexStandard { Position = x, Colour = lineColour, Tint = Vector4.One })); for (var i = 0; i < face.Vertices.Count; i++) { indices.Add(offs + i); indices.Add(offs + (i + 1) % face.Vertices.Count); } // texture axes var lineStart = (face.Vertices.Aggregate(Vector3.Zero, (a, b) => a + b) / face.Vertices.Count) + face.Plane.Normal * 0.5f; var uEnd = lineStart + face.Texture.UAxis * 20; var vEnd = lineStart + face.Texture.VAxis * 20; offs = verts.Count; verts.Add(new VertexStandard { Position = lineStart, Colour = uAxisColour, Tint = Vector4.One }); verts.Add(new VertexStandard { Position = uEnd, Colour = uAxisColour, Tint = Vector4.One }); verts.Add(new VertexStandard { Position = lineStart, Colour = vAxisColour, Tint = Vector4.One }); verts.Add(new VertexStandard { Position = vEnd, Colour = vAxisColour, Tint = Vector4.One }); indices.Add(offs + 0); indices.Add(offs + 1); indices.Add(offs + 2); indices.Add(offs + 3); } groups.Add(new BufferGroup(PipelineType.Wireframe, CameraType.Perspective, (uint)wfIndOffs, (uint)(indices.Count - wfIndOffs))); builder.Append(verts, indices.Select(x => (uint)x), groups); }
protected override void Render(MapDocument document, BufferBuilder builder, ResourceCollector resourceCollector) { base.Render(document, builder, resourceCollector); if (_state != ClipState.None && _clipPlanePoint1 != null && _clipPlanePoint2 != null && _clipPlanePoint3 != null) { // Draw the lines var p1 = _clipPlanePoint1.Value; var p2 = _clipPlanePoint2.Value; var p3 = _clipPlanePoint3.Value; builder.Append( new [] { new VertexStandard { Position = p1, Colour = Vector4.One, Tint = Vector4.One }, new VertexStandard { Position = p2, Colour = Vector4.One, Tint = Vector4.One }, new VertexStandard { Position = p3, Colour = Vector4.One, Tint = Vector4.One }, }, new uint [] { 0, 1, 1, 2, 2, 0 }, new [] { new BufferGroup(PipelineType.Wireframe, CameraType.Both, 0, 6) } ); if (!p1.EquivalentTo(p2) && !p2.EquivalentTo(p3) && !p1.EquivalentTo(p3) && !document.Selection.IsEmpty) { var plane = new Plane(p1, p2, p3); var pp = plane.ToPrecisionPlane(); // Draw the clipped solids var faces = new List <Polygon>(); foreach (var solid in document.Selection.OfType <Solid>().ToList()) { var s = solid.ToPolyhedron().ToPrecisionPolyhedron(); s.Split(pp, out var back, out var front); if (_side != ClipSide.Front && back != null) { faces.AddRange(back.Polygons.Select(x => x.ToStandardPolygon())); } if (_side != ClipSide.Back && front != null) { faces.AddRange(front.Polygons.Select(x => x.ToStandardPolygon())); } } var verts = new List <VertexStandard>(); var indices = new List <int>(); foreach (var polygon in faces) { var c = verts.Count; verts.AddRange(polygon.Vertices.Select(x => new VertexStandard { Position = x, Colour = Vector4.One, Tint = Vector4.One })); for (var i = 0; i < polygon.Vertices.Count; i++) { indices.Add(c + i); indices.Add(c + (i + 1) % polygon.Vertices.Count); } } builder.Append( verts, indices.Select(x => (uint)x), new[] { new BufferGroup(PipelineType.Wireframe, CameraType.Both, 0, (uint)indices.Count) } ); // Draw the clipping plane var poly = new DataStructures.Geometric.Precision.Polygon(pp); var bbox = document.Selection.GetSelectionBoundingBox(); var point = bbox.Center; foreach (var boxPlane in bbox.GetBoxPlanes()) { var proj = boxPlane.Project(point); var dist = (point - proj).Length() * 0.1f; var pln = new Plane(boxPlane.Normal, proj + boxPlane.Normal * Math.Max(dist, 100)).ToPrecisionPlane(); if (poly.Split(pln, out var b, out _)) { poly = b; } } verts.Clear(); indices.Clear(); var clipPoly = poly.ToStandardPolygon(); var colour = Color.FromArgb(64, Color.Turquoise).ToVector4(); // Add the face in both directions so it renders on both sides var polies = new[] { clipPoly.Vertices.ToList(), clipPoly.Vertices.Reverse().ToList() }; foreach (var p in polies) { var offs = verts.Count; verts.AddRange(p.Select(x => new VertexStandard { Position = x, Colour = Vector4.One, Tint = colour, Flags = VertexFlags.FlatColour })); for (var i = 2; i < clipPoly.Vertices.Count; i++) { indices.Add(offs); indices.Add(offs + i - 1); indices.Add(offs + i); } } builder.Append( verts, indices.Select(x => (uint)x), new[] { new BufferGroup(PipelineType.TexturedAlpha, CameraType.Perspective, p1, 0, (uint)indices.Count) } ); } } }
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); }
// 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); }
public void Append(string value) { Debug.Assert(inUse, "Reset() wasn't called"); builder.Append(value); }