public static void DrawRangeCircle(WorldRenderer wr, WPos centerPosition, WDist radius, float width, Color color, float contrastWidth, Color contrastColor) { var wcr = Game.Renderer.WorldRgbaColorRenderer; var offset = new WVec(radius.Length, 0, 0); for (var i = 0; i < RangeCircleSegments; i++) { var a = wr.Screen3DPosition(centerPosition + offset.Rotate(RangeCircleStartRotations[i])); var b = wr.Screen3DPosition(centerPosition + offset.Rotate(RangeCircleEndRotations[i])); if (contrastWidth > 0) wcr.DrawLine(a, b, contrastWidth / wr.Viewport.Zoom, contrastColor); if (width > 0) wcr.DrawLine(a, b, width / wr.Viewport.Zoom, color); } }
public void Render(WorldRenderer wr) { if (!waypoints.Any()) { return; } var first = wr.Viewport.WorldToViewPx(wr.Screen3DPosition(waypoints.First())); var a = first; foreach (var b in waypoints.Skip(1).Select(pos => wr.Viewport.WorldToViewPx(wr.Screen3DPosition(pos)))) { Game.Renderer.RgbaColorRenderer.DrawLine(a, b, width, color); DrawTargetMarker(wr, color, b, markerSize); a = b; } DrawTargetMarker(wr, color, first); }
public void RenderDebugGeometry(WorldRenderer wr) { var groundPos = voxel.pos - new WVec(0, 0, wr.World.Map.DistanceAboveTerrain(voxel.pos).Length); var groundZ = wr.World.Map.Grid.TileSize.Height * (groundPos.Z - voxel.pos.Z) / 1024f; var pxOrigin = wr.Screen3DPosition(voxel.pos); var shadowOrigin = pxOrigin - groundZ * (new float2(renderProxy.ShadowDirection, 1)); var iz = 1 / wr.Viewport.Zoom; // Draw sprite rect var offset = pxOrigin + renderProxy.Sprite.Offset - 0.5f * renderProxy.Sprite.Size; Game.Renderer.WorldRgbaColorRenderer.DrawRect(offset.XY, (offset + renderProxy.Sprite.Size).XY, iz, Color.Red); // Draw transformed shadow sprite rect var c = Color.Purple; var psb = renderProxy.ProjectedShadowBounds; Game.Renderer.WorldRgbaColorRenderer.DrawPolygon(new[] { shadowOrigin + psb[1], shadowOrigin + psb[3], shadowOrigin + psb[0], shadowOrigin + psb[2] }, iz, c); // Draw voxel bounding box var draw = voxel.voxels.Where(v => v.DisableFunc == null || !v.DisableFunc()); var scaleTransform = OpenRA.Graphics.Util.ScaleMatrix(voxel.scale, voxel.scale, voxel.scale); var cameraTransform = OpenRA.Graphics.Util.MakeFloatMatrix(voxel.camera.AsMatrix()); foreach (var v in draw) { var bounds = v.Voxel.Bounds(v.FrameFunc()); var worldTransform = v.RotationFunc().Reverse().Aggregate(scaleTransform, (x, y) => OpenRA.Graphics.Util.MatrixMultiply(x, OpenRA.Graphics.Util.MakeFloatMatrix(y.AsMatrix()))); var pxPos = pxOrigin + wr.ScreenVectorComponents(v.OffsetFunc()); var screenTransform = OpenRA.Graphics.Util.MatrixMultiply(cameraTransform, worldTransform); DrawBoundsBox(pxPos, screenTransform, bounds, iz, Color.Yellow); } }
public void Render(WorldRenderer wr) { var groundPos = voxel.pos - new WVec(0, 0, wr.World.Map.DistanceAboveTerrain(voxel.pos).Length); var groundZ = wr.World.Map.Grid.TileSize.Height * (groundPos.Z - voxel.pos.Z) / 1024f; var pxOrigin = wr.Screen3DPosition(voxel.pos); // HACK: We don't have enough texture channels to pass the depth data to the shader // so for now just offset everything forward so that the back corner is rendered at pos. pxOrigin -= new float3(0, 0, Screen3DBounds(wr).Second.X); var shadowOrigin = pxOrigin - groundZ * (new float2(renderProxy.ShadowDirection, 1)); var psb = renderProxy.ProjectedShadowBounds; var sa = shadowOrigin + psb[0]; var sb = shadowOrigin + psb[2]; var sc = shadowOrigin + psb[1]; var sd = shadowOrigin + psb[3]; Game.Renderer.WorldRgbaSpriteRenderer.DrawSprite(renderProxy.ShadowSprite, sa, sb, sc, sd); Game.Renderer.WorldRgbaSpriteRenderer.DrawSprite(renderProxy.Sprite, pxOrigin - 0.5f * renderProxy.Sprite.Size); }
public void Render(WorldRenderer wr) { if (!waypoints.Any()) return; var iz = 1 / wr.Viewport.Zoom; var first = wr.Screen3DPosition(waypoints.First()); var a = first; foreach (var b in waypoints.Skip(1).Select(pos => wr.Screen3DPosition(pos))) { Game.Renderer.WorldRgbaColorRenderer.DrawLine(a, b, iz, color); DrawTargetMarker(wr, color, b); a = b; } DrawTargetMarker(wr, color, first); }
public void Render(WorldRenderer wr) { var vecLength = length.Length; if (vecLength == 0) return; if (shape == BeamRenderableShape.Flat) { var delta = length * width.Length / (2 * vecLength); var corner = new WVec(-delta.Y, delta.X, delta.Z); var a = wr.Screen3DPosition(pos - corner); var b = wr.Screen3DPosition(pos + corner); var c = wr.Screen3DPosition(pos + corner + length); var d = wr.Screen3DPosition(pos - corner + length); Game.Renderer.WorldRgbaColorRenderer.FillRect(a, b, c, d, color); } else { var start = wr.Screen3DPosition(pos); var end = wr.Screen3DPosition(pos + length); var screenWidth = wr.ScreenVector(new WVec(width, WDist.Zero, WDist.Zero))[0]; Game.Renderer.WorldRgbaColorRenderer.DrawLine(start, end, screenWidth, color); } }
void IWorldLoaded.WorldLoaded(World w, WorldRenderer wr) { // Initialize tile cache // This includes the region outside the visible area to cover any sprites peeking outside the map foreach (var uv in w.Map.AllCells.MapCoords) { var pos = w.Map.CenterOfCell(uv.ToCPos(map)); var screen = wr.Screen3DPosition(pos - new WVec(0, 0, pos.Z)); var variant = (byte)Game.CosmeticRandom.Next(info.ShroudVariants.Length); tileInfos[uv] = new TileInfo(screen, variant); } // Dirty the whole projected space DirtyCells(map.AllCells.MapCoords.Select(uv => (PPos)uv)); // All tiles are visible in the editor if (w.Type == WorldType.Editor) visibleUnderShroud = _ => true; else visibleUnderShroud = puv => map.Contains(puv); visibleUnderFog = puv => map.Contains(puv); var shroudSheet = shroudSprites[0].Sheet; if (shroudSprites.Any(s => s.Sheet != shroudSheet)) throw new InvalidDataException("Shroud sprites span multiple sheets. Try loading their sequences earlier."); var shroudBlend = shroudSprites[0].BlendMode; if (shroudSprites.Any(s => s.BlendMode != shroudBlend)) throw new InvalidDataException("Shroud sprites must all use the same blend mode."); var fogSheet = fogSprites[0].Sheet; if (fogSprites.Any(s => s.Sheet != fogSheet)) throw new InvalidDataException("Fog sprites span multiple sheets. Try loading their sequences earlier."); var fogBlend = fogSprites[0].BlendMode; if (fogSprites.Any(s => s.BlendMode != fogBlend)) throw new InvalidDataException("Fog sprites must all use the same blend mode."); shroudLayer = new TerrainSpriteLayer(w, wr, shroudSheet, shroudBlend, wr.Palette(info.ShroudPalette), false); fogLayer = new TerrainSpriteLayer(w, wr, fogSheet, fogBlend, wr.Palette(info.FogPalette), false); }
public void DrawCombatOverlay(WorldRenderer wr, RgbaColorRenderer wcr, Actor actor) { var actorPos = actor.CenterPosition; var orientation = new WRot(actor.Orientation.Roll, actor.Orientation.Pitch, new WAngle(actor.Orientation.Yaw.Angle + (RotateToIsometry ? 128 : 0))); var targetablePositions = actor.TraitsImplementing<ITargetablePositions>(); if (ApplyToAllTargetablePositions && targetablePositions.Any()) { var positions = targetablePositions.SelectMany(tp => tp.TargetablePositions(actor)); foreach (var pos in positions) { var vertsTop = combatOverlayVertsTop.Select(v => wr.Screen3DPosition(pos + v.Rotate(orientation))); var vertsBottom = combatOverlayVertsBottom.Select(v => wr.Screen3DPosition(pos + v.Rotate(orientation))); wcr.DrawPolygon(vertsTop.ToArray(), 1, Color.Yellow); wcr.DrawPolygon(vertsBottom.ToArray(), 1, Color.Yellow); } } else { var vertsTop = combatOverlayVertsTop.Select(v => wr.Screen3DPosition(actorPos + v.Rotate(orientation))); var vertsBottom = combatOverlayVertsBottom.Select(v => wr.Screen3DPosition(actorPos + v.Rotate(orientation))); wcr.DrawPolygon(vertsTop.ToArray(), 1, Color.Yellow); wcr.DrawPolygon(vertsBottom.ToArray(), 1, Color.Yellow); } }
public void Render(WorldRenderer wr) { // Need at least 4 points to smooth the contrail over if (length - skip < 4) return; var screenWidth = wr.ScreenVector(new WVec(width, WDist.Zero, WDist.Zero))[0]; var wcr = Game.Renderer.WorldRgbaColorRenderer; // Start of the first line segment is the tail of the list - don't smooth it. var curPos = trail[Index(next - skip - 1)]; var curColor = color; for (var i = 0; i < length - skip - 4; i++) { var j = next - skip - i - 2; var nextPos = Average(trail[Index(j)], trail[Index(j - 1)], trail[Index(j - 2)], trail[Index(j - 3)]); var nextColor = Exts.ColorLerp(i * 1f / (length - 4), color, Color.Transparent); if (!world.FogObscures(curPos) && !world.FogObscures(nextPos)) wcr.DrawLine(wr.Screen3DPosition(curPos), wr.Screen3DPosition(nextPos), screenWidth, curColor, nextColor); curPos = nextPos; curColor = nextColor; } }
public void DrawCombatOverlay(WorldRenderer wr, RgbaColorRenderer wcr, Actor actor) { var actorPos = actor.CenterPosition; var a = actorPos + new WVec(PointA.X, PointA.Y, VerticalTopOffset).Rotate(actor.Orientation); var b = actorPos + new WVec(PointB.X, PointB.Y, VerticalTopOffset).Rotate(actor.Orientation); var aa = actorPos + new WVec(PointA.X, PointA.Y, VerticalBottomOffset).Rotate(actor.Orientation); var bb = actorPos + new WVec(PointB.X, PointB.Y, VerticalBottomOffset).Rotate(actor.Orientation); var offset1 = new WVec(a.Y - b.Y, b.X - a.X, 0); offset1 = offset1 * Radius.Length / offset1.Length; var offset2 = new WVec(aa.Y - bb.Y, bb.X - aa.X, 0); offset2 = offset2 * Radius.Length / offset2.Length; var c = Color.Yellow; RangeCircleRenderable.DrawRangeCircle(wr, a, Radius, 1, c, 0, c); RangeCircleRenderable.DrawRangeCircle(wr, b, Radius, 1, c, 0, c); wcr.DrawLine(new[] { wr.Screen3DPosition(a - offset1), wr.Screen3DPosition(b - offset1) }, 1, c); wcr.DrawLine(new[] { wr.Screen3DPosition(a + offset1), wr.Screen3DPosition(b + offset1) }, 1, c); RangeCircleRenderable.DrawRangeCircle(wr, aa, Radius, 1, c, 0, c); RangeCircleRenderable.DrawRangeCircle(wr, bb, Radius, 1, c, 0, c); wcr.DrawLine(new[] { wr.Screen3DPosition(aa - offset2), wr.Screen3DPosition(bb - offset2) }, 1, c); wcr.DrawLine(new[] { wr.Screen3DPosition(aa + offset2), wr.Screen3DPosition(bb + offset2) }, 1, c); }
public void Render(WorldRenderer wr) { var wcr = Game.Renderer.WorldRgbaColorRenderer; var center = wr.Screen3DPosition(centerPosition); for (var i = 0; i < trailCount; i++) { var angle = trailAngle - new WAngle(i * (trailSeparation.Angle <= 512 ? 1 : -1)); var length = radius.Length * new WVec(angle.Cos(), angle.Sin(), 0) / 1024; var end = wr.Screen3DPosition(centerPosition + length); var alpha = color.A - i * color.A / trailCount; wcr.DrawLine(center, end, 3, Color.FromArgb(alpha, contrastColor)); wcr.DrawLine(center, end, 1, Color.FromArgb(alpha, color)); } RangeCircleRenderable.DrawRangeCircle(wr, centerPosition, radius, 1, color, 3, contrastColor); }
void DrawArmaments(Actor self, AttackBase attack, WorldRenderer wr, RgbaColorRenderer wcr, float iz) { var c = Color.White; // Fire ports on garrisonable structures var garrison = attack as AttackGarrisoned; if (garrison != null) { var bodyOrientation = coords.Value.QuantizeOrientation(self, self.Orientation); foreach (var p in garrison.Info.Ports) { var pos = self.CenterPosition + coords.Value.LocalToWorld(p.Offset.Rotate(bodyOrientation)); var da = coords.Value.LocalToWorld(new WVec(224, 0, 0).Rotate(WRot.FromYaw(p.Yaw + p.Cone)).Rotate(bodyOrientation)); var db = coords.Value.LocalToWorld(new WVec(224, 0, 0).Rotate(WRot.FromYaw(p.Yaw - p.Cone)).Rotate(bodyOrientation)); var o = wr.Screen3DPosition(pos); var a = wr.Screen3DPosition(pos + da * 224 / da.Length); var b = wr.Screen3DPosition(pos + db * 224 / db.Length); wcr.DrawLine(o, a, iz, c); wcr.DrawLine(o, b, iz, c); } return; } foreach (var a in attack.Armaments) { foreach (var b in a.Barrels) { var muzzle = self.CenterPosition + a.MuzzleOffset(self, b); var dirOffset = new WVec(0, -224, 0).Rotate(a.MuzzleOrientation(self, b)); var sm = wr.Screen3DPosition(muzzle); var sd = wr.Screen3DPosition(muzzle + dirOffset); wcr.DrawLine(sm, sd, iz, c); TargetLineRenderable.DrawTargetMarker(wr, c, sm); } } }
void IRenderAboveWorld.RenderAboveWorld(Actor self, WorldRenderer wr) { if (devMode == null || !devMode.ShowCombatGeometry) return; var wcr = Game.Renderer.WorldRgbaColorRenderer; var iz = 1 / wr.Viewport.Zoom; if (healthInfo != null) healthInfo.Shape.DrawCombatOverlay(wr, wcr, self); var blockers = allBlockers.Where(Exts.IsTraitEnabled).ToList(); if (blockers.Count > 0) { var hc = Color.Orange; var height = new WVec(0, 0, blockers.Max(b => b.BlockingHeight.Length)); var ha = wr.Screen3DPosition(self.CenterPosition); var hb = wr.Screen3DPosition(self.CenterPosition + height); wcr.DrawLine(ha, hb, iz, hc); TargetLineRenderable.DrawTargetMarker(wr, hc, ha); TargetLineRenderable.DrawTargetMarker(wr, hc, hb); } foreach (var attack in self.TraitsImplementing<AttackBase>().Where(x => !x.IsTraitDisabled)) DrawArmaments(self, attack, wr, wcr, iz); }