public Vector2[] getTransformedPoints() { var pts = new Vector2[points.Length]; var mat = getCombinedMatrix(); Vector2Ext.transform(points, ref mat, pts); return(pts); }
public Vector2[] getTransformedPoints() { var pts = new Vector2[] { start, end }; var mat = getCombinedMatrix(); Vector2Ext.transform(pts, ref mat, pts); return(pts); }
/// <summary> /// gets the points that make up the path with any transforms present applied. The points can be used to approximate the path by /// drawing lines between them. /// /// Important notes: ISvgPathBuilder is a faux interface that is required because PCLs cannot access System.Drawing which is used /// to get the drawing points. In order to use this method you need to put the SvgPathBuilder in your main project and then pass in /// an SvgPathBuilder object to this method. /// </summary> /// <returns>The transformed drawing points.</returns> /// <param name="pathBuilder">Path builder.</param> /// <param name="flatness">Flatness.</param> public Vector2[] getTransformedDrawingPoints(ISvgPathBuilder pathBuilder, float flatness = 3) { var pts = pathBuilder.getDrawingPoints(segments, flatness); var mat = getCombinedMatrix(); Vector2Ext.transform(pts, ref mat, pts); return(pts); }
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> /// gets optimized drawing points with extra points in curves and less in straight lines with any transforms present applied /// </summary> /// <returns>The optimized drawing points.</returns> /// <param name="distanceTolerance">Distance tolerance.</param> public Vector2[] getOptimizedTransformedDrawingPoints(float distanceTolerance = 2f) { var pointList = getOptimizedDrawingPoints(distanceTolerance); var points = pointList.ToArray(); ListPool <Vector2> .free(pointList); var mat = getCombinedMatrix(); Vector2Ext.transform(points, ref mat, points); return(points); }
/// <summary> /// gets the points for the rectangle with all transforms applied /// </summary> /// <returns>The transformed points.</returns> public Vector2[] getTransformedPoints() { var pts = new Vector2[] { new Vector2(x, y), new Vector2(x + width, y), new Vector2(x + width, y + height), new Vector2(x, y + height) }; var mat = getCombinedMatrix(); Vector2Ext.transform(pts, ref mat, pts); return(pts); }
public void update() { Position getMouseTile() { // calculate the selection tilepos var selectionPos = Vector2Ext.transform(Input.mousePosition, entity.scene.camera.inverseTransformMatrix); var relativeSelectionPos = selectionPos - (entity.transform.position + localOffset); var mouseTilePos = new Position((int)relativeSelectionPos.X / TILE_DRAW_SIZE, (int)relativeSelectionPos.Y / TILE_DRAW_SIZE); return(mouseTilePos); } var selectionTilePos = getMouseTile(); if (Input.leftMouseButtonPressed) { // check if there's a selectable item on that tile var therePawn = gameState.pawns.FirstOrDefault(x => x.pos.equalTo(selectionTilePos)); if (therePawn != null) { if (therePawn.lastMove < gameState.time) { selectedThing = therePawn; } } } if (Input.rightMouseButtonPressed) { // check if we had a selection and apply it if (selectedThing != null) { if (selectedThing is PawnRef pawn) { // TODO: queue sending move message pawnMove?.Invoke(pawn, selectionTilePos); pawn.lastMove = gameState.time; selectedThing = null; // deselect } } } }
private void hitMelee() { // perform a melee hit var meleeWeapon = entity.getComponent <MeleeWeapon>(); var dir = lastFacing == Direction.Right ? 1 : -1; var facingFlipScale = new Vector2(dir, 1); var offset = meleeWeapon.offset; offset = Vector2Ext.transform(offset, Matrix2D.createScale(facingFlipScale)); var reach = meleeWeapon.reach; // reflect X based on direction RectangleExt.scale(ref reach, facingFlipScale); // var swordCollider = new BoxCollider(offset.X + reach.X, // offset.Y + reach.Y, reach.Width, reach.Height); var swordCollider = new BoxCollider(0, 0, reach.Width, reach.Height); swordCollider.localOffset = new Vector2(offset.X + reach.X + reach.Width / 2f, offset.Y + reach.Y + reach.Height / 2f); entity.addComponent(swordCollider); collisionResults.Clear(); swordCollider.collidesWithAnyMultiple(Vector2.Zero, collisionResults); for (var i = 0; i < collisionResults.Count; i++) { var result = collisionResults[i]; var character = result.collider?.entity.getComponent <Character>(); if (character != null) { hurtCharacter(character); } } entity.removeComponent(swordCollider); }
/// <summary> /// old SpriteBatch drawing method. This should probably be removed since SpriteBatch was replaced by Batcher /// </summary> /// <param name="spriteBatch">Sprite batch.</param> /// <param name="text">Text.</param> /// <param name="position">Position.</param> /// <param name="color">Color.</param> /// <param name="rotation">Rotation.</param> /// <param name="origin">Origin.</param> /// <param name="scale">Scale.</param> /// <param name="effect">Effect.</param> /// <param name="depth">Depth.</param> internal void drawInto( SpriteBatch spriteBatch, 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) { Vector2 size; measureString(ref text, out size); 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 != Vector2.One; 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); } BitmapFontRegion currentFontRegion = 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; currentFontRegion = null; continue; } if (currentFontRegion != null) { offset.X += spacing + currentFontRegion.xAdvance; } if (!_characterMap.TryGetValue(c, out currentFontRegion)) { currentFontRegion = defaultCharacterRegion; } var p = offset; if (flippedHorz) { p.X += currentFontRegion.width; } p.X += currentFontRegion.xOffset; if (flippedVert) { p.Y += currentFontRegion.height - lineHeight; } p.Y += currentFontRegion.yOffset; // 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, currentFontRegion.width * scale.X, currentFontRegion.height * scale.Y); spriteBatch.Draw( currentFontRegion.subtexture, destRect, currentFontRegion.subtexture.sourceRect, color, rotation, Vector2.Zero, effect, depth); } }
protected void transformByRotation(ref Vector2 vec) { vec = Vector2Ext.transform(vec, Matrix2D.createRotation(entity.transform.localRotation)); }
protected void transformBySurfaceAngle(ref Vector2 vec) { vec = Vector2Ext.transform(vec, Matrix2D.createRotation(calculateSurfaceAngle())); }
public override void update() { base.update(); var sprite = entity.getComponent <Character>(); var animation = Character.Animations.Idle; // movement-based animation if (Math.Abs(angularVelocity) > 0) { animation = Character.Animations.Ready; } if (movementState == MovementState.Attached) { // attached to a surface // get velocity in the direction of the surface // get the surface vector var surfaceVec = Vector2Ext.transform(attachedSurfaceNormal, Matrix2D.createRotation(Mathf.PI / 2)); // the velocity in the direction of the surface is the projection of the velocity onto the surface var velOnSurface = Vector2.Dot(surfaceVec, velocity); if (Math.Abs(velOnSurface) > Mathf.epsilon) { animation = Character.Animations.Run; } } // body-based animation switch (bodyState) { case BodyState.Hurt: animation = Character.Animations.Hurt1; break; } // action-based animation switch (actionState) { case ActionState.Melee: animation = Character.Animations.Melee1; break; case ActionState.Gun: animation = Character.Animations.Gun1; break; default: // attack animations should never be flipped partway through // facing direction sprite.facing = lastFacing; break; } if (!sprite.animation.isAnimationPlaying(animation)) { sprite.animation.play(animation); } }
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.character); 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; } }