diff --git a/AssetStudio/AssetStudio.csproj b/AssetStudio/AssetStudio.csproj index 8ce33cc..d1aa770 100644 --- a/AssetStudio/AssetStudio.csproj +++ b/AssetStudio/AssetStudio.csproj @@ -31,15 +31,9 @@ 4 - - Libraries\SharpDX.Mathematics.dll - - - Libraries\System.Half.dll - @@ -63,6 +57,14 @@ + + + + + + + + @@ -145,5 +147,6 @@ + \ No newline at end of file diff --git a/AssetStudio/Classes/AnimationClip.cs b/AssetStudio/Classes/AnimationClip.cs index 04eb23f..2c0d1cd 100644 --- a/AssetStudio/Classes/AnimationClip.cs +++ b/AssetStudio/Classes/AnimationClip.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using SharpDX; namespace AssetStudio { diff --git a/AssetStudio/Classes/AnimatorController.cs b/AssetStudio/Classes/AnimatorController.cs index ff4962c..24cdcdf 100644 --- a/AssetStudio/Classes/AnimatorController.cs +++ b/AssetStudio/Classes/AnimatorController.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Linq; using System.Text; -using SharpDX; namespace AssetStudio { diff --git a/AssetStudio/Classes/Avatar.cs b/AssetStudio/Classes/Avatar.cs index 074cce3..842b43e 100644 --- a/AssetStudio/Classes/Avatar.cs +++ b/AssetStudio/Classes/Avatar.cs @@ -1,5 +1,4 @@ -using SharpDX; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; namespace AssetStudio diff --git a/AssetStudio/Classes/Material.cs b/AssetStudio/Classes/Material.cs index a855b0a..abc689c 100644 --- a/AssetStudio/Classes/Material.cs +++ b/AssetStudio/Classes/Material.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using SharpDX; namespace AssetStudio { @@ -21,7 +20,7 @@ namespace AssetStudio { public KeyValuePair[] m_TexEnvs; public KeyValuePair[] m_Floats; - public KeyValuePair[] m_Colors; + public KeyValuePair[] m_Colors; public UnityPropertySheet(ObjectReader reader) { @@ -40,10 +39,10 @@ namespace AssetStudio } int m_ColorsSize = reader.ReadInt32(); - m_Colors = new KeyValuePair[m_ColorsSize]; + m_Colors = new KeyValuePair[m_ColorsSize]; for (int i = 0; i < m_ColorsSize; i++) { - m_Colors[i] = new KeyValuePair(reader.ReadAlignedString(), reader.ReadColor4()); + m_Colors[i] = new KeyValuePair(reader.ReadAlignedString(), reader.ReadColor4()); } } } diff --git a/AssetStudio/Classes/Mesh.cs b/AssetStudio/Classes/Mesh.cs index c8baf1d..04187d1 100644 --- a/AssetStudio/Classes/Mesh.cs +++ b/AssetStudio/Classes/Mesh.cs @@ -2,7 +2,6 @@ using System.Collections; using System.Collections.Generic; using System.Linq; -using SharpDX; namespace AssetStudio { @@ -428,7 +427,7 @@ namespace AssetStudio public SubMesh[] m_SubMeshes; private uint[] m_IndexBuffer; public BlendShapeData m_Shapes; - public Matrix[] m_BindPose; + public Matrix4x4[] m_BindPose; public uint[] m_BoneNameHashes; public int m_VertexCount; public float[] m_Vertices; @@ -845,13 +844,13 @@ namespace AssetStudio { if (m_CompressedMesh.m_BindPoses.m_NumItems > 0) { - m_BindPose = new Matrix[m_CompressedMesh.m_BindPoses.m_NumItems / 16]; + m_BindPose = new Matrix4x4[m_CompressedMesh.m_BindPoses.m_NumItems / 16]; var m_BindPoses_Unpacked = m_CompressedMesh.m_BindPoses.UnpackFloats(16, 4 * 16); var buffer = new float[16]; for (int i = 0; i < m_BindPose.Length; i++) { Array.Copy(m_BindPoses_Unpacked, i * 16, buffer, 0, 16); - m_BindPose[i] = new Matrix(buffer); + m_BindPose[i] = new Matrix4x4(buffer); } } } @@ -1082,7 +1081,7 @@ namespace AssetStudio value = inputBytes[i] / 255.0f; break; case 2: - value = System.Half.ToHalf(inputBytes, i * 2); + value = Half.ToHalf(inputBytes, i * 2); break; case 4: value = BitConverter.ToSingle(inputBytes, i * 4); diff --git a/AssetStudio/Classes/Sprite.cs b/AssetStudio/Classes/Sprite.cs index e970099..7500a52 100644 --- a/AssetStudio/Classes/Sprite.cs +++ b/AssetStudio/Classes/Sprite.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; -using SharpDX; -using RectangleF = System.Drawing.RectangleF; +using System.Drawing; namespace AssetStudio { @@ -67,7 +66,7 @@ namespace AssetStudio public VertexData m_VertexData; public SpriteVertex[] vertices; public ushort[] indices; - public Matrix[] m_Bindpose; + public Matrix4x4[] m_Bindpose; public BoneWeights4[] m_SourceSkin; public RectangleF textureRect; public Vector2 textureRectOffset; diff --git a/AssetStudio/Classes/SpriteAtlas.cs b/AssetStudio/Classes/SpriteAtlas.cs index 27df0d6..c0cc60b 100644 --- a/AssetStudio/Classes/SpriteAtlas.cs +++ b/AssetStudio/Classes/SpriteAtlas.cs @@ -1,5 +1,4 @@ -using SharpDX; -using System; +using System; using System.Collections.Generic; namespace AssetStudio diff --git a/AssetStudio/Classes/Transform.cs b/AssetStudio/Classes/Transform.cs index 95050b5..4e730a0 100644 --- a/AssetStudio/Classes/Transform.cs +++ b/AssetStudio/Classes/Transform.cs @@ -1,5 +1,4 @@ -using SharpDX; -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; diff --git a/AssetStudio/Extensions/BinaryReaderExtensions.cs b/AssetStudio/Extensions/BinaryReaderExtensions.cs index 1670aec..bf01a3f 100644 --- a/AssetStudio/Extensions/BinaryReaderExtensions.cs +++ b/AssetStudio/Extensions/BinaryReaderExtensions.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.IO; using System.Text; -using SharpDX; namespace AssetStudio { @@ -78,22 +77,14 @@ namespace AssetStudio return new System.Drawing.RectangleF(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); } - public static Color4 ReadColor4(this BinaryReader reader) + public static Color ReadColor4(this BinaryReader reader) { - return new Color4(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); + return new Color(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); } - public static Matrix ReadMatrix(this BinaryReader reader) + public static Matrix4x4 ReadMatrix(this BinaryReader reader) { - var m = new Matrix(); - for (int i = 0; i < 4; i++) - { - for (int j = 0; j < 4; j++) - { - m[i, j] = reader.ReadSingle(); - } - } - return m; + return new Matrix4x4(reader.ReadSingleArray(16)); } private static T[] ReadArray(Func del, int length) @@ -161,7 +152,7 @@ namespace AssetStudio return ReadArray(reader.ReadVector4, reader.ReadInt32()); } - public static Matrix[] ReadMatrixArray(this BinaryReader reader) + public static Matrix4x4[] ReadMatrixArray(this BinaryReader reader) { return ReadArray(reader.ReadMatrix, reader.ReadInt32()); } diff --git a/AssetStudio/IImported.cs b/AssetStudio/IImported.cs index 16087af..fd142d8 100644 --- a/AssetStudio/IImported.cs +++ b/AssetStudio/IImported.cs @@ -2,7 +2,6 @@ using System; using System.Collections; using System.Collections.Generic; using System.IO; -using SharpDX; namespace AssetStudio { @@ -146,7 +145,7 @@ namespace AssetStudio public class ImportedVertexWithColour : ImportedVertex { - public Color4 Colour { get; set; } + public Color Colour { get; set; } } public class ImportedFace @@ -157,17 +156,17 @@ namespace AssetStudio public class ImportedBone { public string Path { get; set; } - public Matrix Matrix { get; set; } + public Matrix4x4 Matrix { get; set; } } public class ImportedMaterial { public string Name { get; set; } - public Color4 Diffuse { get; set; } - public Color4 Ambient { get; set; } - public Color4 Specular { get; set; } - public Color4 Emissive { get; set; } - public Color4 Reflection { get; set; } + public Color Diffuse { get; set; } + public Color Ambient { get; set; } + public Color Specular { get; set; } + public Color Emissive { get; set; } + public Color Reflection { get; set; } public float Shininess { get; set; } public float Transparency { get; set; } public List Textures { get; set; } diff --git a/AssetStudio/Libraries/SharpDX.Mathematics.dll b/AssetStudio/Libraries/SharpDX.Mathematics.dll deleted file mode 100644 index 75bbb0d..0000000 Binary files a/AssetStudio/Libraries/SharpDX.Mathematics.dll and /dev/null differ diff --git a/AssetStudio/Libraries/System.Half.dll b/AssetStudio/Libraries/System.Half.dll deleted file mode 100644 index 068cb28..0000000 Binary files a/AssetStudio/Libraries/System.Half.dll and /dev/null differ diff --git a/AssetStudio/Math/Color.cs b/AssetStudio/Math/Color.cs new file mode 100644 index 0000000..1c247aa --- /dev/null +++ b/AssetStudio/Math/Color.cs @@ -0,0 +1,84 @@ +using System; +using System.Runtime.InteropServices; + +namespace AssetStudio +{ + [StructLayout(LayoutKind.Sequential, Size = 4)] + public struct Color : IEquatable + { + public float R; + public float G; + public float B; + public float A; + + public Color(float r, float g, float b, float a) + { + R = r; + G = g; + B = b; + A = a; + } + + public override int GetHashCode() + { + return ((Vector4)this).GetHashCode(); + } + + public override bool Equals(object other) + { + if (!(other is Color)) + return false; + return Equals((Color)other); + } + + public bool Equals(Color other) + { + return R.Equals(other.R) && G.Equals(other.G) && B.Equals(other.B) && A.Equals(other.A); + } + + public static Color operator +(Color a, Color b) + { + return new Color(a.R + b.R, a.G + b.G, a.B + b.B, a.A + b.A); + } + + public static Color operator -(Color a, Color b) + { + return new Color(a.R - b.R, a.G - b.G, a.B - b.B, a.A - b.A); + } + + public static Color operator *(Color a, Color b) + { + return new Color(a.R * b.R, a.G * b.G, a.B * b.B, a.A * b.A); + } + + public static Color operator *(Color a, float b) + { + return new Color(a.R * b, a.G * b, a.B * b, a.A * b); + } + + public static Color operator *(float b, Color a) + { + return new Color(a.R * b, a.G * b, a.B * b, a.A * b); + } + + public static Color operator /(Color a, float b) + { + return new Color(a.R / b, a.G / b, a.B / b, a.A / b); + } + + public static bool operator ==(Color lhs, Color rhs) + { + return (Vector4)lhs == (Vector4)rhs; + } + + public static bool operator !=(Color lhs, Color rhs) + { + return !(lhs == rhs); + } + + public static implicit operator Vector4(Color c) + { + return new Vector4(c.R, c.G, c.B, c.A); + } + } +} diff --git a/AssetStudio/Math/Half.cs b/AssetStudio/Math/Half.cs new file mode 100644 index 0000000..4bf2f57 --- /dev/null +++ b/AssetStudio/Math/Half.cs @@ -0,0 +1,888 @@ +using System.Diagnostics; +using System.Globalization; +using System.Runtime.InteropServices; + +namespace System +{ + /// + /// Represents a half-precision floating point number. + /// + /// + /// Note: + /// Half is not fast enought and precision is also very bad, + /// so is should not be used for matemathical computation (use Single instead). + /// The main advantage of Half type is lower memory cost: two bytes per number. + /// Half is typically used in graphical applications. + /// + /// Note: + /// All functions, where is used conversion half->float/float->half, + /// are approx. ten times slower than float->double/double->float, i.e. ~3ns on 2GHz CPU. + /// + /// References: + /// - Fast Half Float Conversions, Jeroen van der Zijp, link: http://www.fox-toolkit.org/ftp/fasthalffloatconversion.pdf + /// - IEEE 754 revision, link: http://grouper.ieee.org/groups/754/ + /// + [Serializable] + public struct Half : IComparable, IFormattable, IConvertible, IComparable, IEquatable + { + /// + /// Internal representation of the half-precision floating-point number. + /// + [DebuggerBrowsable(DebuggerBrowsableState.Never)] + internal ushort value; + + #region Constants + /// + /// Represents the smallest positive System.Half value greater than zero. This field is constant. + /// + public static readonly Half Epsilon = Half.ToHalf(0x0001); + /// + /// Represents the largest possible value of System.Half. This field is constant. + /// + public static readonly Half MaxValue = Half.ToHalf(0x7bff); + /// + /// Represents the smallest possible value of System.Half. This field is constant. + /// + public static readonly Half MinValue = Half.ToHalf(0xfbff); + /// + /// Represents not a number (NaN). This field is constant. + /// + public static readonly Half NaN = Half.ToHalf(0xfe00); + /// + /// Represents negative infinity. This field is constant. + /// + public static readonly Half NegativeInfinity = Half.ToHalf(0xfc00); + /// + /// Represents positive infinity. This field is constant. + /// + public static readonly Half PositiveInfinity = Half.ToHalf(0x7c00); + #endregion + + #region Constructors + /// + /// Initializes a new instance of System.Half to the value of the specified single-precision floating-point number. + /// + /// The value to represent as a System.Half. + public Half(float value) { this = HalfHelper.SingleToHalf(value); } + /// + /// Initializes a new instance of System.Half to the value of the specified 32-bit signed integer. + /// + /// The value to represent as a System.Half. + public Half(int value) : this((float)value) { } + /// + /// Initializes a new instance of System.Half to the value of the specified 64-bit signed integer. + /// + /// The value to represent as a System.Half. + public Half(long value) : this((float)value) { } + /// + /// Initializes a new instance of System.Half to the value of the specified double-precision floating-point number. + /// + /// The value to represent as a System.Half. + public Half(double value) : this((float)value) { } + /// + /// Initializes a new instance of System.Half to the value of the specified decimal number. + /// + /// The value to represent as a System.Half. + public Half(decimal value) : this((float)value) { } + /// + /// Initializes a new instance of System.Half to the value of the specified 32-bit unsigned integer. + /// + /// The value to represent as a System.Half. + public Half(uint value) : this((float)value) { } + /// + /// Initializes a new instance of System.Half to the value of the specified 64-bit unsigned integer. + /// + /// The value to represent as a System.Half. + public Half(ulong value) : this((float)value) { } + #endregion + + #region Numeric operators + + /// + /// Returns the result of multiplying the specified System.Half value by negative one. + /// + /// A System.Half. + /// A System.Half with the value of half, but the opposite sign. -or- Zero, if half is zero. + public static Half Negate(Half half) { return -half; } + /// + /// Adds two specified System.Half values. + /// + /// A System.Half. + /// A System.Half. + /// A System.Half value that is the sum of half1 and half2. + public static Half Add(Half half1, Half half2) { return half1 + half2; } + /// + /// Subtracts one specified System.Half value from another. + /// + /// A System.Half (the minuend). + /// A System.Half (the subtrahend). + /// The System.Half result of subtracting half2 from half1. + public static Half Subtract(Half half1, Half half2) { return half1 - half2; } + /// + /// Multiplies two specified System.Half values. + /// + /// A System.Half (the multiplicand). + /// A System.Half (the multiplier). + /// A System.Half that is the result of multiplying half1 and half2. + public static Half Multiply(Half half1, Half half2) { return half1 * half2; } + /// + /// Divides two specified System.Half values. + /// + /// A System.Half (the dividend). + /// A System.Half (the divisor). + /// The System.Half that is the result of dividing half1 by half2. + /// half2 is zero. + public static Half Divide(Half half1, Half half2) { return half1 / half2; } + + /// + /// Returns the value of the System.Half operand (the sign of the operand is unchanged). + /// + /// The System.Half operand. + /// The value of the operand, half. + public static Half operator +(Half half) { return half; } + /// + /// Negates the value of the specified System.Half operand. + /// + /// The System.Half operand. + /// The result of half multiplied by negative one (-1). + public static Half operator -(Half half) { return HalfHelper.Negate(half); } + /// + /// Increments the System.Half operand by 1. + /// + /// The System.Half operand. + /// The value of half incremented by 1. + public static Half operator ++(Half half) { return (Half)(half + 1f); } + /// + /// Decrements the System.Half operand by one. + /// + /// The System.Half operand. + /// The value of half decremented by 1. + public static Half operator --(Half half) { return (Half)(half - 1f); } + /// + /// Adds two specified System.Half values. + /// + /// A System.Half. + /// A System.Half. + /// The System.Half result of adding half1 and half2. + public static Half operator +(Half half1, Half half2) { return (Half)((float)half1 + (float)half2); } + /// + /// Subtracts two specified System.Half values. + /// + /// A System.Half. + /// A System.Half. + /// The System.Half result of subtracting half1 and half2. + public static Half operator -(Half half1, Half half2) { return (Half)((float)half1 - (float)half2); } + /// + /// Multiplies two specified System.Half values. + /// + /// A System.Half. + /// A System.Half. + /// The System.Half result of multiplying half1 by half2. + public static Half operator *(Half half1, Half half2) { return (Half)((float)half1 * (float)half2); } + /// + /// Divides two specified System.Half values. + /// + /// A System.Half (the dividend). + /// A System.Half (the divisor). + /// The System.Half result of half1 by half2. + public static Half operator /(Half half1, Half half2) { return (Half)((float)half1 / (float)half2); } + /// + /// Returns a value indicating whether two instances of System.Half are equal. + /// + /// A System.Half. + /// A System.Half. + /// true if half1 and half2 are equal; otherwise, false. + public static bool operator ==(Half half1, Half half2) { return (!IsNaN(half1) && (half1.value == half2.value)); } + /// + /// Returns a value indicating whether two instances of System.Half are not equal. + /// + /// A System.Half. + /// A System.Half. + /// true if half1 and half2 are not equal; otherwise, false. + public static bool operator !=(Half half1, Half half2) { return !(half1.value == half2.value); } + /// + /// Returns a value indicating whether a specified System.Half is less than another specified System.Half. + /// + /// A System.Half. + /// A System.Half. + /// true if half1 is less than half1; otherwise, false. + public static bool operator <(Half half1, Half half2) { return (float)half1 < (float)half2; } + /// + /// Returns a value indicating whether a specified System.Half is greater than another specified System.Half. + /// + /// A System.Half. + /// A System.Half. + /// true if half1 is greater than half2; otherwise, false. + public static bool operator >(Half half1, Half half2) { return (float)half1 > (float)half2; } + /// + /// Returns a value indicating whether a specified System.Half is less than or equal to another specified System.Half. + /// + /// A System.Half. + /// A System.Half. + /// true if half1 is less than or equal to half2; otherwise, false. + public static bool operator <=(Half half1, Half half2) { return (half1 == half2) || (half1 < half2); } + /// + /// Returns a value indicating whether a specified System.Half is greater than or equal to another specified System.Half. + /// + /// A System.Half. + /// A System.Half. + /// true if half1 is greater than or equal to half2; otherwise, false. + public static bool operator >=(Half half1, Half half2) { return (half1 == half2) || (half1 > half2); } + #endregion + + #region Type casting operators + /// + /// Converts an 8-bit unsigned integer to a System.Half. + /// + /// An 8-bit unsigned integer. + /// A System.Half that represents the converted 8-bit unsigned integer. + public static implicit operator Half(byte value) { return new Half((float)value); } + /// + /// Converts a 16-bit signed integer to a System.Half. + /// + /// A 16-bit signed integer. + /// A System.Half that represents the converted 16-bit signed integer. + public static implicit operator Half(short value) { return new Half((float)value); } + /// + /// Converts a Unicode character to a System.Half. + /// + /// A Unicode character. + /// A System.Half that represents the converted Unicode character. + public static implicit operator Half(char value) { return new Half((float)value); } + /// + /// Converts a 32-bit signed integer to a System.Half. + /// + /// A 32-bit signed integer. + /// A System.Half that represents the converted 32-bit signed integer. + public static implicit operator Half(int value) { return new Half((float)value); } + /// + /// Converts a 64-bit signed integer to a System.Half. + /// + /// A 64-bit signed integer. + /// A System.Half that represents the converted 64-bit signed integer. + public static implicit operator Half(long value) { return new Half((float)value); } + /// + /// Converts a single-precision floating-point number to a System.Half. + /// + /// A single-precision floating-point number. + /// A System.Half that represents the converted single-precision floating point number. + public static explicit operator Half(float value) { return new Half((float)value); } + /// + /// Converts a double-precision floating-point number to a System.Half. + /// + /// A double-precision floating-point number. + /// A System.Half that represents the converted double-precision floating point number. + public static explicit operator Half(double value) { return new Half((float)value); } + /// + /// Converts a decimal number to a System.Half. + /// + /// decimal number + /// A System.Half that represents the converted decimal number. + public static explicit operator Half(decimal value) { return new Half((float)value); } + /// + /// Converts a System.Half to an 8-bit unsigned integer. + /// + /// A System.Half to convert. + /// An 8-bit unsigned integer that represents the converted System.Half. + public static explicit operator byte(Half value) { return (byte)(float)value; } + /// + /// Converts a System.Half to a Unicode character. + /// + /// A System.Half to convert. + /// A Unicode character that represents the converted System.Half. + public static explicit operator char(Half value) { return (char)(float)value; } + /// + /// Converts a System.Half to a 16-bit signed integer. + /// + /// A System.Half to convert. + /// A 16-bit signed integer that represents the converted System.Half. + public static explicit operator short(Half value) { return (short)(float)value; } + /// + /// Converts a System.Half to a 32-bit signed integer. + /// + /// A System.Half to convert. + /// A 32-bit signed integer that represents the converted System.Half. + public static explicit operator int(Half value) { return (int)(float)value; } + /// + /// Converts a System.Half to a 64-bit signed integer. + /// + /// A System.Half to convert. + /// A 64-bit signed integer that represents the converted System.Half. + public static explicit operator long(Half value) { return (long)(float)value; } + /// + /// Converts a System.Half to a single-precision floating-point number. + /// + /// A System.Half to convert. + /// A single-precision floating-point number that represents the converted System.Half. + public static implicit operator float(Half value) { return (float)HalfHelper.HalfToSingle(value); } + /// + /// Converts a System.Half to a double-precision floating-point number. + /// + /// A System.Half to convert. + /// A double-precision floating-point number that represents the converted System.Half. + public static implicit operator double(Half value) { return (double)(float)value; } + /// + /// Converts a System.Half to a decimal number. + /// + /// A System.Half to convert. + /// A decimal number that represents the converted System.Half. + public static explicit operator decimal(Half value) { return (decimal)(float)value; } + /// + /// Converts an 8-bit signed integer to a System.Half. + /// + /// An 8-bit signed integer. + /// A System.Half that represents the converted 8-bit signed integer. + public static implicit operator Half(sbyte value) { return new Half((float)value); } + /// + /// Converts a 16-bit unsigned integer to a System.Half. + /// + /// A 16-bit unsigned integer. + /// A System.Half that represents the converted 16-bit unsigned integer. + public static implicit operator Half(ushort value) { return new Half((float)value); } + /// + /// Converts a 32-bit unsigned integer to a System.Half. + /// + /// A 32-bit unsigned integer. + /// A System.Half that represents the converted 32-bit unsigned integer. + public static implicit operator Half(uint value) { return new Half((float)value); } + /// + /// Converts a 64-bit unsigned integer to a System.Half. + /// + /// A 64-bit unsigned integer. + /// A System.Half that represents the converted 64-bit unsigned integer. + public static implicit operator Half(ulong value) { return new Half((float)value); } + /// + /// Converts a System.Half to an 8-bit signed integer. + /// + /// A System.Half to convert. + /// An 8-bit signed integer that represents the converted System.Half. + public static explicit operator sbyte(Half value) { return (sbyte)(float)value; } + /// + /// Converts a System.Half to a 16-bit unsigned integer. + /// + /// A System.Half to convert. + /// A 16-bit unsigned integer that represents the converted System.Half. + public static explicit operator ushort(Half value) { return (ushort)(float)value; } + /// + /// Converts a System.Half to a 32-bit unsigned integer. + /// + /// A System.Half to convert. + /// A 32-bit unsigned integer that represents the converted System.Half. + public static explicit operator uint(Half value) { return (uint)(float)value; } + /// + /// Converts a System.Half to a 64-bit unsigned integer. + /// + /// A System.Half to convert. + /// A 64-bit unsigned integer that represents the converted System.Half. + public static explicit operator ulong(Half value) { return (ulong)(float)value; } + #endregion + + /// + /// Compares this instance to a specified System.Half object. + /// + /// A System.Half object. + /// + /// A signed number indicating the relative values of this instance and value. + /// Return Value Meaning Less than zero This instance is less than value. Zero + /// This instance is equal to value. Greater than zero This instance is greater than value. + /// + public int CompareTo(Half other) + { + int result = 0; + if (this < other) + { + result = -1; + } + else if (this > other) + { + result = 1; + } + else if (this != other) + { + if (!IsNaN(this)) + { + result = 1; + } + else if (!IsNaN(other)) + { + result = -1; + } + } + + return result; + } + /// + /// Compares this instance to a specified System.Object. + /// + /// An System.Object or null. + /// + /// A signed number indicating the relative values of this instance and value. + /// Return Value Meaning Less than zero This instance is less than value. Zero + /// This instance is equal to value. Greater than zero This instance is greater + /// than value. -or- value is null. + /// + /// value is not a System.Half + public int CompareTo(object obj) + { + int result = 0; + if (obj == null) + { + result = 1; + } + else + { + if (obj is Half) + { + result = CompareTo((Half)obj); + } + else + { + throw new ArgumentException("Object must be of type Half."); + } + } + + return result; + } + /// + /// Returns a value indicating whether this instance and a specified System.Half object represent the same value. + /// + /// A System.Half object to compare to this instance. + /// true if value is equal to this instance; otherwise, false. + public bool Equals(Half other) + { + return ((other == this) || (IsNaN(other) && IsNaN(this))); + } + /// + /// Returns a value indicating whether this instance and a specified System.Object + /// represent the same type and value. + /// + /// An System.Object. + /// true if value is a System.Half and equal to this instance; otherwise, false. + public override bool Equals(object obj) + { + bool result = false; + if (obj is Half) + { + Half half = (Half)obj; + if ((half == this) || (IsNaN(half) && IsNaN(this))) + { + result = true; + } + } + + return result; + } + /// + /// Returns the hash code for this instance. + /// + /// A 32-bit signed integer hash code. + public override int GetHashCode() + { + return value.GetHashCode(); + } + /// + /// Returns the System.TypeCode for value type System.Half. + /// + /// The enumerated constant (TypeCode)255. + public TypeCode GetTypeCode() + { + return (TypeCode)255; + } + + #region BitConverter & Math methods for Half + /// + /// Returns the specified half-precision floating point value as an array of bytes. + /// + /// The number to convert. + /// An array of bytes with length 2. + public static byte[] GetBytes(Half value) + { + return BitConverter.GetBytes(value.value); + } + /// + /// Converts the value of a specified instance of System.Half to its equivalent binary representation. + /// + /// A System.Half value. + /// A 16-bit unsigned integer that contain the binary representation of value. + public static ushort GetBits(Half value) + { + return value.value; + } + /// + /// Returns a half-precision floating point number converted from two bytes + /// at a specified position in a byte array. + /// + /// An array of bytes. + /// The starting position within value. + /// A half-precision floating point number formed by two bytes beginning at startIndex. + /// + /// startIndex is greater than or equal to the length of value minus 1, and is + /// less than or equal to the length of value minus 1. + /// + /// value is null. + /// startIndex is less than zero or greater than the length of value minus 1. + public static Half ToHalf(byte[] value, int startIndex) + { + return Half.ToHalf((ushort)BitConverter.ToInt16(value, startIndex)); + } + /// + /// Returns a half-precision floating point number converted from its binary representation. + /// + /// Binary representation of System.Half value + /// A half-precision floating point number formed by its binary representation. + public static Half ToHalf(ushort bits) + { + return new Half { value = bits }; + } + + /// + /// Returns a value indicating the sign of a half-precision floating-point number. + /// + /// A signed number. + /// + /// A number indicating the sign of value. Number Description -1 value is less + /// than zero. 0 value is equal to zero. 1 value is greater than zero. + /// + /// value is equal to System.Half.NaN. + public static int Sign(Half value) + { + if (value < 0) + { + return -1; + } + else if (value > 0) + { + return 1; + } + else + { + if (value != 0) + { + throw new ArithmeticException("Function does not accept floating point Not-a-Number values."); + } + } + + return 0; + } + /// + /// Returns the absolute value of a half-precision floating-point number. + /// + /// A number in the range System.Half.MinValue ≤ value ≤ System.Half.MaxValue. + /// A half-precision floating-point number, x, such that 0 ≤ x ≤System.Half.MaxValue. + public static Half Abs(Half value) + { + return HalfHelper.Abs(value); + } + /// + /// Returns the larger of two half-precision floating-point numbers. + /// + /// The first of two half-precision floating-point numbers to compare. + /// The second of two half-precision floating-point numbers to compare. + /// + /// Parameter value1 or value2, whichever is larger. If value1, or value2, or both val1 + /// and value2 are equal to System.Half.NaN, System.Half.NaN is returned. + /// + public static Half Max(Half value1, Half value2) + { + return (value1 < value2) ? value2 : value1; + } + /// + /// Returns the smaller of two half-precision floating-point numbers. + /// + /// The first of two half-precision floating-point numbers to compare. + /// The second of two half-precision floating-point numbers to compare. + /// + /// Parameter value1 or value2, whichever is smaller. If value1, or value2, or both val1 + /// and value2 are equal to System.Half.NaN, System.Half.NaN is returned. + /// + public static Half Min(Half value1, Half value2) + { + return (value1 < value2) ? value1 : value2; + } + #endregion + + /// + /// Returns a value indicating whether the specified number evaluates to not a number (System.Half.NaN). + /// + /// A half-precision floating-point number. + /// true if value evaluates to not a number (System.Half.NaN); otherwise, false. + public static bool IsNaN(Half half) + { + return HalfHelper.IsNaN(half); + } + /// + /// Returns a value indicating whether the specified number evaluates to negative or positive infinity. + /// + /// A half-precision floating-point number. + /// true if half evaluates to System.Half.PositiveInfinity or System.Half.NegativeInfinity; otherwise, false. + public static bool IsInfinity(Half half) + { + return HalfHelper.IsInfinity(half); + } + /// + /// Returns a value indicating whether the specified number evaluates to negative infinity. + /// + /// A half-precision floating-point number. + /// true if half evaluates to System.Half.NegativeInfinity; otherwise, false. + public static bool IsNegativeInfinity(Half half) + { + return HalfHelper.IsNegativeInfinity(half); + } + /// + /// Returns a value indicating whether the specified number evaluates to positive infinity. + /// + /// A half-precision floating-point number. + /// true if half evaluates to System.Half.PositiveInfinity; otherwise, false. + public static bool IsPositiveInfinity(Half half) + { + return HalfHelper.IsPositiveInfinity(half); + } + + #region String operations (Parse and ToString) + /// + /// Converts the string representation of a number to its System.Half equivalent. + /// + /// The string representation of the number to convert. + /// The System.Half number equivalent to the number contained in value. + /// value is null. + /// value is not in the correct format. + /// value represents a number less than System.Half.MinValue or greater than System.Half.MaxValue. + public static Half Parse(string value) + { + return (Half)float.Parse(value, CultureInfo.InvariantCulture); + } + /// + /// Converts the string representation of a number to its System.Half equivalent + /// using the specified culture-specific format information. + /// + /// The string representation of the number to convert. + /// An System.IFormatProvider that supplies culture-specific parsing information about value. + /// The System.Half number equivalent to the number contained in s as specified by provider. + /// value is null. + /// value is not in the correct format. + /// value represents a number less than System.Half.MinValue or greater than System.Half.MaxValue. + public static Half Parse(string value, IFormatProvider provider) + { + return (Half)float.Parse(value, provider); + } + /// + /// Converts the string representation of a number in a specified style to its System.Half equivalent. + /// + /// The string representation of the number to convert. + /// + /// A bitwise combination of System.Globalization.NumberStyles values that indicates + /// the style elements that can be present in value. A typical value to specify is + /// System.Globalization.NumberStyles.Number. + /// + /// The System.Half number equivalent to the number contained in s as specified by style. + /// value is null. + /// + /// style is not a System.Globalization.NumberStyles value. -or- style is the + /// System.Globalization.NumberStyles.AllowHexSpecifier value. + /// + /// value is not in the correct format. + /// value represents a number less than System.Half.MinValue or greater than System.Half.MaxValue. + public static Half Parse(string value, NumberStyles style) + { + return (Half)float.Parse(value, style, CultureInfo.InvariantCulture); + } + /// + /// Converts the string representation of a number to its System.Half equivalent + /// using the specified style and culture-specific format. + /// + /// The string representation of the number to convert. + /// + /// A bitwise combination of System.Globalization.NumberStyles values that indicates + /// the style elements that can be present in value. A typical value to specify is + /// System.Globalization.NumberStyles.Number. + /// + /// An System.IFormatProvider object that supplies culture-specific information about the format of value. + /// The System.Half number equivalent to the number contained in s as specified by style and provider. + /// value is null. + /// + /// style is not a System.Globalization.NumberStyles value. -or- style is the + /// System.Globalization.NumberStyles.AllowHexSpecifier value. + /// + /// value is not in the correct format. + /// value represents a number less than System.Half.MinValue or greater than System.Half.MaxValue. + public static Half Parse(string value, NumberStyles style, IFormatProvider provider) + { + return (Half)float.Parse(value, style, provider); + } + /// + /// Converts the string representation of a number to its System.Half equivalent. + /// A return value indicates whether the conversion succeeded or failed. + /// + /// The string representation of the number to convert. + /// + /// When this method returns, contains the System.Half number that is equivalent + /// to the numeric value contained in value, if the conversion succeeded, or is zero + /// if the conversion failed. The conversion fails if the s parameter is null, + /// is not a number in a valid format, or represents a number less than System.Half.MinValue + /// or greater than System.Half.MaxValue. This parameter is passed uninitialized. + /// + /// true if s was converted successfully; otherwise, false. + public static bool TryParse(string value, out Half result) + { + float f; + if (float.TryParse(value, out f)) + { + result = (Half)f; + return true; + } + + result = new Half(); + return false; + } + /// + /// Converts the string representation of a number to its System.Half equivalent + /// using the specified style and culture-specific format. A return value indicates + /// whether the conversion succeeded or failed. + /// + /// The string representation of the number to convert. + /// + /// A bitwise combination of System.Globalization.NumberStyles values that indicates + /// the permitted format of value. A typical value to specify is System.Globalization.NumberStyles.Number. + /// + /// An System.IFormatProvider object that supplies culture-specific parsing information about value. + /// + /// When this method returns, contains the System.Half number that is equivalent + /// to the numeric value contained in value, if the conversion succeeded, or is zero + /// if the conversion failed. The conversion fails if the s parameter is null, + /// is not in a format compliant with style, or represents a number less than + /// System.Half.MinValue or greater than System.Half.MaxValue. This parameter is passed uninitialized. + /// + /// true if s was converted successfully; otherwise, false. + /// + /// style is not a System.Globalization.NumberStyles value. -or- style + /// is the System.Globalization.NumberStyles.AllowHexSpecifier value. + /// + public static bool TryParse(string value, NumberStyles style, IFormatProvider provider, out Half result) + { + bool parseResult = false; + float f; + if (float.TryParse(value, style, provider, out f)) + { + result = (Half)f; + parseResult = true; + } + else + { + result = new Half(); + } + + return parseResult; + } + /// + /// Converts the numeric value of this instance to its equivalent string representation. + /// + /// A string that represents the value of this instance. + public override string ToString() + { + return ((float)this).ToString(CultureInfo.InvariantCulture); + } + /// + /// Converts the numeric value of this instance to its equivalent string representation + /// using the specified culture-specific format information. + /// + /// An System.IFormatProvider that supplies culture-specific formatting information. + /// The string representation of the value of this instance as specified by provider. + public string ToString(IFormatProvider formatProvider) + { + return ((float)this).ToString(formatProvider); + } + /// + /// Converts the numeric value of this instance to its equivalent string representation, using the specified format. + /// + /// A numeric format string. + /// The string representation of the value of this instance as specified by format. + public string ToString(string format) + { + return ((float)this).ToString(format, CultureInfo.InvariantCulture); + } + /// + /// Converts the numeric value of this instance to its equivalent string representation + /// using the specified format and culture-specific format information. + /// + /// A numeric format string. + /// An System.IFormatProvider that supplies culture-specific formatting information. + /// The string representation of the value of this instance as specified by format and provider. + /// format is invalid. + public string ToString(string format, IFormatProvider formatProvider) + { + return ((float)this).ToString(format, formatProvider); + } + #endregion + + #region IConvertible Members + float IConvertible.ToSingle(IFormatProvider provider) + { + return (float)this; + } + TypeCode IConvertible.GetTypeCode() + { + return GetTypeCode(); + } + bool IConvertible.ToBoolean(IFormatProvider provider) + { + return Convert.ToBoolean((float)this); + } + byte IConvertible.ToByte(IFormatProvider provider) + { + return Convert.ToByte((float)this); + } + char IConvertible.ToChar(IFormatProvider provider) + { + throw new InvalidCastException(string.Format(CultureInfo.CurrentCulture, "Invalid cast from '{0}' to '{1}'.", "Half", "Char")); + } + DateTime IConvertible.ToDateTime(IFormatProvider provider) + { + throw new InvalidCastException(string.Format(CultureInfo.CurrentCulture, "Invalid cast from '{0}' to '{1}'.", "Half", "DateTime")); + } + decimal IConvertible.ToDecimal(IFormatProvider provider) + { + return Convert.ToDecimal((float)this); + } + double IConvertible.ToDouble(IFormatProvider provider) + { + return Convert.ToDouble((float)this); + } + short IConvertible.ToInt16(IFormatProvider provider) + { + return Convert.ToInt16((float)this); + } + int IConvertible.ToInt32(IFormatProvider provider) + { + return Convert.ToInt32((float)this); + } + long IConvertible.ToInt64(IFormatProvider provider) + { + return Convert.ToInt64((float)this); + } + sbyte IConvertible.ToSByte(IFormatProvider provider) + { + return Convert.ToSByte((float)this); + } + string IConvertible.ToString(IFormatProvider provider) + { + return Convert.ToString((float)this, CultureInfo.InvariantCulture); + } + object IConvertible.ToType(Type conversionType, IFormatProvider provider) + { + return (((float)this) as IConvertible).ToType(conversionType, provider); + } + ushort IConvertible.ToUInt16(IFormatProvider provider) + { + return Convert.ToUInt16((float)this); + } + uint IConvertible.ToUInt32(IFormatProvider provider) + { + return Convert.ToUInt32((float)this); + } + ulong IConvertible.ToUInt64(IFormatProvider provider) + { + return Convert.ToUInt64((float)this); + } + #endregion + } +} diff --git a/AssetStudio/Math/HalfHelper.cs b/AssetStudio/Math/HalfHelper.cs new file mode 100644 index 0000000..3020f98 --- /dev/null +++ b/AssetStudio/Math/HalfHelper.cs @@ -0,0 +1,211 @@ +using System.Runtime.InteropServices; + +namespace System +{ + /// + /// Helper class for Half conversions and some low level operations. + /// This class is internally used in the Half class. + /// + /// + /// References: + /// - Fast Half Float Conversions, Jeroen van der Zijp, link: http://www.fox-toolkit.org/ftp/fasthalffloatconversion.pdf + /// + [ComVisible(false)] + internal static class HalfHelper + { + private static uint[] mantissaTable = GenerateMantissaTable(); + private static uint[] exponentTable = GenerateExponentTable(); + private static ushort[] offsetTable = GenerateOffsetTable(); + private static ushort[] baseTable = GenerateBaseTable(); + private static sbyte[] shiftTable = GenerateShiftTable(); + + // Transforms the subnormal representation to a normalized one. + private static uint ConvertMantissa(int i) + { + uint m = (uint)(i << 13); // Zero pad mantissa bits + uint e = 0; // Zero exponent + + // While not normalized + while ((m & 0x00800000) == 0) + { + e -= 0x00800000; // Decrement exponent (1<<23) + m <<= 1; // Shift mantissa + } + m &= unchecked((uint)~0x00800000); // Clear leading 1 bit + e += 0x38800000; // Adjust bias ((127-14)<<23) + return m | e; // Return combined number + } + + private static uint[] GenerateMantissaTable() + { + uint[] mantissaTable = new uint[2048]; + mantissaTable[0] = 0; + for (int i = 1; i < 1024; i++) + { + mantissaTable[i] = ConvertMantissa(i); + } + for (int i = 1024; i < 2048; i++) + { + mantissaTable[i] = (uint)(0x38000000 + ((i - 1024) << 13)); + } + + return mantissaTable; + } + private static uint[] GenerateExponentTable() + { + uint[] exponentTable = new uint[64]; + exponentTable[0] = 0; + for (int i = 1; i < 31; i++) + { + exponentTable[i] = (uint)(i << 23); + } + exponentTable[31] = 0x47800000; + exponentTable[32] = 0x80000000; + for (int i = 33; i < 63; i++) + { + exponentTable[i] = (uint)(0x80000000 + ((i - 32) << 23)); + } + exponentTable[63] = 0xc7800000; + + return exponentTable; + } + private static ushort[] GenerateOffsetTable() + { + ushort[] offsetTable = new ushort[64]; + offsetTable[0] = 0; + for (int i = 1; i < 32; i++) + { + offsetTable[i] = 1024; + } + offsetTable[32] = 0; + for (int i = 33; i < 64; i++) + { + offsetTable[i] = 1024; + } + + return offsetTable; + } + private static ushort[] GenerateBaseTable() + { + ushort[] baseTable = new ushort[512]; + for (int i = 0; i < 256; ++i) + { + sbyte e = (sbyte)(127 - i); + if (e > 24) + { // Very small numbers map to zero + baseTable[i | 0x000] = 0x0000; + baseTable[i | 0x100] = 0x8000; + } + else if (e > 14) + { // Small numbers map to denorms + baseTable[i | 0x000] = (ushort)(0x0400 >> (18 + e)); + baseTable[i | 0x100] = (ushort)((0x0400 >> (18 + e)) | 0x8000); + } + else if (e >= -15) + { // Normal numbers just lose precision + baseTable[i | 0x000] = (ushort)((15 - e) << 10); + baseTable[i | 0x100] = (ushort)(((15 - e) << 10) | 0x8000); + } + else if (e > -128) + { // Large numbers map to Infinity + baseTable[i | 0x000] = 0x7c00; + baseTable[i | 0x100] = 0xfc00; + } + else + { // Infinity and NaN's stay Infinity and NaN's + baseTable[i | 0x000] = 0x7c00; + baseTable[i | 0x100] = 0xfc00; + } + } + + return baseTable; + } + private static sbyte[] GenerateShiftTable() + { + sbyte[] shiftTable = new sbyte[512]; + for (int i = 0; i < 256; ++i) + { + sbyte e = (sbyte)(127 - i); + if (e > 24) + { // Very small numbers map to zero + shiftTable[i | 0x000] = 24; + shiftTable[i | 0x100] = 24; + } + else if (e > 14) + { // Small numbers map to denorms + shiftTable[i | 0x000] = (sbyte)(e - 1); + shiftTable[i | 0x100] = (sbyte)(e - 1); + } + else if (e >= -15) + { // Normal numbers just lose precision + shiftTable[i | 0x000] = 13; + shiftTable[i | 0x100] = 13; + } + else if (e > -128) + { // Large numbers map to Infinity + shiftTable[i | 0x000] = 24; + shiftTable[i | 0x100] = 24; + } + else + { // Infinity and NaN's stay Infinity and NaN's + shiftTable[i | 0x000] = 13; + shiftTable[i | 0x100] = 13; + } + } + + return shiftTable; + } + + /*public static unsafe float HalfToSingle(Half half) + { + uint result = mantissaTable[offsetTable[half.value >> 10] + (half.value & 0x3ff)] + exponentTable[half.value >> 10]; + return *((float*)&result); + } + public static unsafe Half SingleToHalf(float single) + { + uint value = *((uint*)&single); + + ushort result = (ushort)(baseTable[(value >> 23) & 0x1ff] + ((value & 0x007fffff) >> shiftTable[value >> 23])); + return Half.ToHalf(result); + }*/ + public static float HalfToSingle(Half half) + { + uint result = mantissaTable[offsetTable[half.value >> 10] + (half.value & 0x3ff)] + exponentTable[half.value >> 10]; + byte[] uintBytes = BitConverter.GetBytes(result); + return BitConverter.ToSingle(uintBytes, 0); + } + public static Half SingleToHalf(float single) + { + byte[] singleBytes = BitConverter.GetBytes(single); + uint value = BitConverter.ToUInt32(singleBytes, 0); + ushort result = (ushort)(baseTable[(value >> 23) & 0x1ff] + ((value & 0x007fffff) >> shiftTable[value >> 23])); + return Half.ToHalf(result); + } + + public static Half Negate(Half half) + { + return Half.ToHalf((ushort)(half.value ^ 0x8000)); + } + public static Half Abs(Half half) + { + return Half.ToHalf((ushort)(half.value & 0x7fff)); + } + + public static bool IsNaN(Half half) + { + return ((half.value & 0x7fff) > 0x7c00); + } + public static bool IsInfinity(Half half) + { + return ((half.value & 0x7fff) == 0x7c00); + } + public static bool IsPositiveInfinity(Half half) + { + return (half.value == 0x7c00); + } + public static bool IsNegativeInfinity(Half half) + { + return (half.value == 0xfc00); + } + } +} diff --git a/AssetStudio/Math/Matrix4x4f.cs b/AssetStudio/Math/Matrix4x4f.cs new file mode 100644 index 0000000..40c2e35 --- /dev/null +++ b/AssetStudio/Math/Matrix4x4f.cs @@ -0,0 +1,241 @@ +using System; +using System.Runtime.InteropServices; + +namespace AssetStudio +{ + [StructLayout(LayoutKind.Sequential, Pack = 4)] + public struct Matrix4x4 : IEquatable + { + public float M00; + public float M10; + public float M20; + public float M30; + + public float M01; + public float M11; + public float M21; + public float M31; + + public float M02; + public float M12; + public float M22; + public float M32; + + public float M03; + public float M13; + public float M23; + public float M33; + + public Matrix4x4(float[] values) + { + if (values == null) + throw new ArgumentNullException(nameof(values)); + if (values.Length != 16) + throw new ArgumentOutOfRangeException(nameof(values), "There must be sixteen and only sixteen input values for Matrix."); + + M00 = values[0]; + M10 = values[1]; + M20 = values[2]; + M30 = values[3]; + + M01 = values[4]; + M11 = values[5]; + M21 = values[6]; + M31 = values[7]; + + M02 = values[8]; + M12 = values[9]; + M22 = values[10]; + M32 = values[11]; + + M03 = values[12]; + M13 = values[13]; + M23 = values[14]; + M33 = values[15]; + } + + public float this[int row, int column] + { + get => this[row + column * 4]; + + set => this[row + column * 4] = value; + } + + public float this[int index] + { + get + { + switch (index) + { + case 0: return M00; + case 1: return M10; + case 2: return M20; + case 3: return M30; + case 4: return M01; + case 5: return M11; + case 6: return M21; + case 7: return M31; + case 8: return M02; + case 9: return M12; + case 10: return M22; + case 11: return M32; + case 12: return M03; + case 13: return M13; + case 14: return M23; + case 15: return M33; + default: throw new IndexOutOfRangeException("Invalid matrix index!"); + } + } + + set + { + switch (index) + { + case 0: M00 = value; break; + case 1: M10 = value; break; + case 2: M20 = value; break; + case 3: M30 = value; break; + case 4: M01 = value; break; + case 5: M11 = value; break; + case 6: M21 = value; break; + case 7: M31 = value; break; + case 8: M02 = value; break; + case 9: M12 = value; break; + case 10: M22 = value; break; + case 11: M32 = value; break; + case 12: M03 = value; break; + case 13: M13 = value; break; + case 14: M23 = value; break; + case 15: M33 = value; break; + default: throw new IndexOutOfRangeException("Invalid matrix index!"); + } + } + } + + public override int GetHashCode() + { + return GetColumn(0).GetHashCode() ^ (GetColumn(1).GetHashCode() << 2) ^ (GetColumn(2).GetHashCode() >> 2) ^ (GetColumn(3).GetHashCode() >> 1); + } + + public override bool Equals(object other) + { + if (!(other is Matrix4x4)) + return false; + return Equals((Matrix4x4)other); + } + + public bool Equals(Matrix4x4 other) + { + return GetColumn(0).Equals(other.GetColumn(0)) + && GetColumn(1).Equals(other.GetColumn(1)) + && GetColumn(2).Equals(other.GetColumn(2)) + && GetColumn(3).Equals(other.GetColumn(3)); + } + + public Vector4 GetColumn(int index) + { + switch (index) + { + case 0: return new Vector4(M00, M10, M20, M30); + case 1: return new Vector4(M01, M11, M21, M31); + case 2: return new Vector4(M02, M12, M22, M32); + case 3: return new Vector4(M03, M13, M23, M33); + default: throw new IndexOutOfRangeException("Invalid column index!"); + } + } + + public Vector4 GetRow(int index) + { + switch (index) + { + case 0: return new Vector4(M00, M01, M02, M03); + case 1: return new Vector4(M10, M11, M12, M13); + case 2: return new Vector4(M20, M21, M22, M23); + case 3: return new Vector4(M30, M31, M32, M33); + default: throw new IndexOutOfRangeException("Invalid row index!"); + } + } + + public static Matrix4x4 operator *(Matrix4x4 lhs, Matrix4x4 rhs) + { + Matrix4x4 res; + res.M00 = lhs.M00 * rhs.M00 + lhs.M01 * rhs.M10 + lhs.M02 * rhs.M20 + lhs.M03 * rhs.M30; + res.M01 = lhs.M00 * rhs.M01 + lhs.M01 * rhs.M11 + lhs.M02 * rhs.M21 + lhs.M03 * rhs.M31; + res.M02 = lhs.M00 * rhs.M02 + lhs.M01 * rhs.M12 + lhs.M02 * rhs.M22 + lhs.M03 * rhs.M32; + res.M03 = lhs.M00 * rhs.M03 + lhs.M01 * rhs.M13 + lhs.M02 * rhs.M23 + lhs.M03 * rhs.M33; + + res.M10 = lhs.M10 * rhs.M00 + lhs.M11 * rhs.M10 + lhs.M12 * rhs.M20 + lhs.M13 * rhs.M30; + res.M11 = lhs.M10 * rhs.M01 + lhs.M11 * rhs.M11 + lhs.M12 * rhs.M21 + lhs.M13 * rhs.M31; + res.M12 = lhs.M10 * rhs.M02 + lhs.M11 * rhs.M12 + lhs.M12 * rhs.M22 + lhs.M13 * rhs.M32; + res.M13 = lhs.M10 * rhs.M03 + lhs.M11 * rhs.M13 + lhs.M12 * rhs.M23 + lhs.M13 * rhs.M33; + + res.M20 = lhs.M20 * rhs.M00 + lhs.M21 * rhs.M10 + lhs.M22 * rhs.M20 + lhs.M23 * rhs.M30; + res.M21 = lhs.M20 * rhs.M01 + lhs.M21 * rhs.M11 + lhs.M22 * rhs.M21 + lhs.M23 * rhs.M31; + res.M22 = lhs.M20 * rhs.M02 + lhs.M21 * rhs.M12 + lhs.M22 * rhs.M22 + lhs.M23 * rhs.M32; + res.M23 = lhs.M20 * rhs.M03 + lhs.M21 * rhs.M13 + lhs.M22 * rhs.M23 + lhs.M23 * rhs.M33; + + res.M30 = lhs.M30 * rhs.M00 + lhs.M31 * rhs.M10 + lhs.M32 * rhs.M20 + lhs.M33 * rhs.M30; + res.M31 = lhs.M30 * rhs.M01 + lhs.M31 * rhs.M11 + lhs.M32 * rhs.M21 + lhs.M33 * rhs.M31; + res.M32 = lhs.M30 * rhs.M02 + lhs.M31 * rhs.M12 + lhs.M32 * rhs.M22 + lhs.M33 * rhs.M32; + res.M33 = lhs.M30 * rhs.M03 + lhs.M31 * rhs.M13 + lhs.M32 * rhs.M23 + lhs.M33 * rhs.M33; + + return res; + } + + public static bool operator ==(Matrix4x4 lhs, Matrix4x4 rhs) + { + return lhs.GetColumn(0) == rhs.GetColumn(0) + && lhs.GetColumn(1) == rhs.GetColumn(1) + && lhs.GetColumn(2) == rhs.GetColumn(2) + && lhs.GetColumn(3) == rhs.GetColumn(3); + } + + public static bool operator !=(Matrix4x4 lhs, Matrix4x4 rhs) + { + return !(lhs == rhs); + } + + public static Matrix4x4 Scale(Vector3 vector) + { + Matrix4x4 m; + m.M00 = vector.X; m.M01 = 0F; m.M02 = 0F; m.M03 = 0F; + m.M10 = 0F; m.M11 = vector.Y; m.M12 = 0F; m.M13 = 0F; + m.M20 = 0F; m.M21 = 0F; m.M22 = vector.Z; m.M23 = 0F; + m.M30 = 0F; m.M31 = 0F; m.M32 = 0F; m.M33 = 1F; + return m; + } + + public static Matrix4x4 Translate(Vector3 vector) + { + Matrix4x4 m; + m.M00 = 1F; m.M01 = 0F; m.M02 = 0F; m.M03 = vector.X; + m.M10 = 0F; m.M11 = 1F; m.M12 = 0F; m.M13 = vector.Y; + m.M20 = 0F; m.M21 = 0F; m.M22 = 1F; m.M23 = vector.Z; + m.M30 = 0F; m.M31 = 0F; m.M32 = 0F; m.M33 = 1F; + return m; + } + + public static Matrix4x4 Rotate(Quaternion q) + { + float x = q.X * 2.0F; + float y = q.Y * 2.0F; + float z = q.Z * 2.0F; + float xx = q.X * x; + float yy = q.Y * y; + float zz = q.Z * z; + float xy = q.X * y; + float xz = q.X * z; + float yz = q.Y * z; + float wx = q.W * x; + float wy = q.W * y; + float wz = q.W * z; + + Matrix4x4 m; + m.M00 = 1.0f - (yy + zz); m.M10 = xy + wz; m.M20 = xz - wy; m.M30 = 0.0F; + m.M01 = xy - wz; m.M11 = 1.0f - (xx + zz); m.M21 = yz + wx; m.M31 = 0.0F; + m.M02 = xz + wy; m.M12 = yz - wx; m.M22 = 1.0f - (xx + yy); m.M32 = 0.0F; + m.M03 = 0.0F; m.M13 = 0.0F; m.M23 = 0.0F; m.M33 = 1.0F; + return m; + } + } +} diff --git a/AssetStudio/Math/Quaternion.cs b/AssetStudio/Math/Quaternion.cs new file mode 100644 index 0000000..5633ed6 --- /dev/null +++ b/AssetStudio/Math/Quaternion.cs @@ -0,0 +1,66 @@ +using System; +using System.Runtime.InteropServices; + +namespace AssetStudio +{ + [StructLayout(LayoutKind.Sequential)] + public struct Quaternion : IEquatable + { + public float X; + public float Y; + public float Z; + public float W; + + public Quaternion(float x, float y, float z, float w) + { + X = x; + Y = y; + Z = z; + W = w; + } + + public float this[int index] + { + get + { + switch (index) + { + case 0: return X; + case 1: return Y; + case 2: return Z; + case 3: return W; + default: throw new IndexOutOfRangeException("Invalid Quaternion index!"); + } + } + + set + { + switch (index) + { + case 0: X = value; break; + case 1: Y = value; break; + case 2: Z = value; break; + case 3: W = value; break; + default: throw new IndexOutOfRangeException("Invalid Quaternion index!"); + } + } + } + + public override int GetHashCode() + { + return X.GetHashCode() ^ (Y.GetHashCode() << 2) ^ (Z.GetHashCode() >> 2) ^ (W.GetHashCode() >> 1); + } + + public override bool Equals(object other) + { + if (!(other is Quaternion)) + return false; + return Equals((Quaternion)other); + } + + public bool Equals(Quaternion other) + { + return X.Equals(other.X) && Y.Equals(other.Y) && Z.Equals(other.Z) && W.Equals(other.W); + } + } +} diff --git a/AssetStudio/Math/Vector2.cs b/AssetStudio/Math/Vector2.cs new file mode 100644 index 0000000..18e9268 --- /dev/null +++ b/AssetStudio/Math/Vector2.cs @@ -0,0 +1,150 @@ +using System; +using System.Runtime.InteropServices; + +namespace AssetStudio +{ + [StructLayout(LayoutKind.Sequential, Pack = 4)] + public struct Vector2 : IEquatable + { + public float X; + public float Y; + + public Vector2(float x, float y) + { + X = x; + Y = y; + } + + public float this[int index] + { + get + { + switch (index) + { + case 0: return X; + case 1: return Y; + default: + throw new IndexOutOfRangeException("Invalid Vector2 index!"); + } + } + + set + { + switch (index) + { + case 0: X = value; break; + case 1: Y = value; break; + default: + throw new IndexOutOfRangeException("Invalid Vector2 index!"); + } + } + } + + public override int GetHashCode() + { + return X.GetHashCode() ^ (Y.GetHashCode() << 2); + } + + public override bool Equals(object other) + { + if (!(other is Vector2)) + return false; + return Equals((Vector2)other); + } + + public bool Equals(Vector2 other) + { + return X.Equals(other.X) && Y.Equals(other.Y); + } + + public void Normalize() + { + var length = Length(); + if (length > kEpsilon) + { + var invNorm = 1.0f / length; + X *= invNorm; + Y *= invNorm; + } + else + { + X = 0; + Y = 0; + } + } + + public float Length() + { + return (float)Math.Sqrt(LengthSquared()); + } + + public float LengthSquared() + { + return X * X + Y * Y; + } + + public static Vector2 Zero => new Vector2(); + + public static Vector2 operator +(Vector2 a, Vector2 b) + { + return new Vector2(a.X + b.X, a.Y + b.Y); + } + + public static Vector2 operator -(Vector2 a, Vector2 b) + { + return new Vector2(a.X - b.X, a.Y - b.Y); + } + + public static Vector2 operator *(Vector2 a, Vector2 b) + { + return new Vector2(a.X * b.X, a.Y * b.Y); + } + + public static Vector2 operator /(Vector2 a, Vector2 b) + { + return new Vector2(a.X / b.X, a.Y / b.Y); + } + + public static Vector2 operator -(Vector2 a) + { + return new Vector2(-a.X, -a.Y); + } + + public static Vector2 operator *(Vector2 a, float d) + { + return new Vector2(a.X * d, a.Y * d); + } + + public static Vector2 operator *(float d, Vector2 a) + { + return new Vector2(a.X * d, a.Y * d); + } + + public static Vector2 operator /(Vector2 a, float d) + { + return new Vector2(a.X / d, a.Y / d); + } + + public static bool operator ==(Vector2 lhs, Vector2 rhs) + { + return (lhs - rhs).LengthSquared() < kEpsilon * kEpsilon; + } + + public static bool operator !=(Vector2 lhs, Vector2 rhs) + { + return !(lhs == rhs); + } + + public static implicit operator Vector3(Vector2 v) + { + return new Vector3(v.X, v.Y, 0); + } + + public static implicit operator Vector4(Vector2 v) + { + return new Vector4(v.X, v.Y, 0.0F, 0.0F); + } + + private const float kEpsilon = 0.00001F; + } +} diff --git a/AssetStudio/Math/Vector3.cs b/AssetStudio/Math/Vector3.cs new file mode 100644 index 0000000..9bd5c4b --- /dev/null +++ b/AssetStudio/Math/Vector3.cs @@ -0,0 +1,146 @@ +using System; +using System.Runtime.InteropServices; + +namespace AssetStudio +{ + [StructLayout(LayoutKind.Sequential, Pack = 4)] + public struct Vector3 : IEquatable + { + public float X; + public float Y; + public float Z; + + public Vector3(float x, float y, float z) + { + X = x; + Y = y; + Z = z; + } + + public float this[int index] + { + get + { + switch (index) + { + case 0: return X; + case 1: return Y; + case 2: return Z; + default: + throw new IndexOutOfRangeException("Invalid Vector3 index!"); + } + } + + set + { + switch (index) + { + case 0: X = value; break; + case 1: Y = value; break; + case 2: Z = value; break; + default: + throw new IndexOutOfRangeException("Invalid Vector3 index!"); + } + } + } + + public override int GetHashCode() + { + return X.GetHashCode() ^ (Y.GetHashCode() << 2) ^ (Z.GetHashCode() >> 2); + } + + public override bool Equals(object other) + { + if (!(other is Vector3)) + return false; + return Equals((Vector3)other); + } + + public bool Equals(Vector3 other) + { + return X.Equals(other.X) && Y.Equals(other.Y) && Z.Equals(other.Z); + } + + public void Normalize() + { + var length = Length(); + if (length > kEpsilon) + { + var invNorm = 1.0f / length; + X *= invNorm; + Y *= invNorm; + Z *= invNorm; + } + else + { + X = 0; + Y = 0; + Z = 0; + } + } + + public float Length() + { + return (float)Math.Sqrt(LengthSquared()); + } + + public float LengthSquared() + { + return X * X + Y * Y + Z * Z; + } + + public static Vector3 Zero => new Vector3(); + + public static Vector3 operator +(Vector3 a, Vector3 b) + { + return new Vector3(a.X + b.X, a.Y + b.Y, a.Z + b.Z); + } + + public static Vector3 operator -(Vector3 a, Vector3 b) + { + return new Vector3(a.X - b.X, a.Y - b.Y, a.Z - b.Z); + } + + public static Vector3 operator -(Vector3 a) + { + return new Vector3(-a.X, -a.Y, -a.Z); + } + + public static Vector3 operator *(Vector3 a, float d) + { + return new Vector3(a.X * d, a.Y * d, a.Z * d); + } + + public static Vector3 operator *(float d, Vector3 a) + { + return new Vector3(a.X * d, a.Y * d, a.Z * d); + } + + public static Vector3 operator /(Vector3 a, float d) + { + return new Vector3(a.X / d, a.Y / d, a.Z / d); + } + + public static bool operator ==(Vector3 lhs, Vector3 rhs) + { + return (lhs - rhs).LengthSquared() < kEpsilon * kEpsilon; + } + + public static bool operator !=(Vector3 lhs, Vector3 rhs) + { + return !(lhs == rhs); + } + + public static implicit operator Vector2(Vector3 v) + { + return new Vector2(v.X, v.Y); + } + + public static implicit operator Vector4(Vector3 v) + { + return new Vector4(v.X, v.Y, v.Z, 0.0F); + } + + private const float kEpsilon = 0.00001F; + } +} diff --git a/AssetStudio/Math/Vector4.cs b/AssetStudio/Math/Vector4.cs new file mode 100644 index 0000000..ed4dc7a --- /dev/null +++ b/AssetStudio/Math/Vector4.cs @@ -0,0 +1,163 @@ +using System; +using System.Runtime.InteropServices; + +namespace AssetStudio +{ + [StructLayout(LayoutKind.Sequential, Pack = 4)] + public struct Vector4 : IEquatable + { + public float X; + public float Y; + public float Z; + public float W; + + public Vector4(float x, float y, float z, float w) + { + X = x; + Y = y; + Z = z; + W = w; + } + + public Vector4(Vector3 value, float w) + { + X = value.X; + Y = value.Y; + Z = value.Z; + W = w; + } + + public float this[int index] + { + get + { + switch (index) + { + case 0: return X; + case 1: return Y; + case 2: return Z; + case 3: return W; + default: throw new IndexOutOfRangeException("Invalid Vector4 index!"); + } + } + + set + { + switch (index) + { + case 0: X = value; break; + case 1: Y = value; break; + case 2: Z = value; break; + case 3: W = value; break; + default: throw new IndexOutOfRangeException("Invalid Vector4 index!"); + } + } + } + + public override int GetHashCode() + { + return X.GetHashCode() ^ (Y.GetHashCode() << 2) ^ (Z.GetHashCode() >> 2) ^ (W.GetHashCode() >> 1); + } + + public override bool Equals(object other) + { + if (!(other is Vector4)) + return false; + return Equals((Vector4)other); + } + + public bool Equals(Vector4 other) + { + return X.Equals(other.X) && Y.Equals(other.Y) && Z.Equals(other.Z) && W.Equals(other.W); + } + + public void Normalize() + { + var length = Length(); + if (length > kEpsilon) + { + var invNorm = 1.0f / length; + X *= invNorm; + Y *= invNorm; + Z *= invNorm; + W *= invNorm; + } + else + { + X = 0; + Y = 0; + Z = 0; + W = 0; + } + } + + public float Length() + { + return (float)Math.Sqrt(LengthSquared()); + } + + public float LengthSquared() + { + return X * X + Y * Y + Z * Z + W * W; + } + + public static Vector4 Zero => new Vector4(); + + public static Vector4 operator +(Vector4 a, Vector4 b) + { + return new Vector4(a.X + b.X, a.Y + b.Y, a.Z + b.Z, a.W + b.W); + } + + public static Vector4 operator -(Vector4 a, Vector4 b) + { + return new Vector4(a.X - b.X, a.Y - b.Y, a.Z - b.Z, a.W - b.W); + } + + public static Vector4 operator -(Vector4 a) + { + return new Vector4(-a.X, -a.Y, -a.Z, -a.W); + } + + public static Vector4 operator *(Vector4 a, float d) + { + return new Vector4(a.X * d, a.Y * d, a.Z * d, a.W * d); + } + + public static Vector4 operator *(float d, Vector4 a) + { + return new Vector4(a.X * d, a.Y * d, a.Z * d, a.W * d); + } + + public static Vector4 operator /(Vector4 a, float d) + { + return new Vector4(a.X / d, a.Y / d, a.Z / d, a.W / d); + } + + public static bool operator ==(Vector4 lhs, Vector4 rhs) + { + return (lhs - rhs).LengthSquared() < kEpsilon * kEpsilon; + } + + public static bool operator !=(Vector4 lhs, Vector4 rhs) + { + return !(lhs == rhs); + } + + public static implicit operator Vector2(Vector4 v) + { + return new Vector2(v.X, v.Y); + } + + public static implicit operator Vector3(Vector4 v) + { + return new Vector3(v.X, v.Y, v.Z); + } + + public static implicit operator Color(Vector4 v) + { + return new Color(v.X, v.Y, v.Z, v.W); + } + + private const float kEpsilon = 0.00001F; + } +} diff --git a/AssetStudioFBX/AssetStudioFBX.h b/AssetStudioFBX/AssetStudioFBX.h index 0e04841..3cbb0b6 100644 --- a/AssetStudioFBX/AssetStudioFBX.h +++ b/AssetStudioFBX/AssetStudioFBX.h @@ -9,7 +9,6 @@ using namespace System; using namespace System::Collections::Generic; using namespace System::IO; using namespace System::Runtime::InteropServices; -using namespace SharpDX; #define WITH_MARSHALLED_STRING(name,str,block)\ { \ diff --git a/AssetStudioFBX/AssetStudioFBX.vcxproj b/AssetStudioFBX/AssetStudioFBX.vcxproj index 8dde759..ef3e2f4 100644 --- a/AssetStudioFBX/AssetStudioFBX.vcxproj +++ b/AssetStudioFBX/AssetStudioFBX.vcxproj @@ -140,12 +140,6 @@ - - ..\AssetStudio\Libraries\SharpDX.dll - - - ..\AssetStudio\Libraries\SharpDX.Mathematics.dll - diff --git a/AssetStudioFBX/AssetStudioFBXExporter.cpp b/AssetStudioFBX/AssetStudioFBXExporter.cpp index b0244fa..aefa6c5 100644 --- a/AssetStudioFBX/AssetStudioFBXExporter.cpp +++ b/AssetStudioFBX/AssetStudioFBXExporter.cpp @@ -409,7 +409,7 @@ namespace AssetStudio for (int j = 0; j < vertexList->Count; j++) { ImportedVertexWithColour^ vert = (ImportedVertexWithColour^)vertexList[j]; - lGeometryElementVertexColor->GetDirectArray().Add(FbxColor(vert->Colour.Red, vert->Colour.Green, vert->Colour.Blue, vert->Colour.Alpha)); + lGeometryElementVertexColor->GetDirectArray().Add(FbxColor(vert->Colour.R, vert->Colour.G, vert->Colour.B, vert->Colour.A)); } } @@ -451,22 +451,22 @@ namespace AssetStudio else { FbxString lShadingName = "Phong"; - Color4 diffuse = mat->Diffuse; - Color4 ambient = mat->Ambient; - Color4 emissive = mat->Emissive; - Color4 specular = mat->Specular; - Color4 reflection = mat->Reflection; + Color diffuse = mat->Diffuse; + Color ambient = mat->Ambient; + Color emissive = mat->Emissive; + Color specular = mat->Specular; + Color reflection = mat->Reflection; pMat = FbxSurfacePhong::Create(pScene, pMatName); - pMat->Diffuse.Set(FbxDouble3(diffuse.Red, diffuse.Green, diffuse.Blue)); - pMat->DiffuseFactor.Set(FbxDouble(diffuse.Alpha)); - pMat->Ambient.Set(FbxDouble3(ambient.Red, ambient.Green, ambient.Blue)); - pMat->AmbientFactor.Set(FbxDouble(ambient.Alpha)); - pMat->Emissive.Set(FbxDouble3(emissive.Red, emissive.Green, emissive.Blue)); - pMat->EmissiveFactor.Set(FbxDouble(emissive.Alpha)); - pMat->Specular.Set(FbxDouble3(specular.Red, specular.Green, specular.Blue)); - pMat->SpecularFactor.Set(FbxDouble(specular.Alpha)); - pMat->Reflection.Set(FbxDouble3(reflection.Red, reflection.Green, reflection.Blue)); - pMat->ReflectionFactor.Set(FbxDouble(reflection.Alpha)); + pMat->Diffuse.Set(FbxDouble3(diffuse.R, diffuse.G, diffuse.B)); + pMat->DiffuseFactor.Set(FbxDouble(diffuse.A)); + pMat->Ambient.Set(FbxDouble3(ambient.R, ambient.G, ambient.B)); + pMat->AmbientFactor.Set(FbxDouble(ambient.A)); + pMat->Emissive.Set(FbxDouble3(emissive.R, emissive.G, emissive.B)); + pMat->EmissiveFactor.Set(FbxDouble(emissive.A)); + pMat->Specular.Set(FbxDouble3(specular.R, specular.G, specular.B)); + pMat->SpecularFactor.Set(FbxDouble(specular.A)); + pMat->Reflection.Set(FbxDouble3(reflection.R, reflection.G, reflection.B)); + pMat->ReflectionFactor.Set(FbxDouble(reflection.A)); pMat->Shininess.Set(FbxDouble(mat->Shininess)); pMat->TransparencyFactor.Set(FbxDouble(mat->Transparency)); pMat->ShadingModel.Set(lShadingName); diff --git a/AssetStudioGUI/AssetStudioGUIForm.cs b/AssetStudioGUI/AssetStudioGUIForm.cs index 8b00a11..6dc677d 100644 --- a/AssetStudioGUI/AssetStudioGUIForm.cs +++ b/AssetStudioGUI/AssetStudioGUIForm.cs @@ -16,6 +16,8 @@ using AssetStudio; using static AssetStudioGUI.Studio; using Object = AssetStudio.Object; using Font = AssetStudio.Font; +using Vector3 = OpenTK.Vector3; +using Vector4 = OpenTK.Vector4; namespace AssetStudioGUI { @@ -1449,7 +1451,7 @@ namespace AssetStudioGUI private void InitOpenTK() { ChangeGLSize(glControl1.Size); - GL.ClearColor(Color.CadetBlue); + GL.ClearColor(System.Drawing.Color.CadetBlue); pgmID = GL.CreateProgram(); LoadShader("vs", ShaderType.VertexShader, pgmID, out int vsID); LoadShader("fs", ShaderType.FragmentShader, pgmID, out int fsID); diff --git a/AssetStudioUtility/AssetStudioUtility.csproj b/AssetStudioUtility/AssetStudioUtility.csproj index a579872..6569151 100644 --- a/AssetStudioUtility/AssetStudioUtility.csproj +++ b/AssetStudioUtility/AssetStudioUtility.csproj @@ -59,15 +59,9 @@ ..\AssetStudio\Libraries\SharpDX.D3DCompiler.dll - - ..\AssetStudio\Libraries\SharpDX.Mathematics.dll - - - ..\AssetStudio\Libraries\System.Half.dll - diff --git a/AssetStudioUtility/ModelConverter.cs b/AssetStudioUtility/ModelConverter.cs index 17fc5b1..165d1fc 100644 --- a/AssetStudioUtility/ModelConverter.cs +++ b/AssetStudioUtility/ModelConverter.cs @@ -4,7 +4,6 @@ using System.Drawing.Imaging; using System.IO; using System.Linq; using System.Text; -using SharpDX; namespace AssetStudio { @@ -308,11 +307,11 @@ namespace AssetStudio { if (mesh.m_Colors.Length == mesh.m_VertexCount * 3) { - ((ImportedVertexWithColour)iVertex).Colour = new Color4(mesh.m_Colors[j * 3], mesh.m_Colors[j * 3 + 1], mesh.m_Colors[j * 3 + 2], 1.0f); + ((ImportedVertexWithColour)iVertex).Colour = new Color(mesh.m_Colors[j * 3], mesh.m_Colors[j * 3 + 1], mesh.m_Colors[j * 3 + 2], 1.0f); } else { - ((ImportedVertexWithColour)iVertex).Colour = new Color4(mesh.m_Colors[j * 4], mesh.m_Colors[j * 4 + 1], mesh.m_Colors[j * 4 + 2], mesh.m_Colors[j * 4 + 3]); + ((ImportedVertexWithColour)iVertex).Colour = new Color(mesh.m_Colors[j * 4], mesh.m_Colors[j * 4 + 1], mesh.m_Colors[j * 4 + 2], mesh.m_Colors[j * 4 + 3]); } } //UV @@ -364,8 +363,9 @@ namespace AssetStudio //Bone if (sMesh.m_Bones.Length > 0) { - iMesh.BoneList = new List(sMesh.m_Bones.Length); - for (int i = 0; i < sMesh.m_Bones.Length; i++) + var boneMax = Math.Min(sMesh.m_Bones.Length, mesh.m_BindPose.Length); + iMesh.BoneList = new List(boneMax); + for (int i = 0; i < boneMax; i++) { var bone = new ImportedBone(); if (sMesh.m_Bones[i].TryGet(out var m_Transform)) @@ -374,8 +374,8 @@ namespace AssetStudio } if (!string.IsNullOrEmpty(bone.Path)) { - var convert = Matrix.Scaling(new Vector3(-1, 1, 1)); - bone.Matrix = convert * Matrix.Transpose(mesh.m_BindPose[i]) * convert; + var convert = Matrix4x4.Scale(new Vector3(-1, 1, 1)); + bone.Matrix = convert * mesh.m_BindPose[i] * convert; iMesh.BoneList.Add(bone); } } @@ -391,8 +391,8 @@ namespace AssetStudio bone.Path = FixBonePath(path); if (!string.IsNullOrEmpty(bone.Path)) { - var convert = Matrix.Scaling(new Vector3(-1, 1, 1)); - bone.Matrix = convert * Matrix.Transpose(mesh.m_BindPose[i]) * convert; + var convert = Matrix4x4.Scale(new Vector3(-1, 1, 1)); + bone.Matrix = convert * mesh.m_BindPose[i] * convert; iMesh.BoneList.Add(bone); } } diff --git a/AssetStudioUtility/SpriteHelper.cs b/AssetStudioUtility/SpriteHelper.cs index c60b5cf..48e3416 100644 --- a/AssetStudioUtility/SpriteHelper.cs +++ b/AssetStudioUtility/SpriteHelper.cs @@ -4,8 +4,6 @@ using System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.IO; using System.Linq; -using SharpDX; -using RectangleF = System.Drawing.RectangleF; namespace AssetStudio { @@ -73,7 +71,7 @@ namespace AssetStudio { path.AddPolygon(p); } - using (var matr = new System.Drawing.Drawing2D.Matrix()) + using (var matr = new Matrix()) { if (m_Sprite.m_Pivot == Vector2.Zero) //5.4.2 down {