예제 #1
0
        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;
        }
예제 #2
0
파일: Group.cs 프로젝트: Paramecium13/Nez
        /// <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);
        }
예제 #3
0
        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;
            }
        }