public void Render(IGameViewport viewport, LocAndOffsets location, ITexture texture) { var screenPos = viewport.WorldToScreen(location.ToInches3D()); var contentRect = texture.GetContentRect(); var renderArgs = new Render2dArgs { srcRect = contentRect, flags = Render2dFlag.BUFFERTEXTURE, destRect = new Rectangle( (int)(screenPos.X - contentRect.Width / 2), (int)(screenPos.Y - contentRect.Height / 2), contentRect.Width, contentRect.Height ), customTexture = texture }; Tig.ShapeRenderer2d.DrawRectangle(ref renderArgs); }
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); }
private LocAndOffsets AverageLocation(LocAndOffsets a, LocAndOffsets b) { var averaged = (a.ToInches3D() + b.ToInches3D()) / 2; return(LocAndOffsets.FromInches(averaged)); }