From b5e4e0e0745840c01ede91c077ff5c9a56a2614a Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Mon, 21 Jul 2014 17:36:12 +1200 Subject: [PATCH] Add support for voxels in actor previews. --- OpenRA.Mods.RA/Graphics/VoxelActorPreview.cs | 58 ++++++++++++++++++++ OpenRA.Mods.RA/OpenRA.Mods.RA.csproj | 1 + OpenRA.Mods.RA/Render/RenderVoxels.cs | 27 ++++++++- OpenRA.Mods.RA/Render/WithVoxelBarrel.cs | 19 ++++++- OpenRA.Mods.RA/Render/WithVoxelBody.cs | 14 ++++- OpenRA.Mods.RA/Render/WithVoxelTurret.cs | 17 +++++- OpenRA.Mods.TS/Render/WithVoxelUnloadBody.cs | 12 +++- 7 files changed, 142 insertions(+), 6 deletions(-) create mode 100644 OpenRA.Mods.RA/Graphics/VoxelActorPreview.cs diff --git a/OpenRA.Mods.RA/Graphics/VoxelActorPreview.cs b/OpenRA.Mods.RA/Graphics/VoxelActorPreview.cs new file mode 100644 index 0000000000..75f4abeae2 --- /dev/null +++ b/OpenRA.Mods.RA/Graphics/VoxelActorPreview.cs @@ -0,0 +1,58 @@ +#region Copyright & License Information +/* + * Copyright 2007-2014 The OpenRA Developers (see AUTHORS) + * This file is part of OpenRA, which is free software. It is made + * available to you under the terms of the GNU General Public License + * as published by the Free Software Foundation. For more information, + * see COPYING. + */ +#endregion + +using System; +using System.Collections.Generic; +using OpenRA.Graphics; +using OpenRA.Mods.RA.Render; +using OpenRA.Primitives; + +namespace OpenRA.Mods.RA.Graphics +{ + public class VoxelPreview : IActorPreview + { + readonly VoxelAnimation[] components; + readonly RenderVoxelsInfo rvi; + readonly WRot lightSource; + readonly WRot camera; + + readonly PaletteReference colorPalette; + readonly PaletteReference normalsPalette; + readonly PaletteReference shadowPalette; + + readonly WVec offset; + readonly int zOffset; + + public VoxelPreview(VoxelAnimation[] components, WVec offset, int zOffset, RenderVoxelsInfo rvi, WAngle cameraPitch, + PaletteReference colorPalette, PaletteReference normalsPalette, PaletteReference shadowPalette) + { + this.components = components; + this.rvi = rvi; + lightSource = new WRot(WAngle.Zero,new WAngle(256) - rvi.LightPitch, rvi.LightYaw); + camera = new WRot(WAngle.Zero, cameraPitch - new WAngle(256), new WAngle(256)); + + this.colorPalette = colorPalette; + this.normalsPalette = normalsPalette; + this.shadowPalette = shadowPalette; + + this.offset = offset; + this.zOffset = zOffset; + } + + public void Tick() { /* not supported */ } + + public IEnumerable Render(WorldRenderer wr, WPos pos) + { + yield return new VoxelRenderable(components, pos + offset, zOffset, camera, rvi.Scale, + lightSource, rvi.LightAmbientColor, rvi.LightDiffuseColor, + colorPalette, normalsPalette, shadowPalette); + } + } +} diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj index 141d0a0564..1148e35b16 100644 --- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj +++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj @@ -547,6 +547,7 @@ + diff --git a/OpenRA.Mods.RA/Render/RenderVoxels.cs b/OpenRA.Mods.RA/Render/RenderVoxels.cs index 6b466817ff..eb07ff6d8e 100755 --- a/OpenRA.Mods.RA/Render/RenderVoxels.cs +++ b/OpenRA.Mods.RA/Render/RenderVoxels.cs @@ -9,13 +9,16 @@ #endregion using System.Collections.Generic; +using System.Linq; using OpenRA.Graphics; -using OpenRA.Traits; using OpenRA.Mods.RA.Graphics; +using OpenRA.Traits; namespace OpenRA.Mods.RA.Render { - public class RenderVoxelsInfo : ITraitInfo, Requires + public interface IRenderActorPreviewVoxelsInfo { IEnumerable RenderPreviewVoxels(ActorPreviewInitializer init, RenderVoxelsInfo rv, string image, WRot orientation, int facings, PaletteReference p); } + + public class RenderVoxelsInfo : ITraitInfo, IRenderActorPreviewInfo, Requires { [Desc("Defaults to the actor name.")] public readonly string Image = null; @@ -34,7 +37,27 @@ namespace OpenRA.Mods.RA.Render public readonly WAngle LightYaw = WAngle.FromDegrees(240); public readonly float[] LightAmbientColor = new float[] {0.6f, 0.6f, 0.6f}; public readonly float[] LightDiffuseColor = new float[] {0.4f, 0.4f, 0.4f}; + public virtual object Create(ActorInitializer init) { return new RenderVoxels(init.self, this); } + + public virtual IEnumerable RenderPreview(ActorPreviewInitializer init) + { + var body = init.Actor.Traits.Get(); + var sequenceProvider = init.World.Map.SequenceProvider; + var image = Image ?? init.Actor.Name; + var facings = body.QuantizedFacings == -1 ? init.Actor.Traits.Get().QuantizedBodyFacings(sequenceProvider, init.Actor) : body.QuantizedFacings; + var palette = init.WorldRenderer.Palette(Palette ?? (init.Owner != null ? PlayerPalette + init.Owner.InternalName : null)); + + var facing = init.Contains() ? init.Get() : 0; + var orientation = WRot.FromFacing(facing); + var components = init.Actor.Traits.WithInterface() + .SelectMany(rvpi => rvpi.RenderPreviewVoxels(init, this, image, orientation, facings, palette)) + .ToArray(); + + yield return new VoxelPreview(components, WVec.Zero, 0, this, body.CameraPitch, palette, + init.WorldRenderer.Palette(NormalsPalette), init.WorldRenderer.Palette("shadow")); + } + } public class RenderVoxels : IRender, INotifyOwnerChanged diff --git a/OpenRA.Mods.RA/Render/WithVoxelBarrel.cs b/OpenRA.Mods.RA/Render/WithVoxelBarrel.cs index adbe829e89..046be7ff1f 100755 --- a/OpenRA.Mods.RA/Render/WithVoxelBarrel.cs +++ b/OpenRA.Mods.RA/Render/WithVoxelBarrel.cs @@ -11,11 +11,12 @@ using System.Collections.Generic; using System.Linq; using OpenRA.Graphics; +using OpenRA.Mods.RA.Graphics; using OpenRA.Traits; namespace OpenRA.Mods.RA.Render { - public class WithVoxelBarrelInfo : ITraitInfo, Requires + public class WithVoxelBarrelInfo : ITraitInfo, IRenderActorPreviewVoxelsInfo, Requires { [Desc("Voxel sequence name to use")] public readonly string Sequence = "barrel"; @@ -25,6 +26,22 @@ namespace OpenRA.Mods.RA.Render public readonly WVec LocalOffset = WVec.Zero; public object Create(ActorInitializer init) { return new WithVoxelBarrel(init.self, this); } + + public IEnumerable RenderPreviewVoxels(ActorPreviewInitializer init, RenderVoxelsInfo rv, string image, WRot orientation, int facings, PaletteReference p) + { + var body = init.Actor.Traits.Get(); + var armament = init.Actor.Traits.WithInterface() + .First(a => a.Name == Armament); + var t = init.Actor.Traits.WithInterface() + .First(tt => tt.Turret == armament.Turret); + + var voxel = VoxelProvider.GetVoxel(image, Sequence); + var turretOrientation = body.QuantizeOrientation(new WRot(WAngle.Zero, WAngle.Zero, WAngle.FromFacing(t.InitialFacing) - orientation.Yaw), facings); + var turretOffset = body.LocalToWorld(t.Offset.Rotate(orientation)); + + yield return new VoxelAnimation(voxel, () => turretOffset, () => new [] { turretOrientation, orientation }, + () => false, () => 0); + } } public class WithVoxelBarrel diff --git a/OpenRA.Mods.RA/Render/WithVoxelBody.cs b/OpenRA.Mods.RA/Render/WithVoxelBody.cs index 8814ebefaf..430f4fb723 100644 --- a/OpenRA.Mods.RA/Render/WithVoxelBody.cs +++ b/OpenRA.Mods.RA/Render/WithVoxelBody.cs @@ -9,19 +9,31 @@ #endregion using System; +using System.Collections.Generic; using System.Linq; using OpenRA.Graphics; +using OpenRA.Mods.RA.Graphics; using OpenRA.Traits; namespace OpenRA.Mods.RA.Render { [Desc("Also returns a default selection size that is calculated automatically from the voxel dimensions.")] - public class WithVoxelBodyInfo : ITraitInfo, IQuantizeBodyOrientationInfo, Requires + public class WithVoxelBodyInfo : ITraitInfo, IQuantizeBodyOrientationInfo, IRenderActorPreviewVoxelsInfo, Requires { public readonly string Sequence = "idle"; public object Create(ActorInitializer init) { return new WithVoxelBody(init.self, this); } + public IEnumerable RenderPreviewVoxels(ActorPreviewInitializer init, RenderVoxelsInfo rv, string image, WRot orientation, int facings, PaletteReference p) + { + var body = init.Actor.Traits.Get(); + var voxel = VoxelProvider.GetVoxel(image, "idle"); + var bodyOrientation = new[] { body.QuantizeOrientation(orientation, facings) }; + yield return new VoxelAnimation(voxel, () => WVec.Zero, + () => bodyOrientation, + () => false, () => 0); + } + public int QuantizedBodyFacings(SequenceProvider sequenceProvider, ActorInfo ai) { return 0; } } diff --git a/OpenRA.Mods.RA/Render/WithVoxelTurret.cs b/OpenRA.Mods.RA/Render/WithVoxelTurret.cs index 8adfd5c2ac..2568073b95 100755 --- a/OpenRA.Mods.RA/Render/WithVoxelTurret.cs +++ b/OpenRA.Mods.RA/Render/WithVoxelTurret.cs @@ -11,11 +11,12 @@ using System.Collections.Generic; using System.Linq; using OpenRA.Graphics; +using OpenRA.Mods.RA.Graphics; using OpenRA.Traits; namespace OpenRA.Mods.RA.Render { - public class WithVoxelTurretInfo : ITraitInfo, Requires + public class WithVoxelTurretInfo : ITraitInfo, IRenderActorPreviewVoxelsInfo, Requires, Requires { [Desc("Voxel sequence name to use")] public readonly string Sequence = "turret"; @@ -24,6 +25,20 @@ namespace OpenRA.Mods.RA.Render public readonly string Turret = "primary"; public object Create(ActorInitializer init) { return new WithVoxelTurret(init.self, this); } + + public IEnumerable RenderPreviewVoxels(ActorPreviewInitializer init, RenderVoxelsInfo rv, string image, WRot orientation, int facings, PaletteReference p) + { + var body = init.Actor.Traits.Get(); + var t = init.Actor.Traits.WithInterface() + .First(tt => tt.Turret == Turret); + + var voxel = VoxelProvider.GetVoxel(image, Sequence); + var turretOffset = body.LocalToWorld(t.Offset.Rotate(orientation)); + + var turretBodyOrientation = new WRot(WAngle.Zero, WAngle.Zero, WAngle.FromFacing(t.InitialFacing) - orientation.Yaw); + var turretOrientation = new[] { turretBodyOrientation, body.QuantizeOrientation(orientation, facings) }; + yield return new VoxelAnimation(voxel, () => turretOffset, () => turretOrientation, () => false, () => 0); + } } public class WithVoxelTurret diff --git a/OpenRA.Mods.TS/Render/WithVoxelUnloadBody.cs b/OpenRA.Mods.TS/Render/WithVoxelUnloadBody.cs index 2f00fd2a66..b230d39ab4 100755 --- a/OpenRA.Mods.TS/Render/WithVoxelUnloadBody.cs +++ b/OpenRA.Mods.TS/Render/WithVoxelUnloadBody.cs @@ -12,11 +12,12 @@ using System; using System.Collections.Generic; using System.Linq; using OpenRA.Graphics; +using OpenRA.Mods.RA.Graphics; using OpenRA.Traits; namespace OpenRA.Mods.RA.Render { - public class WithVoxelUnloadBodyInfo : ITraitInfo, IQuantizeBodyOrientationInfo, Requires + public class WithVoxelUnloadBodyInfo : ITraitInfo, IQuantizeBodyOrientationInfo, IRenderActorPreviewVoxelsInfo, Requires { [Desc("Voxel sequence name to use when docked to a refinery.")] public readonly string UnloadSequence = "unload"; @@ -26,6 +27,15 @@ namespace OpenRA.Mods.RA.Render public object Create(ActorInitializer init) { return new WithVoxelUnloadBody(init.self, this); } + public IEnumerable RenderPreviewVoxels(ActorPreviewInitializer init, RenderVoxelsInfo rv, string image, WRot orientation, int facings, PaletteReference p) + { + var body = init.Actor.Traits.Get(); + var voxel = VoxelProvider.GetVoxel(image, "idle"); + yield return new VoxelAnimation(voxel, () => WVec.Zero, + () => new[]{ body.QuantizeOrientation(orientation, facings) }, + () => false, () => 0); + } + public int QuantizedBodyFacings(SequenceProvider sequenceProvider, ActorInfo ai) { return 0; } }