Skip to content

Instantly share code, notes, and snippets.

@johngirvin
Created April 28, 2017 11:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save johngirvin/269ddc440aa1c95559d2e4d0ad4b8fea to your computer and use it in GitHub Desktop.
Save johngirvin/269ddc440aa1c95559d2e4d0ad4b8fea to your computer and use it in GitHub Desktop.
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