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) }
                );
        }
Beispiel #2
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)
                });
            }
        }
Beispiel #3
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);
        }
Beispiel #4
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);
        }