Separate IBodyOrientation from render traits.

This commit is contained in:
Paul Chote
2013-05-25 17:21:17 +12:00
parent 53aa698491
commit c149898592
16 changed files with 122 additions and 26 deletions

View File

@@ -226,6 +226,7 @@
<Compile Include="Widgets\ClientTooltipRegionWidget.cs" /> <Compile Include="Widgets\ClientTooltipRegionWidget.cs" />
<Compile Include="Graphics\Renderable.cs" /> <Compile Include="Graphics\Renderable.cs" />
<Compile Include="Traits\Render\RenderSprites.cs" /> <Compile Include="Traits\Render\RenderSprites.cs" />
<Compile Include="Traits\BodyOrientation.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\OpenRA.FileFormats\OpenRA.FileFormats.csproj"> <ProjectReference Include="..\OpenRA.FileFormats\OpenRA.FileFormats.csproj">

View File

@@ -0,0 +1,58 @@
#region Copyright & License Information
/*
* Copyright 2007-2011 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 System.Linq;
using OpenRA.Graphics;
using OpenRA.FileFormats;
namespace OpenRA.Traits
{
public class BodyOrientationInfo : ITraitInfo, IBodyOrientationInfo
{
[Desc("Camera pitch for rotation calculations")]
public readonly WAngle CameraPitch = WAngle.FromDegrees(40);
public object Create(ActorInitializer init) { return new BodyOrientation(init.self, this); }
}
public class BodyOrientation : IBodyOrientation
{
[Sync] public int QuantizedFacings { get; set; }
BodyOrientationInfo Info;
public BodyOrientation(Actor self, BodyOrientationInfo info)
{
Info = info;
}
public WAngle CameraPitch { get { return Info.CameraPitch; } }
public WVec LocalToWorld(WVec vec)
{
// RA's 2d perspective doesn't correspond to an orthonormal 3D
// coordinate system, so fudge the y axis to make things look good
return new WVec(vec.Y, -Info.CameraPitch.Sin()*vec.X/1024, vec.Z);
}
public WRot QuantizeOrientation(Actor self, WRot orientation)
{
// Quantization disabled
if (QuantizedFacings == 0)
return orientation;
// Map yaw to the closest facing
var facing = Util.QuantizeFacing(orientation.Yaw.Angle / 4, QuantizedFacings) * (256 / QuantizedFacings);
// Roll and pitch are always zero if yaw is quantized
return new WRot(WAngle.Zero, WAngle.Zero, WAngle.FromFacing(facing));
}
}
}

View File

@@ -16,13 +16,8 @@ using OpenRA.FileFormats;
namespace OpenRA.Traits namespace OpenRA.Traits
{ {
public class RenderSimpleInfo : RenderSpritesInfo, IBodyOrientationInfo public class RenderSimpleInfo : RenderSpritesInfo, Requires<IBodyOrientationInfo>
{ {
[Desc("Number of facings for gameplay calculations. -1 indiciates auto-detection from sequence")]
public readonly int QuantizedFacings = -1;
[Desc("Camera pitch the sprite was rendered with. Used to determine rotation ellipses")]
public readonly WAngle CameraPitch = WAngle.FromDegrees(40);
public override object Create(ActorInitializer init) { return new RenderSimple(init.self); } public override object Create(ActorInitializer init) { return new RenderSimple(init.self); }
public virtual IEnumerable<IRenderable> RenderPreview(ActorInfo ai, PaletteReference pr) public virtual IEnumerable<IRenderable> RenderPreview(ActorInfo ai, PaletteReference pr)
@@ -34,7 +29,7 @@ namespace OpenRA.Traits
} }
} }
public class RenderSimple : RenderSprites, IBodyOrientation, IAutoSelectionSize public class RenderSimple : RenderSprites, IAutoSelectionSize
{ {
RenderSimpleInfo Info; RenderSimpleInfo Info;
@@ -49,6 +44,7 @@ namespace OpenRA.Traits
: this(self, MakeFacingFunc(self)) : this(self, MakeFacingFunc(self))
{ {
anim.PlayRepeating("idle"); anim.PlayRepeating("idle");
self.Trait<IBodyOrientation>().QuantizedFacings = anim.CurrentSequence.Facings;
} }
public int2 SelectionSize(Actor self) public int2 SelectionSize(Actor self)
@@ -74,22 +70,5 @@ namespace OpenRA.Traits
anim.PlayThen(NormalizeSequence(self, name), anim.PlayThen(NormalizeSequence(self, name),
() => anim.PlayRepeating(NormalizeSequence(self, "idle"))); () => anim.PlayRepeating(NormalizeSequence(self, "idle")));
} }
public WVec LocalToWorld(WVec vec)
{
// RA's 2d perspective doesn't correspond to an orthonormal 3D
// coordinate system, so fudge the y axis to make things look good
return new WVec(vec.Y, -Info.CameraPitch.Sin()*vec.X/1024, vec.Z);
}
public WRot QuantizeOrientation(Actor self, WRot orientation)
{
// Map yaw to the closest facing
var numDirs = Info.QuantizedFacings == -1 ? anim.CurrentSequence.Facings : Info.QuantizedFacings;
var facing = Util.QuantizeFacing(orientation.Yaw.Angle / 4, numDirs) * (256 / numDirs);
// Roll and pitch are always zero
return new WRot(WAngle.Zero, WAngle.Zero, WAngle.FromFacing(facing));
}
} }
} }

View File

@@ -189,6 +189,8 @@ namespace OpenRA.Traits
public interface IRenderAsTerrain { IEnumerable<IRenderable> RenderAsTerrain(WorldRenderer wr, Actor self); } public interface IRenderAsTerrain { IEnumerable<IRenderable> RenderAsTerrain(WorldRenderer wr, Actor self); }
public interface IBodyOrientation public interface IBodyOrientation
{ {
WAngle CameraPitch { get; }
int QuantizedFacings { get; set; }
WVec LocalToWorld(WVec vec); WVec LocalToWorld(WVec vec);
WRot QuantizeOrientation(Actor self, WRot orientation); WRot QuantizeOrientation(Actor self, WRot orientation);
} }

View File

@@ -45,6 +45,8 @@ namespace OpenRA.Mods.RA.Render
anims.Add("wake", new AnimationWithOffset(wake, anims.Add("wake", new AnimationWithOffset(wake,
() => anims["wake"].Animation.CurrentSequence.Name == "left-wake" ? leftOffset : rightOffset, () => anims["wake"].Animation.CurrentSequence.Name == "left-wake" ? leftOffset : rightOffset,
() => false, -87)); () => false, -87));
self.Trait<IBodyOrientation>().QuantizedFacings = anim.CurrentSequence.Facings;
} }
public override void Tick(Actor self) public override void Tick(Actor self)

View File

@@ -57,6 +57,7 @@ namespace OpenRA.Mods.RA.Render
var self = init.self; var self = init.self;
// Work around a bogus crash // Work around a bogus crash
anim.PlayRepeating( NormalizeSequence(self, "idle") ); anim.PlayRepeating( NormalizeSequence(self, "idle") );
self.Trait<IBodyOrientation>().QuantizedFacings = anim.CurrentSequence.Facings;
// Can't call Complete() directly from ctor because other traits haven't been inited yet // Can't call Complete() directly from ctor because other traits haven't been inited yet
if (self.Info.Traits.Get<RenderBuildingInfo>().HasMakeAnimation && !init.Contains<SkipMakeAnimsInit>()) if (self.Info.Traits.Get<RenderBuildingInfo>().HasMakeAnimation && !init.Contains<SkipMakeAnimsInit>())

View File

@@ -61,6 +61,8 @@ namespace OpenRA.Mods.RA.Render
anim.PlayFetchIndex(NormalizeInfantrySequence(self, "stand"), () => 0); anim.PlayFetchIndex(NormalizeInfantrySequence(self, "stand"), () => 0);
State = AnimationState.Waiting; State = AnimationState.Waiting;
mobile = self.Trait<Mobile>(); mobile = self.Trait<Mobile>();
self.Trait<IBodyOrientation>().QuantizedFacings = anim.CurrentSequence.Facings;
} }
public void Attacking(Actor self, Target target) public void Attacking(Actor self, Target target)

View File

@@ -33,7 +33,7 @@ namespace OpenRA.Mods.RA
public class Turreted : ITick, ISync, IResolveOrder public class Turreted : ITick, ISync, IResolveOrder
{ {
[Sync] public int QuantizedFacings = -1; [Sync] public int QuantizedFacings = 0;
[Sync] public int turretFacing = 0; [Sync] public int turretFacing = 0;
public int? desiredFacing; public int? desiredFacing;
TurretedInfo info; TurretedInfo info;
@@ -96,7 +96,7 @@ namespace OpenRA.Mods.RA
// Hack: turretFacing is relative to the world, so subtract the body yaw // Hack: turretFacing is relative to the world, so subtract the body yaw
var local = WRot.FromYaw(WAngle.FromFacing(turretFacing) - self.Orientation.Yaw); var local = WRot.FromYaw(WAngle.FromFacing(turretFacing) - self.Orientation.Yaw);
if (QuantizedFacings == -1) if (QuantizedFacings == 0)
return local; return local;
// Quantize orientation to match a rendered sprite // Quantize orientation to match a rendered sprite

View File

@@ -445,3 +445,4 @@ VICE:
AttackWander: AttackWander:
RenderUnit: RenderUnit:
WithMuzzleFlash: WithMuzzleFlash:
BodyOrientation:

View File

@@ -33,6 +33,7 @@
DebugMuzzlePositions: DebugMuzzlePositions:
Guard: Guard:
Guardable: Guardable:
BodyOrientation:
^Tank: ^Tank:
AppearsOnRadar: AppearsOnRadar:
@@ -72,6 +73,7 @@
DebugMuzzlePositions: DebugMuzzlePositions:
Guard: Guard:
Guardable: Guardable:
BodyOrientation:
^Helicopter: ^Helicopter:
AppearsOnRadar: AppearsOnRadar:
@@ -97,6 +99,7 @@
Weapon: HeliExplode Weapon: HeliExplode
EmptyWeapon: HeliExplode EmptyWeapon: HeliExplode
DebugMuzzlePositions: DebugMuzzlePositions:
BodyOrientation:
^Infantry: ^Infantry:
AppearsOnRadar: AppearsOnRadar:
@@ -149,6 +152,7 @@
DebugMuzzlePositions: DebugMuzzlePositions:
Guard: Guard:
Guardable: Guardable:
BodyOrientation:
^CivInfantry: ^CivInfantry:
Inherits: ^Infantry Inherits: ^Infantry
@@ -197,6 +201,7 @@
DrawLineToTarget: DrawLineToTarget:
ActorLostNotification: ActorLostNotification:
DebugMuzzlePositions: DebugMuzzlePositions:
BodyOrientation:
^Ship: ^Ship:
AppearsOnRadar: AppearsOnRadar:
@@ -218,6 +223,7 @@
DebugMuzzlePositions: DebugMuzzlePositions:
Guard: Guard:
Guardable: Guardable:
BodyOrientation:
^Building: ^Building:
AppearsOnRadar: AppearsOnRadar:
@@ -266,6 +272,7 @@
DebugMuzzlePositions: DebugMuzzlePositions:
Guardable: Guardable:
Range: 3 Range: 3
BodyOrientation:
^CivBuilding: ^CivBuilding:
Inherits: ^Building Inherits: ^Building
@@ -296,6 +303,7 @@
RelativeToTopLeft: yes RelativeToTopLeft: yes
Tooltip: Tooltip:
Name: Civilian Building (Destroyed) Name: Civilian Building (Destroyed)
BodyOrientation:
^TechBuilding: ^TechBuilding:
Inherits: ^CivBuilding Inherits: ^CivBuilding
@@ -326,6 +334,7 @@
Tooltip: Tooltip:
Name: Field (Destroyed) Name: Field (Destroyed)
BelowUnits: BelowUnits:
BodyOrientation:
^Wall: ^Wall:
AppearsOnRadar: AppearsOnRadar:
@@ -354,6 +363,7 @@
AutoTargetIgnore: AutoTargetIgnore:
Sellable: Sellable:
Guardable: Guardable:
BodyOrientation:
^Tree: ^Tree:
Tooltip: Tooltip:
@@ -374,6 +384,7 @@
Armor: Armor:
Type: Wood Type: Wood
AutoTargetIgnore: AutoTargetIgnore:
BodyOrientation:
^Rock: ^Rock:
Tooltip: Tooltip:
@@ -388,6 +399,7 @@
Terrain: Tree Terrain: Tree
EditorAppearance: EditorAppearance:
RelativeToTopLeft: yes RelativeToTopLeft: yes
BodyOrientation:
^Husk: ^Husk:
Health: Health:
@@ -403,6 +415,7 @@
TransformOnCapture: TransformOnCapture:
ForceHealthPercentage: 25 ForceHealthPercentage: 25
BelowUnits: BelowUnits:
BodyOrientation:
# Capturable: # Capturable:
# Type: husk # Type: husk
# AllowAllies: true # AllowAllies: true
@@ -420,3 +433,4 @@
SoundOnDamageTransition: SoundOnDamageTransition:
DamagedSound: xplos.aud DamagedSound: xplos.aud
DestroyedSound: xplobig4.aud DestroyedSound: xplobig4.aud
BodyOrientation:

View File

@@ -351,11 +351,14 @@ CRATE:
Unit: mcv Unit: mcv
RenderSimple: RenderSimple:
BelowUnits: BelowUnits:
BodyOrientation:
mpspawn: mpspawn:
Waypoint: Waypoint:
RenderEditorOnly: RenderEditorOnly:
BodyOrientation:
waypoint: waypoint:
Waypoint: Waypoint:
RenderEditorOnly: RenderEditorOnly:
BodyOrientation:

View File

@@ -33,6 +33,7 @@
DebugMuzzlePositions: DebugMuzzlePositions:
Guard: Guard:
Guardable: Guardable:
BodyOrientation:
^Tank: ^Tank:
AppearsOnRadar: AppearsOnRadar:
@@ -69,6 +70,7 @@
DebugMuzzlePositions: DebugMuzzlePositions:
Guard: Guard:
Guardable: Guardable:
BodyOrientation:
^Husk: ^Husk:
Health: Health:
@@ -84,6 +86,7 @@
Types:Husk Types:Husk
Tooltip: Tooltip:
Name: Destroyed Tank Name: Destroyed Tank
BodyOrientation:
^TowerHusk: ^TowerHusk:
Health: Health:
@@ -101,6 +104,7 @@
Name: Destroyed Tower Name: Destroyed Tower
ProximityCaptor: ProximityCaptor:
Types:Husk Types:Husk
BodyOrientation:
^Infantry: ^Infantry:
AppearsOnRadar: AppearsOnRadar:
@@ -149,6 +153,7 @@
DebugMuzzlePositions: DebugMuzzlePositions:
Guard: Guard:
Guardable: Guardable:
BodyOrientation:
^Plane: ^Plane:
AppearsOnRadar: AppearsOnRadar:
@@ -168,6 +173,7 @@
Types:Plane Types:Plane
GivesBounty: GivesBounty:
DebugMuzzlePositions: DebugMuzzlePositions:
BodyOrientation:
^Helicopter: ^Helicopter:
Inherits: ^Plane Inherits: ^Plane
@@ -216,3 +222,4 @@
Bib: Bib:
Guardable: Guardable:
Range: 3 Range: 3
BodyOrientation:

View File

@@ -372,6 +372,7 @@ WALL:
Types:Wall Types:Wall
Sellable: Sellable:
Guardable: Guardable:
BodyOrientation:
GUNTOWER: GUNTOWER:
Inherits: ^Building Inherits: ^Building

View File

@@ -481,14 +481,17 @@ CRATE:
ProximityCaptor: ProximityCaptor:
Types:Crate Types:Crate
Passenger: Passenger:
BodyOrientation:
mpspawn: mpspawn:
Waypoint: Waypoint:
RenderEditorOnly: RenderEditorOnly:
BodyOrientation:
waypoint: waypoint:
Waypoint: Waypoint:
RenderEditorOnly: RenderEditorOnly:
BodyOrientation:
SPICEBLOOM: SPICEBLOOM:
RenderBuilding: RenderBuilding:
@@ -508,6 +511,7 @@ SPICEBLOOM:
Interval: 75 Interval: 75
RadarColorFromTerrain: RadarColorFromTerrain:
Terrain: Spice Terrain: Spice
BodyOrientation:
#SANDWORM: #SANDWORM:
# Buildable: # Buildable:

View File

@@ -36,6 +36,7 @@
DebugMuzzlePositions: DebugMuzzlePositions:
Guard: Guard:
Guardable: Guardable:
BodyOrientation:
^Tank: ^Tank:
AppearsOnRadar: AppearsOnRadar:
@@ -75,6 +76,7 @@
DebugMuzzlePositions: DebugMuzzlePositions:
Guard: Guard:
Guardable: Guardable:
BodyOrientation:
^Infantry: ^Infantry:
AppearsOnRadar: AppearsOnRadar:
@@ -126,6 +128,7 @@
DebugMuzzlePositions: DebugMuzzlePositions:
Guard: Guard:
Guardable: Guardable:
BodyOrientation:
^Ship: ^Ship:
AppearsOnRadar: AppearsOnRadar:
@@ -157,6 +160,7 @@
DebugMuzzlePositions: DebugMuzzlePositions:
Guard: Guard:
Guardable: Guardable:
BodyOrientation:
^Plane: ^Plane:
AppearsOnRadar: AppearsOnRadar:
@@ -183,6 +187,7 @@
String:Plane String:Plane
UpdatesPlayerStatistics: UpdatesPlayerStatistics:
DebugMuzzlePositions: DebugMuzzlePositions:
BodyOrientation:
^Helicopter: ^Helicopter:
Inherits: ^Plane Inherits: ^Plane
@@ -229,6 +234,7 @@
Guardable: Guardable:
Range: 3 Range: 3
AutoTargetIgnore: AutoTargetIgnore:
BodyOrientation:
^Wall: ^Wall:
AppearsOnRadar: AppearsOnRadar:
@@ -263,6 +269,7 @@
Sellable: Sellable:
UpdatesPlayerStatistics: UpdatesPlayerStatistics:
Guardable: Guardable:
BodyOrientation:
^TechBuilding: ^TechBuilding:
Inherits: ^Building Inherits: ^Building
@@ -344,6 +351,7 @@
Armor: Armor:
Type: Wood Type: Wood
AutoTargetIgnore: AutoTargetIgnore:
BodyOrientation:
^Husk: ^Husk:
Husk: Husk:
@@ -358,6 +366,7 @@
ProximityCaptor: ProximityCaptor:
Types:Husk Types:Husk
BelowUnits: BelowUnits:
BodyOrientation:
^Bridge: ^Bridge:
Tooltip: Tooltip:
@@ -373,6 +382,7 @@
ProximityCaptor: ProximityCaptor:
Types:Bridge Types:Bridge
AutoTargetIgnore: AutoTargetIgnore:
BodyOrientation:
#Temperate Terrain Expansion #Temperate Terrain Expansion
^SVBridge: ^SVBridge:
@@ -389,6 +399,7 @@
ProximityCaptor: ProximityCaptor:
Types:Bridge Types:Bridge
AutoTargetIgnore: AutoTargetIgnore:
BodyOrientation:
^SHBridge: ^SHBridge:
Tooltip: Tooltip:
@@ -404,6 +415,7 @@
ProximityCaptor: ProximityCaptor:
Types:Bridge Types:Bridge
AutoTargetIgnore: AutoTargetIgnore:
BodyOrientation:
^STDBridge: ^STDBridge:
Tooltip: Tooltip:
@@ -419,6 +431,7 @@
ProximityCaptor: ProximityCaptor:
Types:Bridge Types:Bridge
AutoTargetIgnore: AutoTargetIgnore:
BodyOrientation:
#Desert Terrain Expansion: #Desert Terrain Expansion:
^Rock: ^Rock:
@@ -437,6 +450,7 @@
UseTerrainPalette: true UseTerrainPalette: true
ProximityCaptor: ProximityCaptor:
Types:Tree Types:Tree
BodyOrientation:
^DesertCivBuilding: ^DesertCivBuilding:
Inherits: ^CivBuilding Inherits: ^CivBuilding

View File

@@ -670,6 +670,7 @@ MINP:
Types: Mine Types: Mine
TargetableUnit: TargetableUnit:
TargetTypes: Ground TargetTypes: Ground
BodyOrientation:
MINV: MINV:
Mine: Mine:
@@ -695,6 +696,7 @@ MINV:
Types: Mine Types: Mine
TargetableUnit: TargetableUnit:
TargetTypes: Ground TargetTypes: Ground
BodyOrientation:
CRATE: CRATE:
Tooltip: Tooltip:
@@ -757,6 +759,7 @@ CRATE:
ProximityCaptor: ProximityCaptor:
Types:Crate Types:Crate
Passenger: Passenger:
BodyOrientation:
CAMERA: CAMERA:
Aircraft: Aircraft:
@@ -766,6 +769,7 @@ CAMERA:
Range: 10 Range: 10
ProximityCaptor: ProximityCaptor:
Types:Camera Types:Camera
BodyOrientation:
FLARE: FLARE:
Aircraft: Aircraft:
@@ -780,6 +784,7 @@ FLARE:
Name: Flare Name: Flare
ProximityCaptor: ProximityCaptor:
Types: Flare Types: Flare
BodyOrientation:
powerproxy.parabombs: powerproxy.parabombs:
AirstrikePower: AirstrikePower:
@@ -805,7 +810,9 @@ powerproxy.sonarpulse:
mpspawn: mpspawn:
Waypoint: Waypoint:
RenderEditorOnly: RenderEditorOnly:
BodyOrientation:
waypoint: waypoint:
Waypoint: Waypoint:
RenderEditorOnly: RenderEditorOnly:
BodyOrientation: