Created
April 28, 2017 11:45
-
-
Save johngirvin/269ddc440aa1c95559d2e4d0ad4b8fea to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using Microsoft.Xna.Framework; | |
using Microsoft.Xna.Framework.Graphics; | |
using MonoGame.Extended.Entities; | |
using Niv.ECS.Components; | |
using static Niv.Debug.Log; | |
namespace Niv.ECS.Systems | |
{ | |
[Aspect(AspectType.All, typeof(Transform), typeof(Sprite))] | |
[EntitySystem(GameLoopType.Draw, Layer = 0)] | |
public class SpriteRenderSystem : EntityProcessingSystem | |
{ | |
private SpriteBatch spriteBatch; | |
public override void Initialize() | |
{ | |
spriteBatch = NivGame.Service<SpriteBatch>(); | |
} | |
private Matrix LocalTransform(TransformComponent2D t) | |
{ | |
return | |
Matrix.CreateScale(t.Scale.X, t.Scale.Y, 1f) * | |
Matrix.CreateRotationZ(t.Rotation) * | |
Matrix.CreateTranslation(t.Position.X, t.Position.Y, 0f); | |
} | |
private void DecomposeMatrix(ref Matrix matrix, out Vector2 position, out float rotation, out Vector2 scale) | |
{ | |
Vector3 position3, scale3; | |
Quaternion rotationQ; | |
matrix.Decompose(out scale3, out rotationQ, out position3); | |
Vector2 direction = Vector2.Transform(Vector2.UnitX, rotationQ); | |
rotation = (float) Math.Atan2(direction.Y, direction.X); | |
position = new Vector2(position3.X, position3.Y); | |
scale = new Vector2(scale3.X, scale3.Y); | |
} | |
private List<TransformComponent2D> hierarchy = new List<TransformComponent2D>(); | |
protected override void Process(GameTime gameTime, Entity entity) | |
{ | |
// reference components | |
var sprite = entity.Get<Sprite>(); | |
if (!sprite.visible || sprite.alpha < 0.01f) { return; } | |
var transform = entity.Get<Transform>(); | |
// recalculate global transform from entity transform hierarcy | |
// https://gamedev.stackexchange.com/questions/23034/is-there-a-simple-way-to-group-two-or-more-sprites-so-all-of-them-will-be-depen | |
hierarchy.Clear(); | |
var curr = (TransformComponent2D) entity.Get<Transform>(); | |
do { | |
hierarchy.Add(curr); | |
curr = curr.Parent; | |
} while (curr != null); | |
hierarchy.Reverse(); | |
var globalTransform = Matrix.Identity; | |
foreach (TransformComponent2D tc in hierarchy) { | |
globalTransform = LocalTransform(tc) * globalTransform; | |
} | |
Vector2 gposition; float grotation; Vector2 gscale; | |
DecomposeMatrix(ref globalTransform, out gposition, out grotation, out gscale); | |
// compare and contrast | |
// gposition drifts away from transform.WorldPosition if transform has a parent | |
DLOG("P {0} {1} {2}", entity.Name, transform.WorldPosition, gposition); | |
spriteBatch.Draw( | |
sprite.frame.Texture, | |
gposition + new Vector2(-64, 0), | |
sprite.frame.Bounds, | |
Color.White * 0.5f, | |
grotation, | |
sprite.originOffset, | |
gscale, | |
sprite.effects, | |
sprite.depth | |
); | |
spriteBatch.Draw( | |
sprite.frame.Texture, | |
transform.WorldPosition + new Vector2(64, 0), | |
sprite.frame.Bounds, | |
Color.Red * 0.5f, | |
transform.WorldRotation, | |
sprite.originOffset, | |
transform.WorldScale, | |
sprite.effects, | |
sprite.depth | |
); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment