Beispiel #1
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);
    }
    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);
    }
Beispiel #3
0
    public void Render(IGameViewport viewport, Vector3 aoeCenter, Vector3 casterPos, float aoeRadius)
    {
        Span <IntgameVertex> vertices = stackalloc IntgameVertex[4];

        var   elevation = MathF.Sin(-0.77539754f) * -1.5f;
        var   v3        = aoeRadius * 0.56560004f;
        float v14       = v3;

        if (v3 <= 135.744)
        {
            if (v14 < 11.312)
            {
                v14 = 11.312f;
            }
        }
        else
        {
            v14 = 135.744f;
        }


        var dirVector = Vector3.Normalize(casterPos - aoeCenter);

        float v10 = aoeRadius - v14;

        vertices[0] = new IntgameVertex
        {
            pos = new Vector4(
                aoeCenter.X + v10 * dirVector.X,
                elevation,
                aoeCenter.Z + v10 * dirVector.Z,
                1
                ),
            normal  = Vector4.UnitY,
            uv      = new Vector2(0, 1),
            diffuse = PackedLinearColorA.White
        };
        vertices[1] = new IntgameVertex
        {
            pos = new Vector4(
                aoeCenter.X + aoeRadius * dirVector.X + v14 * dirVector.Z,
                elevation,
                aoeCenter.Z + aoeRadius * dirVector.Z - v14 * dirVector.X,
                1
                ),
            normal  = Vector4.UnitY,
            uv      = new Vector2(0, 0),
            diffuse = PackedLinearColorA.White
        };
        vertices[2] = new IntgameVertex
        {
            pos = new Vector4(
                aoeCenter.X + aoeRadius * dirVector.X - v14 * dirVector.Z,
                elevation,
                aoeCenter.Z + v14 * dirVector.X + aoeRadius * dirVector.Z,
                1
                ),
            normal  = Vector4.UnitY,
            uv      = new Vector2(1, 1),
            diffuse = PackedLinearColorA.White
        };
        vertices[3] = new IntgameVertex
        {
            pos = new Vector4(
                aoeCenter.X + (v14 + aoeRadius) * dirVector.X,
                elevation,
                aoeCenter.Z + (v14 + aoeRadius) * dirVector.Z,
                1
                ),
            normal  = Vector4.UnitY,
            uv      = new Vector2(1, 0),
            diffuse = PackedLinearColorA.White
        };

        _vertexBuffer.Resource.Update <IntgameVertex>(vertices);

        _bufferBinding.Resource.Bind();
        _device.SetIndexBuffer(_indexBuffer);

        _material.Resource.Bind(viewport, _device, new List <Light3d>());

        _device.DrawIndexed(
            PrimitiveType.TriangleList,
            vertices.Length,
            Indices.Length);
    }