Exemple #1
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));
        }
        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);
            }
        }
Exemple #3
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);
        }
        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));
        }
Exemple #5
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)
                });
            }
        }
Exemple #6
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);
        }
Exemple #7
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);
        }