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); }
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); }