mirror of
https://github.com/Ellpeck/MLEM.git
synced 2024-11-24 21:48:35 +01:00
Compare commits
7 commits
b30ec9408b
...
a6c06ad980
Author | SHA1 | Date | |
---|---|---|---|
a6c06ad980 | |||
444b5c6afb | |||
84a6e5a29a | |||
c9c9e566b1 | |||
84e2544dc8 | |||
5b99f29490 | |||
5c8ef3d254 |
41 changed files with 361 additions and 113 deletions
|
@ -13,12 +13,17 @@ Additions
|
|||
- Added GenericFont SplitStringSeparate which differentiates between existing newline characters and splits due to maximum width
|
||||
- Added StaticSpriteBatch class
|
||||
- Added missing easing functions Quart and Quint to Easings
|
||||
- Added RotationVector extension methods for Matrix and Quaternion
|
||||
|
||||
Improvements
|
||||
- Cache TokenizedString inner offsets for non-Left text alignments to improve performance
|
||||
- Exposed Camera's RoundPosition
|
||||
- Exposed the epsilon value used by Camera
|
||||
- Added Padding.Empty
|
||||
- Throw an exception when text formatter macros resolve recursively too many times
|
||||
|
||||
Fixes
|
||||
- Fixed some end-of-line inconsistencies when using the Right text alignment
|
||||
|
||||
### MLEM.Ui
|
||||
Additions
|
||||
|
@ -28,6 +33,7 @@ Additions
|
|||
Improvements
|
||||
- *Made Image ScaleToImage take ui scale into account*
|
||||
- *Added style properties for a lot of hardcoded default element styles*
|
||||
- *Allow setting a custom effect and depth stencil state for ui drawing*
|
||||
- Exposed the epsilon value used by Element calculations
|
||||
- Allow style properties to set style values with a higher priority, which allows elements to style their default children
|
||||
- Allow changing the entire ui style for a single element
|
||||
|
@ -39,6 +45,7 @@ Fixes
|
|||
- Fixed VerticalSpace height parameter being an integer
|
||||
- Fixed text not being pasted into a text field at all if it contains characters that don't match the input rule
|
||||
- Fixed panels that don't auto-hide their scroll bars ignoring their width for child padding
|
||||
- Fixed some inconsistencies with element transformations and mouse interaction
|
||||
|
||||
Removals
|
||||
- *Removed ScrollBar ScrollerOffset*
|
||||
|
|
|
@ -44,7 +44,12 @@ namespace MLEM.Data.Content {
|
|||
return this.Read<T>(assetName, default);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
/// <summary>
|
||||
/// Reloads the asset of the given type, with the given original name.
|
||||
/// </summary>
|
||||
/// <param name="originalAssetName">The original name of the asset.</param>
|
||||
/// <param name="currentAsset">The current asset instance.</param>
|
||||
/// <typeparam name="T">The asset's type.</typeparam>
|
||||
protected override void ReloadAsset<T>(string originalAssetName, T currentAsset) {
|
||||
this.Read(originalAssetName, currentAsset);
|
||||
}
|
||||
|
@ -78,7 +83,9 @@ namespace MLEM.Data.Content {
|
|||
throw new ContentLoadException($"Asset {assetName} not found. Tried files {string.Join(", ", triedFiles)}");
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
/// <summary>
|
||||
/// Unloads this content manager, disposing all of the assets that it loaded.
|
||||
/// </summary>
|
||||
public override void Unload() {
|
||||
foreach (var d in this.disposableAssets)
|
||||
d.Dispose();
|
||||
|
@ -86,7 +93,9 @@ namespace MLEM.Data.Content {
|
|||
base.Unload();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
/// <summary>
|
||||
/// Initializes the component. Used to load non-graphical resources.
|
||||
/// </summary>
|
||||
public void Initialize() {
|
||||
}
|
||||
|
||||
|
|
|
@ -82,7 +82,8 @@ namespace MLEM.Data {
|
|||
return ret;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Returns a string that represents the current object.</summary>
|
||||
/// <returns>A string that represents the current object.</returns>
|
||||
public override string ToString() {
|
||||
if (this.name == null) {
|
||||
var included = new List<DynamicEnum>();
|
||||
|
|
|
@ -3,15 +3,26 @@ using MLEM.Misc;
|
|||
using Newtonsoft.Json;
|
||||
|
||||
namespace MLEM.Data.Json {
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Converts a <see cref="Direction2"/> to and from JSON
|
||||
/// </summary>
|
||||
public class Direction2Converter : JsonConverter<Direction2> {
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Writes the JSON representation of the object.</summary>
|
||||
/// <param name="writer">The <see cref="T:Newtonsoft.Json.JsonWriter" /> to write to.</param>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <param name="serializer">The calling serializer.</param>
|
||||
public override void WriteJson(JsonWriter writer, Direction2 value, JsonSerializer serializer) {
|
||||
writer.WriteValue(value.ToString());
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Reads the JSON representation of the object.</summary>
|
||||
/// <param name="reader">The <see cref="T:Newtonsoft.Json.JsonReader" /> to read from.</param>
|
||||
/// <param name="objectType">Type of the object.</param>
|
||||
/// <param name="existingValue">The existing value of object being read. If there is no existing value then <c>null</c> will be used.</param>
|
||||
/// <param name="hasExistingValue">The existing value has a value.</param>
|
||||
/// <param name="serializer">The calling serializer.</param>
|
||||
/// <returns>The object value.</returns>
|
||||
public override Direction2 ReadJson(JsonReader reader, Type objectType, Direction2 existingValue, bool hasExistingValue, JsonSerializer serializer) {
|
||||
Enum.TryParse<Direction2>(reader.Value.ToString(), out var dir);
|
||||
return dir;
|
||||
|
|
|
@ -2,15 +2,26 @@ using System;
|
|||
using Newtonsoft.Json;
|
||||
|
||||
namespace MLEM.Data.Json {
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Converts a <see cref="DynamicEnum"/> to and from JSON
|
||||
/// </summary>
|
||||
public class DynamicEnumConverter : JsonConverter<DynamicEnum> {
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Writes the JSON representation of the object.</summary>
|
||||
/// <param name="writer">The <see cref="T:Newtonsoft.Json.JsonWriter" /> to write to.</param>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <param name="serializer">The calling serializer.</param>
|
||||
public override void WriteJson(JsonWriter writer, DynamicEnum value, JsonSerializer serializer) {
|
||||
writer.WriteValue(value.ToString());
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Reads the JSON representation of the object.</summary>
|
||||
/// <param name="reader">The <see cref="T:Newtonsoft.Json.JsonReader" /> to read from.</param>
|
||||
/// <param name="objectType">Type of the object.</param>
|
||||
/// <param name="existingValue">The existing value of object being read. If there is no existing value then <c>null</c> will be used.</param>
|
||||
/// <param name="hasExistingValue">The existing value has a value.</param>
|
||||
/// <param name="serializer">The calling serializer.</param>
|
||||
/// <returns>The object value.</returns>
|
||||
public override DynamicEnum ReadJson(JsonReader reader, Type objectType, DynamicEnum existingValue, bool hasExistingValue, JsonSerializer serializer) {
|
||||
return DynamicEnum.Parse(objectType, reader.Value.ToString());
|
||||
}
|
||||
|
|
|
@ -4,15 +4,26 @@ using Microsoft.Xna.Framework;
|
|||
using Newtonsoft.Json;
|
||||
|
||||
namespace MLEM.Data.Json {
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Converts a <see cref="Point"/> to and from JSON
|
||||
/// </summary>
|
||||
public class PointConverter : JsonConverter<Point> {
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Writes the JSON representation of the object.</summary>
|
||||
/// <param name="writer">The <see cref="T:Newtonsoft.Json.JsonWriter" /> to write to.</param>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <param name="serializer">The calling serializer.</param>
|
||||
public override void WriteJson(JsonWriter writer, Point value, JsonSerializer serializer) {
|
||||
writer.WriteValue(value.X.ToString(CultureInfo.InvariantCulture) + " " + value.Y.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Reads the JSON representation of the object.</summary>
|
||||
/// <param name="reader">The <see cref="T:Newtonsoft.Json.JsonReader" /> to read from.</param>
|
||||
/// <param name="objectType">Type of the object.</param>
|
||||
/// <param name="existingValue">The existing value of object being read. If there is no existing value then <c>null</c> will be used.</param>
|
||||
/// <param name="hasExistingValue">The existing value has a value.</param>
|
||||
/// <param name="serializer">The calling serializer.</param>
|
||||
/// <returns>The object value.</returns>
|
||||
public override Point ReadJson(JsonReader reader, Type objectType, Point existingValue, bool hasExistingValue, JsonSerializer serializer) {
|
||||
var value = reader.Value.ToString().Split(' ');
|
||||
return new Point(int.Parse(value[0], CultureInfo.InvariantCulture), int.Parse(value[1], CultureInfo.InvariantCulture));
|
||||
|
|
|
@ -4,17 +4,28 @@ using Microsoft.Xna.Framework;
|
|||
using Newtonsoft.Json;
|
||||
|
||||
namespace MLEM.Data.Json {
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Converts a <see cref="Rectangle"/> to and from JSON
|
||||
/// </summary>
|
||||
public class RectangleConverter : JsonConverter<Rectangle> {
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Writes the JSON representation of the object.</summary>
|
||||
/// <param name="writer">The <see cref="T:Newtonsoft.Json.JsonWriter" /> to write to.</param>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <param name="serializer">The calling serializer.</param>
|
||||
public override void WriteJson(JsonWriter writer, Rectangle value, JsonSerializer serializer) {
|
||||
writer.WriteValue(
|
||||
value.X.ToString(CultureInfo.InvariantCulture) + " " + value.Y.ToString(CultureInfo.InvariantCulture) + " " +
|
||||
value.Width.ToString(CultureInfo.InvariantCulture) + " " + value.Height.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Reads the JSON representation of the object.</summary>
|
||||
/// <param name="reader">The <see cref="T:Newtonsoft.Json.JsonReader" /> to read from.</param>
|
||||
/// <param name="objectType">Type of the object.</param>
|
||||
/// <param name="existingValue">The existing value of object being read. If there is no existing value then <c>null</c> will be used.</param>
|
||||
/// <param name="hasExistingValue">The existing value has a value.</param>
|
||||
/// <param name="serializer">The calling serializer.</param>
|
||||
/// <returns>The object value.</returns>
|
||||
public override Rectangle ReadJson(JsonReader reader, Type objectType, Rectangle existingValue, bool hasExistingValue, JsonSerializer serializer) {
|
||||
var value = reader.Value.ToString().Split(' ');
|
||||
return new Rectangle(
|
||||
|
|
|
@ -4,17 +4,28 @@ using MLEM.Misc;
|
|||
using Newtonsoft.Json;
|
||||
|
||||
namespace MLEM.Data.Json {
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Converts a <see cref="RectangleF"/> to and from JSON
|
||||
/// </summary>
|
||||
public class RectangleFConverter : JsonConverter<RectangleF> {
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Writes the JSON representation of the object.</summary>
|
||||
/// <param name="writer">The <see cref="T:Newtonsoft.Json.JsonWriter" /> to write to.</param>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <param name="serializer">The calling serializer.</param>
|
||||
public override void WriteJson(JsonWriter writer, RectangleF value, JsonSerializer serializer) {
|
||||
writer.WriteValue(
|
||||
value.X.ToString(CultureInfo.InvariantCulture) + " " + value.Y.ToString(CultureInfo.InvariantCulture) + " " +
|
||||
value.Width.ToString(CultureInfo.InvariantCulture) + " " + value.Height.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Reads the JSON representation of the object.</summary>
|
||||
/// <param name="reader">The <see cref="T:Newtonsoft.Json.JsonReader" /> to read from.</param>
|
||||
/// <param name="objectType">Type of the object.</param>
|
||||
/// <param name="existingValue">The existing value of object being read. If there is no existing value then <c>null</c> will be used.</param>
|
||||
/// <param name="hasExistingValue">The existing value has a value.</param>
|
||||
/// <param name="serializer">The calling serializer.</param>
|
||||
/// <returns>The object value.</returns>
|
||||
public override RectangleF ReadJson(JsonReader reader, Type objectType, RectangleF existingValue, bool hasExistingValue, JsonSerializer serializer) {
|
||||
var value = reader.Value.ToString().Split(' ');
|
||||
return new RectangleF(
|
||||
|
|
|
@ -33,14 +33,23 @@ namespace MLEM.Data.Json {
|
|||
this(GetEntries(type, memberName)) {
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Writes the JSON representation of the object.</summary>
|
||||
/// <param name="writer">The <see cref="T:Newtonsoft.Json.JsonWriter" /> to write to.</param>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <param name="serializer">The calling serializer.</param>
|
||||
public override void WriteJson(JsonWriter writer, T value, JsonSerializer serializer) {
|
||||
if (!this.inverse.TryGetValue(value, out var key))
|
||||
throw new InvalidOperationException($"Cannot write {value} that is not a registered entry");
|
||||
writer.WriteValue(key);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Reads the JSON representation of the object.</summary>
|
||||
/// <param name="reader">The <see cref="T:Newtonsoft.Json.JsonReader" /> to read from.</param>
|
||||
/// <param name="objectType">Type of the object.</param>
|
||||
/// <param name="existingValue">The existing value of object being read. If there is no existing value then <c>null</c> will be used.</param>
|
||||
/// <param name="hasExistingValue">The existing value has a value.</param>
|
||||
/// <param name="serializer">The calling serializer.</param>
|
||||
/// <returns>The object value.</returns>
|
||||
public override T ReadJson(JsonReader reader, Type objectType, T existingValue, bool hasExistingValue, JsonSerializer serializer) {
|
||||
var val = reader.Value?.ToString();
|
||||
if (val == null)
|
||||
|
|
|
@ -4,15 +4,26 @@ using Microsoft.Xna.Framework;
|
|||
using Newtonsoft.Json;
|
||||
|
||||
namespace MLEM.Data.Json {
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Converts a <see cref="Vector2"/> to and from JSON
|
||||
/// </summary>
|
||||
public class Vector2Converter : JsonConverter<Vector2> {
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Writes the JSON representation of the object.</summary>
|
||||
/// <param name="writer">The <see cref="T:Newtonsoft.Json.JsonWriter" /> to write to.</param>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <param name="serializer">The calling serializer.</param>
|
||||
public override void WriteJson(JsonWriter writer, Vector2 value, JsonSerializer serializer) {
|
||||
writer.WriteValue(value.X.ToString(CultureInfo.InvariantCulture) + " " + value.Y.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Reads the JSON representation of the object.</summary>
|
||||
/// <param name="reader">The <see cref="T:Newtonsoft.Json.JsonReader" /> to read from.</param>
|
||||
/// <param name="objectType">Type of the object.</param>
|
||||
/// <param name="existingValue">The existing value of object being read. If there is no existing value then <c>null</c> will be used.</param>
|
||||
/// <param name="hasExistingValue">The existing value has a value.</param>
|
||||
/// <param name="serializer">The calling serializer.</param>
|
||||
/// <returns>The object value.</returns>
|
||||
public override Vector2 ReadJson(JsonReader reader, Type objectType, Vector2 existingValue, bool hasExistingValue, JsonSerializer serializer) {
|
||||
var value = reader.Value.ToString().Split(' ');
|
||||
return new Vector2(float.Parse(value[0], CultureInfo.InvariantCulture), float.Parse(value[1], CultureInfo.InvariantCulture));
|
||||
|
|
|
@ -148,7 +148,7 @@ namespace MLEM.Data {
|
|||
this.LastPackTime = TimeSpan.Zero;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary>
|
||||
public void Dispose() {
|
||||
this.Reset();
|
||||
}
|
||||
|
|
|
@ -26,7 +26,16 @@ namespace MLEM.Extended.Extensions {
|
|||
return new Misc.RectangleF(rect.X, rect.Y, rect.Width, rect.Height);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="MLEM.Extensions.NumberExtensions.Penetrate"/>
|
||||
/// <summary>
|
||||
/// Calculates the amount that the rectangle <paramref name="rect"/> is penetrating the rectangle <paramref name="other"/> by.
|
||||
/// If a penetration on both axes is occuring, the one with the lower value is returned.
|
||||
/// This is useful for collision detection, as it can be used to push colliding objects out of each other.
|
||||
/// </summary>
|
||||
/// <param name="rect">The rectangle to do the penetration</param>
|
||||
/// <param name="other">The rectangle that should be penetrated</param>
|
||||
/// <param name="normal">The direction that the penetration occured in</param>
|
||||
/// <param name="penetration">The amount that the penetration occured by, in the direction of <paramref name="normal"/></param>
|
||||
/// <returns>Whether or not a penetration occured</returns>
|
||||
public static bool Penetrate(this RectangleF rect, RectangleF other, out Vector2 normal, out float penetration) {
|
||||
return rect.ToMlem().Penetrate(other.ToMlem(), out normal, out penetration);
|
||||
}
|
||||
|
|
|
@ -9,17 +9,35 @@ namespace MLEM.Extended.Extensions {
|
|||
/// </summary>
|
||||
public static class SpriteBatchExtensions {
|
||||
|
||||
/// <inheritdoc cref="SpriteBatch.Draw(Texture2D,Rectangle,Rectangle?,Color,float,Vector2,SpriteEffects,float)"/>
|
||||
/// <summary>Submit a sprite for drawing in the current batch.</summary>
|
||||
/// <param name="batch">The sprite batch to draw with.</param>
|
||||
/// <param name="texture">A texture.</param>
|
||||
/// <param name="destinationRectangle">The drawing bounds on screen.</param>
|
||||
/// <param name="sourceRectangle">An optional region on the texture which will be rendered. If null - draws full texture.</param>
|
||||
/// <param name="color">A color mask.</param>
|
||||
/// <param name="rotation">A rotation of this sprite.</param>
|
||||
/// <param name="origin">Center of the rotation. 0,0 by default.</param>
|
||||
/// <param name="effects">Modificators for drawing. Can be combined.</param>
|
||||
/// <param name="layerDepth">A depth of the layer of this sprite.</param>
|
||||
public static void Draw(this SpriteBatch batch, Texture2D texture, RectangleF destinationRectangle, Rectangle? sourceRectangle, Color color, float rotation, Vector2 origin, SpriteEffects effects, float layerDepth) {
|
||||
batch.Draw(texture, destinationRectangle.ToMlem(), sourceRectangle, color, rotation, origin, effects, layerDepth);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="SpriteBatch.Draw(Texture2D,Rectangle,Rectangle?,Color)"/>
|
||||
/// <summary>Submit a sprite for drawing in the current batch.</summary>
|
||||
/// <param name="batch">The sprite batch to draw with.</param>
|
||||
/// <param name="texture">A texture.</param>
|
||||
/// <param name="destinationRectangle">The drawing bounds on screen.</param>
|
||||
/// <param name="sourceRectangle">An optional region on the texture which will be rendered. If null - draws full texture.</param>
|
||||
/// <param name="color">A color mask.</param>
|
||||
public static void Draw(this SpriteBatch batch, Texture2D texture, RectangleF destinationRectangle, Rectangle? sourceRectangle, Color color) {
|
||||
batch.Draw(texture, destinationRectangle, sourceRectangle, color, 0, Vector2.Zero, SpriteEffects.None, 0);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="SpriteBatch.Draw(Texture2D,Rectangle,Color)"/>
|
||||
/// <summary>Submit a sprite for drawing in the current batch.</summary>
|
||||
/// <param name="batch">The sprite batch to draw with.</param>
|
||||
/// <param name="texture">A texture.</param>
|
||||
/// <param name="destinationRectangle">The drawing bounds on screen.</param>
|
||||
/// <param name="color">A color mask.</param>
|
||||
public static void Draw(this SpriteBatch batch, Texture2D texture, RectangleF destinationRectangle, Color color) {
|
||||
batch.Draw(texture, destinationRectangle, null, color);
|
||||
}
|
||||
|
@ -38,6 +56,7 @@ namespace MLEM.Extended.Extensions {
|
|||
for (var x = 0; x < tileCount.X; x++)
|
||||
batch.DrawRectangle(start + new Vector2(x, y) * tileSize, tileSize, gridColor, gridThickness / 2);
|
||||
}
|
||||
|
||||
var size = tileSize * tileCount.ToVector2() + new Vector2(gridThickness);
|
||||
batch.DrawRectangle(start - new Vector2(gridThickness / 2), size, gridColor, gridThickness / 2);
|
||||
}
|
||||
|
|
|
@ -51,12 +51,15 @@ namespace MLEM.Extended.Tiled {
|
|||
return this.Layer == other.Layer && this.X == other.X && this.Y == other.Y;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Indicates whether this instance and a specified object are equal.</summary>
|
||||
/// <param name="obj">The object to compare with the current instance.</param>
|
||||
/// <returns>true if <paramref name="obj">obj</paramref> and this instance are the same type and represent the same value; otherwise, false.</returns>
|
||||
public override bool Equals(object obj) {
|
||||
return obj is LayerPosition other && this.Equals(other);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Returns the hash code for this instance.</summary>
|
||||
/// <returns>A 32-bit signed integer that is the hash code for this instance.</returns>
|
||||
public override int GetHashCode() {
|
||||
var hashCode = this.Layer.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ this.X;
|
||||
|
|
|
@ -91,7 +91,7 @@ namespace MLEM.Ui.Elements {
|
|||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) {
|
||||
public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, Effect effect, Matrix matrix) {
|
||||
var tex = this.Texture;
|
||||
var color = (Color) this.NormalColor * alpha;
|
||||
if (this.IsDisabled) {
|
||||
|
@ -102,7 +102,7 @@ namespace MLEM.Ui.Elements {
|
|||
color = (Color) this.HoveredColor * alpha;
|
||||
}
|
||||
batch.Draw(tex, this.DisplayArea, color, this.Scale);
|
||||
base.Draw(time, batch, alpha, blendState, samplerState, matrix);
|
||||
base.Draw(time, batch, alpha, blendState, samplerState, depthStencilState, effect, matrix);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
|
|
@ -84,7 +84,7 @@ namespace MLEM.Ui.Elements {
|
|||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) {
|
||||
public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, Effect effect, Matrix matrix) {
|
||||
var tex = this.Texture;
|
||||
var color = Color.White * alpha;
|
||||
if (this.IsMouseOver) {
|
||||
|
@ -96,7 +96,7 @@ namespace MLEM.Ui.Elements {
|
|||
batch.Draw(tex, boxDisplayArea, color, this.Scale);
|
||||
if (this.Checked)
|
||||
batch.Draw(this.Checkmark, boxDisplayArea, Color.White * alpha);
|
||||
base.Draw(time, batch, alpha, blendState, samplerState, matrix);
|
||||
base.Draw(time, batch, alpha, blendState, samplerState, depthStencilState, effect, matrix);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
|
|
@ -885,8 +885,10 @@ namespace MLEM.Ui.Elements {
|
|||
/// <param name="alpha">The alpha to draw this element and its children with</param>
|
||||
/// <param name="blendState">The blend state that is used for drawing</param>
|
||||
/// <param name="samplerState">The sampler state that is used for drawing</param>
|
||||
/// <param name="effect">The effect that is used for drawing</param>
|
||||
/// <param name="depthStencilState">The depth stencil state that is used for drawing</param>
|
||||
/// <param name="matrix">The transformation matrix that is used for drawing</param>
|
||||
public void DrawTransformed(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) {
|
||||
public void DrawTransformed(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, Effect effect, Matrix matrix) {
|
||||
var customDraw = this.BeginImpl != null || this.Transform != Matrix.Identity;
|
||||
var mat = this.Transform * matrix;
|
||||
if (customDraw) {
|
||||
|
@ -894,18 +896,18 @@ namespace MLEM.Ui.Elements {
|
|||
batch.End();
|
||||
// begin our own draw call
|
||||
if (this.BeginImpl != null) {
|
||||
this.BeginImpl(this, time, batch, alpha, blendState, samplerState, mat);
|
||||
this.BeginImpl(this, time, batch, alpha, blendState, samplerState, depthStencilState, effect, mat);
|
||||
} else {
|
||||
batch.Begin(SpriteSortMode.Deferred, blendState, samplerState, null, null, null, mat);
|
||||
batch.Begin(SpriteSortMode.Deferred, blendState, samplerState, depthStencilState, null, effect, mat);
|
||||
}
|
||||
}
|
||||
// draw content in custom begin call
|
||||
this.Draw(time, batch, alpha, blendState, samplerState, mat);
|
||||
this.Draw(time, batch, alpha, blendState, samplerState, depthStencilState, effect, mat);
|
||||
if (customDraw) {
|
||||
// end our draw
|
||||
batch.End();
|
||||
// begin the usual draw again for other elements
|
||||
batch.Begin(SpriteSortMode.Deferred, blendState, samplerState, null, null, null, matrix);
|
||||
batch.Begin(SpriteSortMode.Deferred, blendState, samplerState, depthStencilState, null, effect, matrix);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -918,15 +920,17 @@ namespace MLEM.Ui.Elements {
|
|||
/// <param name="alpha">The alpha to draw this element and its children with</param>
|
||||
/// <param name="blendState">The blend state that is used for drawing</param>
|
||||
/// <param name="samplerState">The sampler state that is used for drawing</param>
|
||||
/// <param name="effect">The effect that is used for drawing</param>
|
||||
/// <param name="depthStencilState">The depth stencil state that is used for drawing</param>
|
||||
/// <param name="matrix">The transformation matrix that is used for drawing</param>
|
||||
public virtual void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) {
|
||||
public virtual void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, Effect effect, Matrix matrix) {
|
||||
this.System.InvokeOnElementDrawn(this, time, batch, alpha);
|
||||
if (this.IsSelected)
|
||||
this.System.InvokeOnSelectedElementDrawn(this, time, batch, alpha);
|
||||
|
||||
foreach (var child in this.GetRelevantChildren()) {
|
||||
if (!child.IsHidden)
|
||||
child.DrawTransformed(time, batch, alpha * child.DrawAlpha, blendState, samplerState, matrix);
|
||||
child.DrawTransformed(time, batch, alpha * child.DrawAlpha, blendState, samplerState, depthStencilState, effect, matrix);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -940,11 +944,13 @@ namespace MLEM.Ui.Elements {
|
|||
/// <param name="alpha">The alpha to draw this element and its children with</param>
|
||||
/// <param name="blendState">The blend state that is used for drawing</param>
|
||||
/// <param name="samplerState">The sampler state that is used for drawing</param>
|
||||
/// <param name="effect">The effect that is used for drawing</param>
|
||||
/// <param name="depthStencilState">The depth stencil state that is used for drawing</param>
|
||||
/// <param name="matrix">The transformation matrix that is used for drawing</param>
|
||||
public virtual void DrawEarly(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) {
|
||||
public virtual void DrawEarly(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, Effect effect, Matrix matrix) {
|
||||
foreach (var child in this.GetRelevantChildren()) {
|
||||
if (!child.IsHidden)
|
||||
child.DrawEarly(time, batch, alpha * child.DrawAlpha, blendState, samplerState, matrix);
|
||||
child.DrawEarly(time, batch, alpha * child.DrawAlpha, blendState, samplerState, depthStencilState, effect, matrix);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -956,8 +962,7 @@ namespace MLEM.Ui.Elements {
|
|||
public virtual Element GetElementUnderPos(Vector2 position) {
|
||||
if (this.IsHidden)
|
||||
return null;
|
||||
if (this.Transform != Matrix.Identity)
|
||||
position = Vector2.Transform(position, Matrix.Invert(this.Transform));
|
||||
position = this.TransformInverse(position);
|
||||
var relevant = this.GetRelevantChildren();
|
||||
for (var i = relevant.Count - 1; i >= 0; i--) {
|
||||
var element = relevant[i].GetElementUnderPos(position);
|
||||
|
@ -1019,6 +1024,28 @@ namespace MLEM.Ui.Elements {
|
|||
this.SecondActionSound.SetFromStyle(style.ActionSound);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transforms the given <paramref name="position"/> by the inverse of this element's <see cref="Transform"/> matrix.
|
||||
/// </summary>
|
||||
/// <param name="position">The position to transform</param>
|
||||
/// <returns>The transformed position</returns>
|
||||
protected Vector2 TransformInverse(Vector2 position) {
|
||||
return this.Transform != Matrix.Identity ? Vector2.Transform(position, Matrix.Invert(this.Transform)) : position;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transforms the given <paramref name="position"/> by this element's <see cref="Root"/>'s <see cref="RootElement.InvTransform"/>, the inverses of all of the <see cref="Transform"/> matrices of this element's parent tree (<see cref="GetParentTree"/>), and the inverse of this element's <see cref="Transform"/> matrix.
|
||||
/// Note that, when using <see cref="UiControls.GetElementUnderPos"/>, this operation is done recursively, which is more efficient.
|
||||
/// </summary>
|
||||
/// <param name="position">The position to transform</param>
|
||||
/// <returns>The transformed position</returns>
|
||||
protected Vector2 TransformInverseAll(Vector2 position) {
|
||||
position = Vector2.Transform(position, this.Root.InvTransform);
|
||||
foreach (var parent in this.GetParentTree().Reverse())
|
||||
position = parent.TransformInverse(position);
|
||||
return this.TransformInverse(position);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A delegate used for the <see cref="Element.OnTextInput"/> event.
|
||||
/// </summary>
|
||||
|
@ -1079,8 +1106,10 @@ namespace MLEM.Ui.Elements {
|
|||
/// <param name="alpha">This element's draw alpha</param>
|
||||
/// <param name="blendState">The blend state used for drawing</param>
|
||||
/// <param name="samplerState">The sampler state used for drawing</param>
|
||||
/// <param name="effect">The effect used for drawing</param>
|
||||
/// <param name="depthStencilState">The depth stencil state used for drawing</param>
|
||||
/// <param name="matrix">The transform matrix used for drawing</param>
|
||||
public delegate void BeginDelegate(Element element, GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix);
|
||||
public delegate void BeginDelegate(Element element, GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, Effect effect, Matrix matrix);
|
||||
|
||||
}
|
||||
}
|
|
@ -20,10 +20,10 @@ namespace MLEM.Ui.Elements {
|
|||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) {
|
||||
public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, Effect effect, Matrix matrix) {
|
||||
// since the group never accesses its own area when drawing, we have to update it manually
|
||||
this.UpdateAreaIfDirty();
|
||||
base.Draw(time, batch, alpha, blendState, samplerState, matrix);
|
||||
base.Draw(time, batch, alpha, blendState, samplerState, depthStencilState, effect, matrix);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -103,7 +103,7 @@ namespace MLEM.Ui.Elements {
|
|||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) {
|
||||
public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, Effect effect, Matrix matrix) {
|
||||
if (this.Texture == null)
|
||||
return;
|
||||
var center = new Vector2(this.Texture.Width / 2F, this.Texture.Height / 2F);
|
||||
|
@ -116,7 +116,7 @@ namespace MLEM.Ui.Elements {
|
|||
var scale = new Vector2(1F / this.Texture.Width, 1F / this.Texture.Height) * this.DisplayArea.Size;
|
||||
batch.Draw(this.Texture, this.DisplayArea.Location + center * scale, color, this.ImageRotation, center, scale * this.ImageScale, this.ImageEffects, 0);
|
||||
}
|
||||
base.Draw(time, batch, alpha, blendState, samplerState, matrix);
|
||||
base.Draw(time, batch, alpha, blendState, samplerState, depthStencilState, effect, matrix);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -155,12 +155,12 @@ namespace MLEM.Ui.Elements {
|
|||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) {
|
||||
public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, Effect effect, Matrix matrix) {
|
||||
if (this.Texture.HasValue())
|
||||
batch.Draw(this.Texture, this.DisplayArea, this.DrawColor.OrDefault(Color.White) * alpha, this.Scale);
|
||||
// if we handle overflow, draw using the render target in DrawUnbound
|
||||
if (!this.scrollOverflow || this.renderTarget == null) {
|
||||
base.Draw(time, batch, alpha, blendState, samplerState, matrix);
|
||||
base.Draw(time, batch, alpha, blendState, samplerState, depthStencilState, effect, matrix);
|
||||
} else {
|
||||
// draw the actual render target (don't apply the alpha here because it's already drawn onto with alpha)
|
||||
batch.Draw(this.renderTarget, this.GetRenderTargetArea(), Color.White);
|
||||
|
@ -168,7 +168,7 @@ namespace MLEM.Ui.Elements {
|
|||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void DrawEarly(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) {
|
||||
public override void DrawEarly(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, Effect effect, Matrix matrix) {
|
||||
this.UpdateAreaIfDirty();
|
||||
if (this.scrollOverflow && this.renderTarget != null) {
|
||||
// draw children onto the render target
|
||||
|
@ -178,19 +178,20 @@ namespace MLEM.Ui.Elements {
|
|||
var area = this.GetRenderTargetArea();
|
||||
var trans = Matrix.CreateTranslation(-area.X, -area.Y, 0);
|
||||
// do the usual draw, but within the render target
|
||||
batch.Begin(SpriteSortMode.Deferred, blendState, samplerState, null, null, null, trans);
|
||||
base.Draw(time, batch, alpha, blendState, samplerState, trans);
|
||||
batch.Begin(SpriteSortMode.Deferred, blendState, samplerState, depthStencilState, null, effect, trans);
|
||||
base.Draw(time, batch, alpha, blendState, samplerState, depthStencilState, effect, trans);
|
||||
batch.End();
|
||||
}
|
||||
}
|
||||
base.DrawEarly(time, batch, alpha, blendState, samplerState, matrix);
|
||||
base.DrawEarly(time, batch, alpha, blendState, samplerState, depthStencilState, effect, matrix);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Element GetElementUnderPos(Vector2 position) {
|
||||
// if overflow is handled, don't propagate mouse checks to hidden children
|
||||
if (this.scrollOverflow && !this.GetRenderTargetArea().Contains(position))
|
||||
return !this.IsHidden && this.CanBeMoused && this.DisplayArea.Contains(position) ? this : null;
|
||||
var transformed = this.TransformInverse(position);
|
||||
if (this.scrollOverflow && !this.GetRenderTargetArea().Contains(transformed))
|
||||
return !this.IsHidden && this.CanBeMoused && this.DisplayArea.Contains(transformed) ? this : null;
|
||||
return base.GetElementUnderPos(position);
|
||||
}
|
||||
|
||||
|
|
|
@ -139,12 +139,12 @@ namespace MLEM.Ui.Elements {
|
|||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) {
|
||||
var pos = this.DisplayArea.Location + new Vector2(GetAlignmentOffset(), 0);
|
||||
public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, Effect effect, Matrix matrix) {
|
||||
var pos = this.DisplayArea.Location + new Vector2(this.GetAlignmentOffset(), 0);
|
||||
var sc = this.TextScale * this.TextScaleMultiplier * this.Scale;
|
||||
var color = this.TextColor.OrDefault(Color.White) * alpha;
|
||||
this.TokenizedText.Draw(time, batch, pos, this.RegularFont, color, sc, 0, this.Alignment);
|
||||
base.Draw(time, batch, alpha, blendState, samplerState, matrix);
|
||||
this.TokenizedText.Draw(time, batch, pos, this.RegularFont, color, sc, 0);
|
||||
base.Draw(time, batch, alpha, blendState, samplerState, depthStencilState, effect, matrix);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
@ -251,7 +251,7 @@ namespace MLEM.Ui.Elements {
|
|||
return ret;
|
||||
// check if any of our token's parts are hovered
|
||||
foreach (var rect in this.Token.GetArea(this.Parent.DisplayArea.Location, this.Scale * this.textScale)) {
|
||||
if (rect.Contains(position))
|
||||
if (rect.Contains(this.TransformInverse(position)))
|
||||
return this;
|
||||
}
|
||||
return null;
|
||||
|
|
|
@ -73,7 +73,7 @@ namespace MLEM.Ui.Elements {
|
|||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) {
|
||||
public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, Effect effect, Matrix matrix) {
|
||||
batch.Draw(this.Texture, this.DisplayArea, (Color) this.Color * alpha, this.Scale);
|
||||
|
||||
var percentage = this.CurrentValue / this.MaxValue;
|
||||
|
@ -106,7 +106,7 @@ namespace MLEM.Ui.Elements {
|
|||
} else {
|
||||
batch.Draw(batch.GetBlankTexture(), offsetArea, (Color) this.ProgressColor * alpha);
|
||||
}
|
||||
base.Draw(time, batch, alpha, blendState, samplerState, matrix);
|
||||
base.Draw(time, batch, alpha, blendState, samplerState, depthStencilState, effect, matrix);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
|
|
@ -137,15 +137,14 @@ namespace MLEM.Ui.Elements {
|
|||
|
||||
// MOUSE INPUT
|
||||
var moused = this.Controls.MousedElement;
|
||||
var mousedPos = Vector2.Transform(this.Input.MousePosition.ToVector2(), this.Root.InvTransform);
|
||||
if (moused == this && this.Controls.Input.IsMouseButtonPressed(MouseButton.Left)) {
|
||||
this.isMouseHeld = true;
|
||||
this.scrollStartOffset = mousedPos - this.ScrollerPosition;
|
||||
this.scrollStartOffset = this.TransformInverseAll(this.Input.MousePosition.ToVector2()) - this.ScrollerPosition;
|
||||
} else if (this.isMouseHeld && !this.Controls.Input.IsMouseButtonDown(MouseButton.Left)) {
|
||||
this.isMouseHeld = false;
|
||||
}
|
||||
if (this.isMouseHeld)
|
||||
this.ScrollToPos(mousedPos);
|
||||
this.ScrollToPos(this.TransformInverseAll(this.Input.MousePosition.ToVector2()));
|
||||
if (!this.Horizontal && moused != null && (moused == this.Parent || moused.GetParentTree().Contains(this.Parent))) {
|
||||
var scroll = this.Input.LastScrollWheel - this.Input.ScrollWheel;
|
||||
if (scroll != 0)
|
||||
|
@ -157,7 +156,7 @@ namespace MLEM.Ui.Elements {
|
|||
// are we dragging on top of the panel?
|
||||
if (this.Input.GetGesture(GestureType.VerticalDrag, out var drag)) {
|
||||
// if the element under the drag's start position is on top of the panel, start dragging
|
||||
var touched = this.Parent.GetElementUnderPos(Vector2.Transform(drag.Position, this.Root.InvTransform));
|
||||
var touched = this.Parent.GetElementUnderPos(this.TransformInverseAll(drag.Position));
|
||||
if (touched != null && touched != this)
|
||||
this.isDragging = true;
|
||||
|
||||
|
@ -173,7 +172,7 @@ namespace MLEM.Ui.Elements {
|
|||
this.isTouchHeld = false;
|
||||
} else {
|
||||
foreach (var loc in this.Input.TouchState) {
|
||||
var pos = Vector2.Transform(loc.Position, this.Root.InvTransform);
|
||||
var pos = this.TransformInverseAll(loc.Position);
|
||||
// if we just started touching and are on top of the scroller, then we should start scrolling
|
||||
if (this.DisplayArea.Contains(pos) && !loc.TryGetPreviousLocation(out _)) {
|
||||
this.isTouchHeld = true;
|
||||
|
@ -206,13 +205,13 @@ namespace MLEM.Ui.Elements {
|
|||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) {
|
||||
public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, Effect effect, Matrix matrix) {
|
||||
batch.Draw(this.Background, this.DisplayArea, Color.White * alpha, this.Scale);
|
||||
if (this.MaxValue > 0) {
|
||||
var scrollerRect = new RectangleF(this.ScrollerPosition, this.ScrollerSize * this.Scale);
|
||||
batch.Draw(this.ScrollerTexture, scrollerRect, Color.White * alpha, this.Scale);
|
||||
}
|
||||
base.Draw(time, batch, alpha, blendState, samplerState, matrix);
|
||||
base.Draw(time, batch, alpha, blendState, samplerState, depthStencilState, effect, matrix);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
|
|
@ -285,7 +285,7 @@ namespace MLEM.Ui.Elements {
|
|||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, Matrix matrix) {
|
||||
public override void Draw(GameTime time, SpriteBatch batch, float alpha, BlendState blendState, SamplerState samplerState, DepthStencilState depthStencilState, Effect effect, Matrix matrix) {
|
||||
var tex = this.Texture;
|
||||
var color = Color.White * alpha;
|
||||
if (this.IsMouseOver) {
|
||||
|
@ -314,7 +314,7 @@ namespace MLEM.Ui.Elements {
|
|||
this.Font.Value.DrawString(batch, this.PlaceholderText, textPos, this.PlaceholderColor.OrDefault(Color.Gray) * alpha, 0, Vector2.Zero, this.TextScale * this.Scale, SpriteEffects.None, 0);
|
||||
}
|
||||
}
|
||||
base.Draw(time, batch, alpha, blendState, samplerState, matrix);
|
||||
base.Draw(time, batch, alpha, blendState, samplerState, depthStencilState, effect, matrix);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -237,11 +237,10 @@ namespace MLEM.Ui {
|
|||
/// Throughout the ui system, this is used for mouse input querying.
|
||||
/// </summary>
|
||||
/// <param name="position">The position to query</param>
|
||||
/// <param name="transform">If this value is true, the <see cref="RootElement.Transform"/> will be applied.</param>
|
||||
/// <returns>The element under the position, or null if there isn't one</returns>
|
||||
public virtual Element GetElementUnderPos(Vector2 position, bool transform = true) {
|
||||
public virtual Element GetElementUnderPos(Vector2 position) {
|
||||
foreach (var root in this.System.GetRootElements()) {
|
||||
var pos = transform ? Vector2.Transform(position, root.InvTransform) : position;
|
||||
var pos = Vector2.Transform(position, root.InvTransform);
|
||||
var moused = root.Element.GetElementUnderPos(pos);
|
||||
if (moused != null)
|
||||
return moused;
|
||||
|
|
|
@ -83,6 +83,16 @@ namespace MLEM.Ui {
|
|||
/// </summary>
|
||||
public SamplerState SamplerState = SamplerState.PointClamp;
|
||||
/// <summary>
|
||||
/// The depth stencil state that this ui system and all of its elements draw with.
|
||||
/// The default is <see cref="Microsoft.Xna.Framework.Graphics.DepthStencilState.None"/>, which is also the default for <see cref="SpriteBatch.Begin"/>.
|
||||
/// </summary>
|
||||
public DepthStencilState DepthStencilState = DepthStencilState.None;
|
||||
/// <summary>
|
||||
/// The effect that this ui system and all of its elements draw with.
|
||||
/// The default is null, which means that no custom effect will be used.
|
||||
/// </summary>
|
||||
public Effect Effect;
|
||||
/// <summary>
|
||||
/// The <see cref="TextFormatter"/> that this ui system's <see cref="Paragraph"/> elements format their text with.
|
||||
/// To add new formatting codes to the ui system, add them to this formatter.
|
||||
/// </summary>
|
||||
|
@ -236,7 +246,7 @@ namespace MLEM.Ui {
|
|||
public void DrawEarly(GameTime time, SpriteBatch batch) {
|
||||
foreach (var root in this.rootElements) {
|
||||
if (!root.Element.IsHidden)
|
||||
root.Element.DrawEarly(time, batch, this.DrawAlpha * root.Element.DrawAlpha, this.BlendState, this.SamplerState, root.Transform);
|
||||
root.Element.DrawEarly(time, batch, this.DrawAlpha * root.Element.DrawAlpha, this.BlendState, this.SamplerState, this.DepthStencilState, this.Effect, root.Transform);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -250,9 +260,9 @@ namespace MLEM.Ui {
|
|||
foreach (var root in this.rootElements) {
|
||||
if (root.Element.IsHidden)
|
||||
continue;
|
||||
batch.Begin(SpriteSortMode.Deferred, this.BlendState, this.SamplerState, null, null, null, root.Transform);
|
||||
batch.Begin(SpriteSortMode.Deferred, this.BlendState, this.SamplerState, this.DepthStencilState, null, this.Effect, root.Transform);
|
||||
var alpha = this.DrawAlpha * root.Element.DrawAlpha;
|
||||
root.Element.DrawTransformed(time, batch, alpha, this.BlendState, this.SamplerState, root.Transform);
|
||||
root.Element.DrawTransformed(time, batch, alpha, this.BlendState, this.SamplerState, this.DepthStencilState, this.Effect, root.Transform);
|
||||
batch.End();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,6 +45,11 @@ namespace MLEM.Extensions {
|
|||
return Math.Abs(first.X - second.X) <= tolerance && Math.Abs(first.Y - second.Y) <= tolerance && Math.Abs(first.Z - second.Z) <= tolerance && Math.Abs(first.W - second.W) <= tolerance;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="Equals(float,float,float)"/>
|
||||
public static bool Equals(this Quaternion first, Quaternion second, float tolerance) {
|
||||
return Math.Abs(first.X - second.X) <= tolerance && Math.Abs(first.Y - second.Y) <= tolerance && Math.Abs(first.Z - second.Z) <= tolerance && Math.Abs(first.W - second.W) <= tolerance;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="Math.Floor(decimal)"/>
|
||||
public static Vector2 FloorCopy(this Vector2 vec) {
|
||||
return new Vector2(vec.X.Floor(), vec.Y.Floor());
|
||||
|
@ -213,7 +218,7 @@ namespace MLEM.Extensions {
|
|||
|
||||
/// <summary>
|
||||
/// Returns the rotation that the given matrix represents, as a <see cref="Quaternion"/>.
|
||||
/// Returns <see cref="Quaternion.Identity"/> if the matrix does not contain valid rotation information.
|
||||
/// Returns <see cref="Quaternion.Identity"/> if the matrix does not contain valid rotation information, or is not rotated.
|
||||
/// </summary>
|
||||
/// <param name="matrix">The matrix</param>
|
||||
/// <returns>The rotation of the matrix</returns>
|
||||
|
@ -228,6 +233,30 @@ namespace MLEM.Extensions {
|
|||
0, 0, 0, 1));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the rotation that the given matrix represents, as a <see cref="Vector3"/> that contains the x, y and z rotations in radians.
|
||||
/// Returns <see cref="Vector3.Zero"/> if the matrix does not contain valid rotation information, or is not rotated.
|
||||
/// </summary>
|
||||
/// <param name="matrix">The matrix</param>
|
||||
/// <returns>The rotation of the matrix</returns>
|
||||
public static Vector3 RotationVector(this Matrix matrix) {
|
||||
return matrix.Rotation().RotationVector();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the rotation that the given quaternion represents, as a <see cref="Vector3"/> that contains the x, y and z rotations in radians.
|
||||
/// Returns <see cref="Vector3.Zero"/> if the quaternion does not contain valid rotation information, or is not rotated.
|
||||
/// </summary>
|
||||
/// <param name="quaternion">The quaternion</param>
|
||||
/// <returns>The rotation of the quaternion</returns>
|
||||
public static Vector3 RotationVector(this Quaternion quaternion) {
|
||||
var (x, y, z, w) = quaternion;
|
||||
return new Vector3(
|
||||
(float) Math.Atan2(2 * (w * x + y * z), 1 - 2 * (x * x + y * y)),
|
||||
(float) Math.Asin(MathHelper.Clamp(2 * (w * y - z * x), -1, 1)),
|
||||
(float) Math.Atan2(2 * (w * z + x * y), 1 - 2 * (y * y + z * z)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the amount that the rectangle <paramref name="rect"/> is penetrating the rectangle <paramref name="other"/> by.
|
||||
/// If a penetration on both axes is occuring, the one with the lower value is returned.
|
||||
|
|
|
@ -110,19 +110,37 @@ namespace MLEM.Extensions {
|
|||
return tex;
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="SpriteBatch.Draw(Texture2D,Rectangle,Rectangle?,Color,float,Vector2,SpriteEffects,float)"/>
|
||||
/// <summary>Submit a sprite for drawing in the current batch.</summary>
|
||||
/// <param name="batch">The sprite batch to draw with.</param>
|
||||
/// <param name="texture">A texture.</param>
|
||||
/// <param name="destinationRectangle">The drawing bounds on screen.</param>
|
||||
/// <param name="sourceRectangle">An optional region on the texture which will be rendered. If null - draws full texture.</param>
|
||||
/// <param name="color">A color mask.</param>
|
||||
/// <param name="rotation">A rotation of this sprite.</param>
|
||||
/// <param name="origin">Center of the rotation. 0,0 by default.</param>
|
||||
/// <param name="effects">Modificators for drawing. Can be combined.</param>
|
||||
/// <param name="layerDepth">A depth of the layer of this sprite.</param>
|
||||
public static void Draw(this SpriteBatch batch, Texture2D texture, RectangleF destinationRectangle, Rectangle? sourceRectangle, Color color, float rotation, Vector2 origin, SpriteEffects effects, float layerDepth) {
|
||||
var source = sourceRectangle ?? new Rectangle(0, 0, texture.Width, texture.Height);
|
||||
var scale = new Vector2(1F / source.Width, 1F / source.Height) * destinationRectangle.Size;
|
||||
batch.Draw(texture, destinationRectangle.Location, sourceRectangle, color, rotation, origin, scale, effects, layerDepth);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="SpriteBatch.Draw(Texture2D,Rectangle,Rectangle?,Color)"/>
|
||||
/// <summary>Submit a sprite for drawing in the current batch.</summary>
|
||||
/// <param name="batch">The sprite batch to draw with.</param>
|
||||
/// <param name="texture">A texture.</param>
|
||||
/// <param name="destinationRectangle">The drawing bounds on screen.</param>
|
||||
/// <param name="sourceRectangle">An optional region on the texture which will be rendered. If null - draws full texture.</param>
|
||||
/// <param name="color">A color mask.</param>
|
||||
public static void Draw(this SpriteBatch batch, Texture2D texture, RectangleF destinationRectangle, Rectangle? sourceRectangle, Color color) {
|
||||
batch.Draw(texture, destinationRectangle, sourceRectangle, color, 0, Vector2.Zero, SpriteEffects.None, 0);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="SpriteBatch.Draw(Texture2D,Rectangle,Color)"/>
|
||||
/// <summary>Submit a sprite for drawing in the current batch.</summary>
|
||||
/// <param name="batch">The sprite batch to draw with.</param>
|
||||
/// <param name="texture">A texture.</param>
|
||||
/// <param name="destinationRectangle">The drawing bounds on screen.</param>
|
||||
/// <param name="color">A color mask.</param>
|
||||
public static void Draw(this SpriteBatch batch, Texture2D texture, RectangleF destinationRectangle, Color color) {
|
||||
batch.Draw(texture, destinationRectangle, null, color);
|
||||
}
|
||||
|
|
|
@ -104,7 +104,7 @@ namespace MLEM.Extensions {
|
|||
return x >= 0 && y >= 0 && x < this.texture.Width && y < this.texture.Height;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary>
|
||||
public void Dispose() {
|
||||
this.Store();
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
|
@ -114,6 +115,7 @@ namespace MLEM.Formatting {
|
|||
/// <returns>The final, recursively resolved string</returns>
|
||||
public string ResolveMacros(string s) {
|
||||
// resolve macros that resolve into macros
|
||||
var rec = 0;
|
||||
bool matched;
|
||||
do {
|
||||
matched = false;
|
||||
|
@ -124,6 +126,9 @@ namespace MLEM.Formatting {
|
|||
return macro.Value(this, m, macro.Key);
|
||||
});
|
||||
}
|
||||
rec++;
|
||||
if (rec >= 16)
|
||||
throw new ArithmeticException($"A string resolved macros recursively too many times. Does it contain any conflicting macros?\n{s}");
|
||||
} while (matched);
|
||||
return s;
|
||||
}
|
||||
|
|
|
@ -111,7 +111,7 @@ namespace MLEM.Formatting {
|
|||
}
|
||||
|
||||
/// <inheritdoc cref="GenericFont.DrawString(SpriteBatch,string,Vector2,Color,float,Vector2,float,SpriteEffects,float)"/>
|
||||
public void Draw(GameTime time, SpriteBatch batch, Vector2 pos, GenericFont font, Color color, float scale, float depth, TextAlignment alignment = TextAlignment.Left) {
|
||||
public void Draw(GameTime time, SpriteBatch batch, Vector2 pos, GenericFont font, Color color, float scale, float depth) {
|
||||
var innerOffset = new Vector2(this.initialInnerOffset * scale, 0);
|
||||
for (var t = 0; t < this.Tokens.Length; t++) {
|
||||
var token = this.Tokens[t];
|
||||
|
@ -178,7 +178,7 @@ namespace MLEM.Formatting {
|
|||
foreach (var token in this.Tokens)
|
||||
token.SplitDisplayString = token.DisplayString.Split('\n');
|
||||
|
||||
// token areas
|
||||
// token areas and inner offsets
|
||||
this.initialInnerOffset = this.GetInnerOffsetX(font, 0, 0, alignment);
|
||||
var innerOffset = new Vector2(this.initialInnerOffset, 0);
|
||||
for (var t = 0; t < this.Tokens.Length; t++) {
|
||||
|
@ -205,18 +205,21 @@ namespace MLEM.Formatting {
|
|||
private float GetInnerOffsetX(GenericFont font, int tokenIndex, int lineIndex, TextAlignment alignment) {
|
||||
if (alignment > TextAlignment.Left) {
|
||||
var token = this.Tokens[tokenIndex];
|
||||
var restOfLine = font.MeasureString(token.SplitDisplayString[lineIndex], true).X;
|
||||
if (lineIndex >= token.SplitDisplayString.Length - 1) {
|
||||
// the line ends somewhere in or after the next token
|
||||
// if we're the last line in our line array, then we don't contain a line split, so the line ends in a later token
|
||||
var endsLater = lineIndex >= token.SplitDisplayString.Length - 1;
|
||||
// if the line ends in our token, we should ignore trailing white space
|
||||
var restOfLine = font.MeasureString(token.SplitDisplayString[lineIndex], !endsLater).X;
|
||||
if (endsLater) {
|
||||
for (var i = tokenIndex + 1; i < this.Tokens.Length; i++) {
|
||||
var other = this.Tokens[i];
|
||||
if (other.SplitDisplayString.Length > 1) {
|
||||
// the line ends in this token
|
||||
restOfLine += font.MeasureString(other.SplitDisplayString[0]).X;
|
||||
// the line ends in this token (so we also ignore trailing whitespaces)
|
||||
restOfLine += font.MeasureString(other.SplitDisplayString[0], true).X;
|
||||
break;
|
||||
} else {
|
||||
// the line doesn't end in this token, so add it fully
|
||||
restOfLine += font.MeasureString(other.DisplayString).X;
|
||||
// the line doesn't end in this token (or it's the last token), so add it fully
|
||||
var lastToken = i >= this.Tokens.Length - 1;
|
||||
restOfLine += font.MeasureString(other.DisplayString, lastToken).X;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,8 @@ namespace MLEM.Input {
|
|||
this.value = value;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Returns this generic input, converted to a string.</summary>
|
||||
/// <returns>This generic input, converted to a string.</returns>
|
||||
public override string ToString() {
|
||||
switch (this.Type) {
|
||||
case InputType.Mouse:
|
||||
|
@ -39,12 +40,15 @@ namespace MLEM.Input {
|
|||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Indicates whether this instance and a specified object are equal.</summary>
|
||||
/// <param name="obj">The object to compare with the current instance.</param>
|
||||
/// <returns><see langword="true" /> if <paramref name="obj" /> and this instance are the same type and represent the same value; otherwise, <see langword="false" />.</returns>
|
||||
public override bool Equals(object obj) {
|
||||
return obj is GenericInput o && this.Type == o.Type && this.value == o.value;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Returns the hash code for this instance.</summary>
|
||||
/// <returns>A 32-bit signed integer that is the hash code for this instance.</returns>
|
||||
public override int GetHashCode() {
|
||||
return ((int) this.Type * 397) ^ this.value;
|
||||
}
|
||||
|
|
|
@ -147,7 +147,10 @@ namespace MLEM.Input {
|
|||
return string.Join(joiner, this.combinations.Select(c => c.ToString(combinationJoiner, inputName)));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Converts this keybind into a string, separating every included <see cref="Combination"/> by a comma
|
||||
/// </summary>
|
||||
/// <returns>This keybind as a string</returns>
|
||||
public override string ToString() {
|
||||
return this.ToString(", ");
|
||||
}
|
||||
|
|
|
@ -129,12 +129,15 @@ namespace MLEM.Misc {
|
|||
return this.Left.Equals(other.Left) && this.Right.Equals(other.Right) && this.Top.Equals(other.Top) && this.Bottom.Equals(other.Bottom);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Indicates whether this instance and a specified object are equal.</summary>
|
||||
/// <param name="obj">The object to compare with the current instance.</param>
|
||||
/// <returns><see langword="true" /> if <paramref name="obj" /> and this instance are the same type and represent the same value; otherwise, <see langword="false" />.</returns>
|
||||
public override bool Equals(object obj) {
|
||||
return obj is Padding other && this.Equals(other);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Returns the hash code for this instance.</summary>
|
||||
/// <returns>A 32-bit signed integer that is the hash code for this instance.</returns>
|
||||
public override int GetHashCode() {
|
||||
var hashCode = this.Left.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ this.Right.GetHashCode();
|
||||
|
|
|
@ -163,17 +163,20 @@ namespace MLEM.Misc {
|
|||
return this.X <= value.X && value.X + value.Width <= this.X + this.Width && this.Y <= value.Y && value.Y + value.Height <= this.Y + this.Height;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Indicates whether this instance and a specified object are equal.</summary>
|
||||
/// <param name="obj">The object to compare with the current instance.</param>
|
||||
/// <returns><see langword="true" /> if <paramref name="obj" /> and this instance are the same type and represent the same value; otherwise, <see langword="false" />.</returns>
|
||||
public override bool Equals(object obj) {
|
||||
return obj is RectangleF f && this == f;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <inheritdoc cref="Equals(object)"/>
|
||||
public bool Equals(RectangleF other) {
|
||||
return this == other;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Returns the hash code for this instance.</summary>
|
||||
/// <returns>A 32-bit signed integer that is the hash code for this instance.</returns>
|
||||
public override int GetHashCode() {
|
||||
return (((17 * 23 + this.X.GetHashCode()) * 23 + this.Y.GetHashCode()) * 23 + this.Width.GetHashCode()) * 23 + this.Height.GetHashCode();
|
||||
}
|
||||
|
|
|
@ -2,11 +2,11 @@ using System;
|
|||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace MLEM.Misc {
|
||||
/// <inheritdoc />
|
||||
/// <inheritdoc cref="Sound.SoundEffectInstanceHandler"/>
|
||||
[Obsolete("This class has been moved to MLEM.Sound.SoundEffectInstanceHandler in 5.1.0")]
|
||||
public class SoundEffectInstanceHandler : Sound.SoundEffectInstanceHandler {
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <inheritdoc cref="Sound.SoundEffectInstanceHandler(Game)"/>
|
||||
public SoundEffectInstanceHandler(Game game) : base(game) {
|
||||
}
|
||||
|
||||
|
|
|
@ -356,7 +356,7 @@ namespace MLEM.Misc {
|
|||
this.batchChanged = true;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.</summary>
|
||||
public void Dispose() {
|
||||
this.spriteEffect.Dispose();
|
||||
this.indices?.Dispose();
|
||||
|
|
|
@ -214,14 +214,17 @@ namespace MLEM.Pathfinding {
|
|||
this.F = this.G + distance * defaultCost;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Indicates whether this instance and a specified object are equal.</summary>
|
||||
/// <param name="obj">The object to compare with the current instance.</param>
|
||||
/// <returns><see langword="true" /> if <paramref name="obj" /> and this instance are the same type and represent the same value; otherwise, <see langword="false" />.</returns>
|
||||
public override bool Equals(object obj) {
|
||||
if (obj == this)
|
||||
return true;
|
||||
return obj is PathPoint<T> point && point.Pos.Equals(this.Pos);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Returns the hash code for this instance.</summary>
|
||||
/// <returns>A 32-bit signed integer that is the hash code for this instance.</returns>
|
||||
public override int GetHashCode() {
|
||||
return this.Pos.GetHashCode();
|
||||
}
|
||||
|
|
|
@ -109,11 +109,14 @@ namespace MLEM.Sound {
|
|||
return this.Add(effect.CreateInstance(), onStopped, emitter);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Returns an enumerator that iterates through the collection.</summary>
|
||||
/// <returns>An enumerator that can be used to iterate through the collection.</returns>
|
||||
public IEnumerator<Entry> GetEnumerator() {
|
||||
return this.playingSounds.GetEnumerator();
|
||||
}
|
||||
|
||||
/// <summary>Returns an enumerator that iterates through a collection.</summary>
|
||||
/// <returns>An <see cref="T:System.Collections.IEnumerator"></see> object that can be used to iterate through the collection.</returns>
|
||||
IEnumerator IEnumerable.GetEnumerator() {
|
||||
return this.GetEnumerator();
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using System;
|
||||
using System.Text.RegularExpressions;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
@ -107,6 +108,11 @@ namespace Tests {
|
|||
const string strg = "This text uses a bunch of non-breaking~spaces to see if macros work. Additionally, it uses a macro that resolves into a bunch of other macros and then, at the end, into <testmacro> text</c>.";
|
||||
const string goal = "This text uses a bunch of non-breaking\u00A0spaces to see if macros work. Additionally, it uses a macro that resolves into a bunch of other macros and then, at the end, into <c Blue>blue text</c>.";
|
||||
Assert.AreEqual(this.formatter.ResolveMacros(strg), goal);
|
||||
|
||||
// test recursive macros
|
||||
this.formatter.Macros.Add(new Regex("<rec1>"), (f, m, r) => "<rec2>");
|
||||
this.formatter.Macros.Add(new Regex("<rec2>"), (f, m, r) => "<rec1>");
|
||||
Assert.Throws<ArithmeticException>(() => this.formatter.ResolveMacros("Test <rec1> string"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
|
|
@ -43,10 +43,17 @@ namespace Tests {
|
|||
}
|
||||
|
||||
[Test]
|
||||
public void TestMatrixOps([Range(0.5F, 2, 0.5F)] float scale, [Range(-1, 1, 1F)] float rotationX) {
|
||||
var matrix = Matrix.CreateRotationX(rotationX) * Matrix.CreateScale(scale, scale, scale);
|
||||
public void TestMatrixOps([Range(0.5F, 2, 1)] float scale, [Range(-0.5F, 0.5F, 1)] float rotationX, [Range(-0.5F, 0.5F, 1)] float rotationY, [Range(-0.5F, 0.5F, 0.5F)] float rotationZ) {
|
||||
var rotation = Matrix.CreateRotationX(rotationX) * Matrix.CreateRotationY(rotationY) * Matrix.CreateRotationZ(rotationZ);
|
||||
var matrix = rotation * Matrix.CreateScale(scale, scale, scale);
|
||||
Assert.IsTrue(matrix.Scale().Equals(new Vector3(scale), 0.001F), $"{matrix.Scale()} does not equal {new Vector2(scale)}");
|
||||
Assert.AreEqual(matrix.Rotation(), Quaternion.CreateFromAxisAngle(Vector3.UnitX, rotationX));
|
||||
Assert.IsTrue(matrix.Rotation().Equals(Quaternion.CreateFromRotationMatrix(rotation), 0.001F), $"{matrix.Rotation()} does not equal {Quaternion.CreateFromRotationMatrix(rotation)}");
|
||||
Assert.IsTrue(matrix.RotationVector().Equals(new Vector3(rotationX, rotationY, rotationZ), 0.001F), $"{matrix.RotationVector()} does not equal {new Vector3(rotationX, rotationY, rotationZ)}");
|
||||
|
||||
// check against decomposed results
|
||||
matrix.Decompose(out var sc, out var rot, out _);
|
||||
Assert.AreEqual(matrix.Rotation(), rot);
|
||||
Assert.AreEqual(matrix.Scale(), sc);
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
|
Loading…
Reference in a new issue