예제 #1
0
        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));
        }
예제 #2
0
        public override string GetDebugName()
        {
            BufferBuilder dbgName = new BufferBuilder();

            dbgName.Append("<xsl:attribute-set name=\"");
            dbgName.Append(Name.QualifiedName);
            dbgName.Append("\">");
            return(dbgName.ToString());
        }
예제 #3
0
        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);
        }
예제 #4
0
        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);
        }
예제 #5
0
        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();
        }
예제 #6
0
        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());
        }
예제 #7
0
        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);
         }
     }
 }
예제 #9
0
        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));
        }
예제 #10
0
        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());
        }
예제 #11
0
        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));
        }
예제 #12
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);
            }
        }
예제 #13
0
        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;
        }
예제 #14
0
        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);
        }
예제 #15
0
        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) }
                );
        }
예제 #16
0
        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));
        }
예제 #17
0
        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);
        }
예제 #18
0
        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));
        }
예제 #19
0
        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);
        }
예제 #20
0
        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));
        }
예제 #21
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);
        }
예제 #22
0
        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);
        }
예제 #23
0
        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));
        }
예제 #25
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)
                });
            }
        }
예제 #26
0
        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 (&amp; &apos; &lt; &gt; &quot;).
        // 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] ) {
                // &apos; or &amp; 
                case 'a':
                    pos++;
                    // &amp;
                    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;
                            }
                        }
                    }
                    // &apos;
                    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;
                // &lt;
                case 'l':
                    if ( ps.charsUsed - pos >= 3 ) {
                        if ( chars[pos+1] == 't' && chars[pos+2] == ';' ) {
                            pos += 3;
                            ch = '<';
                            goto FoundCharRef;
                        }
                        else {
                            return -1;
                        }
                    }
                    break;
                // &gt;
                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. &#32; &#x20;).
        // 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;
        }
예제 #31
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);
         }
     }
 }
예제 #32
0
        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);
        }
예제 #33
0
        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) }
                        );
                }
            }
        }
예제 #34
0
        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);
        }
예제 #35
0
        // 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);
        }
예제 #36
0
 public void Append(string value)
 {
     Debug.Assert(inUse, "Reset() wasn't called");
     builder.Append(value);
 }