Exemplo n.º 1
0
    public void DrawQuad(IGameViewport viewport, ReadOnlySpan <ShapeVertex3d> corners,
                         IMdfRenderMaterial material,
                         PackedLinearColorA color)
    {
        _discVertexBuffer.Resource.Update(corners);
        _discBufferBinding.Resource.Bind();

        MdfRenderOverrides overrides = new MdfRenderOverrides();

        overrides.overrideDiffuse = true;
        overrides.overrideColor   = color;
        material.Bind(viewport, _device, null, overrides);

        _device.SetIndexBuffer(_discIndexBuffer);
        _device.DrawIndexed(PrimitiveType.TriangleList, 4, 2 * 3);
    }
    public void Render(
        IGameViewport viewport,
        Vector3 centerPos,
        float factor,
        float radiusInch,
        IMdfRenderMaterial innerMaterial,
        IMdfRenderMaterial outerMaterial)
    {
        Span <IntgameVertex> vertices = stackalloc IntgameVertex[78];

        var elevation = -(MathF.Sin(-0.77539754f) * factor);

        var outerBorderRadius = Math.Min(24.0f, radiusInch / 7.0f);
        var innerRadius       = radiusInch - outerBorderRadius;

        // Set up the center of the circle position
        vertices[0].uv      = Vector2.Zero;
        vertices[0].normal  = Vector4.UnitY;
        vertices[0].diffuse = PackedLinearColorA.White;
        vertices[0].pos     = new Vector4(
            centerPos,
            1
            );

        for (var i = 1; i < 39; i++)
        {
            ref var vertex = ref vertices[i];

            var angle = i * AnglePerSlice;

            vertex.pos = new Vector4(
                centerPos.X + MathF.Cos(angle) * innerRadius - MathF.Sin(angle) * 0.0f,
                centerPos.Y + elevation,
                centerPos.Z + MathF.Cos(angle) * 0.0f + MathF.Sin(angle) * innerRadius,
                1
                );
            // Vanilla used a borked normal of (undefined, 0, 1, undefined) here
            vertex.normal  = Vector4.UnitY;
            vertex.diffuse = PackedLinearColorA.White;
            vertex.uv      = new Vector2(
                1.0f - (i % 2),
                1.0f
                );
        }
Exemplo n.º 3
0
    public void DrawDisc(IGameViewport viewport, Vector3 center,
                         float rotation,
                         float radius,
                         IMdfRenderMaterial material)
    {
        Span <ShapeVertex3d> vertices = stackalloc ShapeVertex3d[_discVerticesTpl.Length];

        _discVerticesTpl.CopyTo(vertices);

        // There is some sort of rotation going on here that is related to
        // the view transformation
        var v8 = MathF.Cos(-0.77539754f) * -1.5f;
        var v9 = MathF.Sin(-0.77539754f) * -1.5f;

        for (var i = 0; i < _discVerticesTpl.Length; ++i)
        {
            var orgx = _discVerticesTpl[i].pos.X;
            var orgz = _discVerticesTpl[i].pos.Z;

            // The cos/sin magic rotates around the Y axis
            vertices[i].pos.X = MathF.Sin(rotation) * orgz + MathF.Cos(rotation) * orgx;
            vertices[i].pos.Y = v9;
            vertices[i].pos.Z = MathF.Cos(rotation) * orgz - MathF.Sin(rotation) * orgx;

            // Scale is being applied here
            vertices[i].pos.X = radius * vertices[i].pos.X;
            vertices[i].pos.Z = radius * vertices[i].pos.Z;

            vertices[i].pos.X = center.X + MathF.Cos(2.3561945f) * v8 + vertices[i].pos.X;
            vertices[i].pos.Z = center.Z + MathF.Cos(2.3561945f) * v8 + vertices[i].pos.Z;
        }

        _discVertexBuffer.Resource.Update <ShapeVertex3d>(vertices);
        _discBufferBinding.Resource.Bind();
        material.Bind(viewport, _device, null);

        _device.SetIndexBuffer(_discIndexBuffer);
        _device.DrawIndexed(PrimitiveType.TriangleList, 16, 8 * 3);
    }
Exemplo n.º 4
0
    public void DrawRectangleWithMaterial(Span <Vertex2d> corners, IMdfRenderMaterial material)
    {
        MdfRenderOverrides overrides = new MdfRenderOverrides();

        overrides.ignoreLighting = true;
        overrides.uiProjection   = true;
        material?.Bind((WorldCamera)null, _device, Array.Empty <Light3d>(), overrides);

        _device.SetDepthStencilState(noDepthState);

        foreach (ref var vertex in corners)
        {
            vertex.normal = new Vector4(0, 0, -1, 0);
        }

        // Copy the vertices
        _device.UpdateBuffer <Vertex2d>(vertexBuffer, corners);

        mdfBufferBinding.Bind();

        _device.SetIndexBuffer(indexBuffer);

        _device.DrawIndexed(PrimitiveType.TriangleList, 4, 6);
    }
Exemplo n.º 5
0
    public void Render(IGameViewport viewport, LocAndOffsets loc, LocAndOffsets tgtLoc,
                       float degreesTarget,
                       IMdfRenderMaterial materialInside,
                       IMdfRenderMaterial materialOutside)
    {
        Span <IntgameVertex> vertices = stackalloc IntgameVertex[38];

        var elevation      = MathF.Sin(-0.77539754f) * -1.5f;
        var outerConeAngle = Angles.ToRadians(degreesTarget);

        var originPos = loc.ToInches3D();

        var targetPos = tgtLoc.ToInches3D();

        var d          = targetPos - originPos;
        var coneRadius = d.Length();
        // The normal pointing in the direction of the target straight down the middle of the cone
        var coneNormal = d / coneRadius;

        // A portion of the full cone will be rendered as a "rim" on the outside, which
        // will have this radius:
        var ringRadius = MathF.Min(24.0f, coneRadius / 7.0f);

        var innerConeRadius = coneRadius - ringRadius;

        // Set the origin point
        vertices[0].pos     = new Vector4(originPos.X, elevation, originPos.Z, 1);
        vertices[0].normal  = Vector4.UnitY;
        vertices[0].uv      = new Vector2(0, 0);
        vertices[0].diffuse = PackedLinearColorA.White;

        var   innerConeAngle     = (1.0f - (ringRadius + ringRadius) / (outerConeAngle * coneRadius)) * outerConeAngle;
        var   innerConeAngleHalf = innerConeAngle * 0.5f;
        float angleStepInner     = innerConeAngle / 18;

        // This is the point at the center of the cone, but on the inner rim
        var coneNearX = innerConeRadius * coneNormal.X;
        var coneNearY = innerConeRadius * coneNormal.Z;

        for (var i = 1; i < 20; i++)
        {
            // angle=0 is straight down the center of the cone, so it is shifted to the left by coneAngle/2
            var angle = (i - 1) * angleStepInner - innerConeAngleHalf;
            vertices[i].pos = new Vector4(
                originPos.X + MathF.Cos(angle) * coneNearX - MathF.Sin(angle) * coneNearY,
                elevation,
                originPos.Z + MathF.Sin(angle) * coneNearX + MathF.Cos(angle) * coneNearY,
                1
                );

            vertices[i].normal  = Vector4.UnitY;
            vertices[i].diffuse = PackedLinearColorA.White;
            vertices[i].uv      = new Vector2(
                (i + 1) % 2,
                1.0f
                );
        }

        _fanVertexBuffer.Resource.Update <IntgameVertex>(vertices.Slice(0, 20));
        _fanBufferBinding.Resource.Bind();
        _device.SetIndexBuffer(_fanIndexBuffer);
        materialInside.Bind(viewport, _device, new List <Light3d>());
        _device.DrawIndexed(PrimitiveType.TriangleList, 20, FanIndices.Length);

        var slice = 0.0f;
        // Far center point of the cone, on the outside rim
        var coneFarX = coneRadius * coneNormal.X;
        var coneFarY = coneRadius * coneNormal.Z;

        for (var i = 0; i < 38; i += 2)
        {
            var angle = slice * angleStepInner - innerConeAngleHalf;

            vertices[i].pos = new Vector4(
                originPos.X + MathF.Cos(angle) * coneNearX - MathF.Sin(angle) * coneNearY,
                elevation,
                originPos.Z + MathF.Sin(angle) * coneNearX + MathF.Cos(angle) * coneNearY,
                1
                );
            vertices[i].normal  = Vector4.UnitY;
            vertices[i].uv      = new Vector2(slice, 0);
            vertices[i].diffuse = PackedLinearColorA.White;

            vertices[i + 1].pos = new Vector4(
                originPos.X + MathF.Cos(angle) * coneFarX - MathF.Sin(angle) * coneFarY,
                elevation,
                originPos.Z + MathF.Cos(angle) * coneFarY + MathF.Sin(angle) * coneFarX,
                1
                );
            vertices[i + 1].normal  = Vector4.UnitY;
            vertices[i + 1].uv      = new Vector2(slice, 1);
            vertices[i + 1].diffuse = PackedLinearColorA.White;

            slice += 1;
        }

        _ringVertexBuffer.Resource.Update <IntgameVertex>(vertices.Slice(0, 38));
        _ringBufferBinding.Resource.Bind();
        _device.SetIndexBuffer(_ringIndexBuffer);
        materialOutside.Bind(viewport, _device, new List <Light3d>());
        _device.DrawIndexed(PrimitiveType.TriangleList, 38, RingIndices.Length);

        // Render the left and right side of the cone using the same texture as the outside ring

        var innerConeAngleHalfInv = -innerConeAngleHalf;
        var outerConeAngleHalf    = outerConeAngle * 0.5f;
        var outerConeAngleHalfInv = -outerConeAngleHalf;
        var v71 = innerConeRadius / ringRadius;

        // Right flank of the cone
        vertices[0] = new IntgameVertex
        {
            pos = new Vector4(
                originPos.X + MathF.Cos(innerConeAngleHalfInv) * coneFarX - MathF.Sin(innerConeAngleHalfInv) * coneFarY,
                elevation,
                originPos.Z + MathF.Sin(innerConeAngleHalfInv) * coneFarX + MathF.Cos(innerConeAngleHalfInv) * coneFarY,
                1
                ),
            normal  = Vector4.UnitY,
            uv      = new Vector2(0, 1),
            diffuse = PackedLinearColorA.White
        };
        vertices[1] = new IntgameVertex
        {
            pos = new Vector4(
                originPos.X + MathF.Cos(outerConeAngleHalfInv) * coneFarX - MathF.Sin(outerConeAngleHalfInv) * coneFarY,
                elevation,
                originPos.Z + MathF.Sin(outerConeAngleHalfInv) * coneFarX + MathF.Cos(outerConeAngleHalfInv) * coneFarY,
                1
                ),
            normal  = Vector4.UnitY,
            uv      = new Vector2(0, 1),
            diffuse = PackedLinearColorA.White
        };
        vertices[2] = new IntgameVertex
        {
            pos = new Vector4(
                originPos.X + MathF.Cos(innerConeAngleHalfInv) * coneNearX - MathF.Sin(innerConeAngleHalfInv) * coneNearY,
                elevation,
                originPos.Z + MathF.Sin(innerConeAngleHalfInv) * coneNearX + MathF.Cos(innerConeAngleHalfInv) * coneNearY,
                1
                ),
            normal  = Vector4.UnitY,
            uv      = new Vector2(0, 0),
            diffuse = PackedLinearColorA.White
        };
        vertices[3] = new IntgameVertex
        {
            pos = new Vector4(
                originPos.X + MathF.Cos(outerConeAngleHalfInv) * coneNearX - MathF.Sin(outerConeAngleHalfInv) * coneNearY,
                elevation,
                originPos.Z + MathF.Sin(outerConeAngleHalfInv) * coneNearX + MathF.Cos(outerConeAngleHalfInv) * coneNearY,
                1
                ),
            normal  = Vector4.UnitY,
            uv      = new Vector2(0, 1),
            diffuse = PackedLinearColorA.White
        };
        vertices[4] = new IntgameVertex
        {
            pos = new Vector4(
                originPos.X,
                elevation,
                originPos.Z,
                1
                ),
            normal  = Vector4.UnitY,
            uv      = new Vector2(-v71, 0.5f),
            diffuse = PackedLinearColorA.White
        };

        // Left flank of the cone
        vertices[5] = new IntgameVertex
        {
            pos = new Vector4(
                originPos.X + MathF.Cos(innerConeAngleHalf) * coneFarX - MathF.Sin(innerConeAngleHalf) * coneFarY,
                elevation,
                originPos.Z + MathF.Sin(innerConeAngleHalf) * coneFarX + MathF.Cos(innerConeAngleHalf) * coneFarY,
                1
                ),
            normal  = Vector4.UnitY,
            uv      = new Vector2(0, 1),
            diffuse = PackedLinearColorA.White
        };
        vertices[6] = new IntgameVertex
        {
            pos = new Vector4(
                originPos.X + MathF.Cos(outerConeAngleHalf) * coneFarX - MathF.Sin(outerConeAngleHalf) * coneFarY,
                elevation,
                originPos.Z + MathF.Sin(outerConeAngleHalf) * coneFarX + MathF.Cos(outerConeAngleHalf) * coneFarY,
                1
                ),
            normal  = Vector4.UnitY,
            uv      = new Vector2(0, 1),
            diffuse = PackedLinearColorA.White
        };
        vertices[7] = new IntgameVertex
        {
            pos = new Vector4(
                originPos.X + MathF.Cos(innerConeAngleHalf) * coneNearX - MathF.Sin(innerConeAngleHalf) * coneNearY,
                elevation,
                originPos.Z + MathF.Sin(innerConeAngleHalf) * coneNearX + MathF.Cos(innerConeAngleHalf) * coneNearY,
                1
                ),
            normal  = Vector4.UnitY,
            uv      = new Vector2(0, 0),
            diffuse = PackedLinearColorA.White
        };
        vertices[8] = new IntgameVertex
        {
            pos = new Vector4(
                originPos.X + MathF.Cos(outerConeAngleHalf) * coneNearX - MathF.Sin(outerConeAngleHalf) * coneNearY,
                elevation,
                originPos.Z + MathF.Sin(outerConeAngleHalf) * coneNearX + MathF.Cos(outerConeAngleHalf) * coneNearY,
                1
                ),
            normal  = Vector4.UnitY,
            uv      = new Vector2(0, 1),
            diffuse = PackedLinearColorA.White
        };
        // This could reuse vertices[4], but was here in vanilla also
        vertices[9] = new IntgameVertex
        {
            pos = new Vector4(
                originPos.X,
                elevation,
                originPos.Z,
                1
                ),
            normal  = Vector4.UnitY,
            uv      = new Vector2(v71, 0.5f),
            diffuse = PackedLinearColorA.White
        };

        _flankVertexBuffer.Resource.Update <IntgameVertex>(vertices.Slice(0, 10));
        _flankBufferBinding.Resource.Bind();
        _device.SetIndexBuffer(_flankIndexBuffer);
        materialOutside.Bind(viewport, _device, new List <Light3d>());
        _device.DrawIndexed(PrimitiveType.TriangleList, 10, FlankIndices.Length);
    }
Exemplo n.º 6
0
    public void Render(IGameViewport viewport, Vector3 srcPos, Vector3 tgtPos, float rayThickness, float minRange,
                       float maxRange, IMdfRenderMaterial materialInside, IMdfRenderMaterial materialOutside)
    {
        float v11;
        float v69;
        float v70;
        float v71;

        Span <IntgameVertex> vertices = stackalloc IntgameVertex[52];

        var elevation = MathF.Sin(-0.77539754f) * -1.5f;

        var srcAbsX = srcPos.X;
        var srcAbsY = srcPos.Z;

        var tgtAbsX = tgtPos.X;
        var tgtAbsY = tgtPos.Z;

        var   deltaX     = tgtAbsX - srcAbsX;
        var   dettaY     = tgtAbsY - srcAbsY;
        float dist       = MathF.Sqrt(dettaY * dettaY + deltaX * deltaX);
        float normalizer = 1.0f / dist;
        var   xHat       = normalizer * deltaX;
        var   yHat       = normalizer * dettaY;
        var   v62        = -xHat;

        if (dist < minRange)
        {
            dist    = minRange;
            tgtAbsX = xHat * minRange + srcAbsX;
            v11     = yHat * minRange;
            tgtAbsY = v11 + srcAbsY;
        }
        else if (dist > maxRange)
        {
            dist    = maxRange;
            tgtAbsX = xHat * maxRange + srcAbsX;
            v11     = yHat * maxRange;
            tgtAbsY = v11 + srcAbsY;
        }

        var v12 = dist / 7.0f;
        var v59 = v12;

        if (v12 > 24.0f)
        {
            v12 = 24.0f;
        }

        float v56 = rayThickness * 0.25f;

        if (v12 > v56)
        {
            v12 = v56;
        }

        var v16 = rayThickness - v12;
        var v57 = v16;

        if (dist - v12 * 3.0 < v57)
        {
            v57 = v59;
        }

        var v61 = v16;
        var v72 = rayThickness / v61;

        for (var i = 0; i < 22; i += 2)
        {
            float v21 = MathF.Cos((float)(i / 2) * 0.31415927f);
            var   v22 = v21 * v61;
            v70 = yHat * v22;
            var v23 = v22;
            var v24 = MathF.Sqrt(v72 * v72 - v21 * v21) * v57;
            v71 = v24;

            v69 = v23 * v62;
            float v25 = v21 * rayThickness / locXY.INCH_PER_FEET;

            vertices[i] = new IntgameVertex
            {
                pos = new Vector4(
                    srcAbsX + v70 + v24 * xHat,
                    elevation,
                    srcAbsY + v69 + v71 * yHat,
                    1
                    ),
                normal  = Vector4.UnitY,
                uv      = new Vector2(v25, 0),
                diffuse = PackedLinearColorA.White
            };

            vertices[i + 1] = new IntgameVertex
            {
                pos = new Vector4(
                    tgtAbsX + v70 - xHat * v12,
                    elevation,
                    tgtAbsY + v69 - v12 * yHat,
                    1
                    ),
                normal  = Vector4.UnitY,
                uv      = new Vector2(v25, 1.0f),
                diffuse = PackedLinearColorA.White
            };
        }

        _innerVertexBuffer.Resource.Update <IntgameVertex>(vertices.Slice(0, 22));
        _innerBufferBinding.Resource.Bind();
        _device.SetIndexBuffer(_innerIndexBuffer);
        materialInside.Bind(viewport, _device, new List <Light3d>());
        _device.DrawIndexed(PrimitiveType.TriangleList, 22, InnerIndices.Length);

        // Note: Unlike Vanilla, we'll pack the entire rest into a single VB and draw that

        for (var i = 0; i < 22; i += 2)
        {
            float v28 = MathF.Cos((float)(i / 2) * 0.31415927f);
            var   v29 = v28 * v61;
            var   v30 = v29;
            var   v31 = MathF.Sqrt(1.0f - v28 * v28) * v57;
            var   v32 = v30 * v62;
            var   v33 = v28 * rayThickness * 0.083333336f;
            var   v34 = MathF.Sqrt(v72 * v72 - v28 * v28) * v57;

            vertices[i] = new IntgameVertex
            {
                pos = new Vector4(
                    v31 * xHat + yHat * v29 + srcAbsX,
                    elevation,
                    v31 * yHat + v32 + srcAbsY,
                    1
                    ),
                normal  = Vector4.UnitY,
                uv      = new Vector2(v33, 0),
                diffuse = PackedLinearColorA.White
            };

            vertices[i + 1] = new IntgameVertex
            {
                pos = new Vector4(
                    xHat * v34 + yHat * v29 + srcAbsX,
                    elevation,
                    v34 * yHat + v32 + srcAbsY,
                    1
                    ),
                normal  = Vector4.UnitY,
                uv      = new Vector2(v33, 1.0f),
                diffuse = PackedLinearColorA.White
            };
        }

        for (var i = 0; i < 22; i += 2)
        {
            float v39 = MathF.Cos(i / 2 * 0.31415927f);
            var   v40 = v61 * v39;
            var   v41 = yHat * v40;
            var   v42 = v41;
            var   v43 = v40 * v62;
            v72 = v43;
            float v44 = v39 * rayThickness * 0.083333336f;
            vertices[22 + i] = new IntgameVertex
            {
                pos = new Vector4(
                    v41 - xHat * v12 + tgtAbsX,
                    elevation,
                    v43 - v12 * yHat + tgtAbsY,
                    1
                    ),
                normal  = Vector4.UnitY,
                uv      = new Vector2(v44, 0),
                diffuse = PackedLinearColorA.White
            };

            vertices[22 + i + 1] = new IntgameVertex
            {
                pos = new Vector4(
                    v42 + tgtAbsX,
                    elevation,
                    v72 + tgtAbsY,
                    1
                    ),
                normal  = Vector4.UnitY,
                uv      = new Vector2(v44, 1.0f),
                diffuse = PackedLinearColorA.White
            };
        }

        var   vertexIdx = 44;
        var   v45       = v61 * yHat;
        var   v46       = v45;
        var   v47       = v61 * v62;
        var   v48       = v47;
        float v49       = dist * 0.041666668f;
        var   v50       = v49;
        var   v51       = yHat * rayThickness;
        var   v52       = v51;
        var   v53       = v62 * rayThickness;
        var   v54       = v53;

        vertices[vertexIdx++] = new IntgameVertex
        {
            pos = new Vector4(
                v45 + srcAbsX,
                elevation,
                v47 + srcAbsY,
                1
                ),
            normal  = Vector4.UnitY,
            uv      = new Vector2(0, 0),
            diffuse = PackedLinearColorA.White
        };
        vertices[vertexIdx++] = new IntgameVertex
        {
            pos = new Vector4(
                v46 + tgtAbsX,
                elevation,
                v48 + tgtAbsY,
                1
                ),
            normal  = Vector4.UnitY,
            uv      = new Vector2(v49, 0),
            diffuse = PackedLinearColorA.White
        };
        vertices[vertexIdx++] = new IntgameVertex
        {
            pos = new Vector4(
                v51 + srcAbsX,
                elevation,
                v53 + srcAbsY,
                1
                ),
            normal  = Vector4.UnitY,
            uv      = new Vector2(0, 1),
            diffuse = PackedLinearColorA.White
        };
        vertices[vertexIdx++] = new IntgameVertex
        {
            pos = new Vector4(
                v52 + tgtAbsX,
                elevation,
                v54 + tgtAbsY,
                1
                ),
            normal  = Vector4.UnitY,
            uv      = new Vector2(v49, 1),
            diffuse = PackedLinearColorA.White
        };

        vertices[vertexIdx++] = new IntgameVertex
        {
            pos = new Vector4(
                srcAbsX - v46,
                elevation,
                srcAbsY - v48,
                1
                ),
            normal  = Vector4.UnitY,
            uv      = new Vector2(0, 0),
            diffuse = PackedLinearColorA.White
        };
        vertices[vertexIdx++] = new IntgameVertex
        {
            pos = new Vector4(
                tgtAbsX - v46,
                elevation,
                tgtAbsY - v48,
                1
                ),
            normal  = Vector4.UnitY,
            uv      = new Vector2(v50, 0),
            diffuse = PackedLinearColorA.White
        };
        vertices[vertexIdx++] = new IntgameVertex
        {
            pos = new Vector4(
                srcAbsX - v52,
                elevation,
                srcAbsY - v54,
                1
                ),
            normal  = Vector4.UnitY,
            uv      = new Vector2(0, 1),
            diffuse = PackedLinearColorA.White
        };
        vertices[vertexIdx++] = new IntgameVertex
        {
            pos = new Vector4(
                tgtAbsX - v52,
                elevation,
                tgtAbsY - v54,
                1
                ),
            normal  = Vector4.UnitY,
            uv      = new Vector2(v50, 1),
            diffuse = PackedLinearColorA.White
        };

        _outerVertexBuffer.Resource.Update <IntgameVertex>(vertices.Slice(0, vertexIdx));
        _outerBufferBinding.Resource.Bind();
        _device.SetIndexBuffer(_outerIndexBuffer);
        materialOutside.Bind(viewport, _device, new List <Light3d>());
        _device.DrawIndexed(PrimitiveType.TriangleList, vertexIdx, OuterIndices.Length);
    }