internal override void RecalculateBounds(Collider collider) { // if we dont have rotation or dont care about TRS we use localOffset as the center so we'll start with that center = collider.LocalOffset; if (collider.ShouldColliderScaleAndRotateWithTransform) { var hasUnitScale = true; Matrix2D tempMat; var combinedMatrix = Matrix2D.CreateTranslation(-_polygonCenter); if (collider.Entity.Transform.Scale != Vector2.One) { Matrix2D.CreateScale(collider.Entity.Transform.Scale.X, collider.Entity.Transform.Scale.Y, out tempMat); Matrix2D.Multiply(ref combinedMatrix, ref tempMat, out combinedMatrix); hasUnitScale = false; // scale our offset and set it as center. If we have rotation also it will be reset below var scaledOffset = collider.LocalOffset * collider.Entity.Transform.Scale; center = scaledOffset; } if (collider.Entity.Transform.Rotation != 0) { Matrix2D.CreateRotation(collider.Entity.Transform.Rotation, out tempMat); Matrix2D.Multiply(ref combinedMatrix, ref tempMat, out combinedMatrix); // to deal with rotation with an offset origin we just move our center in a circle around 0,0 with our offset making the 0 angle // we have to deal with scale here as well so we scale our offset to get the proper length first. var offsetAngle = Mathf.Atan2(collider.LocalOffset.Y, collider.LocalOffset.X) * Mathf.Rad2Deg; var offsetLength = hasUnitScale ? collider._localOffsetLength : (collider.LocalOffset * collider.Entity.Transform.Scale).Length(); center = Mathf.PointOnCircle(Vector2.Zero, offsetLength, collider.Entity.Transform.RotationDegrees + offsetAngle); } Matrix2D.CreateTranslation(ref _polygonCenter, out tempMat); // translate back center Matrix2D.Multiply(ref combinedMatrix, ref tempMat, out combinedMatrix); // finaly transform our original points Vector2Ext.Transform(_originalPoints, ref combinedMatrix, Points); IsUnrotated = collider.Entity.Transform.Rotation == 0; // we only need to rebuild our edge normals if we rotated if (collider._isRotationDirty) { _areEdgeNormalsDirty = true; } } position = collider.Entity.Transform.Position + center; bounds = RectangleF.RectEncompassingPoints(Points); bounds.Location += position; }
/// <summary> /// Returns the transform for this group's coordinate system /// </summary> /// <returns>The transform.</returns> protected Matrix2D ComputeTransform() { var mat = Matrix2D.Identity; if (originX != 0 || originY != 0) { mat = Matrix2D.Multiply(mat, Matrix2D.CreateTranslation(-originX, -originY)); } if (rotation != 0) { mat = Matrix2D.Multiply(mat, Matrix2D.CreateRotation(MathHelper.ToRadians(rotation))); } if (scaleX != 1 || scaleY != 1) { mat = Matrix2D.Multiply(mat, Matrix2D.CreateScale(scaleX, scaleY)); } mat = Matrix2D.Multiply(mat, Matrix2D.CreateTranslation(x + originX, y + originY)); // Find the first parent that transforms Group parentGroup = parent; while (parentGroup != null) { if (parentGroup.transform) { break; } parentGroup = parentGroup.parent; } if (parentGroup != null) { mat = Matrix2D.Multiply(mat, parentGroup.ComputeTransform()); } return(mat); }
public void DrawInto(Batcher batcher, ref FontCharacterSource text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects effect, float depth) { var flipAdjustment = Vector2.Zero; var flippedVert = (effect & SpriteEffects.FlipVertically) == SpriteEffects.FlipVertically; var flippedHorz = (effect & SpriteEffects.FlipHorizontally) == SpriteEffects.FlipHorizontally; if (flippedVert || flippedHorz) { var size = MeasureString(ref text); if (flippedHorz) { origin.X *= -1; flipAdjustment.X = -size.X; } if (flippedVert) { origin.Y *= -1; flipAdjustment.Y = LineHeight - size.Y; } } var requiresTransformation = flippedHorz || flippedVert || rotation != 0f || scale != new Vector2(1); if (requiresTransformation) { Matrix2D temp; Matrix2D.CreateTranslation(-origin.X, -origin.Y, out _transformationMatrix); Matrix2D.CreateScale((flippedHorz ? -scale.X : scale.X), (flippedVert ? -scale.Y : scale.Y), out temp); Matrix2D.Multiply(ref _transformationMatrix, ref temp, out _transformationMatrix); Matrix2D.CreateTranslation(flipAdjustment.X, flipAdjustment.Y, out temp); Matrix2D.Multiply(ref temp, ref _transformationMatrix, out _transformationMatrix); Matrix2D.CreateRotation(rotation, out temp); Matrix2D.Multiply(ref _transformationMatrix, ref temp, out _transformationMatrix); Matrix2D.CreateTranslation(position.X, position.Y, out temp); Matrix2D.Multiply(ref _transformationMatrix, ref temp, out _transformationMatrix); } var previousCharacter = ' '; Character currentChar = null; var offset = requiresTransformation ? Vector2.Zero : position - origin; for (var i = 0; i < text.Length; ++i) { var c = text[i]; if (c == '\r') { continue; } if (c == '\n') { offset.X = requiresTransformation ? 0f : position.X - origin.X; offset.Y += LineHeight; currentChar = null; continue; } if (currentChar != null) { offset.X += Spacing.X + currentChar.XAdvance; } currentChar = ContainsCharacter(c) ? this[c] : DefaultCharacter; var p = offset; if (flippedHorz) { p.X += currentChar.Bounds.Width; } p.X += currentChar.Offset.X + GetKerning(previousCharacter, currentChar.Char); if (flippedVert) { p.Y += currentChar.Bounds.Height - LineHeight; } p.Y += currentChar.Offset.Y; // transform our point if we need to if (requiresTransformation) { Vector2Ext.Transform(ref p, ref _transformationMatrix, out p); } var destRect = RectangleExt.FromFloats ( p.X, p.Y, currentChar.Bounds.Width * scale.X, currentChar.Bounds.Height * scale.Y ); batcher.Draw(Textures[currentChar.TexturePage], destRect, currentChar.Bounds, color, rotation, Vector2.Zero, effect, depth); previousCharacter = c; } }