Adding Math
This commit is contained in:
parent
335ca7e368
commit
a2dc2bed3c
12
Config.cs
12
Config.cs
@ -6,6 +6,18 @@ using System.Reflection;
|
||||
namespace lib
|
||||
{
|
||||
|
||||
public class DescAttribute : Attribute
|
||||
{
|
||||
public string Desc { get; private set; }
|
||||
|
||||
public DescAttribute( string desc )
|
||||
{
|
||||
Desc = desc;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
[Serializable]
|
||||
public class ResRefConfig<T> : res.Ref<T> where T: Config
|
||||
{
|
||||
|
||||
@ -66,6 +66,56 @@
|
||||
<Compile Include="Config.cs" />
|
||||
<Compile Include="Helpers.cs" />
|
||||
<Compile Include="Log.cs" />
|
||||
<Compile Include="math\AngleSingle.cs" />
|
||||
<Compile Include="math\AngleType.cs" />
|
||||
<Compile Include="math\BoundingBox.cs" />
|
||||
<Compile Include="math\BoundingBoxExt.cs" />
|
||||
<Compile Include="math\BoundingFrustum.cs" />
|
||||
<Compile Include="math\BoundingSphere.cs" />
|
||||
<Compile Include="math\CollisionHelper.cs" />
|
||||
<Compile Include="math\Color.cs" />
|
||||
<Compile Include="math\Color.Palette.cs" />
|
||||
<Compile Include="math\Color3.cs" />
|
||||
<Compile Include="math\Color4.cs" />
|
||||
<Compile Include="math\ColorBGRA.cs" />
|
||||
<Compile Include="math\ColorExtensions.cs" />
|
||||
<Compile Include="math\ColorHSV.cs" />
|
||||
<Compile Include="math\ContainmentType.cs" />
|
||||
<Compile Include="math\DataStyleAttribute.cs" />
|
||||
<Compile Include="math\Double2.cs" />
|
||||
<Compile Include="math\Double3.cs" />
|
||||
<Compile Include="math\Double4.cs" />
|
||||
<Compile Include="math\GuillotinePacker.cs" />
|
||||
<Compile Include="math\Half.cs" />
|
||||
<Compile Include="math\Half2.cs" />
|
||||
<Compile Include="math\Half3.cs" />
|
||||
<Compile Include="math\Half4.cs" />
|
||||
<Compile Include="math\HalfUtils.cs" />
|
||||
<Compile Include="math\Int2.cs" />
|
||||
<Compile Include="math\Int3.cs" />
|
||||
<Compile Include="math\Int4.cs" />
|
||||
<Compile Include="math\MathUtil.cs" />
|
||||
<Compile Include="math\Matrix.cs" />
|
||||
<Compile Include="math\Module.cs" />
|
||||
<Compile Include="math\NamespaceDoc.cs" />
|
||||
<Compile Include="math\Plane.cs" />
|
||||
<Compile Include="math\PlaneIntersectionType.cs" />
|
||||
<Compile Include="math\Point.cs" />
|
||||
<Compile Include="math\Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="math\Quaternion.cs" />
|
||||
<Compile Include="math\RandomSeed.cs" />
|
||||
<Compile Include="math\Ray.cs" />
|
||||
<Compile Include="math\Rectangle.cs" />
|
||||
<Compile Include="math\RectangleF.cs" />
|
||||
<Compile Include="math\Size2.cs" />
|
||||
<Compile Include="math\Size2F.cs" />
|
||||
<Compile Include="math\Size3.cs" />
|
||||
<Compile Include="math\SphericalHarmonics.cs" />
|
||||
<Compile Include="math\UInt4.cs" />
|
||||
<Compile Include="math\Vector2.cs" />
|
||||
<Compile Include="math\Vector3.cs" />
|
||||
<Compile Include="math\Vector4.cs" />
|
||||
<Compile Include="math\VectorExtensions.cs" />
|
||||
<Compile Include="mod\Modules.cs" />
|
||||
<Compile Include="NetMsg.cs" />
|
||||
<Compile Include="Pos.cs" />
|
||||
|
||||
779
math/AngleSingle.cs
Normal file
779
math/AngleSingle.cs
Normal file
@ -0,0 +1,779 @@
|
||||
// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
|
||||
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// Original code from SlimMath project. http://code.google.com/p/slimmath/
|
||||
// Greetings to SlimDX Group. Original code published with the following license:
|
||||
// -----------------------------------------------------------------------------
|
||||
/*
|
||||
* Copyright (c) 2007-2011 SlimDX Group
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace math
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a unit independant angle using a single-precision floating-point
|
||||
/// internal representation.
|
||||
/// </summary>
|
||||
[DataStyle(DataStyle.Compact)]
|
||||
[DataContract]
|
||||
public struct AngleSingle : IComparable, IComparable<AngleSingle>, IEquatable<AngleSingle>, IFormattable
|
||||
{
|
||||
/// <summary>
|
||||
/// A value that specifies the size of a single degree.
|
||||
/// </summary>
|
||||
public const float Degree = 0.002777777777777778f;
|
||||
|
||||
/// <summary>
|
||||
/// A value that specifies the size of a single minute.
|
||||
/// </summary>
|
||||
public const float Minute = 0.000046296296296296f;
|
||||
|
||||
/// <summary>
|
||||
/// A value that specifies the size of a single second.
|
||||
/// </summary>
|
||||
public const float Second = 0.000000771604938272f;
|
||||
|
||||
/// <summary>
|
||||
/// A value that specifies the size of a single radian.
|
||||
/// </summary>
|
||||
public const float Radian = 0.159154943091895336f;
|
||||
|
||||
/// <summary>
|
||||
/// A value that specifies the size of a single milliradian.
|
||||
/// </summary>
|
||||
public const float Milliradian = 0.0001591549431f;
|
||||
|
||||
/// <summary>
|
||||
/// A value that specifies the size of a single gradian.
|
||||
/// </summary>
|
||||
public const float Gradian = 0.0025f;
|
||||
|
||||
/// <summary>
|
||||
/// The internal representation of the angle.
|
||||
/// </summary>
|
||||
private float radians;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AngleSingle"/> struct with the
|
||||
/// given unit dependant angle and unit type.
|
||||
/// </summary>
|
||||
/// <param name="angle">A unit dependant measure of the angle.</param>
|
||||
/// <param name="type">The type of unit the angle argument is.</param>
|
||||
public AngleSingle(float angle, AngleType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case AngleType.Revolution:
|
||||
radians = MathUtil.RevolutionsToRadians(angle);
|
||||
break;
|
||||
|
||||
case AngleType.Degree:
|
||||
radians = MathUtil.DegreesToRadians(angle);
|
||||
break;
|
||||
|
||||
case AngleType.Radian:
|
||||
radians = angle;
|
||||
break;
|
||||
|
||||
case AngleType.Gradian:
|
||||
radians = MathUtil.GradiansToRadians(angle);
|
||||
break;
|
||||
|
||||
default:
|
||||
radians = 0.0f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AngleSingle"/> struct using the
|
||||
/// arc length formula (θ = s/r).
|
||||
/// </summary>
|
||||
/// <param name="arcLength">The measure of the arc.</param>
|
||||
/// <param name="radius">The radius of the circle.</param>
|
||||
public AngleSingle(float arcLength, float radius)
|
||||
{
|
||||
radians = arcLength / radius;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wraps this math.AngleSingle to be in the range [π, -π].
|
||||
/// </summary>
|
||||
public void Wrap()
|
||||
{
|
||||
float newangle = (float)Math.IEEERemainder(radians, MathUtil.TwoPi);
|
||||
|
||||
if (newangle <= -MathUtil.Pi)
|
||||
newangle += MathUtil.TwoPi;
|
||||
else if (newangle > MathUtil.Pi)
|
||||
newangle -= MathUtil.TwoPi;
|
||||
|
||||
radians = newangle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wraps this math.AngleSingle to be in the range [0, 2π).
|
||||
/// </summary>
|
||||
public void WrapPositive()
|
||||
{
|
||||
float newangle = radians % MathUtil.TwoPi;
|
||||
|
||||
if (newangle < 0.0)
|
||||
newangle += MathUtil.TwoPi;
|
||||
|
||||
radians = newangle;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the total number of revolutions this math.AngleSingle represents.
|
||||
/// </summary>
|
||||
[DataMemberIgnore]
|
||||
public float Revolutions
|
||||
{
|
||||
get { return MathUtil.RadiansToRevolutions(radians); }
|
||||
set { radians = MathUtil.RevolutionsToRadians(value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the total number of degrees this math.AngleSingle represents.
|
||||
/// </summary>
|
||||
[DataMemberIgnore]
|
||||
public float Degrees
|
||||
{
|
||||
get { return MathUtil.RadiansToDegrees(radians); }
|
||||
set { radians = MathUtil.DegreesToRadians(value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the minutes component of the degrees this math.AngleSingle represents.
|
||||
/// When setting the minutes, if the value is in the range (-60, 60) the whole degrees are
|
||||
/// not changed; otherwise, the whole degrees may be changed. Fractional values may set
|
||||
/// the seconds component.
|
||||
/// </summary>
|
||||
[DataMemberIgnore]
|
||||
public float Minutes
|
||||
{
|
||||
get
|
||||
{
|
||||
float degrees = MathUtil.RadiansToDegrees(radians);
|
||||
|
||||
if (degrees < 0)
|
||||
{
|
||||
float degreesfloor = (float)Math.Ceiling(degrees);
|
||||
return (degrees - degreesfloor) * 60.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
float degreesfloor = (float)Math.Floor(degrees);
|
||||
return (degrees - degreesfloor) * 60.0f;
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
float degrees = MathUtil.RadiansToDegrees(radians);
|
||||
float degreesfloor = (float)Math.Floor(degrees);
|
||||
|
||||
degreesfloor += value / 60.0f;
|
||||
radians = MathUtil.DegreesToRadians(degreesfloor);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the seconds of the degrees this math.AngleSingle represents.
|
||||
/// When setting te seconds, if the value is in the range (-60, 60) the whole minutes
|
||||
/// or whole degrees are not changed; otherwise, the whole minutes or whole degrees
|
||||
/// may be changed.
|
||||
/// </summary>
|
||||
[DataMemberIgnore]
|
||||
public float Seconds
|
||||
{
|
||||
get
|
||||
{
|
||||
float degrees = MathUtil.RadiansToDegrees(radians);
|
||||
|
||||
if (degrees < 0)
|
||||
{
|
||||
float degreesfloor = (float)Math.Ceiling(degrees);
|
||||
|
||||
float minutes = (degrees - degreesfloor) * 60.0f;
|
||||
float minutesfloor = (float)Math.Ceiling(minutes);
|
||||
|
||||
return (minutes - minutesfloor) * 60.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
float degreesfloor = (float)Math.Floor(degrees);
|
||||
|
||||
float minutes = (degrees - degreesfloor) * 60.0f;
|
||||
float minutesfloor = (float)Math.Floor(minutes);
|
||||
|
||||
return (minutes - minutesfloor) * 60.0f;
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
float degrees = MathUtil.RadiansToDegrees(radians);
|
||||
float degreesfloor = (float)Math.Floor(degrees);
|
||||
|
||||
float minutes = (degrees - degreesfloor) * 60.0f;
|
||||
float minutesfloor = (float)Math.Floor(minutes);
|
||||
|
||||
minutesfloor += value / 60.0f;
|
||||
degreesfloor += minutesfloor / 60.0f;
|
||||
radians = MathUtil.DegreesToRadians(degreesfloor);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the total number of radians this math.AngleSingle represents.
|
||||
/// </summary>
|
||||
public float Radians
|
||||
{
|
||||
get { return radians; }
|
||||
set { radians = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the total number of milliradians this math.AngleSingle represents.
|
||||
/// One milliradian is equal to 1/(2000π).
|
||||
/// </summary>
|
||||
[DataMemberIgnore]
|
||||
public float Milliradians
|
||||
{
|
||||
get { return radians / (Milliradian * MathUtil.TwoPi); }
|
||||
set { radians = value * (Milliradian * MathUtil.TwoPi); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the total number of gradians this math.AngleSingle represents.
|
||||
/// </summary>
|
||||
[DataMemberIgnore]
|
||||
public float Gradians
|
||||
{
|
||||
get { return MathUtil.RadiansToGradians(radians); }
|
||||
set { radians = MathUtil.GradiansToRadians(value); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a System.Boolean that determines whether this math.Angle
|
||||
/// is a right angle (i.e. 90° or π/2).
|
||||
/// </summary>
|
||||
[DataMemberIgnore]
|
||||
public bool IsRight
|
||||
{
|
||||
get { return radians == MathUtil.PiOverTwo; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a System.Boolean that determines whether this math.Angle
|
||||
/// is a straight angle (i.e. 180° or π).
|
||||
/// </summary>
|
||||
[DataMemberIgnore]
|
||||
public bool IsStraight
|
||||
{
|
||||
get { return radians == MathUtil.Pi; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a System.Boolean that determines whether this math.Angle
|
||||
/// is a full rotation angle (i.e. 360° or 2π).
|
||||
/// </summary>
|
||||
[DataMemberIgnore]
|
||||
public bool IsFullRotation
|
||||
{
|
||||
get { return radians == MathUtil.TwoPi; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a System.Boolean that determines whether this math.Angle
|
||||
/// is an oblique angle (i.e. is not 90° or a multiple of 90°).
|
||||
/// </summary>
|
||||
[DataMemberIgnore]
|
||||
public bool IsOblique
|
||||
{
|
||||
get { return WrapPositive(this).radians != MathUtil.PiOverTwo; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a System.Boolean that determines whether this math.Angle
|
||||
/// is an acute angle (i.e. less than 90° but greater than 0°).
|
||||
/// </summary>
|
||||
[DataMemberIgnore]
|
||||
public bool IsAcute
|
||||
{
|
||||
get { return radians > 0.0 && radians < MathUtil.PiOverTwo; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a System.Boolean that determines whether this math.Angle
|
||||
/// is an obtuse angle (i.e. greater than 90° but less than 180°).
|
||||
/// </summary>
|
||||
[DataMemberIgnore]
|
||||
public bool IsObtuse
|
||||
{
|
||||
get { return radians > MathUtil.PiOverTwo && radians < MathUtil.Pi; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a System.Boolean that determines whether this math.Angle
|
||||
/// is a reflex angle (i.e. greater than 180° but less than 360°).
|
||||
/// </summary>
|
||||
[DataMemberIgnore]
|
||||
public bool IsReflex
|
||||
{
|
||||
get { return radians > MathUtil.Pi && radians < MathUtil.TwoPi; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a math.AngleSingle instance that complements this angle (i.e. the two angles add to 90°).
|
||||
/// </summary>
|
||||
[DataMemberIgnore]
|
||||
public AngleSingle Complement
|
||||
{
|
||||
get { return new AngleSingle(MathUtil.PiOverTwo - radians, AngleType.Radian); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a math.AngleSingle instance that supplements this angle (i.e. the two angles add to 180°).
|
||||
/// </summary>
|
||||
[DataMemberIgnore]
|
||||
public AngleSingle Supplement
|
||||
{
|
||||
get { return new AngleSingle(MathUtil.Pi - radians, AngleType.Radian); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wraps the math.AngleSingle given in the value argument to be in the range [π, -π].
|
||||
/// </summary>
|
||||
/// <param name="value">A math.AngleSingle to wrap.</param>
|
||||
/// <returns>The math.AngleSingle that is wrapped.</returns>
|
||||
public static AngleSingle Wrap(AngleSingle value)
|
||||
{
|
||||
value.Wrap();
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Wraps the math.AngleSingle given in the value argument to be in the range [0, 2π).
|
||||
/// </summary>
|
||||
/// <param name="value">A math.AngleSingle to wrap.</param>
|
||||
/// <returns>The math.AngleSingle that is wrapped.</returns>
|
||||
public static AngleSingle WrapPositive(AngleSingle value)
|
||||
{
|
||||
value.WrapPositive();
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two math.AngleSingle instances and returns the smaller angle.
|
||||
/// </summary>
|
||||
/// <param name="left">The first math.AngleSingle instance to compare.</param>
|
||||
/// <param name="right">The second math.AngleSingle instance to compare.</param>
|
||||
/// <returns>The smaller of the two given math.AngleSingle instances.</returns>
|
||||
public static AngleSingle Min(AngleSingle left, AngleSingle right)
|
||||
{
|
||||
if (left.radians < right.radians)
|
||||
return left;
|
||||
|
||||
return right;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two math.AngleSingle instances and returns the greater angle.
|
||||
/// </summary>
|
||||
/// <param name="left">The first math.AngleSingle instance to compare.</param>
|
||||
/// <param name="right">The second math.AngleSingle instance to compare.</param>
|
||||
/// <returns>The greater of the two given math.AngleSingle instances.</returns>
|
||||
public static AngleSingle Max(AngleSingle left, AngleSingle right)
|
||||
{
|
||||
if (left.radians > right.radians)
|
||||
return left;
|
||||
|
||||
return right;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds two math.AngleSingle objects and returns the result.
|
||||
/// </summary>
|
||||
/// <param name="left">The first object to add.</param>
|
||||
/// <param name="right">The second object to add.</param>
|
||||
/// <returns>The value of the two objects added together.</returns>
|
||||
public static AngleSingle Add(AngleSingle left, AngleSingle right)
|
||||
{
|
||||
return new AngleSingle(left.radians + right.radians, AngleType.Radian);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subtracts two math.AngleSingle objects and returns the result.
|
||||
/// </summary>
|
||||
/// <param name="left">The first object to subtract.</param>
|
||||
/// <param name="right">The second object to subtract.</param>
|
||||
/// <returns>The value of the two objects subtracted.</returns>
|
||||
public static AngleSingle Subtract(AngleSingle left, AngleSingle right)
|
||||
{
|
||||
return new AngleSingle(left.radians - right.radians, AngleType.Radian);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Multiplies two math.AngleSingle objects and returns the result.
|
||||
/// </summary>
|
||||
/// <param name="left">The first object to multiply.</param>
|
||||
/// <param name="right">The second object to multiply.</param>
|
||||
/// <returns>The value of the two objects multiplied together.</returns>
|
||||
public static AngleSingle Multiply(AngleSingle left, AngleSingle right)
|
||||
{
|
||||
return new AngleSingle(left.radians * right.radians, AngleType.Radian);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Divides two math.AngleSingle objects and returns the result.
|
||||
/// </summary>
|
||||
/// <param name="left">The numerator object.</param>
|
||||
/// <param name="right">The denominator object.</param>
|
||||
/// <returns>The value of the two objects divided.</returns>
|
||||
public static AngleSingle Divide(AngleSingle left, AngleSingle right)
|
||||
{
|
||||
return new AngleSingle(left.radians / right.radians, AngleType.Radian);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a new math.AngleSingle instance that represents the zero angle (i.e. 0°).
|
||||
/// </summary>
|
||||
public static AngleSingle ZeroAngle
|
||||
{
|
||||
get { return new AngleSingle(0.0f, AngleType.Radian); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a new math.AngleSingle instance that represents the right angle (i.e. 90° or π/2).
|
||||
/// </summary>
|
||||
public static AngleSingle RightAngle
|
||||
{
|
||||
get { return new AngleSingle(MathUtil.PiOverTwo, AngleType.Radian); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a new math.AngleSingle instance that represents the straight angle (i.e. 180° or π).
|
||||
/// </summary>
|
||||
public static AngleSingle StraightAngle
|
||||
{
|
||||
get { return new AngleSingle(MathUtil.Pi, AngleType.Radian); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a new math.AngleSingle instance that represents the full rotation angle (i.e. 360° or 2π).
|
||||
/// </summary>
|
||||
public static AngleSingle FullRotationAngle
|
||||
{
|
||||
get { return new AngleSingle(MathUtil.TwoPi, AngleType.Radian); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a System.Boolean that indicates whether the values of two math.Angle
|
||||
/// objects are equal.
|
||||
/// </summary>
|
||||
/// <param name="left">The first object to compare.</param>
|
||||
/// <param name="right">The second object to compare.</param>
|
||||
/// <returns>True if the left and right parameters have the same value; otherwise, false.</returns>
|
||||
public static bool operator ==(AngleSingle left, AngleSingle right)
|
||||
{
|
||||
return left.radians == right.radians;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a System.Boolean that indicates whether the values of two math.Angle
|
||||
/// objects are not equal.
|
||||
/// </summary>
|
||||
/// <param name="left">The first object to compare.</param>
|
||||
/// <param name="right">The second object to compare.</param>
|
||||
/// <returns>True if the left and right parameters do not have the same value; otherwise, false.</returns>
|
||||
public static bool operator !=(AngleSingle left, AngleSingle right)
|
||||
{
|
||||
return left.radians != right.radians;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a System.Boolean that indicates whether a math.Angle
|
||||
/// object is less than another math.AngleSingle object.
|
||||
/// </summary>
|
||||
/// <param name="left">The first object to compare.</param>
|
||||
/// <param name="right">The second object to compare.</param>
|
||||
/// <returns>True if left is less than right; otherwise, false.</returns>
|
||||
public static bool operator <(AngleSingle left, AngleSingle right)
|
||||
{
|
||||
return left.radians < right.radians;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a System.Boolean that indicates whether a math.Angle
|
||||
/// object is greater than another math.AngleSingle object.
|
||||
/// </summary>
|
||||
/// <param name="left">The first object to compare.</param>
|
||||
/// <param name="right">The second object to compare.</param>
|
||||
/// <returns>True if left is greater than right; otherwise, false.</returns>
|
||||
public static bool operator >(AngleSingle left, AngleSingle right)
|
||||
{
|
||||
return left.radians > right.radians;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a System.Boolean that indicates whether a math.Angle
|
||||
/// object is less than or equal to another math.AngleSingle object.
|
||||
/// </summary>
|
||||
/// <param name="left">The first object to compare.</param>
|
||||
/// <param name="right">The second object to compare.</param>
|
||||
/// <returns>True if left is less than or equal to right; otherwise, false.</returns>
|
||||
public static bool operator <=(AngleSingle left, AngleSingle right)
|
||||
{
|
||||
return left.radians <= right.radians;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a System.Boolean that indicates whether a math.Angle
|
||||
/// object is greater than or equal to another math.AngleSingle object.
|
||||
/// </summary>
|
||||
/// <param name="left">The first object to compare.</param>
|
||||
/// <param name="right">The second object to compare.</param>
|
||||
/// <returns>True if left is greater than or equal to right; otherwise, false.</returns>
|
||||
public static bool operator >=(AngleSingle left, AngleSingle right)
|
||||
{
|
||||
return left.radians >= right.radians;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the value of the math.AngleSingle operand. (The sign of
|
||||
/// the operand is unchanged.)
|
||||
/// </summary>
|
||||
/// <param name="value">A math.AngleSingle object.</param>
|
||||
/// <returns>The value of the value parameter.</returns>
|
||||
public static AngleSingle operator +(AngleSingle value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the the negated value of the math.AngleSingle operand.
|
||||
/// </summary>
|
||||
/// <param name="value">A math.AngleSingle object.</param>
|
||||
/// <returns>The negated value of the value parameter.</returns>
|
||||
public static AngleSingle operator -(AngleSingle value)
|
||||
{
|
||||
return new AngleSingle(-value.radians, AngleType.Radian);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds two math.AngleSingle objects and returns the result.
|
||||
/// </summary>
|
||||
/// <param name="left">The first object to add.</param>
|
||||
/// <param name="right">The second object to add.</param>
|
||||
/// <returns>The value of the two objects added together.</returns>
|
||||
public static AngleSingle operator +(AngleSingle left, AngleSingle right)
|
||||
{
|
||||
return new AngleSingle(left.radians + right.radians, AngleType.Radian);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subtracts two math.AngleSingle objects and returns the result.
|
||||
/// </summary>
|
||||
/// <param name="left">The first object to subtract</param>
|
||||
/// <param name="right">The second object to subtract.</param>
|
||||
/// <returns>The value of the two objects subtracted.</returns>
|
||||
public static AngleSingle operator -(AngleSingle left, AngleSingle right)
|
||||
{
|
||||
return new AngleSingle(left.radians - right.radians, AngleType.Radian);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Multiplies two math.AngleSingle objects and returns the result.
|
||||
/// </summary>
|
||||
/// <param name="left">The first object to multiply.</param>
|
||||
/// <param name="right">The second object to multiply.</param>
|
||||
/// <returns>The value of the two objects multiplied together.</returns>
|
||||
public static AngleSingle operator *(AngleSingle left, AngleSingle right)
|
||||
{
|
||||
return new AngleSingle(left.radians * right.radians, AngleType.Radian);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Divides two math.AngleSingle objects and returns the result.
|
||||
/// </summary>
|
||||
/// <param name="left">The numerator object.</param>
|
||||
/// <param name="right">The denominator object.</param>
|
||||
/// <returns>The value of the two objects divided.</returns>
|
||||
public static AngleSingle operator /(AngleSingle left, AngleSingle right)
|
||||
{
|
||||
return new AngleSingle(left.radians / right.radians, AngleType.Radian);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares this instance to a specified object and returns an integer that
|
||||
/// indicates whether the value of this instance is less than, equal to, or greater
|
||||
/// than the value of the specified object.
|
||||
/// </summary>
|
||||
/// <param name="other">The object to compare.</param>
|
||||
/// <returns>
|
||||
/// A signed integer that indicates the relationship of the current instance
|
||||
/// to the obj parameter. If the value is less than zero, the current instance
|
||||
/// is less than the other. If the value is zero, the current instance is equal
|
||||
/// to the other. If the value is greater than zero, the current instance is
|
||||
/// greater than the other.
|
||||
/// </returns>
|
||||
public int CompareTo(object other)
|
||||
{
|
||||
if (other == null)
|
||||
return 1;
|
||||
|
||||
if (!(other is AngleSingle))
|
||||
throw new ArgumentException("Argument must be of type Angle.", "other");
|
||||
|
||||
float radians = ((AngleSingle)other).radians;
|
||||
|
||||
if (this.radians > radians)
|
||||
return 1;
|
||||
|
||||
if (this.radians < radians)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares this instance to a second math.AngleSingle and returns
|
||||
/// an integer that indicates whether the value of this instance is less than,
|
||||
/// equal to, or greater than the value of the specified object.
|
||||
/// </summary>
|
||||
/// <param name="other">The object to compare.</param>
|
||||
/// <returns>
|
||||
/// A signed integer that indicates the relationship of the current instance
|
||||
/// to the obj parameter. If the value is less than zero, the current instance
|
||||
/// is less than the other. If the value is zero, the current instance is equal
|
||||
/// to the other. If the value is greater than zero, the current instance is
|
||||
/// greater than the other.
|
||||
/// </returns>
|
||||
public int CompareTo(AngleSingle other)
|
||||
{
|
||||
if (this.radians > other.radians)
|
||||
return 1;
|
||||
|
||||
if (this.radians < other.radians)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value that indicates whether the current instance and a specified
|
||||
/// math.AngleSingle object have the same value.
|
||||
/// </summary>
|
||||
/// <param name="other">The object to compare.</param>
|
||||
/// <returns>
|
||||
/// Returns true if this math.AngleSingle object and another have the same value;
|
||||
/// otherwise, false.
|
||||
/// </returns>
|
||||
public bool Equals(AngleSingle other)
|
||||
{
|
||||
return this == other;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="string"/> that represents this instance.
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, MathUtil.RadiansToDegrees(radians).ToString("0.##°"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <param name="format">The format.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="string"/> that represents this instance.
|
||||
/// </returns>
|
||||
public string ToString(string format)
|
||||
{
|
||||
if (format == null)
|
||||
return ToString();
|
||||
|
||||
return string.Format(CultureInfo.CurrentCulture, "{0}°", MathUtil.RadiansToDegrees(radians).ToString(format, CultureInfo.CurrentCulture));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <param name="formatProvider">The format provider.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="string"/> that represents this instance.
|
||||
/// </returns>
|
||||
public string ToString(IFormatProvider formatProvider)
|
||||
{
|
||||
return string.Format(formatProvider, MathUtil.RadiansToDegrees(radians).ToString("0.##°"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <param name="format">The format.</param>
|
||||
/// <param name="formatProvider">The format provider.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="string"/> that represents this instance.
|
||||
/// </returns>
|
||||
public string ToString(string format, IFormatProvider formatProvider)
|
||||
{
|
||||
if (format == null)
|
||||
return ToString(formatProvider);
|
||||
|
||||
return string.Format(formatProvider, "{0}°", MathUtil.RadiansToDegrees(radians).ToString(format, CultureInfo.CurrentCulture));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a hash code for this math.AngleSingle instance.
|
||||
/// </summary>
|
||||
/// <returns>A 32-bit signed integer hash code.</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return (int)(BitConverter.DoubleToInt64Bits(radians) % int.MaxValue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value that indicates whether the current instance and a specified
|
||||
/// object have the same value.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object to compare.</param>
|
||||
/// <returns>
|
||||
/// Returns true if the obj parameter is a math.AngleSingle object or a type
|
||||
/// capable of implicit conversion to a math.AngleSingle value, and
|
||||
/// its value is equal to the value of the current math.Angle
|
||||
/// object; otherwise, false.
|
||||
/// </returns>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return (obj is AngleSingle) && (this == (AngleSingle)obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
56
math/AngleType.cs
Normal file
56
math/AngleType.cs
Normal file
@ -0,0 +1,56 @@
|
||||
// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
|
||||
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// Original code from SlimMath project. http://code.google.com/p/slimmath/
|
||||
// Greetings to SlimDX Group. Original code published with the following license:
|
||||
// -----------------------------------------------------------------------------
|
||||
/*
|
||||
* Copyright (c) 2007-2011 SlimDX Group
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
namespace math
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes the type of angle.
|
||||
/// </summary>
|
||||
public enum AngleType
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies an angle measurement in revolutions.
|
||||
/// </summary>
|
||||
Revolution,
|
||||
|
||||
/// <summary>
|
||||
/// Specifies an angle measurement in degrees.
|
||||
/// </summary>
|
||||
Degree,
|
||||
|
||||
/// <summary>
|
||||
/// Specifies an angle measurement in radians.
|
||||
/// </summary>
|
||||
Radian,
|
||||
|
||||
/// <summary>
|
||||
/// Specifies an angle measurement in gradians.
|
||||
/// </summary>
|
||||
Gradian,
|
||||
}
|
||||
}
|
||||
466
math/BoundingBox.cs
Normal file
466
math/BoundingBox.cs
Normal file
@ -0,0 +1,466 @@
|
||||
// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
|
||||
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// Original code from SlimMath project. http://code.google.com/p/slimmath/
|
||||
// Greetings to SlimDX Group. Original code published with the following license:
|
||||
// -----------------------------------------------------------------------------
|
||||
/*
|
||||
* Copyright (c) 2007-2011 SlimDX Group
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace math
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an axis-aligned bounding box in three dimensional space.
|
||||
/// </summary>
|
||||
[DataContract]
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
||||
public struct BoundingBox : IEquatable<BoundingBox>, IFormattable
|
||||
{
|
||||
/// <summary>
|
||||
/// A <see cref="BoundingBox"/> which represents an empty space.
|
||||
/// </summary>
|
||||
public static readonly BoundingBox Empty = new BoundingBox(new Vector3(float.MaxValue), new Vector3(float.MinValue));
|
||||
|
||||
/// <summary>
|
||||
/// The minimum point of the box.
|
||||
/// </summary>
|
||||
public Vector3 Minimum;
|
||||
|
||||
/// <summary>
|
||||
/// The maximum point of the box.
|
||||
/// </summary>
|
||||
public Vector3 Maximum;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="math.BoundingBox"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="minimum">The minimum vertex of the bounding box.</param>
|
||||
/// <param name="maximum">The maximum vertex of the bounding box.</param>
|
||||
public BoundingBox(Vector3 minimum, Vector3 maximum)
|
||||
{
|
||||
this.Minimum = minimum;
|
||||
this.Maximum = maximum;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the center of this bouding box.
|
||||
/// </summary>
|
||||
public Vector3 Center
|
||||
{
|
||||
get { return (Minimum + Maximum) / 2; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the extent of this bouding box.
|
||||
/// </summary>
|
||||
public Vector3 Extent
|
||||
{
|
||||
get { return (Maximum - Minimum) / 2; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the eight corners of the bounding box.
|
||||
/// </summary>
|
||||
/// <returns>An array of points representing the eight corners of the bounding box.</returns>
|
||||
public Vector3[] GetCorners()
|
||||
{
|
||||
Vector3[] results = new Vector3[8];
|
||||
results[0] = new Vector3(Minimum.X, Maximum.Y, Maximum.Z);
|
||||
results[1] = new Vector3(Maximum.X, Maximum.Y, Maximum.Z);
|
||||
results[2] = new Vector3(Maximum.X, Minimum.Y, Maximum.Z);
|
||||
results[3] = new Vector3(Minimum.X, Minimum.Y, Maximum.Z);
|
||||
results[4] = new Vector3(Minimum.X, Maximum.Y, Minimum.Z);
|
||||
results[5] = new Vector3(Maximum.X, Maximum.Y, Minimum.Z);
|
||||
results[6] = new Vector3(Maximum.X, Minimum.Y, Minimum.Z);
|
||||
results[7] = new Vector3(Minimum.X, Minimum.Y, Minimum.Z);
|
||||
return results;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if there is an intersection between the current object and a <see cref="math.Ray"/>.
|
||||
/// </summary>
|
||||
/// <param name="ray">The ray to test.</param>
|
||||
/// <returns>Whether the two objects intersected.</returns>
|
||||
public bool Intersects(ref Ray ray)
|
||||
{
|
||||
float distance;
|
||||
return CollisionHelper.RayIntersectsBox(ref ray, ref this, out distance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if there is an intersection between the current object and a <see cref="math.Ray"/>.
|
||||
/// </summary>
|
||||
/// <param name="ray">The ray to test.</param>
|
||||
/// <param name="distance">When the method completes, contains the distance of the intersection,
|
||||
/// or 0 if there was no intersection.</param>
|
||||
/// <returns>Whether the two objects intersected.</returns>
|
||||
public bool Intersects(ref Ray ray, out float distance)
|
||||
{
|
||||
return CollisionHelper.RayIntersectsBox(ref ray, ref this, out distance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if there is an intersection between the current object and a <see cref="math.Ray"/>.
|
||||
/// </summary>
|
||||
/// <param name="ray">The ray to test.</param>
|
||||
/// <param name="point">When the method completes, contains the point of intersection,
|
||||
/// or <see cref="math.Vector3.Zero"/> if there was no intersection.</param>
|
||||
/// <returns>Whether the two objects intersected.</returns>
|
||||
public bool Intersects(ref Ray ray, out Vector3 point)
|
||||
{
|
||||
return CollisionHelper.RayIntersectsBox(ref ray, ref this, out point);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if there is an intersection between the current object and a <see cref="math.Plane"/>.
|
||||
/// </summary>
|
||||
/// <param name="plane">The plane to test.</param>
|
||||
/// <returns>Whether the two objects intersected.</returns>
|
||||
public PlaneIntersectionType Intersects(ref Plane plane)
|
||||
{
|
||||
return CollisionHelper.PlaneIntersectsBox(ref plane, ref this);
|
||||
}
|
||||
|
||||
/* This implentation is wrong
|
||||
/// <summary>
|
||||
/// Determines if there is an intersection between the current object and a triangle.
|
||||
/// </summary>
|
||||
/// <param name="vertex1">The first vertex of the triangle to test.</param>
|
||||
/// <param name="vertex2">The second vertex of the triagnle to test.</param>
|
||||
/// <param name="vertex3">The third vertex of the triangle to test.</param>
|
||||
/// <returns>Whether the two objects intersected.</returns>
|
||||
public bool Intersects(ref Vector3 vertex1, ref Vector3 vertex2, ref Vector3 vertex3)
|
||||
{
|
||||
return Collision.BoxIntersectsTriangle(ref this, ref vertex1, ref vertex2, ref vertex3);
|
||||
}
|
||||
*/
|
||||
|
||||
/// <summary>
|
||||
/// Determines if there is an intersection between the current object and a <see cref="math.BoundingBox"/>.
|
||||
/// </summary>
|
||||
/// <param name="box">The box to test.</param>
|
||||
/// <returns>Whether the two objects intersected.</returns>
|
||||
public bool Intersects(ref BoundingBox box)
|
||||
{
|
||||
return CollisionHelper.BoxIntersectsBox(ref this, ref box);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if there is an intersection between the current object and a <see cref="math.BoundingSphere"/>.
|
||||
/// </summary>
|
||||
/// <param name="sphere">The sphere to test.</param>
|
||||
/// <returns>Whether the two objects intersected.</returns>
|
||||
public bool Intersects(ref BoundingSphere sphere)
|
||||
{
|
||||
return CollisionHelper.BoxIntersectsSphere(ref this, ref sphere);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the current objects contains a point.
|
||||
/// </summary>
|
||||
/// <param name="point">The point to test.</param>
|
||||
/// <returns>The type of containment the two objects have.</returns>
|
||||
public ContainmentType Contains(ref Vector3 point)
|
||||
{
|
||||
return CollisionHelper.BoxContainsPoint(ref this, ref point);
|
||||
}
|
||||
|
||||
/* This implentation is wrong
|
||||
/// <summary>
|
||||
/// Determines whether the current objects contains a triangle.
|
||||
/// </summary>
|
||||
/// <param name="vertex1">The first vertex of the triangle to test.</param>
|
||||
/// <param name="vertex2">The second vertex of the triagnle to test.</param>
|
||||
/// <param name="vertex3">The third vertex of the triangle to test.</param>
|
||||
/// <returns>The type of containment the two objects have.</returns>
|
||||
public ContainmentType Contains(ref Vector3 vertex1, ref Vector3 vertex2, ref Vector3 vertex3)
|
||||
{
|
||||
return Collision.BoxContainsTriangle(ref this, ref vertex1, ref vertex2, ref vertex3);
|
||||
}
|
||||
*/
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the current objects contains a <see cref="math.BoundingBox"/>.
|
||||
/// </summary>
|
||||
/// <param name="box">The box to test.</param>
|
||||
/// <returns>The type of containment the two objects have.</returns>
|
||||
public ContainmentType Contains(ref BoundingBox box)
|
||||
{
|
||||
return CollisionHelper.BoxContainsBox(ref this, ref box);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the current objects contains a <see cref="math.BoundingSphere"/>.
|
||||
/// </summary>
|
||||
/// <param name="sphere">The sphere to test.</param>
|
||||
/// <returns>The type of containment the two objects have.</returns>
|
||||
public ContainmentType Contains(ref BoundingSphere sphere)
|
||||
{
|
||||
return CollisionHelper.BoxContainsSphere(ref this, ref sphere);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a <see cref="math.BoundingBox"/> that fully contains the given points.
|
||||
/// </summary>
|
||||
/// <param name="points">The points that will be contained by the box.</param>
|
||||
/// <param name="result">When the method completes, contains the newly constructed bounding box.</param>
|
||||
/// <exception cref="ArgumentNullException">Thrown when <paramref name="points"/> is <c>null</c>.</exception>
|
||||
public static void FromPoints(Vector3[] points, out BoundingBox result)
|
||||
{
|
||||
if (points == null)
|
||||
throw new ArgumentNullException("points");
|
||||
|
||||
Vector3 min = new Vector3(float.MaxValue);
|
||||
Vector3 max = new Vector3(float.MinValue);
|
||||
|
||||
for (int i = 0; i < points.Length; ++i)
|
||||
{
|
||||
Vector3.Min(ref min, ref points[i], out min);
|
||||
Vector3.Max(ref max, ref points[i], out max);
|
||||
}
|
||||
|
||||
result = new BoundingBox(min, max);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a <see cref="math.BoundingBox"/> that fully contains the given points.
|
||||
/// </summary>
|
||||
/// <param name="points">The points that will be contained by the box.</param>
|
||||
/// <returns>The newly constructed bounding box.</returns>
|
||||
/// <exception cref="ArgumentNullException">Thrown when <paramref name="points"/> is <c>null</c>.</exception>
|
||||
public static BoundingBox FromPoints(Vector3[] points)
|
||||
{
|
||||
if (points == null)
|
||||
throw new ArgumentNullException("points");
|
||||
|
||||
Vector3 min = new Vector3(float.MaxValue);
|
||||
Vector3 max = new Vector3(float.MinValue);
|
||||
|
||||
for (int i = 0; i < points.Length; ++i)
|
||||
{
|
||||
Vector3.Min(ref min, ref points[i], out min);
|
||||
Vector3.Max(ref max, ref points[i], out max);
|
||||
}
|
||||
|
||||
return new BoundingBox(min, max);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a <see cref="math.BoundingBox"/> from a given sphere.
|
||||
/// </summary>
|
||||
/// <param name="sphere">The sphere that will designate the extents of the box.</param>
|
||||
/// <param name="result">When the method completes, contains the newly constructed bounding box.</param>
|
||||
public static void FromSphere(ref BoundingSphere sphere, out BoundingBox result)
|
||||
{
|
||||
result.Minimum = new Vector3(sphere.Center.X - sphere.Radius, sphere.Center.Y - sphere.Radius, sphere.Center.Z - sphere.Radius);
|
||||
result.Maximum = new Vector3(sphere.Center.X + sphere.Radius, sphere.Center.Y + sphere.Radius, sphere.Center.Z + sphere.Radius);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a <see cref="math.BoundingBox"/> from a given sphere.
|
||||
/// </summary>
|
||||
/// <param name="sphere">The sphere that will designate the extents of the box.</param>
|
||||
/// <returns>The newly constructed bounding box.</returns>
|
||||
public static BoundingBox FromSphere(BoundingSphere sphere)
|
||||
{
|
||||
BoundingBox box;
|
||||
box.Minimum = new Vector3(sphere.Center.X - sphere.Radius, sphere.Center.Y - sphere.Radius, sphere.Center.Z - sphere.Radius);
|
||||
box.Maximum = new Vector3(sphere.Center.X + sphere.Radius, sphere.Center.Y + sphere.Radius, sphere.Center.Z + sphere.Radius);
|
||||
return box;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transform a bounding box.
|
||||
/// </summary>
|
||||
/// <param name="value">The original bounding box.</param>
|
||||
/// <param name="transform">The transform to apply to the bounding box.</param>
|
||||
/// <param name="result">The transformed bounding box.</param>
|
||||
public static void Transform(ref BoundingBox value, ref Matrix transform, out BoundingBox result)
|
||||
{
|
||||
var boundingBox = new BoundingBoxExt(value);
|
||||
boundingBox.Transform(transform);
|
||||
result = (BoundingBox)boundingBox;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a <see cref="math.BoundingBox"/> that is as large enough to contains the bounding box and the given point.
|
||||
/// </summary>
|
||||
/// <param name="value1">The box to merge.</param>
|
||||
/// <param name="value2">The point to merge.</param>
|
||||
/// <param name="result">When the method completes, contains the newly constructed bounding box.</param>
|
||||
public static void Merge(ref BoundingBox value1, ref Vector3 value2, out BoundingBox result)
|
||||
{
|
||||
Vector3.Min(ref value1.Minimum, ref value2, out result.Minimum);
|
||||
Vector3.Max(ref value1.Maximum, ref value2, out result.Maximum);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a <see cref="math.BoundingBox"/> that is as large as the total combined area of the two specified boxes.
|
||||
/// </summary>
|
||||
/// <param name="value1">The first box to merge.</param>
|
||||
/// <param name="value2">The second box to merge.</param>
|
||||
/// <param name="result">When the method completes, contains the newly constructed bounding box.</param>
|
||||
public static void Merge(ref BoundingBox value1, ref BoundingBox value2, out BoundingBox result)
|
||||
{
|
||||
Vector3.Min(ref value1.Minimum, ref value2.Minimum, out result.Minimum);
|
||||
Vector3.Max(ref value1.Maximum, ref value2.Maximum, out result.Maximum);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a <see cref="math.BoundingBox"/> that is as large as the total combined area of the two specified boxes.
|
||||
/// </summary>
|
||||
/// <param name="value1">The first box to merge.</param>
|
||||
/// <param name="value2">The second box to merge.</param>
|
||||
/// <returns>The newly constructed bounding box.</returns>
|
||||
public static BoundingBox Merge(BoundingBox value1, BoundingBox value2)
|
||||
{
|
||||
BoundingBox box;
|
||||
Vector3.Min(ref value1.Minimum, ref value2.Minimum, out box.Minimum);
|
||||
Vector3.Max(ref value1.Maximum, ref value2.Maximum, out box.Maximum);
|
||||
return box;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests for equality between two objects.
|
||||
/// </summary>
|
||||
/// <param name="left">The first value to compare.</param>
|
||||
/// <param name="right">The second value to compare.</param>
|
||||
/// <returns><c>true</c> if <paramref name="left"/> has the same value as <paramref name="right"/>; otherwise, <c>false</c>.</returns>
|
||||
public static bool operator ==(BoundingBox left, BoundingBox right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests for inequality between two objects.
|
||||
/// </summary>
|
||||
/// <param name="left">The first value to compare.</param>
|
||||
/// <param name="right">The second value to compare.</param>
|
||||
/// <returns><c>true</c> if <paramref name="left"/> has a different value than <paramref name="right"/>; otherwise, <c>false</c>.</returns>
|
||||
public static bool operator !=(BoundingBox left, BoundingBox right)
|
||||
{
|
||||
return !left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="string"/> that represents this instance.
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, "Minimum:{0} Maximum:{1}", Minimum.ToString(), Maximum.ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <param name="format">The format.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="string"/> that represents this instance.
|
||||
/// </returns>
|
||||
public string ToString(string format)
|
||||
{
|
||||
if (format == null)
|
||||
return ToString();
|
||||
|
||||
return string.Format(CultureInfo.CurrentCulture, "Minimum:{0} Maximum:{1}", Minimum.ToString(format, CultureInfo.CurrentCulture),
|
||||
Maximum.ToString(format, CultureInfo.CurrentCulture));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <param name="formatProvider">The format provider.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="string"/> that represents this instance.
|
||||
/// </returns>
|
||||
public string ToString(IFormatProvider formatProvider)
|
||||
{
|
||||
return string.Format(formatProvider, "Minimum:{0} Maximum:{1}", Minimum.ToString(), Maximum.ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <param name="format">The format.</param>
|
||||
/// <param name="formatProvider">The format provider.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="string"/> that represents this instance.
|
||||
/// </returns>
|
||||
public string ToString(string format, IFormatProvider formatProvider)
|
||||
{
|
||||
if (format == null)
|
||||
return ToString(formatProvider);
|
||||
|
||||
return string.Format(formatProvider, "Minimum:{0} Maximum:{1}", Minimum.ToString(format, formatProvider),
|
||||
Maximum.ToString(format, formatProvider));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a hash code for this instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
|
||||
/// </returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Minimum.GetHashCode() + Maximum.GetHashCode();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="math.Vector4"/> is equal to this instance.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="math.Vector4"/> to compare with this instance.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the specified <see cref="math.Vector4"/> is equal to this instance; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public bool Equals(BoundingBox value)
|
||||
{
|
||||
return Minimum == value.Minimum && Maximum == value.Maximum;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="object"/> is equal to this instance.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="object"/> to compare with this instance.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the specified <see cref="object"/> is equal to this instance; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
if (value == null)
|
||||
return false;
|
||||
|
||||
if (value.GetType() != GetType())
|
||||
return false;
|
||||
|
||||
return Equals((BoundingBox)value);
|
||||
}
|
||||
}
|
||||
}
|
||||
186
math/BoundingBoxExt.cs
Normal file
186
math/BoundingBoxExt.cs
Normal file
@ -0,0 +1,186 @@
|
||||
// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
|
||||
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace math
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an axis-aligned bounding box in three dimensional space that store only the Center and Extent.
|
||||
/// </summary>
|
||||
[DataContract]
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
||||
public struct BoundingBoxExt : IEquatable<BoundingBoxExt>
|
||||
{
|
||||
/// <summary>
|
||||
/// A <see cref="BoundingBoxExt"/> which represents an empty space.
|
||||
/// </summary>
|
||||
public static readonly BoundingBoxExt Empty = new BoundingBoxExt(BoundingBox.Empty);
|
||||
|
||||
/// <summary>
|
||||
/// The center of this bounding box.
|
||||
/// </summary>
|
||||
public Vector3 Center;
|
||||
|
||||
/// <summary>
|
||||
/// The extent of this bounding box.
|
||||
/// </summary>
|
||||
public Vector3 Extent;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="math.BoundingBoxExt" /> struct.
|
||||
/// </summary>
|
||||
/// <param name="box">The box.</param>
|
||||
public BoundingBoxExt(BoundingBox box)
|
||||
{
|
||||
this.Center = box.Center;
|
||||
this.Extent = box.Extent;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="math.BoundingBoxExt"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="minimum">The minimum vertex of the bounding box.</param>
|
||||
/// <param name="maximum">The maximum vertex of the bounding box.</param>
|
||||
public BoundingBoxExt(Vector3 minimum, Vector3 maximum)
|
||||
{
|
||||
this.Center = (minimum + maximum) / 2;
|
||||
this.Extent = (maximum - minimum) / 2;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the minimum.
|
||||
/// </summary>
|
||||
/// <value>The minimum.</value>
|
||||
public Vector3 Minimum
|
||||
{
|
||||
get
|
||||
{
|
||||
return Center - Extent;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the maximum.
|
||||
/// </summary>
|
||||
/// <value>The maximum.</value>
|
||||
public Vector3 Maximum
|
||||
{
|
||||
get
|
||||
{
|
||||
return Center + Extent;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transform this Bounding box
|
||||
/// </summary>
|
||||
/// <param name="world">The transform to apply to the bounding box.</param>
|
||||
public void Transform(Matrix world)
|
||||
{
|
||||
// http://zeuxcg.org/2010/10/17/aabb-from-obb-with-component-wise-abs/
|
||||
// Compute transformed AABB (by world)
|
||||
var center = Center;
|
||||
var extent = Extent;
|
||||
|
||||
Vector3.TransformCoordinate(ref center, ref world, out Center);
|
||||
|
||||
// Update world matrix into absolute form
|
||||
unsafe
|
||||
{
|
||||
// Perform an abs on the matrix
|
||||
var matrixData = (float*)&world;
|
||||
for (int j = 0; j < 16; ++j)
|
||||
{
|
||||
//*matrixData &= 0x7FFFFFFF;
|
||||
*matrixData = Math.Abs(*matrixData);
|
||||
++matrixData;
|
||||
}
|
||||
}
|
||||
|
||||
Vector3.TransformNormal(ref extent, ref world, out Extent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a <see cref="math.BoundingBoxExt"/> that is as large as the total combined area of the two specified boxes.
|
||||
/// </summary>
|
||||
/// <param name="value1">The first box to merge.</param>
|
||||
/// <param name="value2">The second box to merge.</param>
|
||||
/// <param name="result">When the method completes, contains the newly constructed bounding box.</param>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void Merge(ref BoundingBoxExt value1, ref BoundingBoxExt value2, out BoundingBoxExt result)
|
||||
{
|
||||
var maximum = Vector3.Max(value1.Maximum, value2.Maximum);
|
||||
var minimum = Vector3.Min(value1.Minimum, value2.Minimum);
|
||||
|
||||
result.Center = (minimum + maximum) / 2;
|
||||
result.Extent = (maximum - minimum) / 2;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Equals(BoundingBoxExt other)
|
||||
{
|
||||
return Center.Equals(other.Center) && Extent.Equals(other.Extent);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj)) return false;
|
||||
return obj is BoundingBoxExt && Equals((BoundingBoxExt)obj);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
return (Center.GetHashCode() * 397) ^ Extent.GetHashCode();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements the ==.
|
||||
/// </summary>
|
||||
/// <param name="left">The left.</param>
|
||||
/// <param name="right">The right.</param>
|
||||
/// <returns>The result of the operator.</returns>
|
||||
public static bool operator ==(BoundingBoxExt left, BoundingBoxExt right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements the !=.
|
||||
/// </summary>
|
||||
/// <param name="left">The left.</param>
|
||||
/// <param name="right">The right.</param>
|
||||
/// <returns>The result of the operator.</returns>
|
||||
public static bool operator !=(BoundingBoxExt left, BoundingBoxExt right)
|
||||
{
|
||||
return !left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an explicit conversion from <see cref="BoundingBoxExt"/> to <see cref="BoundingBox"/>.
|
||||
/// </summary>
|
||||
/// <param name="bbExt">The bb ext.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static explicit operator BoundingBox(BoundingBoxExt bbExt)
|
||||
{
|
||||
return new BoundingBox(bbExt.Minimum, bbExt.Maximum);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an explicit conversion from <see cref="BoundingBox"/> to <see cref="BoundingBoxExt"/>.
|
||||
/// </summary>
|
||||
/// <param name="boundingBox">The bounding box.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static explicit operator BoundingBoxExt(BoundingBox boundingBox)
|
||||
{
|
||||
return new BoundingBoxExt(boundingBox);
|
||||
}
|
||||
}
|
||||
}
|
||||
103
math/BoundingFrustum.cs
Normal file
103
math/BoundingFrustum.cs
Normal file
@ -0,0 +1,103 @@
|
||||
// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
|
||||
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
|
||||
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace math
|
||||
{
|
||||
/// <summary>
|
||||
/// A bounding frustum.
|
||||
/// </summary>
|
||||
public struct BoundingFrustum
|
||||
{
|
||||
/// <summary>
|
||||
/// The left plane of this frustum.
|
||||
/// </summary>
|
||||
public Plane LeftPlane;
|
||||
|
||||
/// <summary>
|
||||
/// The right plane of this frustum.
|
||||
/// </summary>
|
||||
public Plane RightPlane;
|
||||
|
||||
/// <summary>
|
||||
/// The top plane of this frustum.
|
||||
/// </summary>
|
||||
public Plane TopPlane;
|
||||
|
||||
/// <summary>
|
||||
/// The bottom plane of this frustum.
|
||||
/// </summary>
|
||||
public Plane BottomPlane;
|
||||
|
||||
/// <summary>
|
||||
/// The near plane of this frustum.
|
||||
/// </summary>
|
||||
public Plane NearPlane;
|
||||
|
||||
/// <summary>
|
||||
/// The far plane of this frustum.
|
||||
/// </summary>
|
||||
public Plane FarPlane;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BoundingFrustum"/> struct from a matrix view-projection.
|
||||
/// </summary>
|
||||
/// <param name="matrix">The matrix view projection.</param>
|
||||
public BoundingFrustum(ref Matrix matrix)
|
||||
{
|
||||
// Left
|
||||
LeftPlane = Plane.Normalize(new Plane(
|
||||
matrix.M14 + matrix.M11,
|
||||
matrix.M24 + matrix.M21,
|
||||
matrix.M34 + matrix.M31,
|
||||
matrix.M44 + matrix.M41));
|
||||
|
||||
// Right
|
||||
RightPlane = Plane.Normalize(new Plane(
|
||||
matrix.M14 - matrix.M11,
|
||||
matrix.M24 - matrix.M21,
|
||||
matrix.M34 - matrix.M31,
|
||||
matrix.M44 - matrix.M41));
|
||||
|
||||
// Top
|
||||
TopPlane = Plane.Normalize(new Plane(
|
||||
matrix.M14 - matrix.M12,
|
||||
matrix.M24 - matrix.M22,
|
||||
matrix.M34 - matrix.M32,
|
||||
matrix.M44 - matrix.M42));
|
||||
|
||||
// Bottom
|
||||
BottomPlane = Plane.Normalize(new Plane(
|
||||
matrix.M14 + matrix.M12,
|
||||
matrix.M24 + matrix.M22,
|
||||
matrix.M34 + matrix.M32,
|
||||
matrix.M44 + matrix.M42));
|
||||
|
||||
// Near
|
||||
NearPlane = Plane.Normalize(new Plane(
|
||||
matrix.M13,
|
||||
matrix.M23,
|
||||
matrix.M33,
|
||||
matrix.M43));
|
||||
|
||||
// Far
|
||||
FarPlane = Plane.Normalize(new Plane(
|
||||
matrix.M14 - matrix.M13,
|
||||
matrix.M24 - matrix.M23,
|
||||
matrix.M34 - matrix.M33,
|
||||
matrix.M44 - matrix.M43));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check whether this frustum contains the specified <see cref="BoundingBoxExt"/>.
|
||||
/// </summary>
|
||||
/// <param name="boundingBoxExt">The bounding box.</param>
|
||||
/// <returns><c>true</c> if this frustum contains the specified bounding box.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Contains(ref BoundingBoxExt boundingBoxExt)
|
||||
{
|
||||
return CollisionHelper.FrustumContainsBox(ref this, ref boundingBoxExt);
|
||||
}
|
||||
}
|
||||
}
|
||||
539
math/BoundingSphere.cs
Normal file
539
math/BoundingSphere.cs
Normal file
@ -0,0 +1,539 @@
|
||||
// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
|
||||
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// Original code from SlimMath project. http://code.google.com/p/slimmath/
|
||||
// Greetings to SlimDX Group. Original code published with the following license:
|
||||
// -----------------------------------------------------------------------------
|
||||
/*
|
||||
* Copyright (c) 2007-2011 SlimDX Group
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace math
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a bounding sphere in three dimensional space.
|
||||
/// </summary>
|
||||
[DataContract]
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
||||
public struct BoundingSphere : IEquatable<BoundingSphere>, IFormattable
|
||||
{
|
||||
/// <summary>
|
||||
/// An empty bounding sphere (Center = 0 and Radius = 0).
|
||||
/// </summary>
|
||||
public static readonly BoundingSphere Empty = new BoundingSphere();
|
||||
|
||||
/// <summary>
|
||||
/// The center of the sphere in three dimensional space.
|
||||
/// </summary>
|
||||
public Vector3 Center;
|
||||
|
||||
/// <summary>
|
||||
/// The radious of the sphere.
|
||||
/// </summary>
|
||||
public float Radius;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="BoundingSphere"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="center">The center of the sphere in three dimensional space.</param>
|
||||
/// <param name="radius">The radius of the sphere.</param>
|
||||
public BoundingSphere(Vector3 center, float radius)
|
||||
{
|
||||
this.Center = center;
|
||||
this.Radius = radius;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if there is an intersection between the current object and a <see cref="math.Ray"/>.
|
||||
/// </summary>
|
||||
/// <param name="ray">The ray to test.</param>
|
||||
/// <returns>Whether the two objects intersected.</returns>
|
||||
public bool Intersects(ref Ray ray)
|
||||
{
|
||||
float distance;
|
||||
return CollisionHelper.RayIntersectsSphere(ref ray, ref this, out distance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if there is an intersection between the current object and a <see cref="math.Ray"/>.
|
||||
/// </summary>
|
||||
/// <param name="ray">The ray to test.</param>
|
||||
/// <param name="distance">When the method completes, contains the distance of the intersection,
|
||||
/// or 0 if there was no intersection.</param>
|
||||
/// <returns>Whether the two objects intersected.</returns>
|
||||
public bool Intersects(ref Ray ray, out float distance)
|
||||
{
|
||||
return CollisionHelper.RayIntersectsSphere(ref ray, ref this, out distance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if there is an intersection between the current object and a <see cref="math.Ray"/>.
|
||||
/// </summary>
|
||||
/// <param name="ray">The ray to test.</param>
|
||||
/// <param name="point">When the method completes, contains the point of intersection,
|
||||
/// or <see cref="math.Vector3.Zero"/> if there was no intersection.</param>
|
||||
/// <returns>Whether the two objects intersected.</returns>
|
||||
public bool Intersects(ref Ray ray, out Vector3 point)
|
||||
{
|
||||
return CollisionHelper.RayIntersectsSphere(ref ray, ref this, out point);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if there is an intersection between the current object and a <see cref="math.Plane"/>.
|
||||
/// </summary>
|
||||
/// <param name="plane">The plane to test.</param>
|
||||
/// <returns>Whether the two objects intersected.</returns>
|
||||
public PlaneIntersectionType Intersects(ref Plane plane)
|
||||
{
|
||||
return CollisionHelper.PlaneIntersectsSphere(ref plane, ref this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if there is an intersection between the current object and a triangle.
|
||||
/// </summary>
|
||||
/// <param name="vertex1">The first vertex of the triangle to test.</param>
|
||||
/// <param name="vertex2">The second vertex of the triagnle to test.</param>
|
||||
/// <param name="vertex3">The third vertex of the triangle to test.</param>
|
||||
/// <returns>Whether the two objects intersected.</returns>
|
||||
public bool Intersects(ref Vector3 vertex1, ref Vector3 vertex2, ref Vector3 vertex3)
|
||||
{
|
||||
return CollisionHelper.SphereIntersectsTriangle(ref this, ref vertex1, ref vertex2, ref vertex3);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if there is an intersection between the current object and a <see cref="math.BoundingBox"/>.
|
||||
/// </summary>
|
||||
/// <param name="box">The box to test.</param>
|
||||
/// <returns>Whether the two objects intersected.</returns>
|
||||
public bool Intersects(ref BoundingBox box)
|
||||
{
|
||||
return CollisionHelper.BoxIntersectsSphere(ref box, ref this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if there is an intersection between the current object and a <see cref="math.BoundingSphere"/>.
|
||||
/// </summary>
|
||||
/// <param name="sphere">The sphere to test.</param>
|
||||
/// <returns>Whether the two objects intersected.</returns>
|
||||
public bool Intersects(ref BoundingSphere sphere)
|
||||
{
|
||||
return CollisionHelper.SphereIntersectsSphere(ref this, ref sphere);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the current objects contains a point.
|
||||
/// </summary>
|
||||
/// <param name="point">The point to test.</param>
|
||||
/// <returns>The type of containment the two objects have.</returns>
|
||||
public ContainmentType Contains(ref Vector3 point)
|
||||
{
|
||||
return CollisionHelper.SphereContainsPoint(ref this, ref point);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the current objects contains a triangle.
|
||||
/// </summary>
|
||||
/// <param name="vertex1">The first vertex of the triangle to test.</param>
|
||||
/// <param name="vertex2">The second vertex of the triagnle to test.</param>
|
||||
/// <param name="vertex3">The third vertex of the triangle to test.</param>
|
||||
/// <returns>The type of containment the two objects have.</returns>
|
||||
public ContainmentType Contains(ref Vector3 vertex1, ref Vector3 vertex2, ref Vector3 vertex3)
|
||||
{
|
||||
return CollisionHelper.SphereContainsTriangle(ref this, ref vertex1, ref vertex2, ref vertex3);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the current objects contains a <see cref="math.BoundingBox"/>.
|
||||
/// </summary>
|
||||
/// <param name="box">The box to test.</param>
|
||||
/// <returns>The type of containment the two objects have.</returns>
|
||||
public ContainmentType Contains(ref BoundingBox box)
|
||||
{
|
||||
return CollisionHelper.SphereContainsBox(ref this, ref box);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the current objects contains a <see cref="math.BoundingSphere"/>.
|
||||
/// </summary>
|
||||
/// <param name="sphere">The sphere to test.</param>
|
||||
/// <returns>The type of containment the two objects have.</returns>
|
||||
public ContainmentType Contains(ref BoundingSphere sphere)
|
||||
{
|
||||
return CollisionHelper.SphereContainsSphere(ref this, ref sphere);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a <see cref="math.BoundingSphere"/> that fully contains the given points.
|
||||
/// </summary>
|
||||
/// <param name="points">The points that will be contained by the sphere.</param>
|
||||
/// <param name="result">When the method completes, contains the newly constructed bounding sphere.</param>
|
||||
public static unsafe void FromPoints(Vector3[] points, out BoundingSphere result)
|
||||
{
|
||||
if (points == null) throw new ArgumentNullException("points");
|
||||
fixed (void* pointsPtr = points)
|
||||
{
|
||||
FromPoints((IntPtr)pointsPtr, 0, points.Length, Utilities.SizeOf<Vector3>(), out result);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a <see cref="math.BoundingSphere" /> that fully contains the given unmanaged points.
|
||||
/// </summary>
|
||||
/// <param name="vertexBufferPtr">A pointer to of vertices containing points.</param>
|
||||
/// <param name="vertexPositionOffsetInBytes">The point offset in bytes starting from the vertex structure.</param>
|
||||
/// <param name="vertexCount">The verterx vertexCount.</param>
|
||||
/// <param name="vertexStride">The vertex stride (size of vertex).</param>
|
||||
/// <param name="result">When the method completes, contains the newly constructed bounding sphere.</param>
|
||||
public static unsafe void FromPoints(IntPtr vertexBufferPtr, int vertexPositionOffsetInBytes, int vertexCount, int vertexStride, out BoundingSphere result)
|
||||
{
|
||||
if (vertexBufferPtr == IntPtr.Zero)
|
||||
{
|
||||
throw new ArgumentNullException("vertexBufferPtr");
|
||||
}
|
||||
|
||||
var startPoint = (byte*)vertexBufferPtr + vertexPositionOffsetInBytes;
|
||||
|
||||
//Find the center of all points.
|
||||
Vector3 center = Vector3.Zero;
|
||||
var nextPoint = startPoint;
|
||||
for (int i = 0; i < vertexCount; ++i)
|
||||
{
|
||||
Vector3.Add(ref *(Vector3*)nextPoint, ref center, out center);
|
||||
nextPoint += vertexStride;
|
||||
}
|
||||
|
||||
//This is the center of our sphere.
|
||||
center /= (float)vertexCount;
|
||||
|
||||
//Find the radius of the sphere
|
||||
float radius = 0f;
|
||||
nextPoint = startPoint;
|
||||
for (int i = 0; i < vertexCount; ++i)
|
||||
{
|
||||
//We are doing a relative distance comparasin to find the maximum distance
|
||||
//from the center of our sphere.
|
||||
float distance;
|
||||
Vector3.DistanceSquared(ref center, ref *(Vector3*)nextPoint, out distance);
|
||||
|
||||
if (distance > radius)
|
||||
radius = distance;
|
||||
nextPoint += vertexStride;
|
||||
}
|
||||
|
||||
//Find the real distance from the DistanceSquared.
|
||||
radius = (float)Math.Sqrt(radius);
|
||||
|
||||
//Construct the sphere.
|
||||
result.Center = center;
|
||||
result.Radius = radius;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a <see cref="math.BoundingSphere"/> that fully contains the given points.
|
||||
/// </summary>
|
||||
/// <param name="points">The points that will be contained by the sphere.</param>
|
||||
/// <returns>The newly constructed bounding sphere.</returns>
|
||||
public static BoundingSphere FromPoints(Vector3[] points)
|
||||
{
|
||||
BoundingSphere result;
|
||||
FromPoints(points, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a <see cref="math.BoundingSphere"/> from a given box.
|
||||
/// </summary>
|
||||
/// <param name="box">The box that will designate the extents of the sphere.</param>
|
||||
/// <param name="result">When the method completes, the newly constructed bounding sphere.</param>
|
||||
public static void FromBox(ref BoundingBox box, out BoundingSphere result)
|
||||
{
|
||||
Vector3.Lerp(ref box.Minimum, ref box.Maximum, 0.5f, out result.Center);
|
||||
|
||||
float x = box.Minimum.X - box.Maximum.X;
|
||||
float y = box.Minimum.Y - box.Maximum.Y;
|
||||
float z = box.Minimum.Z - box.Maximum.Z;
|
||||
|
||||
float distance = (float)(Math.Sqrt((x * x) + (y * y) + (z * z)));
|
||||
result.Radius = distance * 0.5f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a <see cref="math.BoundingSphere"/> from a given box.
|
||||
/// </summary>
|
||||
/// <param name="box">The box that will designate the extents of the sphere.</param>
|
||||
/// <returns>The newly constructed bounding sphere.</returns>
|
||||
public static BoundingSphere FromBox(BoundingBox box)
|
||||
{
|
||||
BoundingSphere result;
|
||||
FromBox(ref box, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transforms a bounding bounding sphere, yielding the bounding sphere of all points contained by the original one, transformed by the specified transform.
|
||||
/// </summary>
|
||||
/// <param name="value">The original bounding sphere.</param>
|
||||
/// <param name="transform">The transform to apply to the bounding sphere.</param>
|
||||
/// <param name="result">The transformed bounding sphere.</param>
|
||||
public static void Transform(ref BoundingSphere value, ref Matrix transform, out BoundingSphere result)
|
||||
{
|
||||
Vector3.TransformCoordinate(ref value.Center, ref transform, out result.Center);
|
||||
|
||||
var majorAxisLengthSquared = Math.Max(
|
||||
(transform.M11 * transform.M11) + (transform.M12 * transform.M12) + (transform.M13 * transform.M13), Math.Max(
|
||||
(transform.M21 * transform.M21) + (transform.M22 * transform.M22) + (transform.M23 * transform.M23),
|
||||
(transform.M31 * transform.M31) + (transform.M32 * transform.M32) + (transform.M33 * transform.M33)));
|
||||
|
||||
result.Radius = value.Radius * (float)Math.Sqrt(majorAxisLengthSquared);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a <see cref="math.BoundingSphere"/> that is the as large as the total combined area of the two specified spheres.
|
||||
/// </summary>
|
||||
/// <param name="value1">The first sphere to merge.</param>
|
||||
/// <param name="value2">The second sphere to merge.</param>
|
||||
/// <param name="result">When the method completes, contains the newly constructed bounding sphere.</param>
|
||||
public static void Merge(ref BoundingSphere value1, ref BoundingSphere value2, out BoundingSphere result)
|
||||
{
|
||||
// Pre-exit if one of the bounding sphere by assuming that a merge with an empty sphere is equivalent at taking the non-empty sphere
|
||||
if (value1 == Empty)
|
||||
{
|
||||
result = value2;
|
||||
return;
|
||||
}
|
||||
|
||||
if (value2 == Empty)
|
||||
{
|
||||
result = value1;
|
||||
return;
|
||||
}
|
||||
|
||||
Vector3 difference = value2.Center - value1.Center;
|
||||
|
||||
float length = difference.Length();
|
||||
float radius = value1.Radius;
|
||||
float radius2 = value2.Radius;
|
||||
|
||||
if (radius + radius2 >= length)
|
||||
{
|
||||
if (radius - radius2 >= length)
|
||||
{
|
||||
result = value1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (radius2 - radius >= length)
|
||||
{
|
||||
result = value2;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Vector3 vector = difference * (1.0f / length);
|
||||
float min = Math.Min(-radius, length - radius2);
|
||||
float max = (Math.Max(radius, length + radius2) - min) * 0.5f;
|
||||
|
||||
result.Center = value1.Center + vector * (max + min);
|
||||
result.Radius = max;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a <see cref="math.BoundingSphere"/> that is the as large as the total combined area of the two specified spheres.
|
||||
/// </summary>
|
||||
/// <param name="value1">The first sphere to merge.</param>
|
||||
/// <param name="value2">The second sphere to merge.</param>
|
||||
/// <returns>The newly constructed bounding sphere.</returns>
|
||||
public static BoundingSphere Merge(BoundingSphere value1, BoundingSphere value2)
|
||||
{
|
||||
BoundingSphere result;
|
||||
Merge(ref value1, ref value2, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests for equality between two objects.
|
||||
/// </summary>
|
||||
/// <param name="left">The first value to compare.</param>
|
||||
/// <param name="right">The second value to compare.</param>
|
||||
/// <returns><c>true</c> if <paramref name="left"/> has the same value as <paramref name="right"/>; otherwise, <c>false</c>.</returns>
|
||||
public static bool operator ==(BoundingSphere left, BoundingSphere right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests for inequality between two objects.
|
||||
/// </summary>
|
||||
/// <param name="left">The first value to compare.</param>
|
||||
/// <param name="right">The second value to compare.</param>
|
||||
/// <returns><c>true</c> if <paramref name="left"/> has a different value than <paramref name="right"/>; otherwise, <c>false</c>.</returns>
|
||||
public static bool operator !=(BoundingSphere left, BoundingSphere right)
|
||||
{
|
||||
return !left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="string"/> that represents this instance.
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, "Center:{0} Radius:{1}", Center.ToString(), Radius.ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <param name="format">The format.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="string"/> that represents this instance.
|
||||
/// </returns>
|
||||
public string ToString(string format)
|
||||
{
|
||||
if (format == null)
|
||||
return ToString();
|
||||
|
||||
return string.Format(CultureInfo.CurrentCulture, "Center:{0} Radius:{1}", Center.ToString(format, CultureInfo.CurrentCulture),
|
||||
Radius.ToString(format, CultureInfo.CurrentCulture));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <param name="formatProvider">The format provider.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="string"/> that represents this instance.
|
||||
/// </returns>
|
||||
public string ToString(IFormatProvider formatProvider)
|
||||
{
|
||||
return string.Format(formatProvider, "Center:{0} Radius:{1}", Center.ToString(), Radius.ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <param name="format">The format.</param>
|
||||
/// <param name="formatProvider">The format provider.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="string"/> that represents this instance.
|
||||
/// </returns>
|
||||
public string ToString(string format, IFormatProvider formatProvider)
|
||||
{
|
||||
if (format == null)
|
||||
return ToString(formatProvider);
|
||||
|
||||
return string.Format(formatProvider, "Center:{0} Radius:{1}", Center.ToString(format, formatProvider),
|
||||
Radius.ToString(format, formatProvider));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a hash code for this instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
|
||||
/// </returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Center.GetHashCode() + Radius.GetHashCode();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="math.Vector4"/> is equal to this instance.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="math.Vector4"/> to compare with this instance.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the specified <see cref="math.Vector4"/> is equal to this instance; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public bool Equals(BoundingSphere value)
|
||||
{
|
||||
return Center == value.Center && Radius == value.Radius;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="object"/> is equal to this instance.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="object"/> to compare with this instance.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the specified <see cref="object"/> is equal to this instance; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
if (value == null)
|
||||
return false;
|
||||
|
||||
if (value.GetType() != GetType())
|
||||
return false;
|
||||
|
||||
return Equals((BoundingSphere)value);
|
||||
}
|
||||
|
||||
#if SlimDX1xInterop
|
||||
/// <summary>
|
||||
/// Performs an implicit conversion from <see cref="math.BoundingSphere"/> to <see cref="SlimDX.BoundingSphere"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator SlimDX.BoundingSphere(BoundingSphere value)
|
||||
{
|
||||
return new SlimDX.BoundingSphere(value.Center, value.Radius);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an implicit conversion from <see cref="SlimDX.BoundingSphere"/> to <see cref="math.BoundingSphere"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator BoundingSphere(SlimDX.BoundingSphere value)
|
||||
{
|
||||
return new BoundingSphere(value.Center, value.Radius);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SlimDX1xInterop
|
||||
/// <summary>
|
||||
/// Performs an implicit conversion from <see cref="math.BoundingSphere"/> to <see cref="Microsoft.Xna.Framework.BoundingSphere"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator Microsoft.Xna.Framework.BoundingSphere(BoundingSphere value)
|
||||
{
|
||||
return new Microsoft.Xna.Framework.BoundingSphere(value.Center, value.Radius);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an implicit conversion from <see cref="Microsoft.Xna.Framework.BoundingSphere"/> to <see cref="math.BoundingSphere"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator BoundingSphere(Microsoft.Xna.Framework.BoundingSphere value)
|
||||
{
|
||||
return new BoundingSphere(value.Center, value.Radius);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
1551
math/CollisionHelper.cs
Normal file
1551
math/CollisionHelper.cs
Normal file
File diff suppressed because it is too large
Load Diff
725
math/Color.Palette.cs
Normal file
725
math/Color.Palette.cs
Normal file
@ -0,0 +1,725 @@
|
||||
// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
|
||||
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
|
||||
namespace math
|
||||
{
|
||||
/// <summary>
|
||||
/// List of predefined <see cref="Color" />.
|
||||
/// </summary>
|
||||
public partial struct Color
|
||||
{
|
||||
/// <summary>
|
||||
/// Zero color.
|
||||
/// </summary>
|
||||
public static readonly Color Zero = Color.FromBgra(0x00000000);
|
||||
|
||||
/// <summary>
|
||||
/// Transparent color.
|
||||
/// </summary>
|
||||
public static readonly Color Transparent = Color.FromBgra(0x00000000);
|
||||
|
||||
/// <summary>
|
||||
/// AliceBlue color.
|
||||
/// </summary>
|
||||
public static readonly Color AliceBlue = Color.FromBgra(0xFFF0F8FF);
|
||||
|
||||
/// <summary>
|
||||
/// AntiqueWhite color.
|
||||
/// </summary>
|
||||
public static readonly Color AntiqueWhite = Color.FromBgra(0xFFFAEBD7);
|
||||
|
||||
/// <summary>
|
||||
/// Aqua color.
|
||||
/// </summary>
|
||||
public static readonly Color Aqua = Color.FromBgra(0xFF00FFFF);
|
||||
|
||||
/// <summary>
|
||||
/// Aquamarine color.
|
||||
/// </summary>
|
||||
public static readonly Color Aquamarine = Color.FromBgra(0xFF7FFFD4);
|
||||
|
||||
/// <summary>
|
||||
/// Azure color.
|
||||
/// </summary>
|
||||
public static readonly Color Azure = Color.FromBgra(0xFFF0FFFF);
|
||||
|
||||
/// <summary>
|
||||
/// Beige color.
|
||||
/// </summary>
|
||||
public static readonly Color Beige = Color.FromBgra(0xFFF5F5DC);
|
||||
|
||||
/// <summary>
|
||||
/// Bisque color.
|
||||
/// </summary>
|
||||
public static readonly Color Bisque = Color.FromBgra(0xFFFFE4C4);
|
||||
|
||||
/// <summary>
|
||||
/// Black color.
|
||||
/// </summary>
|
||||
public static readonly Color Black = Color.FromBgra(0xFF000000);
|
||||
|
||||
/// <summary>
|
||||
/// BlanchedAlmond color.
|
||||
/// </summary>
|
||||
public static readonly Color BlanchedAlmond = Color.FromBgra(0xFFFFEBCD);
|
||||
|
||||
/// <summary>
|
||||
/// Blue color.
|
||||
/// </summary>
|
||||
public static readonly Color Blue = Color.FromBgra(0xFF0000FF);
|
||||
|
||||
/// <summary>
|
||||
/// BlueViolet color.
|
||||
/// </summary>
|
||||
public static readonly Color BlueViolet = Color.FromBgra(0xFF8A2BE2);
|
||||
|
||||
/// <summary>
|
||||
/// Brown color.
|
||||
/// </summary>
|
||||
public static readonly Color Brown = Color.FromBgra(0xFFA52A2A);
|
||||
|
||||
/// <summary>
|
||||
/// BurlyWood color.
|
||||
/// </summary>
|
||||
public static readonly Color BurlyWood = Color.FromBgra(0xFFDEB887);
|
||||
|
||||
/// <summary>
|
||||
/// CadetBlue color.
|
||||
/// </summary>
|
||||
public static readonly Color CadetBlue = Color.FromBgra(0xFF5F9EA0);
|
||||
|
||||
/// <summary>
|
||||
/// Chartreuse color.
|
||||
/// </summary>
|
||||
public static readonly Color Chartreuse = Color.FromBgra(0xFF7FFF00);
|
||||
|
||||
/// <summary>
|
||||
/// Chocolate color.
|
||||
/// </summary>
|
||||
public static readonly Color Chocolate = Color.FromBgra(0xFFD2691E);
|
||||
|
||||
/// <summary>
|
||||
/// Coral color.
|
||||
/// </summary>
|
||||
public static readonly Color Coral = Color.FromBgra(0xFFFF7F50);
|
||||
|
||||
/// <summary>
|
||||
/// CornflowerBlue color.
|
||||
/// </summary>
|
||||
public static readonly Color CornflowerBlue = Color.FromBgra(0xFF6495ED);
|
||||
|
||||
/// <summary>
|
||||
/// Cornsilk color.
|
||||
/// </summary>
|
||||
public static readonly Color Cornsilk = Color.FromBgra(0xFFFFF8DC);
|
||||
|
||||
/// <summary>
|
||||
/// Crimson color.
|
||||
/// </summary>
|
||||
public static readonly Color Crimson = Color.FromBgra(0xFFDC143C);
|
||||
|
||||
/// <summary>
|
||||
/// Cyan color.
|
||||
/// </summary>
|
||||
public static readonly Color Cyan = Color.FromBgra(0xFF00FFFF);
|
||||
|
||||
/// <summary>
|
||||
/// DarkBlue color.
|
||||
/// </summary>
|
||||
public static readonly Color DarkBlue = Color.FromBgra(0xFF00008B);
|
||||
|
||||
/// <summary>
|
||||
/// DarkCyan color.
|
||||
/// </summary>
|
||||
public static readonly Color DarkCyan = Color.FromBgra(0xFF008B8B);
|
||||
|
||||
/// <summary>
|
||||
/// DarkGoldenrod color.
|
||||
/// </summary>
|
||||
public static readonly Color DarkGoldenrod = Color.FromBgra(0xFFB8860B);
|
||||
|
||||
/// <summary>
|
||||
/// DarkGray color.
|
||||
/// </summary>
|
||||
public static readonly Color DarkGray = Color.FromBgra(0xFFA9A9A9);
|
||||
|
||||
/// <summary>
|
||||
/// DarkGreen color.
|
||||
/// </summary>
|
||||
public static readonly Color DarkGreen = Color.FromBgra(0xFF006400);
|
||||
|
||||
/// <summary>
|
||||
/// DarkKhaki color.
|
||||
/// </summary>
|
||||
public static readonly Color DarkKhaki = Color.FromBgra(0xFFBDB76B);
|
||||
|
||||
/// <summary>
|
||||
/// DarkMagenta color.
|
||||
/// </summary>
|
||||
public static readonly Color DarkMagenta = Color.FromBgra(0xFF8B008B);
|
||||
|
||||
/// <summary>
|
||||
/// DarkOliveGreen color.
|
||||
/// </summary>
|
||||
public static readonly Color DarkOliveGreen = Color.FromBgra(0xFF556B2F);
|
||||
|
||||
/// <summary>
|
||||
/// DarkOrange color.
|
||||
/// </summary>
|
||||
public static readonly Color DarkOrange = Color.FromBgra(0xFFFF8C00);
|
||||
|
||||
/// <summary>
|
||||
/// DarkOrchid color.
|
||||
/// </summary>
|
||||
public static readonly Color DarkOrchid = Color.FromBgra(0xFF9932CC);
|
||||
|
||||
/// <summary>
|
||||
/// DarkRed color.
|
||||
/// </summary>
|
||||
public static readonly Color DarkRed = Color.FromBgra(0xFF8B0000);
|
||||
|
||||
/// <summary>
|
||||
/// DarkSalmon color.
|
||||
/// </summary>
|
||||
public static readonly Color DarkSalmon = Color.FromBgra(0xFFE9967A);
|
||||
|
||||
/// <summary>
|
||||
/// DarkSeaGreen color.
|
||||
/// </summary>
|
||||
public static readonly Color DarkSeaGreen = Color.FromBgra(0xFF8FBC8B);
|
||||
|
||||
/// <summary>
|
||||
/// DarkSlateBlue color.
|
||||
/// </summary>
|
||||
public static readonly Color DarkSlateBlue = Color.FromBgra(0xFF483D8B);
|
||||
|
||||
/// <summary>
|
||||
/// DarkSlateGray color.
|
||||
/// </summary>
|
||||
public static readonly Color DarkSlateGray = Color.FromBgra(0xFF2F4F4F);
|
||||
|
||||
/// <summary>
|
||||
/// DarkTurquoise color.
|
||||
/// </summary>
|
||||
public static readonly Color DarkTurquoise = Color.FromBgra(0xFF00CED1);
|
||||
|
||||
/// <summary>
|
||||
/// DarkViolet color.
|
||||
/// </summary>
|
||||
public static readonly Color DarkViolet = Color.FromBgra(0xFF9400D3);
|
||||
|
||||
/// <summary>
|
||||
/// DeepPink color.
|
||||
/// </summary>
|
||||
public static readonly Color DeepPink = Color.FromBgra(0xFFFF1493);
|
||||
|
||||
/// <summary>
|
||||
/// DeepSkyBlue color.
|
||||
/// </summary>
|
||||
public static readonly Color DeepSkyBlue = Color.FromBgra(0xFF00BFFF);
|
||||
|
||||
/// <summary>
|
||||
/// DimGray color.
|
||||
/// </summary>
|
||||
public static readonly Color DimGray = Color.FromBgra(0xFF696969);
|
||||
|
||||
/// <summary>
|
||||
/// VeryDimGray color.
|
||||
/// </summary>
|
||||
public static readonly Color VeryDimGray = Color.FromBgra(0xFF404040);
|
||||
|
||||
/// <summary>
|
||||
/// DodgerBlue color.
|
||||
/// </summary>
|
||||
public static readonly Color DodgerBlue = Color.FromBgra(0xFF1E90FF);
|
||||
|
||||
/// <summary>
|
||||
/// Firebrick color.
|
||||
/// </summary>
|
||||
public static readonly Color Firebrick = Color.FromBgra(0xFFB22222);
|
||||
|
||||
/// <summary>
|
||||
/// FloralWhite color.
|
||||
/// </summary>
|
||||
public static readonly Color FloralWhite = Color.FromBgra(0xFFFFFAF0);
|
||||
|
||||
/// <summary>
|
||||
/// ForestGreen color.
|
||||
/// </summary>
|
||||
public static readonly Color ForestGreen = Color.FromBgra(0xFF228B22);
|
||||
|
||||
/// <summary>
|
||||
/// Fuchsia color.
|
||||
/// </summary>
|
||||
public static readonly Color Fuchsia = Color.FromBgra(0xFFFF00FF);
|
||||
|
||||
/// <summary>
|
||||
/// Gainsboro color.
|
||||
/// </summary>
|
||||
public static readonly Color Gainsboro = Color.FromBgra(0xFFDCDCDC);
|
||||
|
||||
/// <summary>
|
||||
/// GhostWhite color.
|
||||
/// </summary>
|
||||
public static readonly Color GhostWhite = Color.FromBgra(0xFFF8F8FF);
|
||||
|
||||
/// <summary>
|
||||
/// Gold color.
|
||||
/// </summary>
|
||||
public static readonly Color Gold = Color.FromBgra(0xFFFFD700);
|
||||
|
||||
/// <summary>
|
||||
/// Goldenrod color.
|
||||
/// </summary>
|
||||
public static readonly Color Goldenrod = Color.FromBgra(0xFFDAA520);
|
||||
|
||||
/// <summary>
|
||||
/// Gray color.
|
||||
/// </summary>
|
||||
public static readonly Color Gray = Color.FromBgra(0xFF808080);
|
||||
|
||||
/// <summary>
|
||||
/// Green color.
|
||||
/// </summary>
|
||||
public static readonly Color Green = Color.FromBgra(0xFF008000);
|
||||
|
||||
/// <summary>
|
||||
/// GreenYellow color.
|
||||
/// </summary>
|
||||
public static readonly Color GreenYellow = Color.FromBgra(0xFFADFF2F);
|
||||
|
||||
/// <summary>
|
||||
/// Honeydew color.
|
||||
/// </summary>
|
||||
public static readonly Color Honeydew = Color.FromBgra(0xFFF0FFF0);
|
||||
|
||||
/// <summary>
|
||||
/// HotPink color.
|
||||
/// </summary>
|
||||
public static readonly Color HotPink = Color.FromBgra(0xFFFF69B4);
|
||||
|
||||
/// <summary>
|
||||
/// IndianRed color.
|
||||
/// </summary>
|
||||
public static readonly Color IndianRed = Color.FromBgra(0xFFCD5C5C);
|
||||
|
||||
/// <summary>
|
||||
/// Indigo color.
|
||||
/// </summary>
|
||||
public static readonly Color Indigo = Color.FromBgra(0xFF4B0082);
|
||||
|
||||
/// <summary>
|
||||
/// Ivory color.
|
||||
/// </summary>
|
||||
public static readonly Color Ivory = Color.FromBgra(0xFFFFFFF0);
|
||||
|
||||
/// <summary>
|
||||
/// Khaki color.
|
||||
/// </summary>
|
||||
public static readonly Color Khaki = Color.FromBgra(0xFFF0E68C);
|
||||
|
||||
/// <summary>
|
||||
/// Lavender color.
|
||||
/// </summary>
|
||||
public static readonly Color Lavender = Color.FromBgra(0xFFE6E6FA);
|
||||
|
||||
/// <summary>
|
||||
/// LavenderBlush color.
|
||||
/// </summary>
|
||||
public static readonly Color LavenderBlush = Color.FromBgra(0xFFFFF0F5);
|
||||
|
||||
/// <summary>
|
||||
/// LawnGreen color.
|
||||
/// </summary>
|
||||
public static readonly Color LawnGreen = Color.FromBgra(0xFF7CFC00);
|
||||
|
||||
/// <summary>
|
||||
/// LemonChiffon color.
|
||||
/// </summary>
|
||||
public static readonly Color LemonChiffon = Color.FromBgra(0xFFFFFACD);
|
||||
|
||||
/// <summary>
|
||||
/// LightBlue color.
|
||||
/// </summary>
|
||||
public static readonly Color LightBlue = Color.FromBgra(0xFFADD8E6);
|
||||
|
||||
/// <summary>
|
||||
/// LightCoral color.
|
||||
/// </summary>
|
||||
public static readonly Color LightCoral = Color.FromBgra(0xFFF08080);
|
||||
|
||||
/// <summary>
|
||||
/// LightCyan color.
|
||||
/// </summary>
|
||||
public static readonly Color LightCyan = Color.FromBgra(0xFFE0FFFF);
|
||||
|
||||
/// <summary>
|
||||
/// LightGoldenrodYellow color.
|
||||
/// </summary>
|
||||
public static readonly Color LightGoldenrodYellow = Color.FromBgra(0xFFFAFAD2);
|
||||
|
||||
/// <summary>
|
||||
/// LightGray color.
|
||||
/// </summary>
|
||||
public static readonly Color LightGray = Color.FromBgra(0xFFD3D3D3);
|
||||
|
||||
/// <summary>
|
||||
/// LightGreen color.
|
||||
/// </summary>
|
||||
public static readonly Color LightGreen = Color.FromBgra(0xFF90EE90);
|
||||
|
||||
/// <summary>
|
||||
/// LightPink color.
|
||||
/// </summary>
|
||||
public static readonly Color LightPink = Color.FromBgra(0xFFFFB6C1);
|
||||
|
||||
/// <summary>
|
||||
/// LightSalmon color.
|
||||
/// </summary>
|
||||
public static readonly Color LightSalmon = Color.FromBgra(0xFFFFA07A);
|
||||
|
||||
/// <summary>
|
||||
/// LightSeaGreen color.
|
||||
/// </summary>
|
||||
public static readonly Color LightSeaGreen = Color.FromBgra(0xFF20B2AA);
|
||||
|
||||
/// <summary>
|
||||
/// LightSkyBlue color.
|
||||
/// </summary>
|
||||
public static readonly Color LightSkyBlue = Color.FromBgra(0xFF87CEFA);
|
||||
|
||||
/// <summary>
|
||||
/// LightSlateGray color.
|
||||
/// </summary>
|
||||
public static readonly Color LightSlateGray = Color.FromBgra(0xFF778899);
|
||||
|
||||
/// <summary>
|
||||
/// LightSteelBlue color.
|
||||
/// </summary>
|
||||
public static readonly Color LightSteelBlue = Color.FromBgra(0xFFB0C4DE);
|
||||
|
||||
/// <summary>
|
||||
/// LightYellow color.
|
||||
/// </summary>
|
||||
public static readonly Color LightYellow = Color.FromBgra(0xFFFFFFE0);
|
||||
|
||||
/// <summary>
|
||||
/// Lime color.
|
||||
/// </summary>
|
||||
public static readonly Color Lime = Color.FromBgra(0xFF00FF00);
|
||||
|
||||
/// <summary>
|
||||
/// LimeGreen color.
|
||||
/// </summary>
|
||||
public static readonly Color LimeGreen = Color.FromBgra(0xFF32CD32);
|
||||
|
||||
/// <summary>
|
||||
/// Linen color.
|
||||
/// </summary>
|
||||
public static readonly Color Linen = Color.FromBgra(0xFFFAF0E6);
|
||||
|
||||
/// <summary>
|
||||
/// Magenta color.
|
||||
/// </summary>
|
||||
public static readonly Color Magenta = Color.FromBgra(0xFFFF00FF);
|
||||
|
||||
/// <summary>
|
||||
/// Maroon color.
|
||||
/// </summary>
|
||||
public static readonly Color Maroon = Color.FromBgra(0xFF800000);
|
||||
|
||||
/// <summary>
|
||||
/// MediumAquamarine color.
|
||||
/// </summary>
|
||||
public static readonly Color MediumAquamarine = Color.FromBgra(0xFF66CDAA);
|
||||
|
||||
/// <summary>
|
||||
/// MediumBlue color.
|
||||
/// </summary>
|
||||
public static readonly Color MediumBlue = Color.FromBgra(0xFF0000CD);
|
||||
|
||||
/// <summary>
|
||||
/// MediumOrchid color.
|
||||
/// </summary>
|
||||
public static readonly Color MediumOrchid = Color.FromBgra(0xFFBA55D3);
|
||||
|
||||
/// <summary>
|
||||
/// MediumPurple color.
|
||||
/// </summary>
|
||||
public static readonly Color MediumPurple = Color.FromBgra(0xFF9370DB);
|
||||
|
||||
/// <summary>
|
||||
/// MediumSeaGreen color.
|
||||
/// </summary>
|
||||
public static readonly Color MediumSeaGreen = Color.FromBgra(0xFF3CB371);
|
||||
|
||||
/// <summary>
|
||||
/// MediumSlateBlue color.
|
||||
/// </summary>
|
||||
public static readonly Color MediumSlateBlue = Color.FromBgra(0xFF7B68EE);
|
||||
|
||||
/// <summary>
|
||||
/// MediumSpringGreen color.
|
||||
/// </summary>
|
||||
public static readonly Color MediumSpringGreen = Color.FromBgra(0xFF00FA9A);
|
||||
|
||||
/// <summary>
|
||||
/// MediumTurquoise color.
|
||||
/// </summary>
|
||||
public static readonly Color MediumTurquoise = Color.FromBgra(0xFF48D1CC);
|
||||
|
||||
/// <summary>
|
||||
/// MediumVioletRed color.
|
||||
/// </summary>
|
||||
public static readonly Color MediumVioletRed = Color.FromBgra(0xFFC71585);
|
||||
|
||||
/// <summary>
|
||||
/// MidnightBlue color.
|
||||
/// </summary>
|
||||
public static readonly Color MidnightBlue = Color.FromBgra(0xFF191970);
|
||||
|
||||
/// <summary>
|
||||
/// MintCream color.
|
||||
/// </summary>
|
||||
public static readonly Color MintCream = Color.FromBgra(0xFFF5FFFA);
|
||||
|
||||
/// <summary>
|
||||
/// MistyRose color.
|
||||
/// </summary>
|
||||
public static readonly Color MistyRose = Color.FromBgra(0xFFFFE4E1);
|
||||
|
||||
/// <summary>
|
||||
/// Moccasin color.
|
||||
/// </summary>
|
||||
public static readonly Color Moccasin = Color.FromBgra(0xFFFFE4B5);
|
||||
|
||||
/// <summary>
|
||||
/// NavajoWhite color.
|
||||
/// </summary>
|
||||
public static readonly Color NavajoWhite = Color.FromBgra(0xFFFFDEAD);
|
||||
|
||||
/// <summary>
|
||||
/// Navy color.
|
||||
/// </summary>
|
||||
public static readonly Color Navy = Color.FromBgra(0xFF000080);
|
||||
|
||||
/// <summary>
|
||||
/// OldLace color.
|
||||
/// </summary>
|
||||
public static readonly Color OldLace = Color.FromBgra(0xFFFDF5E6);
|
||||
|
||||
/// <summary>
|
||||
/// Olive color.
|
||||
/// </summary>
|
||||
public static readonly Color Olive = Color.FromBgra(0xFF808000);
|
||||
|
||||
/// <summary>
|
||||
/// OliveDrab color.
|
||||
/// </summary>
|
||||
public static readonly Color OliveDrab = Color.FromBgra(0xFF6B8E23);
|
||||
|
||||
/// <summary>
|
||||
/// Orange color.
|
||||
/// </summary>
|
||||
public static readonly Color Orange = Color.FromBgra(0xFFFFA500);
|
||||
|
||||
/// <summary>
|
||||
/// OrangeRed color.
|
||||
/// </summary>
|
||||
public static readonly Color OrangeRed = Color.FromBgra(0xFFFF4500);
|
||||
|
||||
/// <summary>
|
||||
/// Orchid color.
|
||||
/// </summary>
|
||||
public static readonly Color Orchid = Color.FromBgra(0xFFDA70D6);
|
||||
|
||||
/// <summary>
|
||||
/// PaleGoldenrod color.
|
||||
/// </summary>
|
||||
public static readonly Color PaleGoldenrod = Color.FromBgra(0xFFEEE8AA);
|
||||
|
||||
/// <summary>
|
||||
/// PaleGreen color.
|
||||
/// </summary>
|
||||
public static readonly Color PaleGreen = Color.FromBgra(0xFF98FB98);
|
||||
|
||||
/// <summary>
|
||||
/// PaleTurquoise color.
|
||||
/// </summary>
|
||||
public static readonly Color PaleTurquoise = Color.FromBgra(0xFFAFEEEE);
|
||||
|
||||
/// <summary>
|
||||
/// PaleVioletRed color.
|
||||
/// </summary>
|
||||
public static readonly Color PaleVioletRed = Color.FromBgra(0xFFDB7093);
|
||||
|
||||
/// <summary>
|
||||
/// PapayaWhip color.
|
||||
/// </summary>
|
||||
public static readonly Color PapayaWhip = Color.FromBgra(0xFFFFEFD5);
|
||||
|
||||
/// <summary>
|
||||
/// PeachPuff color.
|
||||
/// </summary>
|
||||
public static readonly Color PeachPuff = Color.FromBgra(0xFFFFDAB9);
|
||||
|
||||
/// <summary>
|
||||
/// Peru color.
|
||||
/// </summary>
|
||||
public static readonly Color Peru = Color.FromBgra(0xFFCD853F);
|
||||
|
||||
/// <summary>
|
||||
/// Pink color.
|
||||
/// </summary>
|
||||
public static readonly Color Pink = Color.FromBgra(0xFFFFC0CB);
|
||||
|
||||
/// <summary>
|
||||
/// Plum color.
|
||||
/// </summary>
|
||||
public static readonly Color Plum = Color.FromBgra(0xFFDDA0DD);
|
||||
|
||||
/// <summary>
|
||||
/// PowderBlue color.
|
||||
/// </summary>
|
||||
public static readonly Color PowderBlue = Color.FromBgra(0xFFB0E0E6);
|
||||
|
||||
/// <summary>
|
||||
/// Purple color.
|
||||
/// </summary>
|
||||
public static readonly Color Purple = Color.FromBgra(0xFF800080);
|
||||
|
||||
/// <summary>
|
||||
/// Red color.
|
||||
/// </summary>
|
||||
public static readonly Color Red = Color.FromBgra(0xFFFF0000);
|
||||
|
||||
/// <summary>
|
||||
/// RosyBrown color.
|
||||
/// </summary>
|
||||
public static readonly Color RosyBrown = Color.FromBgra(0xFFBC8F8F);
|
||||
|
||||
/// <summary>
|
||||
/// RoyalBlue color.
|
||||
/// </summary>
|
||||
public static readonly Color RoyalBlue = Color.FromBgra(0xFF4169E1);
|
||||
|
||||
/// <summary>
|
||||
/// SaddleBrown color.
|
||||
/// </summary>
|
||||
public static readonly Color SaddleBrown = Color.FromBgra(0xFF8B4513);
|
||||
|
||||
/// <summary>
|
||||
/// Salmon color.
|
||||
/// </summary>
|
||||
public static readonly Color Salmon = Color.FromBgra(0xFFFA8072);
|
||||
|
||||
/// <summary>
|
||||
/// SandyBrown color.
|
||||
/// </summary>
|
||||
public static readonly Color SandyBrown = Color.FromBgra(0xFFF4A460);
|
||||
|
||||
/// <summary>
|
||||
/// SeaGreen color.
|
||||
/// </summary>
|
||||
public static readonly Color SeaGreen = Color.FromBgra(0xFF2E8B57);
|
||||
|
||||
/// <summary>
|
||||
/// SeaShell color.
|
||||
/// </summary>
|
||||
public static readonly Color SeaShell = Color.FromBgra(0xFFFFF5EE);
|
||||
|
||||
/// <summary>
|
||||
/// Sienna color.
|
||||
/// </summary>
|
||||
public static readonly Color Sienna = Color.FromBgra(0xFFA0522D);
|
||||
|
||||
/// <summary>
|
||||
/// Silver color.
|
||||
/// </summary>
|
||||
public static readonly Color Silver = Color.FromBgra(0xFFC0C0C0);
|
||||
|
||||
/// <summary>
|
||||
/// SkyBlue color.
|
||||
/// </summary>
|
||||
public static readonly Color SkyBlue = Color.FromBgra(0xFF87CEEB);
|
||||
|
||||
/// <summary>
|
||||
/// SlateBlue color.
|
||||
/// </summary>
|
||||
public static readonly Color SlateBlue = Color.FromBgra(0xFF6A5ACD);
|
||||
|
||||
/// <summary>
|
||||
/// SlateGray color.
|
||||
/// </summary>
|
||||
public static readonly Color SlateGray = Color.FromBgra(0xFF708090);
|
||||
|
||||
/// <summary>
|
||||
/// Snow color.
|
||||
/// </summary>
|
||||
public static readonly Color Snow = Color.FromBgra(0xFFFFFAFA);
|
||||
|
||||
/// <summary>
|
||||
/// SpringGreen color.
|
||||
/// </summary>
|
||||
public static readonly Color SpringGreen = Color.FromBgra(0xFF00FF7F);
|
||||
|
||||
/// <summary>
|
||||
/// SteelBlue color.
|
||||
/// </summary>
|
||||
public static readonly Color SteelBlue = Color.FromBgra(0xFF4682B4);
|
||||
|
||||
/// <summary>
|
||||
/// Tan color.
|
||||
/// </summary>
|
||||
public static readonly Color Tan = Color.FromBgra(0xFFD2B48C);
|
||||
|
||||
/// <summary>
|
||||
/// Teal color.
|
||||
/// </summary>
|
||||
public static readonly Color Teal = Color.FromBgra(0xFF008080);
|
||||
|
||||
/// <summary>
|
||||
/// Thistle color.
|
||||
/// </summary>
|
||||
public static readonly Color Thistle = Color.FromBgra(0xFFD8BFD8);
|
||||
|
||||
/// <summary>
|
||||
/// Tomato color.
|
||||
/// </summary>
|
||||
public static readonly Color Tomato = Color.FromBgra(0xFFFF6347);
|
||||
|
||||
/// <summary>
|
||||
/// Turquoise color.
|
||||
/// </summary>
|
||||
public static readonly Color Turquoise = Color.FromBgra(0xFF40E0D0);
|
||||
|
||||
/// <summary>
|
||||
/// Violet color.
|
||||
/// </summary>
|
||||
public static readonly Color Violet = Color.FromBgra(0xFFEE82EE);
|
||||
|
||||
/// <summary>
|
||||
/// Wheat color.
|
||||
/// </summary>
|
||||
public static readonly Color Wheat = Color.FromBgra(0xFFF5DEB3);
|
||||
|
||||
/// <summary>
|
||||
/// White color.
|
||||
/// </summary>
|
||||
public static readonly Color White = Color.FromBgra(0xFFFFFFFF);
|
||||
|
||||
/// <summary>
|
||||
/// WhiteSmoke color.
|
||||
/// </summary>
|
||||
public static readonly Color WhiteSmoke = Color.FromBgra(0xFFF5F5F5);
|
||||
|
||||
/// <summary>
|
||||
/// Yellow color.
|
||||
/// </summary>
|
||||
public static readonly Color Yellow = Color.FromBgra(0xFFFFFF00);
|
||||
|
||||
/// <summary>
|
||||
/// YellowGreen color.
|
||||
/// </summary>
|
||||
public static readonly Color YellowGreen = Color.FromBgra(0xFF9ACD32);
|
||||
}
|
||||
}
|
||||
1128
math/Color.cs
Normal file
1128
math/Color.cs
Normal file
File diff suppressed because it is too large
Load Diff
905
math/Color3.cs
Normal file
905
math/Color3.cs
Normal file
@ -0,0 +1,905 @@
|
||||
// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
|
||||
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// Original code from SlimMath project. http://code.google.com/p/slimmath/
|
||||
// Greetings to SlimDX Group. Original code published with the following license:
|
||||
// -----------------------------------------------------------------------------
|
||||
/*
|
||||
* Copyright (c) 2007-2011 SlimDX Group
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace math
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a color in the form of rgb.
|
||||
/// </summary>
|
||||
[DataContract( Name = "Color3")]
|
||||
[DataStyle(DataStyle.Compact)]
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
||||
public struct Color3 : IEquatable<Color3>, IFormattable
|
||||
{
|
||||
private const string ToStringFormat = "R:{0} G:{1} B:{2}";
|
||||
|
||||
/// <summary>
|
||||
/// The red component of the color.
|
||||
/// </summary>
|
||||
[DataMember( Order = 0 )]
|
||||
public float R;
|
||||
|
||||
/// <summary>
|
||||
/// The green component of the color.
|
||||
/// </summary>
|
||||
[DataMember( Order = 1 )]
|
||||
public float G;
|
||||
|
||||
/// <summary>
|
||||
/// The blue component of the color.
|
||||
/// </summary>
|
||||
[DataMember( Order = 2 )]
|
||||
public float B;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Color3"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="value">The value that will be assigned to all components.</param>
|
||||
public Color3(float value)
|
||||
{
|
||||
R = G = B = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Color3"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="red">The red component of the color.</param>
|
||||
/// <param name="green">The green component of the color.</param>
|
||||
/// <param name="blue">The blue component of the color.</param>
|
||||
public Color3(float red, float green, float blue)
|
||||
{
|
||||
R = red;
|
||||
G = green;
|
||||
B = blue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Color3"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="value">The red, green, and blue components of the color.</param>
|
||||
public Color3(Vector3 value)
|
||||
{
|
||||
R = value.X;
|
||||
G = value.Y;
|
||||
B = value.Z;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Color3"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="rgb">A packed integer containing all three color components.
|
||||
/// The alpha component is ignored.</param>
|
||||
public Color3(int rgb)
|
||||
{
|
||||
B = ((rgb >> 16) & 255) / 255.0f;
|
||||
G = ((rgb >> 8) & 255) / 255.0f;
|
||||
R = (rgb & 255) / 255.0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Color3"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="rgb">A packed unsigned integer containing all three color components.
|
||||
/// The alpha component is ignored.</param>
|
||||
public Color3(uint rgb)
|
||||
{
|
||||
B = ((rgb >> 16) & 255) / 255.0f;
|
||||
G = ((rgb >> 8) & 255) / 255.0f;
|
||||
R = (rgb & 255) / 255.0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Color3"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="values">The values to assign to the red, green, and blue components of the color. This must be an array with three elements.</param>
|
||||
/// <exception cref="ArgumentNullException">Thrown when <paramref name="values"/> is <c>null</c>.</exception>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Thrown when <paramref name="values"/> contains more or less than four elements.</exception>
|
||||
public Color3(float[] values)
|
||||
{
|
||||
if (values == null)
|
||||
throw new ArgumentNullException(nameof(values));
|
||||
if (values.Length != 3)
|
||||
throw new ArgumentOutOfRangeException(nameof(values), "There must be three and only three input values for Color3.");
|
||||
|
||||
R = values[0];
|
||||
G = values[1];
|
||||
B = values[2];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the component at the specified index.
|
||||
/// </summary>
|
||||
/// <value>The value of the red, green, or blue component, depending on the index.</value>
|
||||
/// <param name="index">The index of the component to access. Use 0 for the red component, 1 for the green component, and 2 for the blue component.</param>
|
||||
/// <returns>The value of the component at the specified index.</returns>
|
||||
/// <exception cref="System.ArgumentOutOfRangeException">Thrown when the <paramref name="index"/> is out of the range [0, 2].</exception>
|
||||
public float this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0: return R;
|
||||
case 1: return G;
|
||||
case 2: return B;
|
||||
}
|
||||
|
||||
throw new ArgumentOutOfRangeException(nameof(index), "Indices for Color3 run from 0 to 2, inclusive.");
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0: R = value; break;
|
||||
case 1: G = value; break;
|
||||
case 2: B = value; break;
|
||||
default: throw new ArgumentOutOfRangeException(nameof(index), "Indices for Color3 run from 0 to 2, inclusive.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the color into a packed integer.
|
||||
/// </summary>
|
||||
/// <returns>A packed integer containing all three color components.
|
||||
/// The alpha channel is set to 255.</returns>
|
||||
public int ToRgb()
|
||||
{
|
||||
uint a = 255;
|
||||
uint r = (uint)(R * 255.0f);
|
||||
uint g = (uint)(G * 255.0f);
|
||||
uint b = (uint)(B * 255.0f);
|
||||
|
||||
uint value = r;
|
||||
value += g << 8;
|
||||
value += b << 16;
|
||||
value += a << 24;
|
||||
|
||||
return (int)value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raises the exponent for each components.
|
||||
/// </summary>
|
||||
/// <param name="exponent">The exponent.</param>
|
||||
public void Pow(float exponent)
|
||||
{
|
||||
R = (float)Math.Pow(R, exponent);
|
||||
G = (float)Math.Pow(G, exponent);
|
||||
B = (float)Math.Pow(B, exponent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the color into a three component vector.
|
||||
/// </summary>
|
||||
/// <returns>A three component vector containing the red, green, and blue components of the color.</returns>
|
||||
public Vector3 ToVector3()
|
||||
{
|
||||
return new Vector3(R, G, B);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an array containing the elements of the color.
|
||||
/// </summary>
|
||||
/// <returns>A three-element array containing the components of the color.</returns>
|
||||
public float[] ToArray()
|
||||
{
|
||||
return new[] { R, G, B };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds two colors.
|
||||
/// </summary>
|
||||
/// <param name="left">The first color to add.</param>
|
||||
/// <param name="right">The second color to add.</param>
|
||||
/// <param name="result">When the method completes, completes the sum of the two colors.</param>
|
||||
public static void Add(ref Color3 left, ref Color3 right, out Color3 result)
|
||||
{
|
||||
result.R = left.R + right.R;
|
||||
result.G = left.G + right.G;
|
||||
result.B = left.B + right.B;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds two colors.
|
||||
/// </summary>
|
||||
/// <param name="left">The first color to add.</param>
|
||||
/// <param name="right">The second color to add.</param>
|
||||
/// <returns>The sum of the two colors.</returns>
|
||||
public static Color3 Add(Color3 left, Color3 right)
|
||||
{
|
||||
return new Color3(left.R + right.R, left.G + right.G, left.B + right.B);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subtracts two colors.
|
||||
/// </summary>
|
||||
/// <param name="left">The first color to subtract.</param>
|
||||
/// <param name="right">The second color to subtract.</param>
|
||||
/// <param name="result">WHen the method completes, contains the difference of the two colors.</param>
|
||||
public static void Subtract(ref Color3 left, ref Color3 right, out Color3 result)
|
||||
{
|
||||
result.R = left.R - right.R;
|
||||
result.G = left.G - right.G;
|
||||
result.B = left.B - right.B;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subtracts two colors.
|
||||
/// </summary>
|
||||
/// <param name="left">The first color to subtract.</param>
|
||||
/// <param name="right">The second color to subtract</param>
|
||||
/// <returns>The difference of the two colors.</returns>
|
||||
public static Color3 Subtract(Color3 left, Color3 right)
|
||||
{
|
||||
return new Color3(left.R - right.R, left.G - right.G, left.B - right.B);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Modulates two colors.
|
||||
/// </summary>
|
||||
/// <param name="left">The first color to modulate.</param>
|
||||
/// <param name="right">The second color to modulate.</param>
|
||||
/// <param name="result">When the method completes, contains the modulated color.</param>
|
||||
public static void Modulate(ref Color3 left, ref Color3 right, out Color3 result)
|
||||
{
|
||||
result.R = left.R * right.R;
|
||||
result.G = left.G * right.G;
|
||||
result.B = left.B * right.B;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Modulates two colors.
|
||||
/// </summary>
|
||||
/// <param name="left">The first color to modulate.</param>
|
||||
/// <param name="right">The second color to modulate.</param>
|
||||
/// <returns>The modulated color.</returns>
|
||||
public static Color3 Modulate(Color3 left, Color3 right)
|
||||
{
|
||||
return new Color3(left.R * right.R, left.G * right.G, left.B * right.B);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scales a color.
|
||||
/// </summary>
|
||||
/// <param name="value">The color to scale.</param>
|
||||
/// <param name="scale">The amount by which to scale.</param>
|
||||
/// <param name="result">When the method completes, contains the scaled color.</param>
|
||||
public static void Scale(ref Color3 value, float scale, out Color3 result)
|
||||
{
|
||||
result.R = value.R * scale;
|
||||
result.G = value.G * scale;
|
||||
result.B = value.B * scale;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scales a color.
|
||||
/// </summary>
|
||||
/// <param name="value">The color to scale.</param>
|
||||
/// <param name="scale">The amount by which to scale.</param>
|
||||
/// <returns>The scaled color.</returns>
|
||||
public static Color3 Scale(Color3 value, float scale)
|
||||
{
|
||||
return new Color3(value.R * scale, value.G * scale, value.B * scale);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Negates a color.
|
||||
/// </summary>
|
||||
/// <param name="value">The color to negate.</param>
|
||||
/// <param name="result">When the method completes, contains the negated color.</param>
|
||||
public static void Negate(ref Color3 value, out Color3 result)
|
||||
{
|
||||
result.R = 1.0f - value.R;
|
||||
result.G = 1.0f - value.G;
|
||||
result.B = 1.0f - value.B;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Negates a color.
|
||||
/// </summary>
|
||||
/// <param name="value">The color to negate.</param>
|
||||
/// <returns>The negated color.</returns>
|
||||
public static Color3 Negate(Color3 value)
|
||||
{
|
||||
return new Color3(1.0f - value.R, 1.0f - value.G, 1.0f - value.B);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restricts a value to be within a specified range.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to clamp.</param>
|
||||
/// <param name="min">The minimum value.</param>
|
||||
/// <param name="max">The maximum value.</param>
|
||||
/// <param name="result">When the method completes, contains the clamped value.</param>
|
||||
public static void Clamp(ref Color3 value, ref Color3 min, ref Color3 max, out Color3 result)
|
||||
{
|
||||
float red = value.R;
|
||||
red = (red > max.R) ? max.R : red;
|
||||
red = (red < min.R) ? min.R : red;
|
||||
|
||||
float green = value.G;
|
||||
green = (green > max.G) ? max.G : green;
|
||||
green = (green < min.G) ? min.G : green;
|
||||
|
||||
float blue = value.B;
|
||||
blue = (blue > max.B) ? max.B : blue;
|
||||
blue = (blue < min.B) ? min.B : blue;
|
||||
|
||||
result = new Color3(red, green, blue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restricts a value to be within a specified range.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to clamp.</param>
|
||||
/// <param name="min">The minimum value.</param>
|
||||
/// <param name="max">The maximum value.</param>
|
||||
/// <returns>The clamped value.</returns>
|
||||
public static Color3 Clamp(Color3 value, Color3 min, Color3 max)
|
||||
{
|
||||
Color3 result;
|
||||
Clamp(ref value, ref min, ref max, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs a linear interpolation between two colors.
|
||||
/// </summary>
|
||||
/// <param name="start">Start color.</param>
|
||||
/// <param name="end">End color.</param>
|
||||
/// <param name="amount">Value between 0 and 1 indicating the weight of <paramref name="end"/>.</param>
|
||||
/// <param name="result">When the method completes, contains the linear interpolation of the two colors.</param>
|
||||
/// <remarks>
|
||||
/// This method performs the linear interpolation based on the following formula.
|
||||
/// <code>start + (end - start) * amount</code>
|
||||
/// Passing <paramref name="amount"/> a value of 0 will cause <paramref name="start"/> to be returned; a value of 1 will cause <paramref name="end"/> to be returned.
|
||||
/// </remarks>
|
||||
public static void Lerp(ref Color3 start, ref Color3 end, float amount, out Color3 result)
|
||||
{
|
||||
result.R = start.R + amount * (end.R - start.R);
|
||||
result.G = start.G + amount * (end.G - start.G);
|
||||
result.B = start.B + amount * (end.B - start.B);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs a linear interpolation between two colors.
|
||||
/// </summary>
|
||||
/// <param name="start">Start color.</param>
|
||||
/// <param name="end">End color.</param>
|
||||
/// <param name="amount">Value between 0 and 1 indicating the weight of <paramref name="end"/>.</param>
|
||||
/// <returns>The linear interpolation of the two colors.</returns>
|
||||
/// <remarks>
|
||||
/// This method performs the linear interpolation based on the following formula.
|
||||
/// <code>start + (end - start) * amount</code>
|
||||
/// Passing <paramref name="amount"/> a value of 0 will cause <paramref name="start"/> to be returned; a value of 1 will cause <paramref name="end"/> to be returned.
|
||||
/// </remarks>
|
||||
public static Color3 Lerp(Color3 start, Color3 end, float amount)
|
||||
{
|
||||
return new Color3(
|
||||
start.R + amount * (end.R - start.R),
|
||||
start.G + amount * (end.G - start.G),
|
||||
start.B + amount * (end.B - start.B));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs a cubic interpolation between two colors.
|
||||
/// </summary>
|
||||
/// <param name="start">Start color.</param>
|
||||
/// <param name="end">End color.</param>
|
||||
/// <param name="amount">Value between 0 and 1 indicating the weight of <paramref name="end"/>.</param>
|
||||
/// <param name="result">When the method completes, contains the cubic interpolation of the two colors.</param>
|
||||
public static void SmoothStep(ref Color3 start, ref Color3 end, float amount, out Color3 result)
|
||||
{
|
||||
amount = (amount > 1.0f) ? 1.0f : ((amount < 0.0f) ? 0.0f : amount);
|
||||
amount = (amount * amount) * (3.0f - (2.0f * amount));
|
||||
|
||||
result.R = start.R + ((end.R - start.R) * amount);
|
||||
result.G = start.G + ((end.G - start.G) * amount);
|
||||
result.B = start.B + ((end.B - start.B) * amount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs a cubic interpolation between two colors.
|
||||
/// </summary>
|
||||
/// <param name="start">Start color.</param>
|
||||
/// <param name="end">End color.</param>
|
||||
/// <param name="amount">Value between 0 and 1 indicating the weight of <paramref name="end"/>.</param>
|
||||
/// <returns>The cubic interpolation of the two colors.</returns>
|
||||
public static Color3 SmoothStep(Color3 start, Color3 end, float amount)
|
||||
{
|
||||
amount = (amount > 1.0f) ? 1.0f : ((amount < 0.0f) ? 0.0f : amount);
|
||||
amount = (amount * amount) * (3.0f - (2.0f * amount));
|
||||
|
||||
return new Color3(
|
||||
start.R + ((end.R - start.R) * amount),
|
||||
start.G + ((end.G - start.G) * amount),
|
||||
start.B + ((end.B - start.B) * amount));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a color containing the smallest components of the specified colorss.
|
||||
/// </summary>
|
||||
/// <param name="left">The first source color.</param>
|
||||
/// <param name="right">The second source color.</param>
|
||||
/// <param name="result">When the method completes, contains an new color composed of the largest components of the source colorss.</param>
|
||||
public static void Max(ref Color3 left, ref Color3 right, out Color3 result)
|
||||
{
|
||||
result.R = (left.R > right.R) ? left.R : right.R;
|
||||
result.G = (left.G > right.G) ? left.G : right.G;
|
||||
result.B = (left.B > right.B) ? left.B : right.B;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a color containing the largest components of the specified colorss.
|
||||
/// </summary>
|
||||
/// <param name="left">The first source color.</param>
|
||||
/// <param name="right">The second source color.</param>
|
||||
/// <returns>A color containing the largest components of the source colors.</returns>
|
||||
public static Color3 Max(Color3 left, Color3 right)
|
||||
{
|
||||
Color3 result;
|
||||
Max(ref left, ref right, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a color containing the smallest components of the specified colors.
|
||||
/// </summary>
|
||||
/// <param name="left">The first source color.</param>
|
||||
/// <param name="right">The second source color.</param>
|
||||
/// <param name="result">When the method completes, contains an new color composed of the smallest components of the source colors.</param>
|
||||
public static void Min(ref Color3 left, ref Color3 right, out Color3 result)
|
||||
{
|
||||
result.R = (left.R < right.R) ? left.R : right.R;
|
||||
result.G = (left.G < right.G) ? left.G : right.G;
|
||||
result.B = (left.B < right.B) ? left.B : right.B;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a color containing the smallest components of the specified colors.
|
||||
/// </summary>
|
||||
/// <param name="left">The first source color.</param>
|
||||
/// <param name="right">The second source color.</param>
|
||||
/// <returns>A color containing the smallest components of the source colors.</returns>
|
||||
public static Color3 Min(Color3 left, Color3 right)
|
||||
{
|
||||
Color3 result;
|
||||
Min(ref left, ref right, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adjusts the contrast of a color.
|
||||
/// </summary>
|
||||
/// <param name="value">The color whose contrast is to be adjusted.</param>
|
||||
/// <param name="contrast">The amount by which to adjust the contrast.</param>
|
||||
/// <param name="result">When the method completes, contains the adjusted color.</param>
|
||||
public static void AdjustContrast(ref Color3 value, float contrast, out Color3 result)
|
||||
{
|
||||
result.R = 0.5f + contrast * (value.R - 0.5f);
|
||||
result.G = 0.5f + contrast * (value.G - 0.5f);
|
||||
result.B = 0.5f + contrast * (value.B - 0.5f);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adjusts the contrast of a color.
|
||||
/// </summary>
|
||||
/// <param name="value">The color whose contrast is to be adjusted.</param>
|
||||
/// <param name="contrast">The amount by which to adjust the contrast.</param>
|
||||
/// <returns>The adjusted color.</returns>
|
||||
public static Color3 AdjustContrast(Color3 value, float contrast)
|
||||
{
|
||||
return new Color3(
|
||||
0.5f + contrast * (value.R - 0.5f),
|
||||
0.5f + contrast * (value.G - 0.5f),
|
||||
0.5f + contrast * (value.B - 0.5f));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adjusts the saturation of a color.
|
||||
/// </summary>
|
||||
/// <param name="value">The color whose saturation is to be adjusted.</param>
|
||||
/// <param name="saturation">The amount by which to adjust the saturation.</param>
|
||||
/// <param name="result">When the method completes, contains the adjusted color.</param>
|
||||
public static void AdjustSaturation(ref Color3 value, float saturation, out Color3 result)
|
||||
{
|
||||
float grey = value.R * 0.2125f + value.G * 0.7154f + value.B * 0.0721f;
|
||||
|
||||
result.R = grey + saturation * (value.R - grey);
|
||||
result.G = grey + saturation * (value.G - grey);
|
||||
result.B = grey + saturation * (value.B - grey);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adjusts the saturation of a color.
|
||||
/// </summary>
|
||||
/// <param name="value">The color whose saturation is to be adjusted.</param>
|
||||
/// <param name="saturation">The amount by which to adjust the saturation.</param>
|
||||
/// <returns>The adjusted color.</returns>
|
||||
public static Color3 AdjustSaturation(Color3 value, float saturation)
|
||||
{
|
||||
float grey = value.R * 0.2125f + value.G * 0.7154f + value.B * 0.0721f;
|
||||
|
||||
return new Color3(
|
||||
grey + saturation * (value.R - grey),
|
||||
grey + saturation * (value.G - grey),
|
||||
grey + saturation * (value.B - grey));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts this color from linear space to sRGB space.
|
||||
/// </summary>
|
||||
/// <returns>A color3 in sRGB space.</returns>
|
||||
public Color3 ToSRgb()
|
||||
{
|
||||
return new Color3(MathUtil.LinearToSRgb(R), MathUtil.LinearToSRgb(G), MathUtil.LinearToSRgb(B));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts this color from sRGB space to linear space.
|
||||
/// </summary>
|
||||
/// <returns>Color3.</returns>
|
||||
public Color3 ToLinear()
|
||||
{
|
||||
return new Color3(MathUtil.SRgbToLinear(R), MathUtil.SRgbToLinear(G), MathUtil.SRgbToLinear(B));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds two colors.
|
||||
/// </summary>
|
||||
/// <param name="left">The first color to add.</param>
|
||||
/// <param name="right">The second color to add.</param>
|
||||
/// <returns>The sum of the two colors.</returns>
|
||||
public static Color3 operator +(Color3 left, Color3 right)
|
||||
{
|
||||
return new Color3(left.R + right.R, left.G + right.G, left.B + right.B);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assert a color (return it unchanged).
|
||||
/// </summary>
|
||||
/// <param name="value">The color to assert (unchange).</param>
|
||||
/// <returns>The asserted (unchanged) color.</returns>
|
||||
public static Color3 operator +(Color3 value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subtracts two colors.
|
||||
/// </summary>
|
||||
/// <param name="left">The first color to subtract.</param>
|
||||
/// <param name="right">The second color to subtract.</param>
|
||||
/// <returns>The difference of the two colors.</returns>
|
||||
public static Color3 operator -(Color3 left, Color3 right)
|
||||
{
|
||||
return new Color3(left.R - right.R, left.G - right.G, left.B - right.B);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Negates a color.
|
||||
/// </summary>
|
||||
/// <param name="value">The color to negate.</param>
|
||||
/// <returns>A negated color.</returns>
|
||||
public static Color3 operator -(Color3 value)
|
||||
{
|
||||
return new Color3(-value.R, -value.G, -value.B);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scales a color.
|
||||
/// </summary>
|
||||
/// <param name="scale">The factor by which to scale the color.</param>
|
||||
/// <param name="value">The color to scale.</param>
|
||||
/// <returns>The scaled color.</returns>
|
||||
public static Color3 operator *(float scale, Color3 value)
|
||||
{
|
||||
return new Color3(value.R * scale, value.G * scale, value.B * scale);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scales a color.
|
||||
/// </summary>
|
||||
/// <param name="value">The factor by which to scale the color.</param>
|
||||
/// <param name="scale">The color to scale.</param>
|
||||
/// <returns>The scaled color.</returns>
|
||||
public static Color3 operator *(Color3 value, float scale)
|
||||
{
|
||||
return new Color3(value.R * scale, value.G * scale, value.B * scale);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Modulates two colors.
|
||||
/// </summary>
|
||||
/// <param name="left">The first color to modulate.</param>
|
||||
/// <param name="right">The second color to modulate.</param>
|
||||
/// <returns>The modulated color.</returns>
|
||||
public static Color3 operator *(Color3 left, Color3 right)
|
||||
{
|
||||
return new Color3(left.R * right.R, left.G * right.G, left.B * right.B);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests for equality between two objects.
|
||||
/// </summary>
|
||||
/// <param name="left">The first value to compare.</param>
|
||||
/// <param name="right">The second value to compare.</param>
|
||||
/// <returns><c>true</c> if <paramref name="left"/> has the same value as <paramref name="right"/>; otherwise, <c>false</c>.</returns>
|
||||
public static bool operator ==(Color3 left, Color3 right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests for inequality between two objects.
|
||||
/// </summary>
|
||||
/// <param name="left">The first value to compare.</param>
|
||||
/// <param name="right">The second value to compare.</param>
|
||||
/// <returns><c>true</c> if <paramref name="left"/> has a different value than <paramref name="right"/>; otherwise, <c>false</c>.</returns>
|
||||
public static bool operator !=(Color3 left, Color3 right)
|
||||
{
|
||||
return !left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an explicit conversion from <see cref="Color3"/> to <see cref="Color4"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static explicit operator Color4(Color3 value)
|
||||
{
|
||||
return new Color4(value.R, value.G, value.B, 1.0f);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an explicit conversion from <see cref="Color3"/> to <see cref="math.Vector3"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static explicit operator Vector3(Color3 value)
|
||||
{
|
||||
return new Vector3(value.R, value.G, value.B);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an explicit conversion from <see cref="math.Vector3"/> to <see cref="Color3"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static explicit operator Color3(Vector3 value)
|
||||
{
|
||||
return new Color3(value.X, value.Y, value.Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an explicit conversion from <see cref="int"/> to <see cref="Color3"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static explicit operator Color3(int value)
|
||||
{
|
||||
return new Color3(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="string"/> that represents this instance.
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return ToString(CultureInfo.CurrentCulture);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert this color to an equivalent <see cref="Color4"/> with an opaque alpha.
|
||||
/// </summary>
|
||||
/// <returns>An equivalent <see cref="Color4"/> with an opaque alpha.</returns>
|
||||
public Color4 ToColor4()
|
||||
{
|
||||
return new Color4(R, G, B, 1.0f);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <param name="format">The format.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="string"/> that represents this instance.
|
||||
/// </returns>
|
||||
public string ToString(string format)
|
||||
{
|
||||
return ToString(format, CultureInfo.CurrentCulture);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <param name="formatProvider">The format provider.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="string"/> that represents this instance.
|
||||
/// </returns>
|
||||
public string ToString(IFormatProvider formatProvider)
|
||||
{
|
||||
return string.Format(formatProvider, ToStringFormat, R, G, B);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <param name="format">The format.</param>
|
||||
/// <param name="formatProvider">The format provider.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="string"/> that represents this instance.
|
||||
/// </returns>
|
||||
public string ToString(string format, IFormatProvider formatProvider)
|
||||
{
|
||||
if (format == null)
|
||||
return ToString(formatProvider);
|
||||
|
||||
return string.Format(formatProvider, ToStringFormat,
|
||||
R.ToString(format, formatProvider),
|
||||
G.ToString(format, formatProvider),
|
||||
B.ToString(format, formatProvider));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a hash code for this instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
|
||||
/// </returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return R.GetHashCode() + G.GetHashCode() + B.GetHashCode();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="Color3"/> is equal to this instance.
|
||||
/// </summary>
|
||||
/// <param name="other">The <see cref="Color3"/> to compare with this instance.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the specified <see cref="Color3"/> is equal to this instance; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public bool Equals(Color3 other)
|
||||
{
|
||||
return R == other.R && G == other.G && B == other.B;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="object"/> is equal to this instance.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="object"/> to compare with this instance.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the specified <see cref="object"/> is equal to this instance; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
if (value == null)
|
||||
return false;
|
||||
|
||||
if (value.GetType() != GetType())
|
||||
return false;
|
||||
|
||||
return Equals((Color3)value);
|
||||
}
|
||||
|
||||
#if SlimDX1xInterop
|
||||
/// <summary>
|
||||
/// Performs an implicit conversion from <see cref="math.Color3"/> to <see cref="SlimDX.Color3"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator SlimDX.Color3(Color3 value)
|
||||
{
|
||||
return new SlimDX.Color3(value.Red, value.Green, value.Blue);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an implicit conversion from <see cref="SlimDX.Color3"/> to <see cref="math.Color3"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator Color3(SlimDX.Color3 value)
|
||||
{
|
||||
return new Color3(value.Red, value.Green, value.Blue);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if WPFInterop
|
||||
/// <summary>
|
||||
/// Performs an explicit conversion from <see cref="math.Color3"/> to <see cref="System.Windows.Media.Color"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static explicit operator System.Windows.Media.Color(Color3 value)
|
||||
{
|
||||
return new System.Windows.Media.Color()
|
||||
{
|
||||
A = 255,
|
||||
R = (byte)(255f * value.Red),
|
||||
G = (byte)(255f * value.Green),
|
||||
B = (byte)(255f * value.Blue)
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an explicit conversion from <see cref="System.Windows.Media.Color"/> to <see cref="math.Color3"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static explicit operator Color3(System.Windows.Media.Color value)
|
||||
{
|
||||
return new Color3()
|
||||
{
|
||||
Red = (float)value.R / 255f,
|
||||
Green = (float)value.G / 255f,
|
||||
Blue = (float)value.B / 255f
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
#if WinFormsInterop
|
||||
/// <summary>
|
||||
/// Performs an explicit conversion from <see cref="math.Color3"/> to <see cref="System.Drawing.Color"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator System.Drawing.Color(Color3 value)
|
||||
{
|
||||
return System.Drawing.Color.FromArgb(
|
||||
(byte)(255f * value.Red),
|
||||
(byte)(255f * value.Green),
|
||||
(byte)(255f * value.Blue));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an explicit conversion from <see cref="System.Drawing.Color"/> to <see cref="math.Color3"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator Color3(System.Drawing.Color value)
|
||||
{
|
||||
return new Color3()
|
||||
{
|
||||
Red = (float)value.R / 255f,
|
||||
Green = (float)value.G / 255f,
|
||||
Blue = (float)value.B / 255f
|
||||
};
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
999
math/Color4.cs
Normal file
999
math/Color4.cs
Normal file
@ -0,0 +1,999 @@
|
||||
// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
|
||||
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// Original code from SlimMath project. http://code.google.com/p/slimmath/
|
||||
// Greetings to SlimDX Group. Original code published with the following license:
|
||||
// -----------------------------------------------------------------------------
|
||||
/*
|
||||
* Copyright (c) 2007-2011 SlimDX Group
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace math
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a color in the form of rgba.
|
||||
/// </summary>
|
||||
[DataContract( Name = "Color4")]
|
||||
[DataStyle(DataStyle.Compact)]
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
||||
public struct Color4 : IEquatable<Color4>, IFormattable
|
||||
{
|
||||
private const string ToStringFormat = "A:{0} R:{1} G:{2} B:{3}";
|
||||
|
||||
/// <summary>
|
||||
/// The Black color (0, 0, 0, 1).
|
||||
/// </summary>
|
||||
public static readonly Color4 Black = new Color4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
/// <summary>
|
||||
/// The White color (1, 1, 1, 1).
|
||||
/// </summary>
|
||||
public static readonly Color4 White = new Color4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
/// <summary>
|
||||
/// The red component of the color.
|
||||
/// </summary>
|
||||
[DataMember( Order = 0 )]
|
||||
public float R;
|
||||
|
||||
/// <summary>
|
||||
/// The green component of the color.
|
||||
/// </summary>
|
||||
[DataMember( Order = 1 )]
|
||||
public float G;
|
||||
|
||||
/// <summary>
|
||||
/// The blue component of the color.
|
||||
/// </summary>
|
||||
[DataMember( Order = 2 )]
|
||||
public float B;
|
||||
|
||||
/// <summary>
|
||||
/// The alpha component of the color.
|
||||
/// </summary>
|
||||
[DataMember( Order = 3 )]
|
||||
public float A;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Color4"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="value">The value that will be assigned to all components.</param>
|
||||
public Color4(float value)
|
||||
{
|
||||
A = R = G = B = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Color4"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="red">The red component of the color.</param>
|
||||
/// <param name="green">The green component of the color.</param>
|
||||
/// <param name="blue">The blue component of the color.</param>
|
||||
/// <param name="alpha">The alpha component of the color.</param>
|
||||
public Color4(float red, float green, float blue, float alpha)
|
||||
{
|
||||
R = red;
|
||||
G = green;
|
||||
B = blue;
|
||||
A = alpha;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Color4"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="value">The red, green, blue, and alpha components of the color.</param>
|
||||
public Color4(Vector4 value)
|
||||
{
|
||||
R = value.X;
|
||||
G = value.Y;
|
||||
B = value.Z;
|
||||
A = value.W;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Color4"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="value">The red, green, and blue components of the color.</param>
|
||||
/// <param name="alpha">The alpha component of the color.</param>
|
||||
public Color4(Vector3 value, float alpha)
|
||||
{
|
||||
R = value.X;
|
||||
G = value.Y;
|
||||
B = value.Z;
|
||||
A = alpha;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Color4"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="rgba">A packed integer containing all four color components in RGBA order.</param>
|
||||
public Color4(uint rgba)
|
||||
{
|
||||
A = ((rgba >> 24) & 255) / 255.0f;
|
||||
B = ((rgba >> 16) & 255) / 255.0f;
|
||||
G = ((rgba >> 8) & 255) / 255.0f;
|
||||
R = (rgba & 255) / 255.0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Color4"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="rgba">A packed integer containing all four color components in RGBA order.</param>
|
||||
public Color4(int rgba)
|
||||
{
|
||||
A = ((rgba >> 24) & 255) / 255.0f;
|
||||
B = ((rgba >> 16) & 255) / 255.0f;
|
||||
G = ((rgba >> 8) & 255) / 255.0f;
|
||||
R = (rgba & 255) / 255.0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Color4"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="values">The values to assign to the red, green, blue, and alpha components of the color. This must be an array with four elements.</param>
|
||||
/// <exception cref="ArgumentNullException">Thrown when <paramref name="values"/> is <c>null</c>.</exception>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Thrown when <paramref name="values"/> contains more or less than four elements.</exception>
|
||||
public Color4(float[] values)
|
||||
{
|
||||
if (values == null)
|
||||
throw new ArgumentNullException(nameof(values));
|
||||
if (values.Length != 4)
|
||||
throw new ArgumentOutOfRangeException(nameof(values), "There must be four and only four input values for Color4.");
|
||||
|
||||
R = values[0];
|
||||
G = values[1];
|
||||
B = values[2];
|
||||
A = values[3];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Color4"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="color"><see cref="Color3"/> used to initialize the color.</param>
|
||||
public Color4(Color3 color)
|
||||
{
|
||||
R = color.R;
|
||||
G = color.G;
|
||||
B = color.B;
|
||||
A = 1.0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Color4"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="color"><see cref="Color"/> used to initialize the color.</param>
|
||||
public Color4(Color color)
|
||||
{
|
||||
R = color.R / 255.0f;
|
||||
G = color.G / 255.0f;
|
||||
B = color.B / 255.0f;
|
||||
A = color.A / 255.0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Color4"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="color"><see cref="Color"/> used to initialize the color.</param>
|
||||
public Color4(ColorBGRA color)
|
||||
{
|
||||
R = color.R / 255.0f;
|
||||
G = color.G / 255.0f;
|
||||
B = color.B / 255.0f;
|
||||
A = color.A / 255.0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Color4"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="color"><see cref="Color3"/> used to initialize the color.</param>
|
||||
/// <param name="alpha">The alpha component of the color.</param>
|
||||
public Color4(Color3 color, float alpha)
|
||||
{
|
||||
R = color.R;
|
||||
G = color.G;
|
||||
B = color.B;
|
||||
A = alpha;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the component at the specified index.
|
||||
/// </summary>
|
||||
/// <value>The value of the red, green, blue, and alpha components, depending on the index.</value>
|
||||
/// <param name="index">The index of the component to access. Use 0 for the alpha component, 1 for the red component, 2 for the green component, and 3 for the blue component.</param>
|
||||
/// <returns>The value of the component at the specified index.</returns>
|
||||
/// <exception cref="System.ArgumentOutOfRangeException">Thrown when the <paramref name="index"/> is out of the range [0, 3].</exception>
|
||||
public float this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0: return R;
|
||||
case 1: return G;
|
||||
case 2: return B;
|
||||
case 3: return A;
|
||||
}
|
||||
|
||||
throw new ArgumentOutOfRangeException(nameof(index), "Indices for Color4 run from 0 to 3, inclusive.");
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0: R = value; break;
|
||||
case 1: G = value; break;
|
||||
case 2: B = value; break;
|
||||
case 3: A = value; break;
|
||||
default: throw new ArgumentOutOfRangeException(nameof(index), "Indices for Color4 run from 0 to 3, inclusive.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the color into a packed integer.
|
||||
/// </summary>
|
||||
/// <returns>A packed integer containing all four color components.</returns>
|
||||
public int ToBgra()
|
||||
{
|
||||
uint a = (uint)(A * 255.0f) & 255;
|
||||
uint r = (uint)(R * 255.0f) & 255;
|
||||
uint g = (uint)(G * 255.0f) & 255;
|
||||
uint b = (uint)(B * 255.0f) & 255;
|
||||
|
||||
uint value = b;
|
||||
value |= g << 8;
|
||||
value |= r << 16;
|
||||
value |= a << 24;
|
||||
|
||||
return (int)value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the color into a packed integer.
|
||||
/// </summary>
|
||||
public void ToBgra(out byte r, out byte g, out byte b, out byte a)
|
||||
{
|
||||
a = (byte)(A * 255.0f);
|
||||
r = (byte)(R * 255.0f);
|
||||
g = (byte)(G * 255.0f);
|
||||
b = (byte)(B * 255.0f);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the color into a packed integer.
|
||||
/// </summary>
|
||||
/// <returns>A packed integer containing all four color components.</returns>
|
||||
public int ToRgba()
|
||||
{
|
||||
uint a = (uint)(A * 255.0f) & 255;
|
||||
uint r = (uint)(R * 255.0f) & 255;
|
||||
uint g = (uint)(G * 255.0f) & 255;
|
||||
uint b = (uint)(B * 255.0f) & 255;
|
||||
|
||||
uint value = r;
|
||||
value |= g << 8;
|
||||
value |= b << 16;
|
||||
value |= a << 24;
|
||||
|
||||
return (int)value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the color into a three component vector.
|
||||
/// </summary>
|
||||
/// <returns>A three component vector containing the red, green, and blue components of the color.</returns>
|
||||
public Vector3 ToVector3()
|
||||
{
|
||||
return new Vector3(R, G, B);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the color into a four component vector.
|
||||
/// </summary>
|
||||
/// <returns>A four component vector containing all four color components.</returns>
|
||||
public Vector4 ToVector4()
|
||||
{
|
||||
return new Vector4(R, G, B, A);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an array containing the elements of the color.
|
||||
/// </summary>
|
||||
/// <returns>A four-element array containing the components of the color.</returns>
|
||||
public float[] ToArray()
|
||||
{
|
||||
return new[] { R, G, B, A };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts this color from linear space to sRGB space.
|
||||
/// </summary>
|
||||
/// <returns>A color3 in sRGB space.</returns>
|
||||
public Color4 ToSRgb()
|
||||
{
|
||||
return new Color4(MathUtil.LinearToSRgb(R), MathUtil.LinearToSRgb(G), MathUtil.LinearToSRgb(B), A);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts this color from sRGB space to linear space.
|
||||
/// </summary>
|
||||
/// <returns>A color4 in linear space.</returns>
|
||||
public Color4 ToLinear()
|
||||
{
|
||||
return new Color4(MathUtil.SRgbToLinear(R), MathUtil.SRgbToLinear(G), MathUtil.SRgbToLinear(B), A);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds two colors.
|
||||
/// </summary>
|
||||
/// <param name="left">The first color to add.</param>
|
||||
/// <param name="right">The second color to add.</param>
|
||||
/// <param name="result">When the method completes, completes the sum of the two colors.</param>
|
||||
public static void Add(ref Color4 left, ref Color4 right, out Color4 result)
|
||||
{
|
||||
result.A = left.A + right.A;
|
||||
result.R = left.R + right.R;
|
||||
result.G = left.G + right.G;
|
||||
result.B = left.B + right.B;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds two colors.
|
||||
/// </summary>
|
||||
/// <param name="left">The first color to add.</param>
|
||||
/// <param name="right">The second color to add.</param>
|
||||
/// <returns>The sum of the two colors.</returns>
|
||||
public static Color4 Add(Color4 left, Color4 right)
|
||||
{
|
||||
return new Color4(left.R + right.R, left.G + right.G, left.B + right.B, left.A + right.A);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subtracts two colors.
|
||||
/// </summary>
|
||||
/// <param name="left">The first color to subtract.</param>
|
||||
/// <param name="right">The second color to subtract.</param>
|
||||
/// <param name="result">WHen the method completes, contains the difference of the two colors.</param>
|
||||
public static void Subtract(ref Color4 left, ref Color4 right, out Color4 result)
|
||||
{
|
||||
result.A = left.A - right.A;
|
||||
result.R = left.R - right.R;
|
||||
result.G = left.G - right.G;
|
||||
result.B = left.B - right.B;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subtracts two colors.
|
||||
/// </summary>
|
||||
/// <param name="left">The first color to subtract.</param>
|
||||
/// <param name="right">The second color to subtract</param>
|
||||
/// <returns>The difference of the two colors.</returns>
|
||||
public static Color4 Subtract(Color4 left, Color4 right)
|
||||
{
|
||||
return new Color4(left.R - right.R, left.G - right.G, left.B - right.B, left.A - right.A);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Modulates two colors.
|
||||
/// </summary>
|
||||
/// <param name="left">The first color to modulate.</param>
|
||||
/// <param name="right">The second color to modulate.</param>
|
||||
/// <param name="result">When the method completes, contains the modulated color.</param>
|
||||
public static void Modulate(ref Color4 left, ref Color4 right, out Color4 result)
|
||||
{
|
||||
result.A = left.A * right.A;
|
||||
result.R = left.R * right.R;
|
||||
result.G = left.G * right.G;
|
||||
result.B = left.B * right.B;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Modulates two colors.
|
||||
/// </summary>
|
||||
/// <param name="left">The first color to modulate.</param>
|
||||
/// <param name="right">The second color to modulate.</param>
|
||||
/// <returns>The modulated color.</returns>
|
||||
public static Color4 Modulate(Color4 left, Color4 right)
|
||||
{
|
||||
return new Color4(left.R * right.R, left.G * right.G, left.B * right.B, left.A * right.A);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scales a color.
|
||||
/// </summary>
|
||||
/// <param name="value">The color to scale.</param>
|
||||
/// <param name="scale">The amount by which to scale.</param>
|
||||
/// <param name="result">When the method completes, contains the scaled color.</param>
|
||||
public static void Scale(ref Color4 value, float scale, out Color4 result)
|
||||
{
|
||||
result.A = value.A * scale;
|
||||
result.R = value.R * scale;
|
||||
result.G = value.G * scale;
|
||||
result.B = value.B * scale;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scales a color.
|
||||
/// </summary>
|
||||
/// <param name="value">The color to scale.</param>
|
||||
/// <param name="scale">The amount by which to scale.</param>
|
||||
/// <returns>The scaled color.</returns>
|
||||
public static Color4 Scale(Color4 value, float scale)
|
||||
{
|
||||
return new Color4(value.R * scale, value.G * scale, value.B * scale, value.A * scale);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Negates a color.
|
||||
/// </summary>
|
||||
/// <param name="value">The color to negate.</param>
|
||||
/// <param name="result">When the method completes, contains the negated color.</param>
|
||||
public static void Negate(ref Color4 value, out Color4 result)
|
||||
{
|
||||
result.A = 1.0f - value.A;
|
||||
result.R = 1.0f - value.R;
|
||||
result.G = 1.0f - value.G;
|
||||
result.B = 1.0f - value.B;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Negates a color.
|
||||
/// </summary>
|
||||
/// <param name="value">The color to negate.</param>
|
||||
/// <returns>The negated color.</returns>
|
||||
public static Color4 Negate(Color4 value)
|
||||
{
|
||||
return new Color4(1.0f - value.R, 1.0f - value.G, 1.0f - value.B, 1.0f - value.A);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restricts a value to be within a specified range.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to clamp.</param>
|
||||
/// <param name="min">The minimum value.</param>
|
||||
/// <param name="max">The maximum value.</param>
|
||||
/// <param name="result">When the method completes, contains the clamped value.</param>
|
||||
public static void Clamp(ref Color4 value, ref Color4 min, ref Color4 max, out Color4 result)
|
||||
{
|
||||
float alpha = value.A;
|
||||
alpha = (alpha > max.A) ? max.A : alpha;
|
||||
alpha = (alpha < min.A) ? min.A : alpha;
|
||||
|
||||
float red = value.R;
|
||||
red = (red > max.R) ? max.R : red;
|
||||
red = (red < min.R) ? min.R : red;
|
||||
|
||||
float green = value.G;
|
||||
green = (green > max.G) ? max.G : green;
|
||||
green = (green < min.G) ? min.G : green;
|
||||
|
||||
float blue = value.B;
|
||||
blue = (blue > max.B) ? max.B : blue;
|
||||
blue = (blue < min.B) ? min.B : blue;
|
||||
|
||||
result = new Color4(red, green, blue, alpha);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restricts a value to be within a specified range.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to clamp.</param>
|
||||
/// <param name="min">The minimum value.</param>
|
||||
/// <param name="max">The maximum value.</param>
|
||||
/// <returns>The clamped value.</returns>
|
||||
public static Color4 Clamp(Color4 value, Color4 min, Color4 max)
|
||||
{
|
||||
Color4 result;
|
||||
Clamp(ref value, ref min, ref max, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs a linear interpolation between two colors.
|
||||
/// </summary>
|
||||
/// <param name="start">Start color.</param>
|
||||
/// <param name="end">End color.</param>
|
||||
/// <param name="amount">Value between 0 and 1 indicating the weight of <paramref name="end"/>.</param>
|
||||
/// <param name="result">When the method completes, contains the linear interpolation of the two colors.</param>
|
||||
/// <remarks>
|
||||
/// Passing <paramref name="amount"/> a value of 0 will cause <paramref name="start"/> to be returned; a value of 1 will cause <paramref name="end"/> to be returned.
|
||||
/// </remarks>
|
||||
public static void Lerp(ref Color4 start, ref Color4 end, float amount, out Color4 result)
|
||||
{
|
||||
result.R = MathUtil.Lerp(start.R, end.R, amount);
|
||||
result.G = MathUtil.Lerp(start.G, end.G, amount);
|
||||
result.B = MathUtil.Lerp(start.B, end.B, amount);
|
||||
result.A = MathUtil.Lerp(start.A, end.A, amount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs a linear interpolation between two colors.
|
||||
/// </summary>
|
||||
/// <param name="start">Start color.</param>
|
||||
/// <param name="end">End color.</param>
|
||||
/// <param name="amount">Value between 0 and 1 indicating the weight of <paramref name="end"/>.</param>
|
||||
/// <returns>The linear interpolation of the two colors.</returns>
|
||||
/// <remarks>
|
||||
/// Passing <paramref name="amount"/> a value of 0 will cause <paramref name="start"/> to be returned; a value of 1 will cause <paramref name="end"/> to be returned.
|
||||
/// </remarks>
|
||||
public static Color4 Lerp(Color4 start, Color4 end, float amount)
|
||||
{
|
||||
Color4 result;
|
||||
Lerp(ref start, ref end, amount, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs a cubic interpolation between two colors.
|
||||
/// </summary>
|
||||
/// <param name="start">Start color.</param>
|
||||
/// <param name="end">End color.</param>
|
||||
/// <param name="amount">Value between 0 and 1 indicating the weight of <paramref name="end"/>.</param>
|
||||
/// <param name="result">When the method completes, contains the cubic interpolation of the two colors.</param>
|
||||
public static void SmoothStep(ref Color4 start, ref Color4 end, float amount, out Color4 result)
|
||||
{
|
||||
amount = MathUtil.SmoothStep(amount);
|
||||
Lerp(ref start, ref end, amount, out result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs a cubic interpolation between two colors.
|
||||
/// </summary>
|
||||
/// <param name="start">Start color.</param>
|
||||
/// <param name="end">End color.</param>
|
||||
/// <param name="amount">Value between 0 and 1 indicating the weight of <paramref name="end"/>.</param>
|
||||
/// <returns>The cubic interpolation of the two colors.</returns>
|
||||
public static Color4 SmoothStep(Color4 start, Color4 end, float amount)
|
||||
{
|
||||
Color4 result;
|
||||
SmoothStep(ref start, ref end, amount, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a color containing the smallest components of the specified colors.
|
||||
/// </summary>
|
||||
/// <param name="left">The first source color.</param>
|
||||
/// <param name="right">The second source color.</param>
|
||||
/// <param name="result">When the method completes, contains an new color composed of the largest components of the source colors.</param>
|
||||
public static void Max(ref Color4 left, ref Color4 right, out Color4 result)
|
||||
{
|
||||
result.A = (left.A > right.A) ? left.A : right.A;
|
||||
result.R = (left.R > right.R) ? left.R : right.R;
|
||||
result.G = (left.G > right.G) ? left.G : right.G;
|
||||
result.B = (left.B > right.B) ? left.B : right.B;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a color containing the largest components of the specified colors.
|
||||
/// </summary>
|
||||
/// <param name="left">The first source color.</param>
|
||||
/// <param name="right">The second source color.</param>
|
||||
/// <returns>A color containing the largest components of the source colors.</returns>
|
||||
public static Color4 Max(Color4 left, Color4 right)
|
||||
{
|
||||
Color4 result;
|
||||
Max(ref left, ref right, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a color containing the smallest components of the specified colors.
|
||||
/// </summary>
|
||||
/// <param name="left">The first source color.</param>
|
||||
/// <param name="right">The second source color.</param>
|
||||
/// <param name="result">When the method completes, contains an new color composed of the smallest components of the source colors.</param>
|
||||
public static void Min(ref Color4 left, ref Color4 right, out Color4 result)
|
||||
{
|
||||
result.A = (left.A < right.A) ? left.A : right.A;
|
||||
result.R = (left.R < right.R) ? left.R : right.R;
|
||||
result.G = (left.G < right.G) ? left.G : right.G;
|
||||
result.B = (left.B < right.B) ? left.B : right.B;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a color containing the smallest components of the specified colors.
|
||||
/// </summary>
|
||||
/// <param name="left">The first source color.</param>
|
||||
/// <param name="right">The second source color.</param>
|
||||
/// <returns>A color containing the smallest components of the source colors.</returns>
|
||||
public static Color4 Min(Color4 left, Color4 right)
|
||||
{
|
||||
Color4 result;
|
||||
Min(ref left, ref right, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adjusts the contrast of a color.
|
||||
/// </summary>
|
||||
/// <param name="value">The color whose contrast is to be adjusted.</param>
|
||||
/// <param name="contrast">The amount by which to adjust the contrast.</param>
|
||||
/// <param name="result">When the method completes, contains the adjusted color.</param>
|
||||
public static void AdjustContrast(ref Color4 value, float contrast, out Color4 result)
|
||||
{
|
||||
result.A = value.A;
|
||||
result.R = 0.5f + contrast * (value.R - 0.5f);
|
||||
result.G = 0.5f + contrast * (value.G - 0.5f);
|
||||
result.B = 0.5f + contrast * (value.B - 0.5f);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adjusts the contrast of a color.
|
||||
/// </summary>
|
||||
/// <param name="value">The color whose contrast is to be adjusted.</param>
|
||||
/// <param name="contrast">The amount by which to adjust the contrast.</param>
|
||||
/// <returns>The adjusted color.</returns>
|
||||
public static Color4 AdjustContrast(Color4 value, float contrast)
|
||||
{
|
||||
return new Color4(
|
||||
0.5f + contrast * (value.R - 0.5f),
|
||||
0.5f + contrast * (value.G - 0.5f),
|
||||
0.5f + contrast * (value.B - 0.5f),
|
||||
value.A);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adjusts the saturation of a color.
|
||||
/// </summary>
|
||||
/// <param name="value">The color whose saturation is to be adjusted.</param>
|
||||
/// <param name="saturation">The amount by which to adjust the saturation.</param>
|
||||
/// <param name="result">When the method completes, contains the adjusted color.</param>
|
||||
public static void AdjustSaturation(ref Color4 value, float saturation, out Color4 result)
|
||||
{
|
||||
float grey = value.R * 0.2125f + value.G * 0.7154f + value.B * 0.0721f;
|
||||
|
||||
result.A = value.A;
|
||||
result.R = grey + saturation * (value.R - grey);
|
||||
result.G = grey + saturation * (value.G - grey);
|
||||
result.B = grey + saturation * (value.B - grey);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adjusts the saturation of a color.
|
||||
/// </summary>
|
||||
/// <param name="value">The color whose saturation is to be adjusted.</param>
|
||||
/// <param name="saturation">The amount by which to adjust the saturation.</param>
|
||||
/// <returns>The adjusted color.</returns>
|
||||
public static Color4 AdjustSaturation(Color4 value, float saturation)
|
||||
{
|
||||
float grey = value.R * 0.2125f + value.G * 0.7154f + value.B * 0.0721f;
|
||||
|
||||
return new Color4(
|
||||
grey + saturation * (value.R - grey),
|
||||
grey + saturation * (value.G - grey),
|
||||
grey + saturation * (value.B - grey),
|
||||
value.A);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Premultiplies the color components by the alpha value.
|
||||
/// </summary>
|
||||
/// <param name="value">The color to premultiply.</param>
|
||||
/// <returns>A color with premultiplied alpha.</returns>
|
||||
public static Color4 PremultiplyAlpha(Color4 value)
|
||||
{
|
||||
return new Color4(value.R * value.A, value.G * value.A, value.B * value.A, value.A);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds two colors.
|
||||
/// </summary>
|
||||
/// <param name="left">The first color to add.</param>
|
||||
/// <param name="right">The second color to add.</param>
|
||||
/// <returns>The sum of the two colors.</returns>
|
||||
public static Color4 operator +(Color4 left, Color4 right)
|
||||
{
|
||||
return new Color4(left.R + right.R, left.G + right.G, left.B + right.B, left.A + right.A);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assert a color (return it unchanged).
|
||||
/// </summary>
|
||||
/// <param name="value">The color to assert (unchanged).</param>
|
||||
/// <returns>The asserted (unchanged) color.</returns>
|
||||
public static Color4 operator +(Color4 value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subtracts two colors.
|
||||
/// </summary>
|
||||
/// <param name="left">The first color to subtract.</param>
|
||||
/// <param name="right">The second color to subtract.</param>
|
||||
/// <returns>The difference of the two colors.</returns>
|
||||
public static Color4 operator -(Color4 left, Color4 right)
|
||||
{
|
||||
return new Color4(left.R - right.R, left.G - right.G, left.B - right.B, left.A - right.A);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Negates a color.
|
||||
/// </summary>
|
||||
/// <param name="value">The color to negate.</param>
|
||||
/// <returns>A negated color.</returns>
|
||||
public static Color4 operator -(Color4 value)
|
||||
{
|
||||
return new Color4(-value.R, -value.G, -value.B, -value.A);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scales a color.
|
||||
/// </summary>
|
||||
/// <param name="scale">The factor by which to scale the color.</param>
|
||||
/// <param name="value">The color to scale.</param>
|
||||
/// <returns>The scaled color.</returns>
|
||||
public static Color4 operator *(float scale, Color4 value)
|
||||
{
|
||||
return new Color4(value.R * scale, value.G * scale, value.B * scale, value.A * scale);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scales a color.
|
||||
/// </summary>
|
||||
/// <param name="value">The factor by which to scale the color.</param>
|
||||
/// <param name="scale">The color to scale.</param>
|
||||
/// <returns>The scaled color.</returns>
|
||||
public static Color4 operator *(Color4 value, float scale)
|
||||
{
|
||||
return new Color4(value.R * scale, value.G * scale, value.B * scale, value.A * scale);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Modulates two colors.
|
||||
/// </summary>
|
||||
/// <param name="left">The first color to modulate.</param>
|
||||
/// <param name="right">The second color to modulate.</param>
|
||||
/// <returns>The modulated color.</returns>
|
||||
public static Color4 operator *(Color4 left, Color4 right)
|
||||
{
|
||||
return new Color4(left.R * right.R, left.G * right.G, left.B * right.B, left.A * right.A);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests for equality between two objects.
|
||||
/// </summary>
|
||||
/// <param name="left">The first value to compare.</param>
|
||||
/// <param name="right">The second value to compare.</param>
|
||||
/// <returns><c>true</c> if <paramref name="left"/> has the same value as <paramref name="right"/>; otherwise, <c>false</c>.</returns>
|
||||
public static bool operator ==(Color4 left, Color4 right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests for inequality between two objects.
|
||||
/// </summary>
|
||||
/// <param name="left">The first value to compare.</param>
|
||||
/// <param name="right">The second value to compare.</param>
|
||||
/// <returns><c>true</c> if <paramref name="left"/> has a different value than <paramref name="right"/>; otherwise, <c>false</c>.</returns>
|
||||
public static bool operator !=(Color4 left, Color4 right)
|
||||
{
|
||||
return !left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an explicit conversion from <see cref="Color4"/> to <see cref="Color3"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static explicit operator Color3(Color4 value)
|
||||
{
|
||||
return new Color3(value.R, value.G, value.B);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an explicit conversion from <see cref="Color4"/> to <see cref="Vector3"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static explicit operator Vector3(Color4 value)
|
||||
{
|
||||
return new Vector3(value.R, value.G, value.B);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an implicit conversion from <see cref="Color4"/> to <see cref="Vector4"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator Vector4(Color4 value)
|
||||
{
|
||||
return new Vector4(value.R, value.G, value.B, value.A);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an explicit conversion from <see cref="Vector3"/> to <see cref="Color4"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static explicit operator Color4(Vector3 value)
|
||||
{
|
||||
return new Color4(value.X, value.Y, value.Z, 1.0f);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an explicit conversion from <see cref="Vector4"/> to <see cref="Color4"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static explicit operator Color4(Vector4 value)
|
||||
{
|
||||
return new Color4(value.X, value.Y, value.Z, value.W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an explicit conversion from <see cref="Vector3"/> to <see cref="Color4"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static explicit operator Color4(ColorBGRA value)
|
||||
{
|
||||
return new Color4(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an explicit conversion from <see cref="Vector4"/> to <see cref="Color4"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static explicit operator ColorBGRA(Color4 value)
|
||||
{
|
||||
return new ColorBGRA(value.R, value.G, value.B, value.A);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an explicit conversion from <see cref="Color4"/> to <see cref="int"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>
|
||||
/// The result of the conversion.
|
||||
/// </returns>
|
||||
public static explicit operator int(Color4 value)
|
||||
{
|
||||
return value.ToRgba();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an explicit conversion from <see cref="int"/> to <see cref="Color4"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>
|
||||
/// The result of the conversion.
|
||||
/// </returns>
|
||||
public static explicit operator Color4(int value)
|
||||
{
|
||||
return new Color4(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts this color to an equivalent <see cref="Color3"/>, discarding the alpha channel.
|
||||
/// </summary>
|
||||
/// <returns>An equivalent <see cref="Color3"/>, discarding the alpha channel.</returns>
|
||||
public Color3 ToColor3()
|
||||
{
|
||||
return new Color3(R, G, B);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="string"/> that represents this instance.
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return ToString(CultureInfo.CurrentCulture);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <param name="format">The format to apply to each channel (float).</param>
|
||||
/// <returns>
|
||||
/// A <see cref="string"/> that represents this instance.
|
||||
/// </returns>
|
||||
public string ToString(string format)
|
||||
{
|
||||
return ToString(format, CultureInfo.CurrentCulture);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <param name="formatProvider">The format provider.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="string"/> that represents this instance.
|
||||
/// </returns>
|
||||
public string ToString(IFormatProvider formatProvider)
|
||||
{
|
||||
return string.Format(formatProvider, ToStringFormat, A, R, G, B);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <param name="format">The format to apply to each channel (float).</param>
|
||||
/// <param name="formatProvider">The format provider.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="string"/> that represents this instance.
|
||||
/// </returns>
|
||||
public string ToString(string format, IFormatProvider formatProvider)
|
||||
{
|
||||
if (format == null)
|
||||
return ToString(formatProvider);
|
||||
|
||||
return string.Format(formatProvider, ToStringFormat,
|
||||
A.ToString(format, formatProvider),
|
||||
R.ToString(format, formatProvider),
|
||||
G.ToString(format, formatProvider),
|
||||
B.ToString(format, formatProvider));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a hash code for this instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
|
||||
/// </returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return A.GetHashCode() + R.GetHashCode() + G.GetHashCode() + B.GetHashCode();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="Color4"/> is equal to this instance.
|
||||
/// </summary>
|
||||
/// <param name="other">The <see cref="Color4"/> to compare with this instance.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the specified <see cref="Color4"/> is equal to this instance; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public bool Equals(Color4 other)
|
||||
{
|
||||
return A == other.A && R == other.R && G == other.G && B == other.B;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="object"/> is equal to this instance.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="object"/> to compare with this instance.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the specified <see cref="object"/> is equal to this instance; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
if (value == null)
|
||||
return false;
|
||||
|
||||
if (!ReferenceEquals(value.GetType(), typeof(Color4)))
|
||||
return false;
|
||||
|
||||
return Equals((Color4)value);
|
||||
}
|
||||
}
|
||||
}
|
||||
1097
math/ColorBGRA.cs
Normal file
1097
math/ColorBGRA.cs
Normal file
File diff suppressed because it is too large
Load Diff
94
math/ColorExtensions.cs
Normal file
94
math/ColorExtensions.cs
Normal file
@ -0,0 +1,94 @@
|
||||
// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
|
||||
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
|
||||
using System.Globalization;
|
||||
using Xenko.Core.Annotations;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace math
|
||||
{
|
||||
/// <summary>
|
||||
/// A class containing extension methods for processing colors.
|
||||
/// </summary>
|
||||
public static class ColorExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates if the given string can be converted to an <see cref="uint"/> RGBA value using <see cref="StringToRgba"/>.
|
||||
/// </summary>
|
||||
/// <param name="stringColor">The string to convert.</param>
|
||||
/// <returns>True if the string can be converted, false otherwise.</returns>
|
||||
public static bool CanConvertStringToRgba([CanBeNull] string stringColor)
|
||||
{
|
||||
return stringColor?.StartsWith("#") ?? false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given string to an <see cref="uint"/> RGBA value.
|
||||
/// </summary>
|
||||
/// <param name="stringColor">The string to convert.</param>
|
||||
/// <returns>The converted RGBA value.</returns>
|
||||
public static uint StringToRgba([CanBeNull] string stringColor)
|
||||
{
|
||||
var intValue = 0xFF000000;
|
||||
if (stringColor != null)
|
||||
{
|
||||
if (stringColor.StartsWith("#"))
|
||||
{
|
||||
if (stringColor.Length == "#000".Length && uint.TryParse(stringColor.Substring(1, 3), NumberStyles.HexNumber, null, out intValue))
|
||||
{
|
||||
intValue = ((intValue & 0x00F) << 16)
|
||||
| ((intValue & 0x00F) << 20)
|
||||
| ((intValue & 0x0F0) << 4)
|
||||
| ((intValue & 0x0F0) << 8)
|
||||
| ((intValue & 0xF00) >> 4)
|
||||
| ((intValue & 0xF00) >> 8)
|
||||
| (0xFF000000);
|
||||
}
|
||||
if (stringColor.Length == "#000000".Length && uint.TryParse(stringColor.Substring(1, 6), NumberStyles.HexNumber, null, out intValue))
|
||||
{
|
||||
intValue = ((intValue & 0x000000FF) << 16)
|
||||
| (intValue & 0x0000FF00)
|
||||
| ((intValue & 0x00FF0000) >> 16)
|
||||
| (0xFF000000);
|
||||
}
|
||||
if (stringColor.Length == "#00000000".Length && uint.TryParse(stringColor.Substring(1, 8), NumberStyles.HexNumber, null, out intValue))
|
||||
{
|
||||
intValue = ((intValue & 0x000000FF) << 16)
|
||||
| (intValue & 0x0000FF00)
|
||||
| ((intValue & 0x00FF0000) >> 16)
|
||||
| (intValue & 0xFF000000);
|
||||
}
|
||||
}
|
||||
}
|
||||
return intValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given RGB value to a string.
|
||||
/// </summary>
|
||||
/// <param name="value">The RGB value to convert.</param>
|
||||
/// <returns>The converted string.</returns>
|
||||
[NotNull]
|
||||
public static string RgbToString(int value)
|
||||
{
|
||||
var r = (value & 0x000000FF);
|
||||
var g = (value & 0x0000FF00) >> 8;
|
||||
var b = (value & 0x00FF0000) >> 16;
|
||||
return $"#{r:X2}{g:X2}{b:X2}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the given RGBA value to a string.
|
||||
/// </summary>
|
||||
/// <param name="value">The RGBA value to convert.</param>
|
||||
/// <returns>The converted string.</returns>
|
||||
[NotNull]
|
||||
public static string RgbaToString(int value)
|
||||
{
|
||||
var r = (value & 0x000000FF);
|
||||
var g = (value & 0x0000FF00) >> 8;
|
||||
var b = (value & 0x00FF0000) >> 16;
|
||||
var a = (value & 0xFF000000) >> 24;
|
||||
return $"#{a:X2}{r:X2}{g:X2}{b:X2}";
|
||||
}
|
||||
}
|
||||
}
|
||||
203
math/ColorHSV.cs
Normal file
203
math/ColorHSV.cs
Normal file
@ -0,0 +1,203 @@
|
||||
// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
|
||||
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace math
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a color in the form of Hue, Saturation, Value, Alpha.
|
||||
/// </summary>
|
||||
[DataContract( Name = "ColorHSV")]
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
||||
public struct ColorHSV : IEquatable<ColorHSV>, IFormattable
|
||||
{
|
||||
private const string ToStringFormat = "Hue:{0} Saturation:{1} Value:{2} Alpha:{3}";
|
||||
|
||||
/// <summary>
|
||||
/// The Hue of the color.
|
||||
/// </summary>
|
||||
[DataMember( Order = 0 )]
|
||||
public float H;
|
||||
|
||||
/// <summary>
|
||||
/// The Saturation of the color.
|
||||
/// </summary>
|
||||
[DataMember( Order = 1 )]
|
||||
public float S;
|
||||
|
||||
/// <summary>
|
||||
/// The Value of the color.
|
||||
/// </summary>
|
||||
[DataMember( Order = 2 )]
|
||||
public float V;
|
||||
|
||||
/// <summary>
|
||||
/// The alpha component of the color.
|
||||
/// </summary>
|
||||
[DataMember( Order = 3 )]
|
||||
public float A;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ColorHSV"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="h">The h.</param>
|
||||
/// <param name="s">The s.</param>
|
||||
/// <param name="v">The v.</param>
|
||||
/// <param name="a">A.</param>
|
||||
public ColorHSV(float h, float s, float v, float a)
|
||||
{
|
||||
H = h;
|
||||
S = s;
|
||||
V = v;
|
||||
A = a;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the color into a three component vector.
|
||||
/// </summary>
|
||||
/// <returns>A three component vector containing the red, green, and blue components of the color.</returns>
|
||||
public Color4 ToColor()
|
||||
{
|
||||
float hdiv = H / 60;
|
||||
int hi = (int)hdiv;
|
||||
float f = hdiv - hi;
|
||||
|
||||
float p = V * (1 - S);
|
||||
float q = V * (1 - (S * f));
|
||||
float t = V * (1 - (S * (1 - f)));
|
||||
|
||||
switch (hi)
|
||||
{
|
||||
case 0:
|
||||
return new Color4(V, t, p, A);
|
||||
case 1:
|
||||
return new Color4(q, V, p, A);
|
||||
case 2:
|
||||
return new Color4(p, V, t, A);
|
||||
case 3:
|
||||
return new Color4(p, q, V, A);
|
||||
case 4:
|
||||
return new Color4(t, p, V, A);
|
||||
default:
|
||||
return new Color4(V, p, q, A);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the color into a HSV color.
|
||||
/// </summary>
|
||||
/// <param name="color">The color.</param>
|
||||
/// <returns>A HSV color</returns>
|
||||
public static ColorHSV FromColor(Color4 color)
|
||||
{
|
||||
float max = Math.Max(color.R, Math.Max(color.G, color.B));
|
||||
float min = Math.Min(color.R, Math.Min(color.G, color.B));
|
||||
|
||||
float delta = max - min;
|
||||
float h = 0.0f;
|
||||
|
||||
if (delta > 0.0f)
|
||||
{
|
||||
if (color.R >= max)
|
||||
h = (color.G - color.B) / delta;
|
||||
else if (color.G >= max)
|
||||
h = (color.B - color.R) / delta + 2.0f;
|
||||
else
|
||||
h = (color.R - color.G) / delta + 4.0f;
|
||||
h *= 60.0f;
|
||||
|
||||
if (h < 0)
|
||||
h += 360f;
|
||||
}
|
||||
|
||||
float s = MathUtil.IsZero(max) ? 0.0f : delta / max;
|
||||
|
||||
return new ColorHSV(h, s, max, color.A);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Equals(ColorHSV other)
|
||||
{
|
||||
return other.H.Equals(H) && other.S.Equals(S) && other.V.Equals(V) && other.A.Equals(A);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj)) return false;
|
||||
if (obj.GetType() != typeof(ColorHSV)) return false;
|
||||
return Equals((ColorHSV)obj);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
int result = H.GetHashCode();
|
||||
result = (result * 397) ^ S.GetHashCode();
|
||||
result = (result * 397) ^ V.GetHashCode();
|
||||
result = (result * 397) ^ A.GetHashCode();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="string"/> that represents this instance.
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return ToString(CultureInfo.CurrentCulture);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <param name="format">The format.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="string"/> that represents this instance.
|
||||
/// </returns>
|
||||
public string ToString(string format)
|
||||
{
|
||||
return ToString(format, CultureInfo.CurrentCulture);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <param name="formatProvider">The format provider.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="string"/> that represents this instance.
|
||||
/// </returns>
|
||||
public string ToString(IFormatProvider formatProvider)
|
||||
{
|
||||
return string.Format(formatProvider, ToStringFormat, H, S, V, A);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <param name="format">The format.</param>
|
||||
/// <param name="formatProvider">The format provider.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="string"/> that represents this instance.
|
||||
/// </returns>
|
||||
public string ToString(string format, IFormatProvider formatProvider)
|
||||
{
|
||||
if (format == null)
|
||||
return ToString(formatProvider);
|
||||
|
||||
return string.Format(formatProvider, ToStringFormat,
|
||||
H.ToString(format, formatProvider),
|
||||
S.ToString(format, formatProvider),
|
||||
V.ToString(format, formatProvider),
|
||||
A.ToString(format, formatProvider));
|
||||
}
|
||||
}
|
||||
}
|
||||
51
math/ContainmentType.cs
Normal file
51
math/ContainmentType.cs
Normal file
@ -0,0 +1,51 @@
|
||||
// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
|
||||
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// Original code from SlimMath project. http://code.google.com/p/slimmath/
|
||||
// Greetings to SlimDX Group. Original code published with the following license:
|
||||
// -----------------------------------------------------------------------------
|
||||
/*
|
||||
* Copyright (c) 2007-2011 SlimDX Group
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
namespace math
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes how one bounding volume contains another.
|
||||
/// </summary>
|
||||
public enum ContainmentType
|
||||
{
|
||||
/// <summary>
|
||||
/// The two bounding volumes don't intersect at all.
|
||||
/// </summary>
|
||||
Disjoint,
|
||||
|
||||
/// <summary>
|
||||
/// One bounding volume completely contains another.
|
||||
/// </summary>
|
||||
Contains,
|
||||
|
||||
/// <summary>
|
||||
/// The two bounding volumes overlap.
|
||||
/// </summary>
|
||||
Intersects,
|
||||
}
|
||||
}
|
||||
53
math/DataStyleAttribute.cs
Normal file
53
math/DataStyleAttribute.cs
Normal file
@ -0,0 +1,53 @@
|
||||
// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
|
||||
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// Original code from SlimMath project. http://code.google.com/p/slimmath/
|
||||
// Greetings to SlimDX Group. Original code published with the following license:
|
||||
// -----------------------------------------------------------------------------
|
||||
/*
|
||||
* Copyright (c) 2007-2011 SlimDX Group
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
using System;
|
||||
|
||||
//TODO @@ Move this stuff
|
||||
|
||||
namespace math
|
||||
{
|
||||
public enum DataStyle
|
||||
{
|
||||
Invalid = 0,
|
||||
Compact = 1,
|
||||
|
||||
}
|
||||
|
||||
public class DataStyleAttribute : Attribute
|
||||
{
|
||||
|
||||
public DataStyle style { get; private set; }
|
||||
|
||||
public DataStyleAttribute( DataStyle n_style )
|
||||
{
|
||||
style = n_style;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
1486
math/Double2.cs
Normal file
1486
math/Double2.cs
Normal file
File diff suppressed because it is too large
Load Diff
1765
math/Double3.cs
Normal file
1765
math/Double3.cs
Normal file
File diff suppressed because it is too large
Load Diff
1436
math/Double4.cs
Normal file
1436
math/Double4.cs
Normal file
File diff suppressed because it is too large
Load Diff
183
math/GuillotinePacker.cs
Normal file
183
math/GuillotinePacker.cs
Normal file
@ -0,0 +1,183 @@
|
||||
// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
|
||||
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace math
|
||||
{
|
||||
/// <summary>
|
||||
/// Implementation of a "Guillotine" packer.
|
||||
/// More information at http://clb.demon.fi/files/RectangleBinPack.pdf.
|
||||
/// </summary>
|
||||
public class GuillotinePacker
|
||||
{
|
||||
private readonly List<Rectangle> freeRectangles = new List<Rectangle>();
|
||||
private readonly List<Rectangle> tempFreeRectangles = new List<Rectangle>();
|
||||
|
||||
/// <summary>
|
||||
/// A delegate callback used by <see cref="TryInsert"/>
|
||||
/// </summary>
|
||||
/// <param name="cascadeIndex">The index of the rectangle</param>
|
||||
/// <param name="rectangle">The rectangle found</param>
|
||||
public delegate void InsertRectangleCallback(int cascadeIndex, ref Rectangle rectangle);
|
||||
|
||||
/// <summary>
|
||||
/// Current width used by the packer.
|
||||
/// </summary>
|
||||
public int Width { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Current height used by the packer.
|
||||
/// </summary>
|
||||
public int Height { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Clears the specified region.
|
||||
/// </summary>
|
||||
/// <param name="width">The width.</param>
|
||||
/// <param name="height">The height.</param>
|
||||
public void Clear(int width, int height)
|
||||
{
|
||||
freeRectangles.Clear();
|
||||
freeRectangles.Add(new Rectangle { X = 0, Y = 0, Width = width, Height = height });
|
||||
|
||||
Width = width;
|
||||
Height = height;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the whole region.
|
||||
/// </summary>
|
||||
public virtual void Clear()
|
||||
{
|
||||
Clear(Width, Height);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Frees the specified old rectangle.
|
||||
/// </summary>
|
||||
/// <param name="oldRectangle">The old rectangle.</param>
|
||||
public void Free(ref Rectangle oldRectangle)
|
||||
{
|
||||
freeRectangles.Add(oldRectangle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to fit a single rectangle with the specified width and height.
|
||||
/// </summary>
|
||||
/// <param name="width">Width requested.</param>
|
||||
/// <param name="height">Height requested</param>
|
||||
/// <param name="bestRectangle">Fill with the rectangle if it was successfully inserted.</param>
|
||||
/// <returns><c>true</c> if it was successfully inserted.</returns>
|
||||
public bool Insert(int width, int height, ref Rectangle bestRectangle)
|
||||
{
|
||||
return Insert(width, height, freeRectangles, ref bestRectangle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to fit multiple rectangle with (width, height).
|
||||
/// </summary>
|
||||
/// <param name="width">Width requested.</param>
|
||||
/// <param name="height">Height requested</param>
|
||||
/// <param name="count">The number of rectangle to fit.</param>
|
||||
/// <param name="inserted">A callback called for each rectangle successfully fitted.</param>
|
||||
/// <returns><c>true</c> if all rectangles were successfully fitted.</returns>
|
||||
public bool TryInsert(int width, int height, int count, InsertRectangleCallback inserted)
|
||||
{
|
||||
var bestRectangle = new Rectangle();
|
||||
tempFreeRectangles.Clear();
|
||||
foreach (var freeRectangle in freeRectangles)
|
||||
{
|
||||
tempFreeRectangles.Add(freeRectangle);
|
||||
}
|
||||
|
||||
for (var i = 0; i < count; ++i)
|
||||
{
|
||||
if (!Insert(width, height, tempFreeRectangles, ref bestRectangle))
|
||||
{
|
||||
tempFreeRectangles.Clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
inserted(i, ref bestRectangle);
|
||||
}
|
||||
|
||||
// if the insertion went well, use the new configuration
|
||||
freeRectangles.Clear();
|
||||
foreach (var tempFreeRectangle in tempFreeRectangles)
|
||||
{
|
||||
freeRectangles.Add(tempFreeRectangle);
|
||||
}
|
||||
tempFreeRectangles.Clear();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool Insert(int width, int height, List<Rectangle> freeRectanglesList, ref Rectangle bestRectangle)
|
||||
{
|
||||
// Info on algorithm: http://clb.demon.fi/files/RectangleBinPack.pdf
|
||||
int bestScore = int.MaxValue;
|
||||
int freeRectangleIndex = -1;
|
||||
|
||||
// Find space for new rectangle
|
||||
for (int i = 0; i < freeRectanglesList.Count; ++i)
|
||||
{
|
||||
var currentFreeRectangle = freeRectanglesList[i];
|
||||
if (width == currentFreeRectangle.Width && height == currentFreeRectangle.Height)
|
||||
{
|
||||
// Perfect fit
|
||||
bestRectangle.X = currentFreeRectangle.X;
|
||||
bestRectangle.Y = currentFreeRectangle.Y;
|
||||
bestRectangle.Width = width;
|
||||
bestRectangle.Height = height;
|
||||
freeRectangleIndex = i;
|
||||
break;
|
||||
}
|
||||
if (width <= currentFreeRectangle.Width && height <= currentFreeRectangle.Height)
|
||||
{
|
||||
// Can fit inside
|
||||
// Use "BAF" heuristic (best area fit)
|
||||
var score = currentFreeRectangle.Width * currentFreeRectangle.Height - width * height;
|
||||
if (score < bestScore)
|
||||
{
|
||||
bestRectangle.X = currentFreeRectangle.X;
|
||||
bestRectangle.Y = currentFreeRectangle.Y;
|
||||
bestRectangle.Width = width;
|
||||
bestRectangle.Height = height;
|
||||
bestScore = score;
|
||||
freeRectangleIndex = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// No space could be found
|
||||
if (freeRectangleIndex == -1)
|
||||
return false;
|
||||
|
||||
var freeRectangle = freeRectanglesList[freeRectangleIndex];
|
||||
|
||||
// Choose an axis to split (trying to minimize the smaller area "MINAS")
|
||||
int w = freeRectangle.Width - bestRectangle.Width;
|
||||
int h = freeRectangle.Height - bestRectangle.Height;
|
||||
var splitHorizontal = (bestRectangle.Width * h > w * bestRectangle.Height);
|
||||
|
||||
// Form the two new rectangles.
|
||||
var bottom = new Rectangle { X = freeRectangle.X, Y = freeRectangle.Y + bestRectangle.Height, Width = splitHorizontal ? freeRectangle.Width : bestRectangle.Width, Height = h };
|
||||
var right = new Rectangle { X = freeRectangle.X + bestRectangle.Width, Y = freeRectangle.Y, Width = w, Height = splitHorizontal ? bestRectangle.Height : freeRectangle.Height };
|
||||
|
||||
if (bottom.Width > 0 && bottom.Height > 0)
|
||||
freeRectanglesList.Add(bottom);
|
||||
if (right.Width > 0 && right.Height > 0)
|
||||
freeRectanglesList.Add(right);
|
||||
|
||||
// Remove previously selected freeRectangle
|
||||
if (freeRectangleIndex != freeRectanglesList.Count - 1)
|
||||
freeRectanglesList[freeRectangleIndex] = freeRectanglesList[freeRectanglesList.Count - 1];
|
||||
freeRectanglesList.RemoveAt(freeRectanglesList.Count - 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
268
math/Half.cs
Normal file
268
math/Half.cs
Normal file
@ -0,0 +1,268 @@
|
||||
// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
|
||||
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
|
||||
//
|
||||
// Copyright (c) 2010-2011 SharpDX - Alexandre Mutel
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.Runtime.InteropServices;
|
||||
using Xenko.Core.Serialization;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace math
|
||||
{
|
||||
/// <summary>
|
||||
/// A half precision (16 bit) floating point value.
|
||||
/// </summary>
|
||||
[DataContract]
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||
public struct Half
|
||||
{
|
||||
private ushort value;
|
||||
|
||||
/// <summary>
|
||||
/// Number of decimal digits of precision.
|
||||
/// </summary>
|
||||
public const int PrecisionDigits = 3;
|
||||
|
||||
/// <summary>
|
||||
/// Number of bits in the mantissa.
|
||||
/// </summary>
|
||||
public const int MantissaBits = 11;
|
||||
|
||||
/// <summary>
|
||||
/// Maximum decimal exponent.
|
||||
/// </summary>
|
||||
public const int MaximumDecimalExponent = 4;
|
||||
|
||||
/// <summary>
|
||||
/// Maximum binary exponent.
|
||||
/// </summary>
|
||||
public const int MaximumBinaryExponent = 15;
|
||||
|
||||
/// <summary>
|
||||
/// Minimum decimal exponent.
|
||||
/// </summary>
|
||||
public const int MinimumDecimalExponent = -4;
|
||||
|
||||
/// <summary>
|
||||
/// Minimum binary exponent.
|
||||
/// </summary>
|
||||
public const int MinimumBinaryExponent = -14;
|
||||
|
||||
/// <summary>
|
||||
/// Exponent radix.
|
||||
/// </summary>
|
||||
public const int ExponentRadix = 2;
|
||||
|
||||
/// <summary>
|
||||
/// Additional rounding.
|
||||
/// </summary>
|
||||
public const int AdditionRounding = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Smallest such that 1.0 + epsilon != 1.0
|
||||
/// </summary>
|
||||
public static readonly float Epsilon;
|
||||
|
||||
/// <summary>
|
||||
/// Maximum value of the number.
|
||||
/// </summary>
|
||||
public static readonly float MaxValue;
|
||||
|
||||
/// <summary>
|
||||
/// Minimum value of the number.
|
||||
/// </summary>
|
||||
public static readonly float MinValue;
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="Half"/> whose value is 0.0f.
|
||||
/// </summary>
|
||||
public static readonly Half Zero;
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="Half"/> whose value is 1.0f.
|
||||
/// </summary>
|
||||
public static readonly Half One;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Half"/> structure.
|
||||
/// </summary>
|
||||
/// <param name = "value">The floating point value that should be stored in 16 bit format.</param>
|
||||
public Half(float value)
|
||||
{
|
||||
this.value = HalfUtils.Pack(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the raw 16 bit value used to back this half-float.
|
||||
/// </summary>
|
||||
public ushort RawValue
|
||||
{
|
||||
get { return value; }
|
||||
set { this.value = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts an array of half precision values into full precision values.
|
||||
/// </summary>
|
||||
/// <param name = "values">The values to be converted.</param>
|
||||
/// <returns>An array of converted values.</returns>
|
||||
public static float[] ConvertToFloat(Half[] values)
|
||||
{
|
||||
float[] results = new float[values.Length];
|
||||
for (int i = 0; i < results.Length; i++)
|
||||
results[i] = HalfUtils.Unpack(values[i].RawValue);
|
||||
return results;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts an array of full precision values into half precision values.
|
||||
/// </summary>
|
||||
/// <param name = "values">The values to be converted.</param>
|
||||
/// <returns>An array of converted values.</returns>
|
||||
public static Half[] ConvertToHalf(float[] values)
|
||||
{
|
||||
Half[] results = new Half[values.Length];
|
||||
for (int i = 0; i < results.Length; i++)
|
||||
results[i] = new Half(values[i]);
|
||||
return results;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an explicit conversion from <see cref = "T:System.Single" /> to <see cref = "T:math.Half" />.
|
||||
/// </summary>
|
||||
/// <param name = "value">The value to be converted.</param>
|
||||
/// <returns>The converted value.</returns>
|
||||
public static explicit operator Half(float value)
|
||||
{
|
||||
return new Half(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an implicit conversion from <see cref = "T:math.Half" /> to <see cref = "T:System.Single" />.
|
||||
/// </summary>
|
||||
/// <param name = "value">The value to be converted.</param>
|
||||
/// <returns>The converted value.</returns>
|
||||
public static implicit operator float(Half value)
|
||||
{
|
||||
return HalfUtils.Unpack(value.value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests for equality between two objects.
|
||||
/// </summary>
|
||||
/// <param name = "left">The first value to compare.</param>
|
||||
/// <param name = "right">The second value to compare.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if <paramref name = "left" /> has the same value as <paramref name = "right" />; otherwise, <c>false</c>.</returns>
|
||||
public static bool operator ==(Half left, Half right)
|
||||
{
|
||||
return left.value == right.value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests for inequality between two objects.
|
||||
/// </summary>
|
||||
/// <param name = "left">The first value to compare.</param>
|
||||
/// <param name = "right">The second value to compare.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if <paramref name = "left" /> has a different value than <paramref name = "right" />; otherwise, <c>false</c>.</returns>
|
||||
public static bool operator !=(Half left, Half right)
|
||||
{
|
||||
return left.value != right.value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts the value of the object to its equivalent string representation.
|
||||
/// </summary>
|
||||
/// <returns>The string representation of the value of this instance.</returns>
|
||||
public override string ToString()
|
||||
{
|
||||
float num = this;
|
||||
return num.ToString(CultureInfo.CurrentCulture);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the hash code for this instance.
|
||||
/// </summary>
|
||||
/// <returns>A 32-bit signed integer hash code.</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
ushort num = value;
|
||||
return ((num * 3) / 2) ^ num;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified object instances are considered equal.
|
||||
/// </summary>
|
||||
/// <param name = "value1">The first value.</param>
|
||||
/// <param name = "value2">The second value.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if <paramref name = "value1" /> is the same instance as <paramref name = "value2" /> or
|
||||
/// if both are <c>null</c> references or if <c>value1.Equals(value2)</c> returns <c>true</c>; otherwise, <c>false</c>.</returns>
|
||||
public static bool Equals(ref Half value1, ref Half value2)
|
||||
{
|
||||
return value1.value == value2.value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value that indicates whether the current instance is equal to the specified object.
|
||||
/// </summary>
|
||||
/// <param name = "other">Object to make the comparison with.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the current instance is equal to the specified object; <c>false</c> otherwise.</returns>
|
||||
public bool Equals(Half other)
|
||||
{
|
||||
return other.value == value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value that indicates whether the current instance is equal to a specified object.
|
||||
/// </summary>
|
||||
/// <param name = "obj">Object to make the comparison with.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the current instance is equal to the specified object; <c>false</c> otherwise.</returns>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (obj.GetType() != GetType())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Half half = (Half)obj;
|
||||
return half.value == value;
|
||||
}
|
||||
|
||||
static Half()
|
||||
{
|
||||
Epsilon = 0.0004887581f;
|
||||
MaxValue = 65504f;
|
||||
MinValue = 6.103516E-05f;
|
||||
Zero = (Half)0.0f;
|
||||
One = (Half)1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
190
math/Half2.cs
Normal file
190
math/Half2.cs
Normal file
@ -0,0 +1,190 @@
|
||||
// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
|
||||
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
|
||||
//
|
||||
// Copyright (c) 2010-2011 SharpDX - Alexandre Mutel
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.InteropServices;
|
||||
using Xenko.Core.Serialization;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace math
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a two dimensional mathematical vector with half-precision floats.
|
||||
/// </summary>
|
||||
[DataContract]
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||
public struct Half2 : IEquatable<Half2>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the X component of the vector.
|
||||
/// </summary>
|
||||
/// <value>The X component of the vector.</value>
|
||||
public Half X;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Y component of the vector.
|
||||
/// </summary>
|
||||
/// <value>The Y component of the vector.</value>
|
||||
public Half Y;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Half2"/> structure.
|
||||
/// </summary>
|
||||
/// <param name="x">The X component.</param>
|
||||
/// <param name="y">The Y component.</param>
|
||||
public Half2(Half x, Half y)
|
||||
{
|
||||
this.X = x;
|
||||
this.Y = y;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Half2"/> structure.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to set for both the X and Y components.</param>
|
||||
public Half2(Half value)
|
||||
{
|
||||
this.X = value;
|
||||
this.Y = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Half2"/> structure.
|
||||
/// </summary>
|
||||
/// <param name="x">The X component.</param>
|
||||
/// <param name="y">The Y component.</param>
|
||||
public Half2(float x, float y)
|
||||
{
|
||||
this.X = (Half)x;
|
||||
this.Y = (Half)y;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Half2"/> structure.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to set for both the X and Y components.</param>
|
||||
public Half2(float value)
|
||||
{
|
||||
this.X = (Half)value;
|
||||
this.Y = (Half)value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests for equality between two objects.
|
||||
/// </summary>
|
||||
/// <param name="left">The first value to compare.</param>
|
||||
/// <param name="right">The second value to compare.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if <paramref name="left" /> has the same value as <paramref name="right" />; otherwise, <c>false</c>.</returns>
|
||||
public static bool operator ==(Half2 left, Half2 right)
|
||||
{
|
||||
return Equals(ref left, ref right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests for inequality between two objects.
|
||||
/// </summary>
|
||||
/// <param name="left">The first value to compare.</param>
|
||||
/// <param name="right">The second value to compare.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if <paramref name="left" /> has a different value than <paramref name="right" />; otherwise, <c>false</c>.</returns>
|
||||
[return: MarshalAs(UnmanagedType.U1)]
|
||||
public static bool operator !=(Half2 left, Half2 right)
|
||||
{
|
||||
return !Equals(ref left, ref right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the hash code for this instance.
|
||||
/// </summary>
|
||||
/// <returns>A 32-bit signed integer hash code.</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return (this.Y.GetHashCode() + this.X.GetHashCode());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified object instances are considered equal.
|
||||
/// </summary>
|
||||
/// <param name="value1">The first value.</param>
|
||||
/// <param name="value2">The second value.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if <paramref name="value1" /> is the same instance as <paramref name="value2" /> or
|
||||
/// if both are <c>null</c> references or if <c>value1.Equals(value2)</c> returns <c>true</c>; otherwise, <c>false</c>.</returns>
|
||||
public static bool Equals(ref Half2 value1, ref Half2 value2)
|
||||
{
|
||||
return ((value1.X == value2.X) && (value1.Y == value2.Y));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value that indicates whether the current instance is equal to the specified object.
|
||||
/// </summary>
|
||||
/// <param name="other">Object to make the comparison with.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the current instance is equal to the specified object; <c>false</c> otherwise.</returns>
|
||||
public bool Equals(Half2 other)
|
||||
{
|
||||
return ((this.X == other.X) && (this.Y == other.Y));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value that indicates whether the current instance is equal to a specified object.
|
||||
/// </summary>
|
||||
/// <param name="obj">Object to make the comparison with.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the current instance is equal to the specified object; <c>false</c> otherwise.</returns>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (obj.GetType() != GetType())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return this.Equals((Half2)obj);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an explicit conversion from <see cref="Vec2"/> to <see cref="Half2"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static explicit operator Half2(Vec2 value)
|
||||
{
|
||||
return new Half2((Half)value.X, (Half)value.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an explicit conversion from <see cref="Half2"/> to <see cref="Vec2"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static explicit operator Vec2(Half2 value)
|
||||
{
|
||||
return new Vec2(value.X, value.Y);
|
||||
}
|
||||
}
|
||||
}
|
||||
203
math/Half3.cs
Normal file
203
math/Half3.cs
Normal file
@ -0,0 +1,203 @@
|
||||
// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
|
||||
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
|
||||
//
|
||||
// Copyright (c) 2010-2011 SharpDX - Alexandre Mutel
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.InteropServices;
|
||||
using Xenko.Core.Serialization;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace math
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a three dimensional mathematical vector with half-precision floats.
|
||||
/// </summary>
|
||||
[DataContract]
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||
public struct Half3 : IEquatable<Half3>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the X component of the vector.
|
||||
/// </summary>
|
||||
/// <value>The X component of the vector.</value>
|
||||
public Half X;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Y component of the vector.
|
||||
/// </summary>
|
||||
/// <value>The Y component of the vector.</value>
|
||||
public Half Y;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Z component of the vector.
|
||||
/// </summary>
|
||||
/// <value>The Z component of the vector.</value>
|
||||
public Half Z;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Half3"/> structure.
|
||||
/// </summary>
|
||||
/// <param name="x">The X component.</param>
|
||||
/// <param name="y">The Y component.</param>
|
||||
/// <param name="z">The Z component.</param>
|
||||
public Half3(Half x, Half y, Half z)
|
||||
{
|
||||
this.X = x;
|
||||
this.Y = y;
|
||||
this.Z = z;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Half3"/> structure.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to set for the X, Y, and Z components.</param>
|
||||
public Half3(Half value)
|
||||
{
|
||||
this.X = value;
|
||||
this.Y = value;
|
||||
this.Z = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Half3"/> structure.
|
||||
/// </summary>
|
||||
/// <param name="x">The X component.</param>
|
||||
/// <param name="y">The Y component.</param>
|
||||
/// <param name="z">The Z component.</param>
|
||||
public Half3(float x, float y, float z)
|
||||
{
|
||||
this.X = (Half)x;
|
||||
this.Y = (Half)y;
|
||||
this.Z = (Half)z;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Half3"/> structure.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to set for the X, Y, and Z components.</param>
|
||||
public Half3(float value)
|
||||
{
|
||||
this.X = (Half)value;
|
||||
this.Y = (Half)value;
|
||||
this.Z = (Half)value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests for equality between two objects.
|
||||
/// </summary>
|
||||
/// <param name="left">The first value to compare.</param>
|
||||
/// <param name="right">The second value to compare.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if <paramref name="left" /> has the same value as <paramref name="right" />; otherwise, <c>false</c>.</returns>
|
||||
public static bool operator ==(Half3 left, Half3 right)
|
||||
{
|
||||
return Equals(ref left, ref right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests for inequality between two objects.
|
||||
/// </summary>
|
||||
/// <param name="left">The first value to compare.</param>
|
||||
/// <param name="right">The second value to compare.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if <paramref name="left" /> has a different value than <paramref name="right" />; otherwise, <c>false</c>.</returns>
|
||||
[return: MarshalAs(UnmanagedType.U1)]
|
||||
public static bool operator !=(Half3 left, Half3 right)
|
||||
{
|
||||
return !Equals(ref left, ref right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the hash code for this instance.
|
||||
/// </summary>
|
||||
/// <returns>A 32-bit signed integer hash code.</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
int num = this.Z.GetHashCode() + this.Y.GetHashCode();
|
||||
return (this.X.GetHashCode() + num);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified object instances are considered equal.
|
||||
/// </summary>
|
||||
/// <param name="value1">The first value.</param>
|
||||
/// <param name="value2">The second value.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if <paramref name="value1" /> is the same instance as <paramref name="value2" /> or
|
||||
/// if both are <c>null</c> references or if <c>value1.Equals(value2)</c> returns <c>true</c>; otherwise, <c>false</c>.</returns>
|
||||
public static bool Equals(ref Half3 value1, ref Half3 value2)
|
||||
{
|
||||
return (((value1.X == value2.X) && (value1.Y == value2.Y)) && (value1.Z == value2.Z));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value that indicates whether the current instance is equal to the specified object.
|
||||
/// </summary>
|
||||
/// <param name="other">Object to make the comparison with.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the current instance is equal to the specified object; <c>false</c> otherwise.</returns>
|
||||
public bool Equals(Half3 other)
|
||||
{
|
||||
return (((this.X == other.X) && (this.Y == other.Y)) && (this.Z == other.Z));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an explicit conversion from <see cref="Vector3"/> to <see cref="Half3"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static explicit operator Half3(Vector3 value)
|
||||
{
|
||||
return new Half3((Half)value.X, (Half)value.Y, (Half)value.Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an explicit conversion from <see cref="Half3"/> to <see cref="Vector3"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static explicit operator Vector3(Half3 value)
|
||||
{
|
||||
return new Vector3(value.X, value.Y, value.Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value that indicates whether the current instance is equal to a specified object.
|
||||
/// </summary>
|
||||
/// <param name="obj">Object to make the comparison with.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the current instance is equal to the specified object; <c>false</c> otherwise.</returns>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (obj.GetType() != GetType())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return this.Equals((Half3)obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
188
math/Half4.cs
Normal file
188
math/Half4.cs
Normal file
@ -0,0 +1,188 @@
|
||||
// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
|
||||
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
|
||||
//
|
||||
// Copyright (c) 2010-2011 SharpDX - Alexandre Mutel
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.InteropServices;
|
||||
using Xenko.Core.Serialization;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace math
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a four dimensional mathematical vector with half-precision floats.
|
||||
/// </summary>
|
||||
[DataContract]
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 2)]
|
||||
public struct Half4 : IEquatable<Half4>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the X component of the vector.
|
||||
/// </summary>
|
||||
/// <value>The X component of the vector.</value>
|
||||
public Half X;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Y component of the vector.
|
||||
/// </summary>
|
||||
/// <value>The Y component of the vector.</value>
|
||||
public Half Y;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Z component of the vector.
|
||||
/// </summary>
|
||||
/// <value>The Z component of the vector.</value>
|
||||
public Half Z;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the W component of the vector.
|
||||
/// </summary>
|
||||
/// <value>The W component of the vector.</value>
|
||||
public Half W;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Half4"/> structure.
|
||||
/// </summary>
|
||||
/// <param name="x">The X component.</param>
|
||||
/// <param name="y">The Y component.</param>
|
||||
/// <param name="z">The Z component.</param>
|
||||
/// <param name="w">The W component.</param>
|
||||
public Half4(Half x, Half y, Half z, Half w)
|
||||
{
|
||||
this.X = x;
|
||||
this.Y = y;
|
||||
this.Z = z;
|
||||
this.W = w;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Half4"/> structure.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to set for the X, Y, Z, and W components.</param>
|
||||
public Half4(Half value)
|
||||
{
|
||||
this.X = value;
|
||||
this.Y = value;
|
||||
this.Z = value;
|
||||
this.W = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests for equality between two objects.
|
||||
/// </summary>
|
||||
/// <param name="left">The first value to compare.</param>
|
||||
/// <param name="right">The second value to compare.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if <paramref name="left" /> has the same value as <paramref name="right" />; otherwise, <c>false</c>.</returns>
|
||||
public static bool operator ==(Half4 left, Half4 right)
|
||||
{
|
||||
return Equals(ref left, ref right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests for inequality between two objects.
|
||||
/// </summary>
|
||||
/// <param name="left">The first value to compare.</param>
|
||||
/// <param name="right">The second value to compare.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if <paramref name="left" /> has a different value than <paramref name="right" />; otherwise, <c>false</c>.</returns>
|
||||
public static bool operator !=(Half4 left, Half4 right)
|
||||
{
|
||||
return !Equals(ref left, ref right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the hash code for this instance.
|
||||
/// </summary>
|
||||
/// <returns>A 32-bit signed integer hash code.</returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
int num2 = this.W.GetHashCode() + this.Z.GetHashCode();
|
||||
int num = this.Y.GetHashCode() + num2;
|
||||
return (this.X.GetHashCode() + num);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified object instances are considered equal.
|
||||
/// </summary>
|
||||
/// <param name="value1">The first value.</param>
|
||||
/// <param name="value2">The second value.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if <paramref name="value1" /> is the same instance as <paramref name="value2" /> or
|
||||
/// if both are <c>null</c> references or if <c>value1.Equals(value2)</c> returns <c>true</c>; otherwise, <c>false</c>.</returns>
|
||||
public static bool Equals(ref Half4 value1, ref Half4 value2)
|
||||
{
|
||||
return (((value1.X == value2.X) && (value1.Y == value2.Y)) && ((value1.Z == value2.Z) && (value1.W == value2.W)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value that indicates whether the current instance is equal to the specified object.
|
||||
/// </summary>
|
||||
/// <param name="other">Object to make the comparison with.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the current instance is equal to the specified object; <c>false</c> otherwise.</returns>
|
||||
public bool Equals(Half4 other)
|
||||
{
|
||||
return (((this.X == other.X) && (this.Y == other.Y)) && ((this.Z == other.Z) && (this.W == other.W)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an explicit conversion from <see cref="Vector4"/> to <see cref="Half4"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static explicit operator Half4(Vector4 value)
|
||||
{
|
||||
return new Half4((Half)value.X, (Half)value.Y, (Half)value.Z, (Half)value.W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an explicit conversion from <see cref="Half4"/> to <see cref="Vector4"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static explicit operator Vector4(Half4 value)
|
||||
{
|
||||
return new Vector4(value.X, value.Y, value.Z, value.W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a value that indicates whether the current instance is equal to a specified object.
|
||||
/// </summary>
|
||||
/// <param name="obj">Object to make the comparison with.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the current instance is equal to the specified object; <c>false</c> otherwise.</returns>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (obj.GetType() != GetType())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return this.Equals((Half4)obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
173
math/HalfUtils.cs
Normal file
173
math/HalfUtils.cs
Normal file
@ -0,0 +1,173 @@
|
||||
// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
|
||||
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
|
||||
//
|
||||
// Copyright (c) 2010-2011 SharpDX - Alexandre Mutel
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace math
|
||||
{
|
||||
/// <summary>
|
||||
/// Helper class to perform Half/Float conversion.
|
||||
/// Code extract from paper : www.fox-toolkit.org/ftp/fasthalffloatconversion.pdf by Jeroen van der Zijp
|
||||
/// </summary>
|
||||
internal class HalfUtils
|
||||
{
|
||||
[StructLayout(LayoutKind.Explicit, Pack = 4)]
|
||||
private struct FloatToUint
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
public uint UIntValue;
|
||||
[FieldOffset(0)]
|
||||
public float FloatValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unpacks the specified h.
|
||||
/// </summary>
|
||||
/// <param name="h">The packed value.</param>
|
||||
/// <returns>The float representation of the packed value.</returns>
|
||||
public static float Unpack(ushort h)
|
||||
{
|
||||
var conv = new FloatToUint();
|
||||
conv.UIntValue = HalfToFloatMantissaTable[HalfToFloatOffsetTable[h >> 10] + (((uint)h) & 0x3ff)] + HalfToFloatExponentTable[h >> 10];
|
||||
return conv.FloatValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Packs the specified f.
|
||||
/// </summary>
|
||||
/// <param name="f">The float value.</param>
|
||||
/// <returns>The packed representation of the float value.</returns>
|
||||
public static ushort Pack(float f)
|
||||
{
|
||||
FloatToUint conv = new FloatToUint();
|
||||
conv.FloatValue = f;
|
||||
return (ushort)(FloatToHalfBaseTable[(conv.UIntValue >> 23) & 0x1ff] + ((conv.UIntValue & 0x007fffff) >> FloatToHalfShiftTable[(conv.UIntValue >> 23) & 0x1ff]));
|
||||
}
|
||||
|
||||
private static readonly uint[] HalfToFloatMantissaTable = new uint[2048];
|
||||
private static readonly uint[] HalfToFloatExponentTable = new uint[64];
|
||||
private static readonly uint[] HalfToFloatOffsetTable = new uint[64];
|
||||
private static readonly ushort[] FloatToHalfBaseTable = new ushort[512];
|
||||
private static readonly byte[] FloatToHalfShiftTable = new byte[512];
|
||||
|
||||
static HalfUtils()
|
||||
{
|
||||
int i;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Half to Float tables
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
// Mantissa table
|
||||
|
||||
// 0 => 0
|
||||
HalfToFloatMantissaTable[0] = 0;
|
||||
|
||||
// Transform subnormal to normalized
|
||||
for (i = 1; i < 1024; i++)
|
||||
{
|
||||
uint m = ((uint)i) << 13;
|
||||
uint e = 0;
|
||||
|
||||
while ((m & 0x00800000) == 0)
|
||||
{
|
||||
e -= 0x00800000;
|
||||
m <<= 1;
|
||||
}
|
||||
m &= ~0x00800000U;
|
||||
e += 0x38800000;
|
||||
HalfToFloatMantissaTable[i] = m | e;
|
||||
}
|
||||
|
||||
// Normal case
|
||||
for (i = 1024; i < 2048; i++)
|
||||
HalfToFloatMantissaTable[i] = 0x38000000 + (((uint)(i - 1024)) << 13);
|
||||
|
||||
// Exponent table
|
||||
|
||||
// 0 => 0
|
||||
HalfToFloatExponentTable[0] = 0;
|
||||
|
||||
for (i = 1; i < 63; i++)
|
||||
{
|
||||
if (i < 31) // Positive Numbers
|
||||
HalfToFloatExponentTable[i] = ((uint)i) << 23;
|
||||
else // Negative Numbers
|
||||
HalfToFloatExponentTable[i] = 0x80000000 + (((uint)(i - 32)) << 23);
|
||||
}
|
||||
HalfToFloatExponentTable[31] = 0x47800000;
|
||||
HalfToFloatExponentTable[32] = 0x80000000;
|
||||
HalfToFloatExponentTable[63] = 0xC7800000;
|
||||
|
||||
// Offset table
|
||||
HalfToFloatOffsetTable[0] = 0;
|
||||
for (i = 1; i < 64; i++)
|
||||
HalfToFloatOffsetTable[i] = 1024;
|
||||
HalfToFloatOffsetTable[32] = 0;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Float to Half tables
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
int e = i - 127;
|
||||
if (e < -24)
|
||||
{ // Very small numbers map to zero
|
||||
FloatToHalfBaseTable[i | 0x000] = 0x0000;
|
||||
FloatToHalfBaseTable[i | 0x100] = 0x8000;
|
||||
FloatToHalfShiftTable[i | 0x000] = 24;
|
||||
FloatToHalfShiftTable[i | 0x100] = 24;
|
||||
}
|
||||
else if (e < -14)
|
||||
{ // Small numbers map to denorms
|
||||
FloatToHalfBaseTable[i | 0x000] = (ushort)((0x0400 >> (-e - 14)));
|
||||
FloatToHalfBaseTable[i | 0x100] = (ushort)((0x0400 >> (-e - 14)) | 0x8000);
|
||||
FloatToHalfShiftTable[i | 0x000] = (byte)(-e - 1);
|
||||
FloatToHalfShiftTable[i | 0x100] = (byte)(-e - 1);
|
||||
}
|
||||
else if (e <= 15)
|
||||
{ // Normal numbers just lose precision
|
||||
FloatToHalfBaseTable[i | 0x000] = (ushort)(((e + 15) << 10));
|
||||
FloatToHalfBaseTable[i | 0x100] = (ushort)(((e + 15) << 10) | 0x8000);
|
||||
FloatToHalfShiftTable[i | 0x000] = 13;
|
||||
FloatToHalfShiftTable[i | 0x100] = 13;
|
||||
}
|
||||
else if (e < 128)
|
||||
{ // Large numbers map to Infinity
|
||||
FloatToHalfBaseTable[i | 0x000] = 0x7C00;
|
||||
FloatToHalfBaseTable[i | 0x100] = 0xFC00;
|
||||
FloatToHalfShiftTable[i | 0x000] = 24;
|
||||
FloatToHalfShiftTable[i | 0x100] = 24;
|
||||
}
|
||||
else
|
||||
{ // Infinity and NaN's stay Infinity and NaN's
|
||||
FloatToHalfBaseTable[i | 0x000] = 0x7C00;
|
||||
FloatToHalfBaseTable[i | 0x100] = 0xFC00;
|
||||
FloatToHalfShiftTable[i | 0x000] = 13;
|
||||
FloatToHalfShiftTable[i | 0x100] = 13;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
764
math/Int2.cs
Normal file
764
math/Int2.cs
Normal file
@ -0,0 +1,764 @@
|
||||
// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
|
||||
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// Original code from SlimMath project. http://code.google.com/p/slimmath/
|
||||
// Greetings to SlimDX Group. Original code published with the following license:
|
||||
// -----------------------------------------------------------------------------
|
||||
/*
|
||||
* Copyright (c) 2007-2011 SlimDX Group
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace math
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a three dimensional mathematical vector.
|
||||
/// </summary>
|
||||
[DataContract( Name = "Int2")]
|
||||
[DataStyle(DataStyle.Compact)]
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
||||
public struct Int2 : IEquatable<Int2>, IFormattable
|
||||
{
|
||||
/// <summary>
|
||||
/// The size of the <see cref="math.Int2"/> type, in bytes.
|
||||
/// </summary>
|
||||
public static readonly int SizeInBytes = Utilities.SizeOf<Int2>();
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="math.Int2"/> with all of its components set to zero.
|
||||
/// </summary>
|
||||
public static readonly Int2 Zero = new Int2();
|
||||
|
||||
/// <summary>
|
||||
/// The X unit <see cref="math.Int2"/> (1, 0, 0).
|
||||
/// </summary>
|
||||
public static readonly Int2 UnitX = new Int2(1, 0);
|
||||
|
||||
/// <summary>
|
||||
/// The Y unit <see cref="math.Int2"/> (0, 1, 0).
|
||||
/// </summary>
|
||||
public static readonly Int2 UnitY = new Int2(0, 1);
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="math.Int2"/> with all of its components set to one.
|
||||
/// </summary>
|
||||
public static readonly Int2 One = new Int2(1, 1);
|
||||
|
||||
/// <summary>
|
||||
/// The X component of the vector.
|
||||
/// </summary>
|
||||
[DataMember( Order = 0 )]
|
||||
public int X;
|
||||
|
||||
/// <summary>
|
||||
/// The Y component of the vector.
|
||||
/// </summary>
|
||||
[DataMember( Order = 1 )]
|
||||
public int Y;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="math.Int2"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="value">The value that will be assigned to all components.</param>
|
||||
public Int2(int value)
|
||||
{
|
||||
X = value;
|
||||
Y = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="math.Int2"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="x">Initial value for the X component of the vector.</param>
|
||||
/// <param name="y">Initial value for the Y component of the vector.</param>
|
||||
public Int2(int x, int y)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="math.Int2"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="value">A vector containing the values with which to initialize the X and Y components.</param>
|
||||
public Int2(Vec2 value)
|
||||
{
|
||||
X = (int)value.X;
|
||||
Y = (int)value.Y;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="math.Int2"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="values">The values to assign to the X, Y, and Z components of the vector. This must be an array with three elements.</param>
|
||||
/// <exception cref="ArgumentNullException">Thrown when <paramref name="values"/> is <c>null</c>.</exception>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Thrown when <paramref name="values"/> contains more or less than three elements.</exception>
|
||||
public Int2(int[] values)
|
||||
{
|
||||
if (values == null)
|
||||
throw new ArgumentNullException("values");
|
||||
if (values.Length != 2)
|
||||
throw new ArgumentOutOfRangeException("values", "There must be two and only two input values for Int2.");
|
||||
|
||||
X = values[0];
|
||||
Y = values[1];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the component at the specified index.
|
||||
/// </summary>
|
||||
/// <value>The value of the X or Y component, depending on the index.</value>
|
||||
/// <param name="index">The index of the component to access. Use 0 for the X component and 1 for the Y component.</param>
|
||||
/// <returns>The value of the component at the specified index.</returns>
|
||||
/// <exception cref="System.ArgumentOutOfRangeException">Thrown when the <paramref name="index"/> is out of the range [0, 1].</exception>
|
||||
public int this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0: return X;
|
||||
case 1: return Y;
|
||||
}
|
||||
|
||||
throw new ArgumentOutOfRangeException("index", "Indices for Int2 run from 0 to 1, inclusive.");
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0: X = value; break;
|
||||
case 1: Y = value; break;
|
||||
default: throw new ArgumentOutOfRangeException("index", "Indices for Int2 run from 0 to 1, inclusive.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the length of the vector.
|
||||
/// </summary>
|
||||
/// <returns>The length of the vector.</returns>
|
||||
/// <remarks>
|
||||
/// <see cref="math.Int2.LengthSquared"/> may be preferred when only the relative length is needed
|
||||
/// and speed is of the essence.
|
||||
/// </remarks>
|
||||
public int Length()
|
||||
{
|
||||
return (int)Math.Sqrt((X * X) + (Y * Y));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the squared length of the vector.
|
||||
/// </summary>
|
||||
/// <returns>The squared length of the vector.</returns>
|
||||
/// <remarks>
|
||||
/// This method may be preferred to <see cref="math.Int2.Length"/> when only a relative length is needed
|
||||
/// and speed is of the essence.
|
||||
/// </remarks>
|
||||
public int LengthSquared()
|
||||
{
|
||||
return (X * X) + (Y * Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raises the exponent for each components.
|
||||
/// </summary>
|
||||
/// <param name="exponent">The exponent.</param>
|
||||
public void Pow(int exponent)
|
||||
{
|
||||
X = (int)Math.Pow(X, exponent);
|
||||
Y = (int)Math.Pow(Y, exponent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an array containing the elements of the vector.
|
||||
/// </summary>
|
||||
/// <returns>A two-element array containing the components of the vector.</returns>
|
||||
public int[] ToArray()
|
||||
{
|
||||
return new int[] { X, Y };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds two vectors.
|
||||
/// </summary>
|
||||
/// <param name="left">The first vector to add.</param>
|
||||
/// <param name="right">The second vector to add.</param>
|
||||
/// <param name="result">When the method completes, contains the sum of the two vectors.</param>
|
||||
public static void Add(ref Int2 left, ref Int2 right, out Int2 result)
|
||||
{
|
||||
result = new Int2(left.X + right.X, left.Y + right.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds two vectors.
|
||||
/// </summary>
|
||||
/// <param name="left">The first vector to add.</param>
|
||||
/// <param name="right">The second vector to add.</param>
|
||||
/// <returns>The sum of the two vectors.</returns>
|
||||
public static Int2 Add(Int2 left, Int2 right)
|
||||
{
|
||||
return new Int2(left.X + right.X, left.Y + right.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subtracts two vectors.
|
||||
/// </summary>
|
||||
/// <param name="left">The first vector to subtract.</param>
|
||||
/// <param name="right">The second vector to subtract.</param>
|
||||
/// <param name="result">When the method completes, contains the difference of the two vectors.</param>
|
||||
public static void Subtract(ref Int2 left, ref Int2 right, out Int2 result)
|
||||
{
|
||||
result = new Int2(left.X - right.X, left.Y - right.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subtracts two vectors.
|
||||
/// </summary>
|
||||
/// <param name="left">The first vector to subtract.</param>
|
||||
/// <param name="right">The second vector to subtract.</param>
|
||||
/// <returns>The difference of the two vectors.</returns>
|
||||
public static Int2 Subtract(Int2 left, Int2 right)
|
||||
{
|
||||
return new Int2(left.X - right.X, left.Y - right.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scales a vector by the given value.
|
||||
/// </summary>
|
||||
/// <param name="value">The vector to scale.</param>
|
||||
/// <param name="scale">The amount by which to scale the vector.</param>
|
||||
/// <param name="result">When the method completes, contains the scaled vector.</param>
|
||||
public static void Multiply(ref Int2 value, int scale, out Int2 result)
|
||||
{
|
||||
result = new Int2(value.X * scale, value.Y * scale);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scales a vector by the given value.
|
||||
/// </summary>
|
||||
/// <param name="value">The vector to scale.</param>
|
||||
/// <param name="scale">The amount by which to scale the vector.</param>
|
||||
/// <returns>The scaled vector.</returns>
|
||||
public static Int2 Multiply(Int2 value, int scale)
|
||||
{
|
||||
return new Int2(value.X * scale, value.Y * scale);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Modulates a vector with another by performing component-wise multiplication.
|
||||
/// </summary>
|
||||
/// <param name="left">The first vector to modulate.</param>
|
||||
/// <param name="right">The second vector to modulate.</param>
|
||||
/// <param name="result">When the method completes, contains the modulated vector.</param>
|
||||
public static void Modulate(ref Int2 left, ref Int2 right, out Int2 result)
|
||||
{
|
||||
result = new Int2(left.X * right.X, left.Y * right.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Modulates a vector with another by performing component-wise multiplication.
|
||||
/// </summary>
|
||||
/// <param name="left">The first vector to modulate.</param>
|
||||
/// <param name="right">The second vector to modulate.</param>
|
||||
/// <returns>The modulated vector.</returns>
|
||||
public static Int2 Modulate(Int2 left, Int2 right)
|
||||
{
|
||||
return new Int2(left.X * right.X, left.Y * right.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scales a vector by the given value.
|
||||
/// </summary>
|
||||
/// <param name="value">The vector to scale.</param>
|
||||
/// <param name="scale">The amount by which to scale the vector.</param>
|
||||
/// <param name="result">When the method completes, contains the scaled vector.</param>
|
||||
public static void Divide(ref Int2 value, int scale, out Int2 result)
|
||||
{
|
||||
result = new Int2(value.X / scale, value.Y / scale);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scales a vector by the given value.
|
||||
/// </summary>
|
||||
/// <param name="value">The vector to scale.</param>
|
||||
/// <param name="scale">The amount by which to scale the vector.</param>
|
||||
/// <returns>The scaled vector.</returns>
|
||||
public static Int2 Divide(Int2 value, int scale)
|
||||
{
|
||||
return new Int2(value.X / scale, value.Y / scale);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reverses the direction of a given vector.
|
||||
/// </summary>
|
||||
/// <param name="value">The vector to negate.</param>
|
||||
/// <param name="result">When the method completes, contains a vector facing in the opposite direction.</param>
|
||||
public static void Negate(ref Int2 value, out Int2 result)
|
||||
{
|
||||
result = new Int2(-value.X, -value.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reverses the direction of a given vector.
|
||||
/// </summary>
|
||||
/// <param name="value">The vector to negate.</param>
|
||||
/// <returns>A vector facing in the opposite direction.</returns>
|
||||
public static Int2 Negate(Int2 value)
|
||||
{
|
||||
return new Int2(-value.X, -value.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restricts a value to be within a specified range.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to clamp.</param>
|
||||
/// <param name="min">The minimum value.</param>
|
||||
/// <param name="max">The maximum value.</param>
|
||||
/// <param name="result">When the method completes, contains the clamped value.</param>
|
||||
public static void Clamp(ref Int2 value, ref Int2 min, ref Int2 max, out Int2 result)
|
||||
{
|
||||
int x = value.X;
|
||||
x = (x > max.X) ? max.X : x;
|
||||
x = (x < min.X) ? min.X : x;
|
||||
|
||||
int y = value.Y;
|
||||
y = (y > max.Y) ? max.Y : y;
|
||||
y = (y < min.Y) ? min.Y : y;
|
||||
|
||||
result = new Int2(x, y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restricts a value to be within a specified range.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to clamp.</param>
|
||||
/// <param name="min">The minimum value.</param>
|
||||
/// <param name="max">The maximum value.</param>
|
||||
/// <returns>The clamped value.</returns>
|
||||
public static Int2 Clamp(Int2 value, Int2 min, Int2 max)
|
||||
{
|
||||
Int2 result;
|
||||
Clamp(ref value, ref min, ref max, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the dot product of two vectors.
|
||||
/// </summary>
|
||||
/// <param name="left">First source vector.</param>
|
||||
/// <param name="right">Second source vector.</param>
|
||||
/// <param name="result">When the method completes, contains the dot product of the two vectors.</param>
|
||||
public static void Dot(ref Int2 left, ref Int2 right, out int result)
|
||||
{
|
||||
result = (left.X * right.X) + (left.Y * right.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the dot product of two vectors.
|
||||
/// </summary>
|
||||
/// <param name="left">First source vector.</param>
|
||||
/// <param name="right">Second source vector.</param>
|
||||
/// <returns>The dot product of the two vectors.</returns>
|
||||
public static int Dot(Int2 left, Int2 right)
|
||||
{
|
||||
return (left.X * right.X) + (left.Y * right.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs a linear interpolation between two vectors.
|
||||
/// </summary>
|
||||
/// <param name="start">Start vector.</param>
|
||||
/// <param name="end">End vector.</param>
|
||||
/// <param name="amount">Value between 0 and 1 indicating the weight of <paramref name="end"/>.</param>
|
||||
/// <param name="result">When the method completes, contains the linear interpolation of the two vectors.</param>
|
||||
/// <remarks>
|
||||
/// This method performs the linear interpolation based on the following formula.
|
||||
/// <code>start + (end - start) * amount</code>
|
||||
/// Passing <paramref name="amount"/> a value of 0 will cause <paramref name="start"/> to be returned; a value of 1 will cause <paramref name="end"/> to be returned.
|
||||
/// </remarks>
|
||||
public static void Lerp(ref Int2 start, ref Int2 end, float amount, out Int2 result)
|
||||
{
|
||||
result.X = (int)(start.X + ((end.X - start.X) * amount));
|
||||
result.Y = (int)(start.Y + ((end.Y - start.Y) * amount));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs a linear interpolation between two vectors.
|
||||
/// </summary>
|
||||
/// <param name="start">Start vector.</param>
|
||||
/// <param name="end">End vector.</param>
|
||||
/// <param name="amount">Value between 0 and 1 indicating the weight of <paramref name="end"/>.</param>
|
||||
/// <returns>The linear interpolation of the two vectors.</returns>
|
||||
/// <remarks>
|
||||
/// This method performs the linear interpolation based on the following formula.
|
||||
/// <code>start + (end - start) * amount</code>
|
||||
/// Passing <paramref name="amount"/> a value of 0 will cause <paramref name="start"/> to be returned; a value of 1 will cause <paramref name="end"/> to be returned.
|
||||
/// </remarks>
|
||||
public static Int2 Lerp(Int2 start, Int2 end, float amount)
|
||||
{
|
||||
Int2 result;
|
||||
Lerp(ref start, ref end, amount, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs a cubic interpolation between two vectors.
|
||||
/// </summary>
|
||||
/// <param name="start">Start vector.</param>
|
||||
/// <param name="end">End vector.</param>
|
||||
/// <param name="amount">Value between 0 and 1 indicating the weight of <paramref name="end"/>.</param>
|
||||
/// <param name="result">When the method completes, contains the cubic interpolation of the two vectors.</param>
|
||||
public static void SmoothStep(ref Int2 start, ref Int2 end, float amount, out Int2 result)
|
||||
{
|
||||
amount = (amount > 1) ? 1 : ((amount < 0) ? 0 : amount);
|
||||
amount = (amount * amount) * (3 - (2 * amount));
|
||||
|
||||
result.X = (int)(start.X + ((end.X - start.X) * amount));
|
||||
result.Y = (int)(start.Y + ((end.Y - start.Y) * amount));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs a cubic interpolation between two vectors.
|
||||
/// </summary>
|
||||
/// <param name="start">Start vector.</param>
|
||||
/// <param name="end">End vector.</param>
|
||||
/// <param name="amount">Value between 0 and 1 indicating the weight of <paramref name="end"/>.</param>
|
||||
/// <returns>The cubic interpolation of the two vectors.</returns>
|
||||
public static Int2 SmoothStep(Int2 start, Int2 end, float amount)
|
||||
{
|
||||
Int2 result;
|
||||
SmoothStep(ref start, ref end, amount, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a vector containing the smallest components of the specified vectors.
|
||||
/// </summary>
|
||||
/// <param name="left">The first source vector.</param>
|
||||
/// <param name="right">The second source vector.</param>
|
||||
/// <param name="result">When the method completes, contains an new vector composed of the largest components of the source vectors.</param>
|
||||
public static void Max(ref Int2 left, ref Int2 right, out Int2 result)
|
||||
{
|
||||
result.X = (left.X > right.X) ? left.X : right.X;
|
||||
result.Y = (left.Y > right.Y) ? left.Y : right.Y;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a vector containing the largest components of the specified vectors.
|
||||
/// </summary>
|
||||
/// <param name="left">The first source vector.</param>
|
||||
/// <param name="right">The second source vector.</param>
|
||||
/// <returns>A vector containing the largest components of the source vectors.</returns>
|
||||
public static Int2 Max(Int2 left, Int2 right)
|
||||
{
|
||||
Int2 result;
|
||||
Max(ref left, ref right, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a vector containing the smallest components of the specified vectors.
|
||||
/// </summary>
|
||||
/// <param name="left">The first source vector.</param>
|
||||
/// <param name="right">The second source vector.</param>
|
||||
/// <param name="result">When the method completes, contains an new vector composed of the smallest components of the source vectors.</param>
|
||||
public static void Min(ref Int2 left, ref Int2 right, out Int2 result)
|
||||
{
|
||||
result.X = (left.X < right.X) ? left.X : right.X;
|
||||
result.Y = (left.Y < right.Y) ? left.Y : right.Y;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a vector containing the smallest components of the specified vectors.
|
||||
/// </summary>
|
||||
/// <param name="left">The first source vector.</param>
|
||||
/// <param name="right">The second source vector.</param>
|
||||
/// <returns>A vector containing the smallest components of the source vectors.</returns>
|
||||
public static Int2 Min(Int2 left, Int2 right)
|
||||
{
|
||||
Int2 result;
|
||||
Min(ref left, ref right, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds two vectors.
|
||||
/// </summary>
|
||||
/// <param name="left">The first vector to add.</param>
|
||||
/// <param name="right">The second vector to add.</param>
|
||||
/// <returns>The sum of the two vectors.</returns>
|
||||
public static Int2 operator +(Int2 left, Int2 right)
|
||||
{
|
||||
return new Int2(left.X + right.X, left.Y + right.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assert a vector (return it unchanged).
|
||||
/// </summary>
|
||||
/// <param name="value">The vector to assert (unchange).</param>
|
||||
/// <returns>The asserted (unchanged) vector.</returns>
|
||||
public static Int2 operator +(Int2 value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subtracts two vectors.
|
||||
/// </summary>
|
||||
/// <param name="left">The first vector to subtract.</param>
|
||||
/// <param name="right">The second vector to subtract.</param>
|
||||
/// <returns>The difference of the two vectors.</returns>
|
||||
public static Int2 operator -(Int2 left, Int2 right)
|
||||
{
|
||||
return new Int2(left.X - right.X, left.Y - right.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reverses the direction of a given vector.
|
||||
/// </summary>
|
||||
/// <param name="value">The vector to negate.</param>
|
||||
/// <returns>A vector facing in the opposite direction.</returns>
|
||||
public static Int2 operator -(Int2 value)
|
||||
{
|
||||
return new Int2(-value.X, -value.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scales a vector by the given value.
|
||||
/// </summary>
|
||||
/// <param name="value">The vector to scale.</param>
|
||||
/// <param name="scale">The amount by which to scale the vector.</param>
|
||||
/// <returns>The scaled vector.</returns>
|
||||
public static Int2 operator *(float scale, Int2 value)
|
||||
{
|
||||
return new Int2((int)(value.X * scale), (int)(value.Y * scale));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scales a vector by the given value.
|
||||
/// </summary>
|
||||
/// <param name="value">The vector to scale.</param>
|
||||
/// <param name="scale">The amount by which to scale the vector.</param>
|
||||
/// <returns>The scaled vector.</returns>
|
||||
public static Int2 operator *(Int2 value, float scale)
|
||||
{
|
||||
return new Int2((int)(value.X * scale), (int)(value.Y * scale));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scales a vector by the given value.
|
||||
/// </summary>
|
||||
/// <param name="value">The vector to scale.</param>
|
||||
/// <param name="scale">The amount by which to scale the vector.</param>
|
||||
/// <returns>The scaled vector.</returns>
|
||||
public static Int2 operator /(Int2 value, float scale)
|
||||
{
|
||||
return new Int2((int)(value.X / scale), (int)(value.Y / scale));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests for equality between two objects.
|
||||
/// </summary>
|
||||
/// <param name="left">The first value to compare.</param>
|
||||
/// <param name="right">The second value to compare.</param>
|
||||
/// <returns><c>true</c> if <paramref name="left"/> has the same value as <paramref name="right"/>; otherwise, <c>false</c>.</returns>
|
||||
public static bool operator ==(Int2 left, Int2 right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests for inequality between two objects.
|
||||
/// </summary>
|
||||
/// <param name="left">The first value to compare.</param>
|
||||
/// <param name="right">The second value to compare.</param>
|
||||
/// <returns><c>true</c> if <paramref name="left"/> has a different value than <paramref name="right"/>; otherwise, <c>false</c>.</returns>
|
||||
public static bool operator !=(Int2 left, Int2 right)
|
||||
{
|
||||
return !left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an explicit conversion from <see cref="math.Int2"/> to <see cref="Vec2"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static explicit operator Vec2(Int2 value)
|
||||
{
|
||||
return new Vec2(value.X, value.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an explicit conversion from <see cref="math.Int2"/> to <see cref="Vector4"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static explicit operator Vector4(Int2 value)
|
||||
{
|
||||
return new Vector4(value.X, value.Y, 0, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="string"/> that represents this instance.
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, "X:{0} Y:{1}", X, Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <param name="format">The format.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="string"/> that represents this instance.
|
||||
/// </returns>
|
||||
public string ToString(string format)
|
||||
{
|
||||
if (format == null)
|
||||
return ToString();
|
||||
|
||||
return string.Format(CultureInfo.CurrentCulture, "X:{0} Y:{1}", X.ToString(format, CultureInfo.CurrentCulture), Y.ToString(format, CultureInfo.CurrentCulture));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <param name="formatProvider">The format provider.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="string"/> that represents this instance.
|
||||
/// </returns>
|
||||
public string ToString(IFormatProvider formatProvider)
|
||||
{
|
||||
return string.Format(formatProvider, "X:{0} Y:{1}", X, Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <param name="format">The format.</param>
|
||||
/// <param name="formatProvider">The format provider.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="string"/> that represents this instance.
|
||||
/// </returns>
|
||||
public string ToString(string format, IFormatProvider formatProvider)
|
||||
{
|
||||
if (format == null)
|
||||
return ToString(formatProvider);
|
||||
|
||||
return string.Format(formatProvider, "X:{0} Y:{1}", X.ToString(format, formatProvider), Y.ToString(format, formatProvider));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a hash code for this instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
|
||||
/// </returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return X.GetHashCode() + Y.GetHashCode();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="math.Int2"/> is equal to this instance.
|
||||
/// </summary>
|
||||
/// <param name="other">The <see cref="math.Int2"/> to compare with this instance.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the specified <see cref="math.Int2"/> is equal to this instance; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public bool Equals(Int2 other)
|
||||
{
|
||||
return ((float)Math.Abs(other.X - X) < MathUtil.ZeroTolerance &&
|
||||
(float)Math.Abs(other.Y - Y) < MathUtil.ZeroTolerance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="object"/> is equal to this instance.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="object"/> to compare with this instance.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the specified <see cref="object"/> is equal to this instance; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
if (value == null)
|
||||
return false;
|
||||
|
||||
if (value.GetType() != GetType())
|
||||
return false;
|
||||
|
||||
return Equals((Int2)value);
|
||||
}
|
||||
#if WPFInterop
|
||||
/// <summary>
|
||||
/// Performs an implicit conversion from <see cref="math.Int2"/> to <see cref="System.Windows.Media.Media3D.Int3D"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator System.Windows.Media.Media3D.Int3D(Int2 value)
|
||||
{
|
||||
return new System.Windows.Media.Media3D.Int3D(value.X, value.Y, 0.0f);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an explicit conversion from <see cref="System.Windows.Media.Media3D.Int3D"/> to <see cref="math.Int2"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static explicit operator Int2(System.Windows.Media.Media3D.Int3D value)
|
||||
{
|
||||
return new Int2((float)value.X, (float)value.Y);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if XnaInterop
|
||||
/// <summary>
|
||||
/// Performs an implicit conversion from <see cref="math.Int2"/> to <see cref="Microsoft.Xna.Framework.Int2"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator Microsoft.Xna.Framework.Int2(Int2 value)
|
||||
{
|
||||
return new Microsoft.Xna.Framework.Int2(value.X, value.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an implicit conversion from <see cref="Microsoft.Xna.Framework.Int2"/> to <see cref="math.Int2"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator Int2(Microsoft.Xna.Framework.Int2 value)
|
||||
{
|
||||
return new Int2(value.X, value.Y);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
805
math/Int3.cs
Normal file
805
math/Int3.cs
Normal file
@ -0,0 +1,805 @@
|
||||
// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
|
||||
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// Original code from SlimMath project. http://code.google.com/p/slimmath/
|
||||
// Greetings to SlimDX Group. Original code published with the following license:
|
||||
// -----------------------------------------------------------------------------
|
||||
/*
|
||||
* Copyright (c) 2007-2011 SlimDX Group
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace math
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a three dimensional mathematical vector.
|
||||
/// </summary>
|
||||
[DataContract( Name = "Int3")]
|
||||
[DataStyle(DataStyle.Compact)]
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
||||
public struct Int3 : IEquatable<Int3>, IFormattable
|
||||
{
|
||||
/// <summary>
|
||||
/// The size of the <see cref="Int3"/> type, in bytes.
|
||||
/// </summary>
|
||||
public static readonly int SizeInBytes = Utilities.SizeOf<Int3>();
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="Int3"/> with all of its components set to zero.
|
||||
/// </summary>
|
||||
public static readonly Int3 Zero = new Int3();
|
||||
|
||||
/// <summary>
|
||||
/// The X unit <see cref="Int3"/> (1, 0, 0).
|
||||
/// </summary>
|
||||
public static readonly Int3 UnitX = new Int3(1, 0, 0);
|
||||
|
||||
/// <summary>
|
||||
/// The Y unit <see cref="Int3"/> (0, 1, 0).
|
||||
/// </summary>
|
||||
public static readonly Int3 UnitY = new Int3(0, 1, 0);
|
||||
|
||||
/// <summary>
|
||||
/// The Z unit <see cref="Int3"/> (0, 0, 1).
|
||||
/// </summary>
|
||||
public static readonly Int3 UnitZ = new Int3(0, 0, 1);
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="Int3"/> with all of its components set to one.
|
||||
/// </summary>
|
||||
public static readonly Int3 One = new Int3(1, 1, 1);
|
||||
|
||||
/// <summary>
|
||||
/// The X component of the vector.
|
||||
/// </summary>
|
||||
[DataMember( Order = 0 )]
|
||||
public int X;
|
||||
|
||||
/// <summary>
|
||||
/// The Y component of the vector.
|
||||
/// </summary>
|
||||
[DataMember( Order = 1 )]
|
||||
public int Y;
|
||||
|
||||
/// <summary>
|
||||
/// The Z component of the vector.
|
||||
/// </summary>
|
||||
[DataMember( Order = 2 )]
|
||||
public int Z;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Int3"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="value">The value that will be assigned to all components.</param>
|
||||
public Int3(int value)
|
||||
{
|
||||
X = value;
|
||||
Y = value;
|
||||
Z = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Int3"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="x">Initial value for the X component of the vector.</param>
|
||||
/// <param name="y">Initial value for the Y component of the vector.</param>
|
||||
/// <param name="z">Initial value for the Z component of the vector.</param>
|
||||
public Int3(int x, int y, int z)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
Z = z;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Int3"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="value">A vector containing the values with which to initialize the X and Y components.</param>
|
||||
/// <param name="z">Initial value for the Z component of the vector.</param>
|
||||
public Int3(Vec2 value, int z)
|
||||
{
|
||||
X = (int)value.X;
|
||||
Y = (int)value.Y;
|
||||
Z = z;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Int3"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="values">The values to assign to the X, Y, and Z components of the vector. This must be an array with three elements.</param>
|
||||
/// <exception cref="ArgumentNullException">Thrown when <paramref name="values"/> is <c>null</c>.</exception>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Thrown when <paramref name="values"/> contains more or less than three elements.</exception>
|
||||
public Int3(int[] values)
|
||||
{
|
||||
if (values == null)
|
||||
throw new ArgumentNullException("values");
|
||||
if (values.Length != 3)
|
||||
throw new ArgumentOutOfRangeException("values", "There must be three and only three input values for Int3.");
|
||||
|
||||
X = values[0];
|
||||
Y = values[1];
|
||||
Z = values[2];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the component at the specified index.
|
||||
/// </summary>
|
||||
/// <value>The value of the X, Y, or Z component, depending on the index.</value>
|
||||
/// <param name="index">The index of the component to access. Use 0 for the X component, 1 for the Y component, and 2 for the Z component.</param>
|
||||
/// <returns>The value of the component at the specified index.</returns>
|
||||
/// <exception cref="System.ArgumentOutOfRangeException">Thrown when the <paramref name="index"/> is out of the range [0, 2].</exception>
|
||||
public int this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0: return X;
|
||||
case 1: return Y;
|
||||
case 2: return Z;
|
||||
}
|
||||
|
||||
throw new ArgumentOutOfRangeException("index", "Indices for Int3 run from 0 to 2, inclusive.");
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0: X = value; break;
|
||||
case 1: Y = value; break;
|
||||
case 2: Z = value; break;
|
||||
default: throw new ArgumentOutOfRangeException("index", "Indices for Int3 run from 0 to 2, inclusive.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the length of the vector.
|
||||
/// </summary>
|
||||
/// <returns>The length of the vector.</returns>
|
||||
/// <remarks>
|
||||
/// <see cref="Int3.LengthSquared"/> may be preferred when only the relative length is needed
|
||||
/// and speed is of the essence.
|
||||
/// </remarks>
|
||||
public int Length()
|
||||
{
|
||||
return (int)Math.Sqrt((X * X) + (Y * Y) + (Z * Z));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the squared length of the vector.
|
||||
/// </summary>
|
||||
/// <returns>The squared length of the vector.</returns>
|
||||
/// <remarks>
|
||||
/// This method may be preferred to <see cref="Int3.Length"/> when only a relative length is needed
|
||||
/// and speed is of the essence.
|
||||
/// </remarks>
|
||||
public int LengthSquared()
|
||||
{
|
||||
return (X * X) + (Y * Y) + (Z * Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raises the exponent for each components.
|
||||
/// </summary>
|
||||
/// <param name="exponent">The exponent.</param>
|
||||
public void Pow(int exponent)
|
||||
{
|
||||
X = (int)Math.Pow(X, exponent);
|
||||
Y = (int)Math.Pow(Y, exponent);
|
||||
Z = (int)Math.Pow(Z, exponent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an array containing the elements of the vector.
|
||||
/// </summary>
|
||||
/// <returns>A three-element array containing the components of the vector.</returns>
|
||||
public int[] ToArray()
|
||||
{
|
||||
return new int[] { X, Y, Z };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds two vectors.
|
||||
/// </summary>
|
||||
/// <param name="left">The first vector to add.</param>
|
||||
/// <param name="right">The second vector to add.</param>
|
||||
/// <param name="result">When the method completes, contains the sum of the two vectors.</param>
|
||||
public static void Add(ref Int3 left, ref Int3 right, out Int3 result)
|
||||
{
|
||||
result = new Int3(left.X + right.X, left.Y + right.Y, left.Z + right.Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds two vectors.
|
||||
/// </summary>
|
||||
/// <param name="left">The first vector to add.</param>
|
||||
/// <param name="right">The second vector to add.</param>
|
||||
/// <returns>The sum of the two vectors.</returns>
|
||||
public static Int3 Add(Int3 left, Int3 right)
|
||||
{
|
||||
return new Int3(left.X + right.X, left.Y + right.Y, left.Z + right.Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subtracts two vectors.
|
||||
/// </summary>
|
||||
/// <param name="left">The first vector to subtract.</param>
|
||||
/// <param name="right">The second vector to subtract.</param>
|
||||
/// <param name="result">When the method completes, contains the difference of the two vectors.</param>
|
||||
public static void Subtract(ref Int3 left, ref Int3 right, out Int3 result)
|
||||
{
|
||||
result = new Int3(left.X - right.X, left.Y - right.Y, left.Z - right.Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subtracts two vectors.
|
||||
/// </summary>
|
||||
/// <param name="left">The first vector to subtract.</param>
|
||||
/// <param name="right">The second vector to subtract.</param>
|
||||
/// <returns>The difference of the two vectors.</returns>
|
||||
public static Int3 Subtract(Int3 left, Int3 right)
|
||||
{
|
||||
return new Int3(left.X - right.X, left.Y - right.Y, left.Z - right.Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scales a vector by the given value.
|
||||
/// </summary>
|
||||
/// <param name="value">The vector to scale.</param>
|
||||
/// <param name="scale">The amount by which to scale the vector.</param>
|
||||
/// <param name="result">When the method completes, contains the scaled vector.</param>
|
||||
public static void Multiply(ref Int3 value, int scale, out Int3 result)
|
||||
{
|
||||
result = new Int3(value.X * scale, value.Y * scale, value.Z * scale);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scales a vector by the given value.
|
||||
/// </summary>
|
||||
/// <param name="value">The vector to scale.</param>
|
||||
/// <param name="scale">The amount by which to scale the vector.</param>
|
||||
/// <returns>The scaled vector.</returns>
|
||||
public static Int3 Multiply(Int3 value, int scale)
|
||||
{
|
||||
return new Int3(value.X * scale, value.Y * scale, value.Z * scale);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Modulates a vector with another by performing component-wise multiplication.
|
||||
/// </summary>
|
||||
/// <param name="left">The first vector to modulate.</param>
|
||||
/// <param name="right">The second vector to modulate.</param>
|
||||
/// <param name="result">When the method completes, contains the modulated vector.</param>
|
||||
public static void Modulate(ref Int3 left, ref Int3 right, out Int3 result)
|
||||
{
|
||||
result = new Int3(left.X * right.X, left.Y * right.Y, left.Z * right.Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Modulates a vector with another by performing component-wise multiplication.
|
||||
/// </summary>
|
||||
/// <param name="left">The first vector to modulate.</param>
|
||||
/// <param name="right">The second vector to modulate.</param>
|
||||
/// <returns>The modulated vector.</returns>
|
||||
public static Int3 Modulate(Int3 left, Int3 right)
|
||||
{
|
||||
return new Int3(left.X * right.X, left.Y * right.Y, left.Z * right.Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scales a vector by the given value.
|
||||
/// </summary>
|
||||
/// <param name="value">The vector to scale.</param>
|
||||
/// <param name="scale">The amount by which to scale the vector.</param>
|
||||
/// <param name="result">When the method completes, contains the scaled vector.</param>
|
||||
public static void Divide(ref Int3 value, int scale, out Int3 result)
|
||||
{
|
||||
result = new Int3(value.X / scale, value.Y / scale, value.Z / scale);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scales a vector by the given value.
|
||||
/// </summary>
|
||||
/// <param name="value">The vector to scale.</param>
|
||||
/// <param name="scale">The amount by which to scale the vector.</param>
|
||||
/// <returns>The scaled vector.</returns>
|
||||
public static Int3 Divide(Int3 value, int scale)
|
||||
{
|
||||
return new Int3(value.X / scale, value.Y / scale, value.Z / scale);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reverses the direction of a given vector.
|
||||
/// </summary>
|
||||
/// <param name="value">The vector to negate.</param>
|
||||
/// <param name="result">When the method completes, contains a vector facing in the opposite direction.</param>
|
||||
public static void Negate(ref Int3 value, out Int3 result)
|
||||
{
|
||||
result = new Int3(-value.X, -value.Y, -value.Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reverses the direction of a given vector.
|
||||
/// </summary>
|
||||
/// <param name="value">The vector to negate.</param>
|
||||
/// <returns>A vector facing in the opposite direction.</returns>
|
||||
public static Int3 Negate(Int3 value)
|
||||
{
|
||||
return new Int3(-value.X, -value.Y, -value.Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restricts a value to be within a specified range.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to clamp.</param>
|
||||
/// <param name="min">The minimum value.</param>
|
||||
/// <param name="max">The maximum value.</param>
|
||||
/// <param name="result">When the method completes, contains the clamped value.</param>
|
||||
public static void Clamp(ref Int3 value, ref Int3 min, ref Int3 max, out Int3 result)
|
||||
{
|
||||
int x = value.X;
|
||||
x = (x > max.X) ? max.X : x;
|
||||
x = (x < min.X) ? min.X : x;
|
||||
|
||||
int y = value.Y;
|
||||
y = (y > max.Y) ? max.Y : y;
|
||||
y = (y < min.Y) ? min.Y : y;
|
||||
|
||||
int z = value.Z;
|
||||
z = (z > max.Z) ? max.Z : z;
|
||||
z = (z < min.Z) ? min.Z : z;
|
||||
|
||||
result = new Int3(x, y, z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restricts a value to be within a specified range.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to clamp.</param>
|
||||
/// <param name="min">The minimum value.</param>
|
||||
/// <param name="max">The maximum value.</param>
|
||||
/// <returns>The clamped value.</returns>
|
||||
public static Int3 Clamp(Int3 value, Int3 min, Int3 max)
|
||||
{
|
||||
Int3 result;
|
||||
Clamp(ref value, ref min, ref max, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the dot product of two vectors.
|
||||
/// </summary>
|
||||
/// <param name="left">First source vector.</param>
|
||||
/// <param name="right">Second source vector.</param>
|
||||
/// <param name="result">When the method completes, contains the dot product of the two vectors.</param>
|
||||
public static void Dot(ref Int3 left, ref Int3 right, out int result)
|
||||
{
|
||||
result = (left.X * right.X) + (left.Y * right.Y) + (left.Z * right.Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the dot product of two vectors.
|
||||
/// </summary>
|
||||
/// <param name="left">First source vector.</param>
|
||||
/// <param name="right">Second source vector.</param>
|
||||
/// <returns>The dot product of the two vectors.</returns>
|
||||
public static int Dot(Int3 left, Int3 right)
|
||||
{
|
||||
return (left.X * right.X) + (left.Y * right.Y) + (left.Z * right.Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs a linear interpolation between two vectors.
|
||||
/// </summary>
|
||||
/// <param name="start">Start vector.</param>
|
||||
/// <param name="end">End vector.</param>
|
||||
/// <param name="amount">Value between 0 and 1 indicating the weight of <paramref name="end"/>.</param>
|
||||
/// <param name="result">When the method completes, contains the linear interpolation of the two vectors.</param>
|
||||
/// <remarks>
|
||||
/// This method performs the linear interpolation based on the following formula.
|
||||
/// <code>start + (end - start) * amount</code>
|
||||
/// Passing <paramref name="amount"/> a value of 0 will cause <paramref name="start"/> to be returned; a value of 1 will cause <paramref name="end"/> to be returned.
|
||||
/// </remarks>
|
||||
public static void Lerp(ref Int3 start, ref Int3 end, float amount, out Int3 result)
|
||||
{
|
||||
result.X = (int)(start.X + ((end.X - start.X) * amount));
|
||||
result.Y = (int)(start.Y + ((end.Y - start.Y) * amount));
|
||||
result.Z = (int)(start.Z + ((end.Z - start.Z) * amount));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs a linear interpolation between two vectors.
|
||||
/// </summary>
|
||||
/// <param name="start">Start vector.</param>
|
||||
/// <param name="end">End vector.</param>
|
||||
/// <param name="amount">Value between 0 and 1 indicating the weight of <paramref name="end"/>.</param>
|
||||
/// <returns>The linear interpolation of the two vectors.</returns>
|
||||
/// <remarks>
|
||||
/// This method performs the linear interpolation based on the following formula.
|
||||
/// <code>start + (end - start) * amount</code>
|
||||
/// Passing <paramref name="amount"/> a value of 0 will cause <paramref name="start"/> to be returned; a value of 1 will cause <paramref name="end"/> to be returned.
|
||||
/// </remarks>
|
||||
public static Int3 Lerp(Int3 start, Int3 end, float amount)
|
||||
{
|
||||
Int3 result;
|
||||
Lerp(ref start, ref end, amount, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs a cubic interpolation between two vectors.
|
||||
/// </summary>
|
||||
/// <param name="start">Start vector.</param>
|
||||
/// <param name="end">End vector.</param>
|
||||
/// <param name="amount">Value between 0 and 1 indicating the weight of <paramref name="end"/>.</param>
|
||||
/// <param name="result">When the method completes, contains the cubic interpolation of the two vectors.</param>
|
||||
public static void SmoothStep(ref Int3 start, ref Int3 end, float amount, out Int3 result)
|
||||
{
|
||||
amount = (amount > 1) ? 1 : ((amount < 0) ? 0 : amount);
|
||||
amount = (amount * amount) * (3 - (2 * amount));
|
||||
|
||||
result.X = (int)(start.X + ((end.X - start.X) * amount));
|
||||
result.Y = (int)(start.Y + ((end.Y - start.Y) * amount));
|
||||
result.Z = (int)(start.Z + ((end.Z - start.Z) * amount));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs a cubic interpolation between two vectors.
|
||||
/// </summary>
|
||||
/// <param name="start">Start vector.</param>
|
||||
/// <param name="end">End vector.</param>
|
||||
/// <param name="amount">Value between 0 and 1 indicating the weight of <paramref name="end"/>.</param>
|
||||
/// <returns>The cubic interpolation of the two vectors.</returns>
|
||||
public static Int3 SmoothStep(Int3 start, Int3 end, float amount)
|
||||
{
|
||||
Int3 result;
|
||||
SmoothStep(ref start, ref end, amount, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a vector containing the smallest components of the specified vectors.
|
||||
/// </summary>
|
||||
/// <param name="left">The first source vector.</param>
|
||||
/// <param name="right">The second source vector.</param>
|
||||
/// <param name="result">When the method completes, contains an new vector composed of the largest components of the source vectors.</param>
|
||||
public static void Max(ref Int3 left, ref Int3 right, out Int3 result)
|
||||
{
|
||||
result.X = (left.X > right.X) ? left.X : right.X;
|
||||
result.Y = (left.Y > right.Y) ? left.Y : right.Y;
|
||||
result.Z = (left.Z > right.Z) ? left.Z : right.Z;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a vector containing the largest components of the specified vectors.
|
||||
/// </summary>
|
||||
/// <param name="left">The first source vector.</param>
|
||||
/// <param name="right">The second source vector.</param>
|
||||
/// <returns>A vector containing the largest components of the source vectors.</returns>
|
||||
public static Int3 Max(Int3 left, Int3 right)
|
||||
{
|
||||
Int3 result;
|
||||
Max(ref left, ref right, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a vector containing the smallest components of the specified vectors.
|
||||
/// </summary>
|
||||
/// <param name="left">The first source vector.</param>
|
||||
/// <param name="right">The second source vector.</param>
|
||||
/// <param name="result">When the method completes, contains an new vector composed of the smallest components of the source vectors.</param>
|
||||
public static void Min(ref Int3 left, ref Int3 right, out Int3 result)
|
||||
{
|
||||
result.X = (left.X < right.X) ? left.X : right.X;
|
||||
result.Y = (left.Y < right.Y) ? left.Y : right.Y;
|
||||
result.Z = (left.Z < right.Z) ? left.Z : right.Z;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a vector containing the smallest components of the specified vectors.
|
||||
/// </summary>
|
||||
/// <param name="left">The first source vector.</param>
|
||||
/// <param name="right">The second source vector.</param>
|
||||
/// <returns>A vector containing the smallest components of the source vectors.</returns>
|
||||
public static Int3 Min(Int3 left, Int3 right)
|
||||
{
|
||||
Int3 result;
|
||||
Min(ref left, ref right, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds two vectors.
|
||||
/// </summary>
|
||||
/// <param name="left">The first vector to add.</param>
|
||||
/// <param name="right">The second vector to add.</param>
|
||||
/// <returns>The sum of the two vectors.</returns>
|
||||
public static Int3 operator +(Int3 left, Int3 right)
|
||||
{
|
||||
return new Int3(left.X + right.X, left.Y + right.Y, left.Z + right.Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assert a vector (return it unchanged).
|
||||
/// </summary>
|
||||
/// <param name="value">The vector to assert (unchange).</param>
|
||||
/// <returns>The asserted (unchanged) vector.</returns>
|
||||
public static Int3 operator +(Int3 value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subtracts two vectors.
|
||||
/// </summary>
|
||||
/// <param name="left">The first vector to subtract.</param>
|
||||
/// <param name="right">The second vector to subtract.</param>
|
||||
/// <returns>The difference of the two vectors.</returns>
|
||||
public static Int3 operator -(Int3 left, Int3 right)
|
||||
{
|
||||
return new Int3(left.X - right.X, left.Y - right.Y, left.Z - right.Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reverses the direction of a given vector.
|
||||
/// </summary>
|
||||
/// <param name="value">The vector to negate.</param>
|
||||
/// <returns>A vector facing in the opposite direction.</returns>
|
||||
public static Int3 operator -(Int3 value)
|
||||
{
|
||||
return new Int3(-value.X, -value.Y, -value.Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scales a vector by the given value.
|
||||
/// </summary>
|
||||
/// <param name="value">The vector to scale.</param>
|
||||
/// <param name="scale">The amount by which to scale the vector.</param>
|
||||
/// <returns>The scaled vector.</returns>
|
||||
public static Int3 operator *(float scale, Int3 value)
|
||||
{
|
||||
return new Int3((int)(value.X * scale), (int)(value.Y * scale), (int)(value.Z * scale));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scales a vector by the given value.
|
||||
/// </summary>
|
||||
/// <param name="value">The vector to scale.</param>
|
||||
/// <param name="scale">The amount by which to scale the vector.</param>
|
||||
/// <returns>The scaled vector.</returns>
|
||||
public static Int3 operator *(Int3 value, float scale)
|
||||
{
|
||||
return new Int3((int)(value.X * scale), (int)(value.Y * scale), (int)(value.Z * scale));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scales a vector by the given value.
|
||||
/// </summary>
|
||||
/// <param name="value">The vector to scale.</param>
|
||||
/// <param name="scale">The amount by which to scale the vector.</param>
|
||||
/// <returns>The scaled vector.</returns>
|
||||
public static Int3 operator /(Int3 value, float scale)
|
||||
{
|
||||
return new Int3((int)(value.X / scale), (int)(value.Y / scale), (int)(value.Z / scale));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests for equality between two objects.
|
||||
/// </summary>
|
||||
/// <param name="left">The first value to compare.</param>
|
||||
/// <param name="right">The second value to compare.</param>
|
||||
/// <returns><c>true</c> if <paramref name="left"/> has the same value as <paramref name="right"/>; otherwise, <c>false</c>.</returns>
|
||||
public static bool operator ==(Int3 left, Int3 right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests for inequality between two objects.
|
||||
/// </summary>
|
||||
/// <param name="left">The first value to compare.</param>
|
||||
/// <param name="right">The second value to compare.</param>
|
||||
/// <returns><c>true</c> if <paramref name="left"/> has a different value than <paramref name="right"/>; otherwise, <c>false</c>.</returns>
|
||||
public static bool operator !=(Int3 left, Int3 right)
|
||||
{
|
||||
return !left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an explicit conversion from <see cref="Int3"/> to <see cref="Vec2"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static explicit operator Vec2(Int3 value)
|
||||
{
|
||||
return new Vec2(value.X, value.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an explicit conversion from <see cref="Int3"/> to <see cref="Vector3"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static explicit operator Vector3(Int3 value)
|
||||
{
|
||||
return new Vector3(value.X, value.Y, value.Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an explicit conversion from <see cref="Int3"/> to <see cref="Vector4"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static explicit operator Vector4(Int3 value)
|
||||
{
|
||||
return new Vector4(value.X, value.Y, value.Z, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="string"/> that represents this instance.
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, "X:{0} Y:{1} Z:{2}", X, Y, Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <param name="format">The format.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="string"/> that represents this instance.
|
||||
/// </returns>
|
||||
public string ToString(string format)
|
||||
{
|
||||
if (format == null)
|
||||
return ToString();
|
||||
|
||||
return string.Format(CultureInfo.CurrentCulture, "X:{0} Y:{1} Z:{2}", X.ToString(format, CultureInfo.CurrentCulture),
|
||||
Y.ToString(format, CultureInfo.CurrentCulture), Z.ToString(format, CultureInfo.CurrentCulture));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <param name="formatProvider">The format provider.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="string"/> that represents this instance.
|
||||
/// </returns>
|
||||
public string ToString(IFormatProvider formatProvider)
|
||||
{
|
||||
return string.Format(formatProvider, "X:{0} Y:{1} Z:{2}", X, Y, Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <param name="format">The format.</param>
|
||||
/// <param name="formatProvider">The format provider.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="string"/> that represents this instance.
|
||||
/// </returns>
|
||||
public string ToString(string format, IFormatProvider formatProvider)
|
||||
{
|
||||
if (format == null)
|
||||
return ToString(formatProvider);
|
||||
|
||||
return string.Format(formatProvider, "X:{0} Y:{1} Z:{2}", X.ToString(format, formatProvider),
|
||||
Y.ToString(format, formatProvider), Z.ToString(format, formatProvider));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a hash code for this instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
|
||||
/// </returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return X.GetHashCode() + Y.GetHashCode() + Z.GetHashCode();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="Int3"/> is equal to this instance.
|
||||
/// </summary>
|
||||
/// <param name="other">The <see cref="Int3"/> to compare with this instance.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the specified <see cref="Int3"/> is equal to this instance; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public bool Equals(Int3 other)
|
||||
{
|
||||
return ((float)Math.Abs(other.X - X) < MathUtil.ZeroTolerance &&
|
||||
(float)Math.Abs(other.Y - Y) < MathUtil.ZeroTolerance &&
|
||||
(float)Math.Abs(other.Z - Z) < MathUtil.ZeroTolerance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="object"/> is equal to this instance.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="object"/> to compare with this instance.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the specified <see cref="object"/> is equal to this instance; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
if (value == null)
|
||||
return false;
|
||||
|
||||
if (value.GetType() != GetType())
|
||||
return false;
|
||||
|
||||
return Equals((Int3)value);
|
||||
}
|
||||
#if WPFInterop
|
||||
/// <summary>
|
||||
/// Performs an implicit conversion from <see cref="math.Int3"/> to <see cref="System.Windows.Media.Media3D.Int3D"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator System.Windows.Media.Media3D.Int3D(Int3 value)
|
||||
{
|
||||
return new System.Windows.Media.Media3D.Int3D(value.X, value.Y, value.Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an explicit conversion from <see cref="System.Windows.Media.Media3D.Int3D"/> to <see cref="math.Int3"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static explicit operator Int3(System.Windows.Media.Media3D.Int3D value)
|
||||
{
|
||||
return new Int3((float)value.X, (float)value.Y, (float)value.Z);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if XnaInterop
|
||||
/// <summary>
|
||||
/// Performs an implicit conversion from <see cref="math.Int3"/> to <see cref="Microsoft.Xna.Framework.Int3"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator Microsoft.Xna.Framework.Int3(Int3 value)
|
||||
{
|
||||
return new Microsoft.Xna.Framework.Int3(value.X, value.Y, value.Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an implicit conversion from <see cref="Microsoft.Xna.Framework.Int3"/> to <see cref="math.Int3"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator Int3(Microsoft.Xna.Framework.Int3 value)
|
||||
{
|
||||
return new Int3(value.X, value.Y, value.Z);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
700
math/Int4.cs
Normal file
700
math/Int4.cs
Normal file
@ -0,0 +1,700 @@
|
||||
// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
|
||||
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
|
||||
//
|
||||
// Copyright (c) 2010-2011 SharpDX - Alexandre Mutel
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace math
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a four dimensional mathematical vector.
|
||||
/// </summary>
|
||||
[DataContract( Name = "Int4")]
|
||||
[DataStyle(DataStyle.Compact)]
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
||||
public struct Int4 : IEquatable<Int4>, IFormattable
|
||||
{
|
||||
/// <summary>
|
||||
/// The size of the <see cref = "Int4" /> type, in bytes.
|
||||
/// </summary>
|
||||
public static readonly int SizeInBytes = Utilities.SizeOf<Int4>();
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref = "Int4" /> with all of its components set to zero.
|
||||
/// </summary>
|
||||
public static readonly Int4 Zero = new Int4();
|
||||
|
||||
/// <summary>
|
||||
/// The X unit <see cref = "Int4" /> (1, 0, 0, 0).
|
||||
/// </summary>
|
||||
public static readonly Int4 UnitX = new Int4(1, 0, 0, 0);
|
||||
|
||||
/// <summary>
|
||||
/// The Y unit <see cref = "Int4" /> (0, 1, 0, 0).
|
||||
/// </summary>
|
||||
public static readonly Int4 UnitY = new Int4(0, 1, 0, 0);
|
||||
|
||||
/// <summary>
|
||||
/// The Z unit <see cref = "Int4" /> (0, 0, 1, 0).
|
||||
/// </summary>
|
||||
public static readonly Int4 UnitZ = new Int4(0, 0, 1, 0);
|
||||
|
||||
/// <summary>
|
||||
/// The W unit <see cref = "Int4" /> (0, 0, 0, 1).
|
||||
/// </summary>
|
||||
public static readonly Int4 UnitW = new Int4(0, 0, 0, 1);
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref = "Int4" /> with all of its components set to one.
|
||||
/// </summary>
|
||||
public static readonly Int4 One = new Int4(1, 1, 1, 1);
|
||||
|
||||
/// <summary>
|
||||
/// The X component of the vector.
|
||||
/// </summary>
|
||||
[DataMember( Order = 0 )]
|
||||
public int X;
|
||||
|
||||
/// <summary>
|
||||
/// The Y component of the vector.
|
||||
/// </summary>
|
||||
[DataMember( Order = 1 )]
|
||||
public int Y;
|
||||
|
||||
/// <summary>
|
||||
/// The Z component of the vector.
|
||||
/// </summary>
|
||||
[DataMember( Order = 2 )]
|
||||
public int Z;
|
||||
|
||||
/// <summary>
|
||||
/// The W component of the vector.
|
||||
/// </summary>
|
||||
[DataMember( Order = 3 )]
|
||||
public int W;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref = "Int4" /> struct.
|
||||
/// </summary>
|
||||
/// <param name = "value">The value that will be assigned to all components.</param>
|
||||
public Int4(int value)
|
||||
{
|
||||
X = value;
|
||||
Y = value;
|
||||
Z = value;
|
||||
W = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref = "Int4" /> struct.
|
||||
/// </summary>
|
||||
/// <param name = "x">Initial value for the X component of the vector.</param>
|
||||
/// <param name = "y">Initial value for the Y component of the vector.</param>
|
||||
/// <param name = "z">Initial value for the Z component of the vector.</param>
|
||||
/// <param name = "w">Initial value for the W component of the vector.</param>
|
||||
public Int4(int x, int y, int z, int w)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
Z = z;
|
||||
W = w;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref = "Int4" /> struct.
|
||||
/// </summary>
|
||||
/// <param name = "values">The values to assign to the X, Y, Z, and W components of the vector. This must be an array with four elements.</param>
|
||||
/// <exception cref = "ArgumentNullException">Thrown when <paramref name = "values" /> is <c>null</c>.</exception>
|
||||
/// <exception cref = "ArgumentOutOfRangeException">Thrown when <paramref name = "values" /> contains more or less than four elements.</exception>
|
||||
public Int4(int[] values)
|
||||
{
|
||||
if (values == null)
|
||||
throw new ArgumentNullException("values");
|
||||
if (values.Length != 4)
|
||||
throw new ArgumentOutOfRangeException("values", "There must be four and only four input values for Int4.");
|
||||
|
||||
X = values[0];
|
||||
Y = values[1];
|
||||
Z = values[2];
|
||||
W = values[3];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the component at the specified index.
|
||||
/// </summary>
|
||||
/// <value>The value of the X, Y, Z, or W component, depending on the index.</value>
|
||||
/// <param name = "index">The index of the component to access. Use 0 for the X component, 1 for the Y component, 2 for the Z component, and 3 for the W component.</param>
|
||||
/// <returns>The value of the component at the specified index.</returns>
|
||||
/// <exception cref = "System.ArgumentOutOfRangeException">Thrown when the <paramref name = "index" /> is out of the range [0, 3].</exception>
|
||||
public int this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
return X;
|
||||
case 1:
|
||||
return Y;
|
||||
case 2:
|
||||
return Z;
|
||||
case 3:
|
||||
return W;
|
||||
}
|
||||
|
||||
throw new ArgumentOutOfRangeException("index", "Indices for Int4 run from 0 to 3, inclusive.");
|
||||
}
|
||||
|
||||
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 ArgumentOutOfRangeException("index", "Indices for Int4 run from 0 to 3, inclusive.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the length of the vector.
|
||||
/// </summary>
|
||||
/// <returns>The length of the vector.</returns>
|
||||
/// <remarks>
|
||||
/// <see cref="Int4.LengthSquared"/> may be preferred when only the relative length is needed
|
||||
/// and speed is of the essence.
|
||||
/// </remarks>
|
||||
public int Length()
|
||||
{
|
||||
return (int)Math.Sqrt((X * X) + (Y * Y) + (Z * Z) + (W * W));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the squared length of the vector.
|
||||
/// </summary>
|
||||
/// <returns>The squared length of the vector.</returns>
|
||||
/// <remarks>
|
||||
/// This method may be preferred to <see cref="Int4.Length"/> when only a relative length is needed
|
||||
/// and speed is of the essence.
|
||||
/// </remarks>
|
||||
public int LengthSquared()
|
||||
{
|
||||
return (X * X) + (Y * Y) + (Z * Z) + (W * W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an array containing the elements of the vector.
|
||||
/// </summary>
|
||||
/// <returns>A four-element array containing the components of the vector.</returns>
|
||||
public int[] ToArray()
|
||||
{
|
||||
return new int[] { X, Y, Z, W };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds two vectors.
|
||||
/// </summary>
|
||||
/// <param name = "left">The first vector to add.</param>
|
||||
/// <param name = "right">The second vector to add.</param>
|
||||
/// <param name = "result">When the method completes, contains the sum of the two vectors.</param>
|
||||
public static void Add(ref Int4 left, ref Int4 right, out Int4 result)
|
||||
{
|
||||
result = new Int4(left.X + right.X, left.Y + right.Y, left.Z + right.Z, left.W + right.W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds two vectors.
|
||||
/// </summary>
|
||||
/// <param name = "left">The first vector to add.</param>
|
||||
/// <param name = "right">The second vector to add.</param>
|
||||
/// <returns>The sum of the two vectors.</returns>
|
||||
public static Int4 Add(Int4 left, Int4 right)
|
||||
{
|
||||
return new Int4(left.X + right.X, left.Y + right.Y, left.Z + right.Z, left.W + right.W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subtracts two vectors.
|
||||
/// </summary>
|
||||
/// <param name = "left">The first vector to subtract.</param>
|
||||
/// <param name = "right">The second vector to subtract.</param>
|
||||
/// <param name = "result">When the method completes, contains the difference of the two vectors.</param>
|
||||
public static void Subtract(ref Int4 left, ref Int4 right, out Int4 result)
|
||||
{
|
||||
result = new Int4(left.X - right.X, left.Y - right.Y, left.Z - right.Z, left.W - right.W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subtracts two vectors.
|
||||
/// </summary>
|
||||
/// <param name = "left">The first vector to subtract.</param>
|
||||
/// <param name = "right">The second vector to subtract.</param>
|
||||
/// <returns>The difference of the two vectors.</returns>
|
||||
public static Int4 Subtract(Int4 left, Int4 right)
|
||||
{
|
||||
return new Int4(left.X - right.X, left.Y - right.Y, left.Z - right.Z, left.W - right.W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scales a vector by the given value.
|
||||
/// </summary>
|
||||
/// <param name = "value">The vector to scale.</param>
|
||||
/// <param name = "scale">The amount by which to scale the vector.</param>
|
||||
/// <param name = "result">When the method completes, contains the scaled vector.</param>
|
||||
public static void Multiply(ref Int4 value, int scale, out Int4 result)
|
||||
{
|
||||
result = new Int4(value.X * scale, value.Y * scale, value.Z * scale, value.W * scale);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scales a vector by the given value.
|
||||
/// </summary>
|
||||
/// <param name = "value">The vector to scale.</param>
|
||||
/// <param name = "scale">The amount by which to scale the vector.</param>
|
||||
/// <returns>The scaled vector.</returns>
|
||||
public static Int4 Multiply(Int4 value, int scale)
|
||||
{
|
||||
return new Int4(value.X * scale, value.Y * scale, value.Z * scale, value.W * scale);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Modulates a vector with another by performing component-wise multiplication.
|
||||
/// </summary>
|
||||
/// <param name = "left">The first vector to modulate.</param>
|
||||
/// <param name = "right">The second vector to modulate.</param>
|
||||
/// <param name = "result">When the method completes, contains the modulated vector.</param>
|
||||
public static void Modulate(ref Int4 left, ref Int4 right, out Int4 result)
|
||||
{
|
||||
result = new Int4(left.X * right.X, left.Y * right.Y, left.Z * right.Z, left.W * right.W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Modulates a vector with another by performing component-wise multiplication.
|
||||
/// </summary>
|
||||
/// <param name = "left">The first vector to modulate.</param>
|
||||
/// <param name = "right">The second vector to modulate.</param>
|
||||
/// <returns>The modulated vector.</returns>
|
||||
public static Int4 Modulate(Int4 left, Int4 right)
|
||||
{
|
||||
return new Int4(left.X * right.X, left.Y * right.Y, left.Z * right.Z, left.W * right.W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scales a vector by the given value.
|
||||
/// </summary>
|
||||
/// <param name = "value">The vector to scale.</param>
|
||||
/// <param name = "scale">The amount by which to scale the vector.</param>
|
||||
/// <param name = "result">When the method completes, contains the scaled vector.</param>
|
||||
public static void Divide(ref Int4 value, int scale, out Int4 result)
|
||||
{
|
||||
result = new Int4(value.X / scale, value.Y / scale, value.Z / scale, value.W / scale);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scales a vector by the given value.
|
||||
/// </summary>
|
||||
/// <param name = "value">The vector to scale.</param>
|
||||
/// <param name = "scale">The amount by which to scale the vector.</param>
|
||||
/// <returns>The scaled vector.</returns>
|
||||
public static Int4 Divide(Int4 value, int scale)
|
||||
{
|
||||
return new Int4(value.X / scale, value.Y / scale, value.Z / scale, value.W / scale);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reverses the direction of a given vector.
|
||||
/// </summary>
|
||||
/// <param name = "value">The vector to negate.</param>
|
||||
/// <param name = "result">When the method completes, contains a vector facing in the opposite direction.</param>
|
||||
public static void Negate(ref Int4 value, out Int4 result)
|
||||
{
|
||||
result = new Int4(-value.X, -value.Y, -value.Z, -value.W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reverses the direction of a given vector.
|
||||
/// </summary>
|
||||
/// <param name = "value">The vector to negate.</param>
|
||||
/// <returns>A vector facing in the opposite direction.</returns>
|
||||
public static Int4 Negate(Int4 value)
|
||||
{
|
||||
return new Int4(-value.X, -value.Y, -value.Z, -value.W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restricts a value to be within a specified range.
|
||||
/// </summary>
|
||||
/// <param name = "value">The value to clamp.</param>
|
||||
/// <param name = "min">The minimum value.</param>
|
||||
/// <param name = "max">The maximum value.</param>
|
||||
/// <param name = "result">When the method completes, contains the clamped value.</param>
|
||||
public static void Clamp(ref Int4 value, ref Int4 min, ref Int4 max, out Int4 result)
|
||||
{
|
||||
int x = value.X;
|
||||
x = (x > max.X) ? max.X : x;
|
||||
x = (x < min.X) ? min.X : x;
|
||||
|
||||
int y = value.Y;
|
||||
y = (y > max.Y) ? max.Y : y;
|
||||
y = (y < min.Y) ? min.Y : y;
|
||||
|
||||
int z = value.Z;
|
||||
z = (z > max.Z) ? max.Z : z;
|
||||
z = (z < min.Z) ? min.Z : z;
|
||||
|
||||
int w = value.W;
|
||||
w = (w > max.W) ? max.W : w;
|
||||
w = (w < min.W) ? min.W : w;
|
||||
|
||||
result = new Int4(x, y, z, w);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restricts a value to be within a specified range.
|
||||
/// </summary>
|
||||
/// <param name = "value">The value to clamp.</param>
|
||||
/// <param name = "min">The minimum value.</param>
|
||||
/// <param name = "max">The maximum value.</param>
|
||||
/// <returns>The clamped value.</returns>
|
||||
public static Int4 Clamp(Int4 value, Int4 min, Int4 max)
|
||||
{
|
||||
Int4 result;
|
||||
Clamp(ref value, ref min, ref max, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a vector containing the smallest components of the specified vectors.
|
||||
/// </summary>
|
||||
/// <param name = "left">The first source vector.</param>
|
||||
/// <param name = "right">The second source vector.</param>
|
||||
/// <param name = "result">When the method completes, contains an new vector composed of the largest components of the source vectors.</param>
|
||||
public static void Max(ref Int4 left, ref Int4 right, out Int4 result)
|
||||
{
|
||||
result.X = (left.X > right.X) ? left.X : right.X;
|
||||
result.Y = (left.Y > right.Y) ? left.Y : right.Y;
|
||||
result.Z = (left.Z > right.Z) ? left.Z : right.Z;
|
||||
result.W = (left.W > right.W) ? left.W : right.W;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a vector containing the largest components of the specified vectors.
|
||||
/// </summary>
|
||||
/// <param name = "left">The first source vector.</param>
|
||||
/// <param name = "right">The second source vector.</param>
|
||||
/// <returns>A vector containing the largest components of the source vectors.</returns>
|
||||
public static Int4 Max(Int4 left, Int4 right)
|
||||
{
|
||||
Int4 result;
|
||||
Max(ref left, ref right, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a vector containing the smallest components of the specified vectors.
|
||||
/// </summary>
|
||||
/// <param name = "left">The first source vector.</param>
|
||||
/// <param name = "right">The second source vector.</param>
|
||||
/// <param name = "result">When the method completes, contains an new vector composed of the smallest components of the source vectors.</param>
|
||||
public static void Min(ref Int4 left, ref Int4 right, out Int4 result)
|
||||
{
|
||||
result.X = (left.X < right.X) ? left.X : right.X;
|
||||
result.Y = (left.Y < right.Y) ? left.Y : right.Y;
|
||||
result.Z = (left.Z < right.Z) ? left.Z : right.Z;
|
||||
result.W = (left.W < right.W) ? left.W : right.W;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a vector containing the smallest components of the specified vectors.
|
||||
/// </summary>
|
||||
/// <param name = "left">The first source vector.</param>
|
||||
/// <param name = "right">The second source vector.</param>
|
||||
/// <returns>A vector containing the smallest components of the source vectors.</returns>
|
||||
public static Int4 Min(Int4 left, Int4 right)
|
||||
{
|
||||
Int4 result;
|
||||
Min(ref left, ref right, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds two vectors.
|
||||
/// </summary>
|
||||
/// <param name = "left">The first vector to add.</param>
|
||||
/// <param name = "right">The second vector to add.</param>
|
||||
/// <returns>The sum of the two vectors.</returns>
|
||||
public static Int4 operator +(Int4 left, Int4 right)
|
||||
{
|
||||
return new Int4(left.X + right.X, left.Y + right.Y, left.Z + right.Z, left.W + right.W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assert a vector (return it unchanged).
|
||||
/// </summary>
|
||||
/// <param name = "value">The vector to assert (unchange).</param>
|
||||
/// <returns>The asserted (unchanged) vector.</returns>
|
||||
public static Int4 operator +(Int4 value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subtracts two vectors.
|
||||
/// </summary>
|
||||
/// <param name = "left">The first vector to subtract.</param>
|
||||
/// <param name = "right">The second vector to subtract.</param>
|
||||
/// <returns>The difference of the two vectors.</returns>
|
||||
public static Int4 operator -(Int4 left, Int4 right)
|
||||
{
|
||||
return new Int4(left.X - right.X, left.Y - right.Y, left.Z - right.Z, left.W - right.W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reverses the direction of a given vector.
|
||||
/// </summary>
|
||||
/// <param name = "value">The vector to negate.</param>
|
||||
/// <returns>A vector facing in the opposite direction.</returns>
|
||||
public static Int4 operator -(Int4 value)
|
||||
{
|
||||
return new Int4(-value.X, -value.Y, -value.Z, -value.W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scales a vector by the given value.
|
||||
/// </summary>
|
||||
/// <param name = "value">The vector to scale.</param>
|
||||
/// <param name = "scale">The amount by which to scale the vector.</param>
|
||||
/// <returns>The scaled vector.</returns>
|
||||
public static Int4 operator *(int scale, Int4 value)
|
||||
{
|
||||
return new Int4(value.X * scale, value.Y * scale, value.Z * scale, value.W * scale);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scales a vector by the given value.
|
||||
/// </summary>
|
||||
/// <param name = "value">The vector to scale.</param>
|
||||
/// <param name = "scale">The amount by which to scale the vector.</param>
|
||||
/// <returns>The scaled vector.</returns>
|
||||
public static Int4 operator *(Int4 value, int scale)
|
||||
{
|
||||
return new Int4(value.X * scale, value.Y * scale, value.Z * scale, value.W * scale);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scales a vector by the given value.
|
||||
/// </summary>
|
||||
/// <param name = "value">The vector to scale.</param>
|
||||
/// <param name = "scale">The amount by which to scale the vector.</param>
|
||||
/// <returns>The scaled vector.</returns>
|
||||
public static Int4 operator /(Int4 value, int scale)
|
||||
{
|
||||
return new Int4(value.X / scale, value.Y / scale, value.Z / scale, value.W / scale);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests for equality between two objects.
|
||||
/// </summary>
|
||||
/// <param name = "left">The first value to compare.</param>
|
||||
/// <param name = "right">The second value to compare.</param>
|
||||
/// <returns><c>true</c> if <paramref name = "left" /> has the same value as <paramref name = "right" />; otherwise, <c>false</c>.</returns>
|
||||
public static bool operator ==(Int4 left, Int4 right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests for inequality between two objects.
|
||||
/// </summary>
|
||||
/// <param name = "left">The first value to compare.</param>
|
||||
/// <param name = "right">The second value to compare.</param>
|
||||
/// <returns><c>true</c> if <paramref name = "left" /> has a different value than <paramref name = "right" />; otherwise, <c>false</c>.</returns>
|
||||
public static bool operator !=(Int4 left, Int4 right)
|
||||
{
|
||||
return !left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an explicit conversion from <see cref = "Int4" /> to <see cref = "Vec2" />.
|
||||
/// </summary>
|
||||
/// <param name = "value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static explicit operator Vec2(Int4 value)
|
||||
{
|
||||
return new Vec2(value.X, value.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an explicit conversion from <see cref = "Int4" /> to <see cref = "Vector3" />.
|
||||
/// </summary>
|
||||
/// <param name = "value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static explicit operator Vector3(Int4 value)
|
||||
{
|
||||
return new Vector3(value.X, value.Y, value.Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an explicit conversion from <see cref = "Int4" /> to <see cref = "Vector4" />.
|
||||
/// </summary>
|
||||
/// <param name = "value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static explicit operator Vector4(Int4 value)
|
||||
{
|
||||
return new Vector4(value.X, value.Y, value.Z, value.W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref = "string" /> that represents this instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref = "string" /> that represents this instance.
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, "X:{0} Y:{1} Z:{2} W:{3}", X, Y, Z, W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref = "string" /> that represents this instance.
|
||||
/// </summary>
|
||||
/// <param name = "format">The format.</param>
|
||||
/// <returns>
|
||||
/// A <see cref = "string" /> that represents this instance.
|
||||
/// </returns>
|
||||
public string ToString(string format)
|
||||
{
|
||||
if (format == null)
|
||||
return ToString();
|
||||
|
||||
return string.Format(CultureInfo.CurrentCulture, "X:{0} Y:{1} Z:{2} W:{3}",
|
||||
X.ToString(format, CultureInfo.CurrentCulture),
|
||||
Y.ToString(format, CultureInfo.CurrentCulture),
|
||||
Z.ToString(format, CultureInfo.CurrentCulture),
|
||||
W.ToString(format, CultureInfo.CurrentCulture));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref = "string" /> that represents this instance.
|
||||
/// </summary>
|
||||
/// <param name = "formatProvider">The format provider.</param>
|
||||
/// <returns>
|
||||
/// A <see cref = "string" /> that represents this instance.
|
||||
/// </returns>
|
||||
public string ToString(IFormatProvider formatProvider)
|
||||
{
|
||||
return string.Format(formatProvider, "X:{0} Y:{1} Z:{2} W:{3}", X, Y, Z, W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref = "string" /> that represents this instance.
|
||||
/// </summary>
|
||||
/// <param name = "format">The format.</param>
|
||||
/// <param name = "formatProvider">The format provider.</param>
|
||||
/// <returns>
|
||||
/// A <see cref = "string" /> that represents this instance.
|
||||
/// </returns>
|
||||
public string ToString(string format, IFormatProvider formatProvider)
|
||||
{
|
||||
if (format == null)
|
||||
ToString(formatProvider);
|
||||
|
||||
return string.Format(formatProvider, "X:{0} Y:{1} Z:{2} W:{3}", X.ToString(format, formatProvider),
|
||||
Y.ToString(format, formatProvider), Z.ToString(format, formatProvider),
|
||||
W.ToString(format, formatProvider));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a hash code for this instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
|
||||
/// </returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return X.GetHashCode() + Y.GetHashCode() + Z.GetHashCode() + W.GetHashCode();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref = "Int4" /> is equal to this instance.
|
||||
/// </summary>
|
||||
/// <param name = "other">The <see cref = "Int4" /> to compare with this instance.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the specified <see cref = "Int4" /> is equal to this instance; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public bool Equals(Int4 other)
|
||||
{
|
||||
return other.X == X && other.Y == Y && other.Z == Z && other.W == W;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref = "object" /> is equal to this instance.
|
||||
/// </summary>
|
||||
/// <param name = "value">The <see cref = "object" /> to compare with this instance.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the specified <see cref = "object" /> is equal to this instance; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
if (value == null)
|
||||
return false;
|
||||
|
||||
if (value.GetType() != GetType())
|
||||
return false;
|
||||
|
||||
return Equals((Int4)value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an implicit conversion from <see cref="int"/> array to <see cref="math.Int4"/>.
|
||||
/// </summary>
|
||||
/// <param name="input">The input.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator Int4(int[] input)
|
||||
{
|
||||
return new Int4(input);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an implicit conversion from <see cref="math.Int4"/> to <see cref="int"/> array.
|
||||
/// </summary>
|
||||
/// <param name="input">The input.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator int[](Int4 input)
|
||||
{
|
||||
return input.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
656
math/MathUtil.cs
Normal file
656
math/MathUtil.cs
Normal file
@ -0,0 +1,656 @@
|
||||
// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
|
||||
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// Original code from SlimMath project. http://code.google.com/p/slimmath/
|
||||
// Greetings to SlimDX Group. Original code published with the following license:
|
||||
// -----------------------------------------------------------------------------
|
||||
/*
|
||||
* Copyright (c) 2007-2011 SlimDX Group
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace math
|
||||
{
|
||||
/// <summary>
|
||||
/// Common utility methods for math operations.
|
||||
/// </summary>
|
||||
public static class MathUtil
|
||||
{
|
||||
/// <summary>
|
||||
/// The value for which all absolute numbers smaller than are considered equal to zero.
|
||||
/// </summary>
|
||||
public const float ZeroTolerance = 1e-6f; // Value a 8x higher than 1.19209290E-07F
|
||||
|
||||
/// <summary>
|
||||
/// The value for which all absolute numbers smaller than are considered equal to zero.
|
||||
/// </summary>
|
||||
public const double ZeroToleranceDouble = double.Epsilon * 8;
|
||||
|
||||
/// <summary>
|
||||
/// A value specifying the approximation of π which is 180 degrees.
|
||||
/// </summary>
|
||||
public const float Pi = (float)Math.PI;
|
||||
|
||||
/// <summary>
|
||||
/// A value specifying the approximation of 2π which is 360 degrees.
|
||||
/// </summary>
|
||||
public const float TwoPi = (float)(2 * Math.PI);
|
||||
|
||||
/// <summary>
|
||||
/// A value specifying the approximation of π/2 which is 90 degrees.
|
||||
/// </summary>
|
||||
public const float PiOverTwo = (float)(Math.PI / 2);
|
||||
|
||||
/// <summary>
|
||||
/// A value specifying the approximation of π/4 which is 45 degrees.
|
||||
/// </summary>
|
||||
public const float PiOverFour = (float)(Math.PI / 4);
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a and b are almost equals, taking into account the magnitude of floating point numbers (unlike <see cref="WithinEpsilon"/> method). See Remarks.
|
||||
/// See remarks.
|
||||
/// </summary>
|
||||
/// <param name="a">The left value to compare.</param>
|
||||
/// <param name="b">The right value to compare.</param>
|
||||
/// <returns><c>true</c> if a almost equal to b, <c>false</c> otherwise</returns>
|
||||
/// <remarks>
|
||||
/// The code is using the technique described by Bruce Dawson in
|
||||
/// <a href="http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/">Comparing Floating point numbers 2012 edition</a>.
|
||||
/// </remarks>
|
||||
public static unsafe bool NearEqual(float a, float b)
|
||||
{
|
||||
// Check if the numbers are really close -- needed
|
||||
// when comparing numbers near zero.
|
||||
if (IsZero(a - b))
|
||||
return true;
|
||||
|
||||
// Original from Bruce Dawson: http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
|
||||
int aInt = *(int*)&a;
|
||||
int bInt = *(int*)&b;
|
||||
|
||||
// Different signs means they do not match.
|
||||
if ((aInt < 0) != (bInt < 0))
|
||||
return false;
|
||||
|
||||
// Find the difference in ULPs.
|
||||
int ulp = Math.Abs(aInt - bInt);
|
||||
|
||||
// Choose of maxUlp = 4
|
||||
// according to http://code.google.com/p/googletest/source/browse/trunk/include/gtest/internal/gtest-internal.h
|
||||
const int maxUlp = 4;
|
||||
return (ulp <= maxUlp);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified value is close to zero (0.0f).
|
||||
/// </summary>
|
||||
/// <param name="a">The floating value.</param>
|
||||
/// <returns><c>true</c> if the specified value is close to zero (0.0f); otherwise, <c>false</c>.</returns>
|
||||
public static bool IsZero(float a)
|
||||
{
|
||||
return Math.Abs(a) < ZeroTolerance;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified value is close to zero (0.0f).
|
||||
/// </summary>
|
||||
/// <param name="a">The floating value.</param>
|
||||
/// <returns><c>true</c> if the specified value is close to zero (0.0f); otherwise, <c>false</c>.</returns>
|
||||
public static bool IsZero(double a)
|
||||
{
|
||||
return Math.Abs(a) < ZeroToleranceDouble;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified value is close to one (1.0f).
|
||||
/// </summary>
|
||||
/// <param name="a">The floating value.</param>
|
||||
/// <returns><c>true</c> if the specified value is close to one (1.0f); otherwise, <c>false</c>.</returns>
|
||||
public static bool IsOne(float a)
|
||||
{
|
||||
return IsZero(a - 1.0f);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a - b are almost equals within a float epsilon.
|
||||
/// </summary>
|
||||
/// <param name="a">The left value to compare.</param>
|
||||
/// <param name="b">The right value to compare.</param>
|
||||
/// <param name="epsilon">Epsilon value</param>
|
||||
/// <returns><c>true</c> if a almost equal to b within a float epsilon, <c>false</c> otherwise</returns>
|
||||
public static bool WithinEpsilon(float a, float b, float epsilon)
|
||||
{
|
||||
float num = a - b;
|
||||
return ((-epsilon <= num) && (num <= epsilon));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a one-dimensional array of the specified <typeparamref name="T"/> and <paramref name="length"/> filled with the specified <paramref name="value"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The Type of the array to create.</typeparam>
|
||||
/// <param name="value">The value to fill the array with.</param>
|
||||
/// <param name="length">The size of the array to create.</param>
|
||||
/// <returns>A new one-dimensional array of the specified type with the specified length and filled with the specified value.</returns>
|
||||
public static T[] Array<T>(T value, int length)
|
||||
{
|
||||
var result = new T[length];
|
||||
for (var i = 0; i < length; i++)
|
||||
result[i] = value;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts revolutions to degrees.
|
||||
/// </summary>
|
||||
/// <param name="revolution">The value to convert.</param>
|
||||
/// <returns>The converted value.</returns>
|
||||
public static float RevolutionsToDegrees(float revolution)
|
||||
{
|
||||
return revolution * 360.0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts revolutions to radians.
|
||||
/// </summary>
|
||||
/// <param name="revolution">The value to convert.</param>
|
||||
/// <returns>The converted value.</returns>
|
||||
public static float RevolutionsToRadians(float revolution)
|
||||
{
|
||||
return revolution * TwoPi;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts revolutions to gradians.
|
||||
/// </summary>
|
||||
/// <param name="revolution">The value to convert.</param>
|
||||
/// <returns>The converted value.</returns>
|
||||
public static float RevolutionsToGradians(float revolution)
|
||||
{
|
||||
return revolution * 400.0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts degrees to revolutions.
|
||||
/// </summary>
|
||||
/// <param name="degree">The value to convert.</param>
|
||||
/// <returns>The converted value.</returns>
|
||||
public static float DegreesToRevolutions(float degree)
|
||||
{
|
||||
return degree / 360.0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts degrees to radians.
|
||||
/// </summary>
|
||||
/// <param name="degree">The value to convert.</param>
|
||||
/// <returns>The converted value.</returns>
|
||||
public static float DegreesToRadians(float degree)
|
||||
{
|
||||
return degree * (Pi / 180.0f);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts radians to revolutions.
|
||||
/// </summary>
|
||||
/// <param name="radian">The value to convert.</param>
|
||||
/// <returns>The converted value.</returns>
|
||||
public static float RadiansToRevolutions(float radian)
|
||||
{
|
||||
return radian / TwoPi;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts radians to gradians.
|
||||
/// </summary>
|
||||
/// <param name="radian">The value to convert.</param>
|
||||
/// <returns>The converted value.</returns>
|
||||
public static float RadiansToGradians(float radian)
|
||||
{
|
||||
return radian * (200.0f / Pi);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts gradians to revolutions.
|
||||
/// </summary>
|
||||
/// <param name="gradian">The value to convert.</param>
|
||||
/// <returns>The converted value.</returns>
|
||||
public static float GradiansToRevolutions(float gradian)
|
||||
{
|
||||
return gradian / 400.0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts gradians to degrees.
|
||||
/// </summary>
|
||||
/// <param name="gradian">The value to convert.</param>
|
||||
/// <returns>The converted value.</returns>
|
||||
public static float GradiansToDegrees(float gradian)
|
||||
{
|
||||
return gradian * (9.0f / 10.0f);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts gradians to radians.
|
||||
/// </summary>
|
||||
/// <param name="gradian">The value to convert.</param>
|
||||
/// <returns>The converted value.</returns>
|
||||
public static float GradiansToRadians(float gradian)
|
||||
{
|
||||
return gradian * (Pi / 200.0f);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts radians to degrees.
|
||||
/// </summary>
|
||||
/// <param name="radian">The value to convert.</param>
|
||||
/// <returns>The converted value.</returns>
|
||||
public static float RadiansToDegrees(float radian)
|
||||
{
|
||||
return radian * (180.0f / Pi);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clamps the specified value.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <param name="min">The min.</param>
|
||||
/// <param name="max">The max.</param>
|
||||
/// <returns>The result of clamping a value between min and max</returns>
|
||||
public static float Clamp(float value, float min, float max)
|
||||
{
|
||||
return value < min ? min : value > max ? max : value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clamps the specified value.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <param name="min">The min.</param>
|
||||
/// <param name="max">The max.</param>
|
||||
/// <returns>The result of clamping a value between min and max</returns>
|
||||
public static double Clamp(double value, double min, double max)
|
||||
{
|
||||
return value < min ? min : value > max ? max : value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clamps the specified value.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <param name="min">The min.</param>
|
||||
/// <param name="max">The max.</param>
|
||||
/// <returns>The result of clamping a value between min and max</returns>
|
||||
public static int Clamp(int value, int min, int max)
|
||||
{
|
||||
return value < min ? min : value > max ? max : value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inverse-interpolates a value linearly.
|
||||
/// </summary>
|
||||
/// <param name="min">Minimum value that takes place in inverse-interpolation.</param>
|
||||
/// <param name="max">Maximum value that takes place in inverse-interpolation.</param>
|
||||
/// <param name="value">Value to get inverse interpolation.</param>
|
||||
/// <returns>Returns an inverse-linearly interpolated coeficient.</returns>
|
||||
public static float InverseLerp(float min, float max, float value)
|
||||
{
|
||||
if (IsZero(Math.Abs(max - min)))
|
||||
return float.NaN;
|
||||
return (value - min) / (max - min);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Inverse-interpolates a value linearly.
|
||||
/// </summary>
|
||||
/// <param name="min">Minimum value that takes place in inverse-interpolation.</param>
|
||||
/// <param name="max">Maximum value that takes place in inverse-interpolation.</param>
|
||||
/// <param name="value">Value to get inverse interpolation.</param>
|
||||
/// <returns>Returns an inverse-linearly interpolated coeficient.</returns>
|
||||
public static double InverseLerp(double min, double max, double value)
|
||||
{
|
||||
if (IsZero(Math.Abs(max - min)))
|
||||
return double.NaN;
|
||||
return (value - min) / (max - min);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Interpolates between two values using a linear function by a given amount.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// See http://www.encyclopediaofmath.org/index.php/Linear_interpolation and
|
||||
/// http://fgiesen.wordpress.com/2012/08/15/linear-interpolation-past-present-and-future/
|
||||
/// </remarks>
|
||||
/// <param name="from">Value to interpolate from.</param>
|
||||
/// <param name="to">Value to interpolate to.</param>
|
||||
/// <param name="amount">Interpolation amount.</param>
|
||||
/// <returns>The result of linear interpolation of values based on the amount.</returns>
|
||||
public static double Lerp(double from, double to, double amount)
|
||||
{
|
||||
return (1 - amount) * from + amount * to;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Interpolates between two values using a linear function by a given amount.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// See http://www.encyclopediaofmath.org/index.php/Linear_interpolation and
|
||||
/// http://fgiesen.wordpress.com/2012/08/15/linear-interpolation-past-present-and-future/
|
||||
/// </remarks>
|
||||
/// <param name="from">Value to interpolate from.</param>
|
||||
/// <param name="to">Value to interpolate to.</param>
|
||||
/// <param name="amount">Interpolation amount.</param>
|
||||
/// <returns>The result of linear interpolation of values based on the amount.</returns>
|
||||
public static float Lerp(float from, float to, float amount)
|
||||
{
|
||||
return (1 - amount) * from + amount * to;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Interpolates between two values using a linear function by a given amount.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// See http://www.encyclopediaofmath.org/index.php/Linear_interpolation and
|
||||
/// http://fgiesen.wordpress.com/2012/08/15/linear-interpolation-past-present-and-future/
|
||||
/// </remarks>
|
||||
/// <param name="from">Value to interpolate from.</param>
|
||||
/// <param name="to">Value to interpolate to.</param>
|
||||
/// <param name="amount">Interpolation amount.</param>
|
||||
/// <returns>The result of linear interpolation of values based on the amount.</returns>
|
||||
public static byte Lerp(byte from, byte to, float amount)
|
||||
{
|
||||
return (byte)Lerp((float)from, (float)to, amount);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs smooth (cubic Hermite) interpolation between 0 and 1.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// See https://en.wikipedia.org/wiki/Smoothstep
|
||||
/// </remarks>
|
||||
/// <param name="amount">Value between 0 and 1 indicating interpolation amount.</param>
|
||||
public static float SmoothStep(float amount)
|
||||
{
|
||||
return (amount <= 0) ? 0
|
||||
: (amount >= 1) ? 1
|
||||
: amount * amount * (3 - (2 * amount));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs a smooth(er) interpolation between 0 and 1 with 1st and 2nd order derivatives of zero at endpoints.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// See https://en.wikipedia.org/wiki/Smoothstep
|
||||
/// </remarks>
|
||||
/// <param name="amount">Value between 0 and 1 indicating interpolation amount.</param>
|
||||
public static float SmootherStep(float amount)
|
||||
{
|
||||
return (amount <= 0) ? 0
|
||||
: (amount >= 1) ? 1
|
||||
: amount * amount * amount * (amount * ((amount * 6) - 15) + 10);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the value is inside the given range (inclusively).
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <param name="min">The minimum value of the range.</param>
|
||||
/// <param name="max">The maximum value of the range.</param>
|
||||
/// <returns><c>true</c> if value is inside the specified range; otherwise, <c>false</c>.</returns>
|
||||
public static bool IsInRange(float value, float min, float max)
|
||||
{
|
||||
return min <= value && value <= max;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the value is inside the given range (inclusively).
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <param name="min">The minimum value of the range.</param>
|
||||
/// <param name="max">The maximum value of the range.</param>
|
||||
/// <returns><c>true</c> if value is inside the specified range; otherwise, <c>false</c>.</returns>
|
||||
public static bool IsInRange(int value, int min, int max)
|
||||
{
|
||||
return min <= value && value <= max;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified x is pow2.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <returns><c>true</c> if the specified x is pow2; otherwise, <c>false</c>.</returns>
|
||||
public static bool IsPow2(int x)
|
||||
{
|
||||
return ((x != 0) && (x & (x - 1)) == 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a float value from sRGB to linear.
|
||||
/// </summary>
|
||||
/// <param name="sRgbValue">The sRGB value.</param>
|
||||
/// <returns>A linear value.</returns>
|
||||
public static float SRgbToLinear(float sRgbValue)
|
||||
{
|
||||
if (sRgbValue < 0.04045f) return sRgbValue / 12.92f;
|
||||
return (float)Math.Pow((sRgbValue + 0.055) / 1.055, 2.4);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts a float value from linear to sRGB.
|
||||
/// </summary>
|
||||
/// <param name="linearValue">The linear value.</param>
|
||||
/// <returns>The encoded sRGB value.</returns>
|
||||
public static float LinearToSRgb(float linearValue)
|
||||
{
|
||||
if (linearValue < 0.0031308f) return linearValue * 12.92f;
|
||||
return (float)(1.055 * Math.Pow(linearValue, 1 / 2.4) - 0.055);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculate the logarithm 2 of a floating point.
|
||||
/// </summary>
|
||||
/// <param name="x">The input float</param>
|
||||
/// <returns><value>Log2(x)</value></returns>
|
||||
public static float Log2(float x)
|
||||
{
|
||||
return (float)Math.Log(x) / 0.6931471805599453f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculate the logarithm 2 of an integer.
|
||||
/// </summary>
|
||||
/// <param name="i">The input integer</param>
|
||||
/// <returns><value>the log2(i) rounded to lower integer</value></returns>
|
||||
public static int Log2(int i)
|
||||
{
|
||||
var r = 0;
|
||||
|
||||
while ((i >>= 1) != 0)
|
||||
++r;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the next power of two of an integer.
|
||||
/// </summary>
|
||||
/// <param name="x">The size.</param>
|
||||
/// <returns>System.Int32.</returns>
|
||||
/// <remarks>https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2</remarks>
|
||||
public static int NextPowerOfTwo(int x)
|
||||
{
|
||||
if (x < 0)
|
||||
return 0;
|
||||
|
||||
x--;
|
||||
x |= x >> 1;
|
||||
x |= x >> 2;
|
||||
x |= x >> 4;
|
||||
x |= x >> 8;
|
||||
x |= x >> 16;
|
||||
return x + 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the next power of two for a size.
|
||||
/// </summary>
|
||||
/// <param name="size">The size.</param>
|
||||
/// <returns>System.Int32.</returns>
|
||||
public static float NextPowerOfTwo(float size)
|
||||
{
|
||||
return (float)Math.Pow(2, Math.Ceiling(Math.Log(size, 2)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the previous power of two of the provided integer.
|
||||
/// </summary>
|
||||
/// <param name="size">The value</param>
|
||||
public static int PreviousPowerOfTwo(int size)
|
||||
{
|
||||
return 1 << (int)Math.Floor(Math.Log(size, 2));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the previous power of two of the provided float.
|
||||
/// </summary>
|
||||
/// <param name="size">The value</param>
|
||||
public static float PreviousPowerOfTwo(float size)
|
||||
{
|
||||
return (float)Math.Pow(2, Math.Floor(Math.Log(size, 2)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Alignes value up to match desire alignment.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <param name="alignment">The alignment.</param>
|
||||
/// <returns>Aligned value (multiple of alignment).</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int AlignUp(int value, int alignment)
|
||||
{
|
||||
int mask = alignment - 1;
|
||||
return (value + mask) & ~mask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Alignes value down to match desire alignment.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <param name="alignment">The alignment.</param>
|
||||
/// <returns>Aligned value (multiple of alignment).</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int AlignDown(int value, int alignment)
|
||||
{
|
||||
int mask = alignment - 1;
|
||||
return value & ~mask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified value is aligned.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <param name="alignment">The alignment.</param>
|
||||
/// <returns><c>true</c> if the specified value is aligned; otherwise, <c>false</c>.</returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool IsAligned(int value, int alignment)
|
||||
{
|
||||
return (value & (alignment - 1)) == 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Snaps a value to the nearest interval.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to snap.</param>
|
||||
/// <param name="gap">The interval gap.</param>
|
||||
/// <returns>The nearest interval to the provided value.</returns>
|
||||
public static float Snap(float value, float gap)
|
||||
{
|
||||
if (gap == 0)
|
||||
return value;
|
||||
return (float)Math.Round((value / gap), MidpointRounding.AwayFromZero) * gap;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Snaps a value to the nearest interval.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to snap.</param>
|
||||
/// <param name="gap">The interval gap.</param>
|
||||
/// <returns>The nearest interval to the provided value.</returns>
|
||||
public static double Snap(double value, double gap)
|
||||
{
|
||||
if (gap == 0)
|
||||
return value;
|
||||
return Math.Round((value / gap), MidpointRounding.AwayFromZero) * gap;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Snaps all vector components to the nearest interval.
|
||||
/// </summary>
|
||||
/// <param name="value">The vector to snap.</param>
|
||||
/// <param name="gap">The interval gap.</param>
|
||||
/// <returns>A vector which components are snapped to the nearest interval.</returns>
|
||||
public static Vec2 Snap(Vec2 value, float gap)
|
||||
{
|
||||
if (gap == 0)
|
||||
return value;
|
||||
return new Vec2(
|
||||
(float)Math.Round((value.X / gap), MidpointRounding.AwayFromZero) * gap,
|
||||
(float)Math.Round((value.Y / gap), MidpointRounding.AwayFromZero) * gap);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Snaps all vector components to the nearest interval.
|
||||
/// </summary>
|
||||
/// <param name="value">The vector to snap.</param>
|
||||
/// <param name="gap">The interval gap.</param>
|
||||
/// <returns>A vector which components are snapped to the nearest interval.</returns>
|
||||
public static Vector3 Snap(Vector3 value, float gap)
|
||||
{
|
||||
if (gap == 0)
|
||||
return value;
|
||||
return new Vector3(
|
||||
(float)Math.Round((value.X / gap), MidpointRounding.AwayFromZero) * gap,
|
||||
(float)Math.Round((value.Y / gap), MidpointRounding.AwayFromZero) * gap,
|
||||
(float)Math.Round((value.Z / gap), MidpointRounding.AwayFromZero) * gap);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Snaps all vector components to the nearest interval.
|
||||
/// </summary>
|
||||
/// <param name="value">The vector to snap.</param>
|
||||
/// <param name="gap">The interval gap.</param>
|
||||
/// <returns>A vector which components are snapped to the nearest interval.</returns>
|
||||
public static Vector4 Snap(Vector4 value, float gap)
|
||||
{
|
||||
if (gap == 0)
|
||||
return value;
|
||||
return new Vector4(
|
||||
(float)Math.Round((value.X / gap), MidpointRounding.AwayFromZero) * gap,
|
||||
(float)Math.Round((value.Y / gap), MidpointRounding.AwayFromZero) * gap,
|
||||
(float)Math.Round((value.Z / gap), MidpointRounding.AwayFromZero) * gap,
|
||||
(float)Math.Round((value.W / gap), MidpointRounding.AwayFromZero) * gap);
|
||||
}
|
||||
}
|
||||
}
|
||||
3482
math/Matrix.cs
Normal file
3482
math/Matrix.cs
Normal file
File diff suppressed because it is too large
Load Diff
22
math/Module.cs
Normal file
22
math/Module.cs
Normal file
@ -0,0 +1,22 @@
|
||||
// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
|
||||
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
|
||||
using System.Reflection;
|
||||
using Xenko.Core.Reflection;
|
||||
|
||||
namespace math
|
||||
{
|
||||
/// <summary>
|
||||
/// Module initializer.
|
||||
/// </summary>
|
||||
internal class Module
|
||||
{
|
||||
/// <summary>
|
||||
/// Module initializer.
|
||||
/// </summary>
|
||||
[ModuleInitializer]
|
||||
public static void Initialize()
|
||||
{
|
||||
AssemblyRegistry.Register(typeof(Module).GetTypeInfo().Assembly, AssemblyCommonCategories.Assets);
|
||||
}
|
||||
}
|
||||
}
|
||||
12
math/NamespaceDoc.cs
Normal file
12
math/NamespaceDoc.cs
Normal file
@ -0,0 +1,12 @@
|
||||
// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
|
||||
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
|
||||
namespace math
|
||||
{
|
||||
/// <summary>
|
||||
/// The <see cref="math"/> namespace contains types that allows to manipulate mathematical objects, such as vectors, points, quaternions, planes, etc.
|
||||
/// </summary>
|
||||
[System.Runtime.CompilerServices.CompilerGenerated]
|
||||
internal class NamespaceDoc
|
||||
{
|
||||
}
|
||||
}
|
||||
838
math/Plane.cs
Normal file
838
math/Plane.cs
Normal file
@ -0,0 +1,838 @@
|
||||
// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
|
||||
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// Original code from SlimMath project. http://code.google.com/p/slimmath/
|
||||
// Greetings to SlimDX Group. Original code published with the following license:
|
||||
// -----------------------------------------------------------------------------
|
||||
/*
|
||||
* Copyright (c) 2007-2011 SlimDX Group
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace math
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a plane in three dimensional space.
|
||||
/// </summary>
|
||||
[DataContract]
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
||||
public struct Plane : IEquatable<Plane>, IFormattable
|
||||
{
|
||||
/// <summary>
|
||||
/// The normal vector of the plane.
|
||||
/// </summary>
|
||||
public Vector3 Normal;
|
||||
|
||||
/// <summary>
|
||||
/// The distance of the plane along its normal from the origin.
|
||||
/// </summary>
|
||||
public float D;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="math.Plane"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="value">The value that will be assigned to all components.</param>
|
||||
public Plane(float value)
|
||||
{
|
||||
Normal.X = Normal.Y = Normal.Z = D = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="math.Plane"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="a">The X component of the normal.</param>
|
||||
/// <param name="b">The Y component of the normal.</param>
|
||||
/// <param name="c">The Z component of the normal.</param>
|
||||
/// <param name="d">The distance of the plane along its normal from the origin.</param>
|
||||
public Plane(float a, float b, float c, float d)
|
||||
{
|
||||
Normal.X = a;
|
||||
Normal.Y = b;
|
||||
Normal.Z = c;
|
||||
D = d;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Plane"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="point">Any point that lies along the plane.</param>
|
||||
/// <param name="normal">The normal vector to the plane.</param>
|
||||
public Plane(Vector3 point, Vector3 normal)
|
||||
{
|
||||
this.Normal = normal;
|
||||
this.D = Vector3.Dot(normal, point);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="math.Plane"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="value">The normal of the plane.</param>
|
||||
/// <param name="d">The distance of the plane along its normal from the origin</param>
|
||||
public Plane(Vector3 value, float d)
|
||||
{
|
||||
Normal = value;
|
||||
D = d;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="math.Plane"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="point1">First point of a triangle defining the plane.</param>
|
||||
/// <param name="point2">Second point of a triangle defining the plane.</param>
|
||||
/// <param name="point3">Third point of a triangle defining the plane.</param>
|
||||
public Plane(Vector3 point1, Vector3 point2, Vector3 point3)
|
||||
{
|
||||
float x1 = point2.X - point1.X;
|
||||
float y1 = point2.Y - point1.Y;
|
||||
float z1 = point2.Z - point1.Z;
|
||||
float x2 = point3.X - point1.X;
|
||||
float y2 = point3.Y - point1.Y;
|
||||
float z2 = point3.Z - point1.Z;
|
||||
float yz = (y1 * z2) - (z1 * y2);
|
||||
float xz = (z1 * x2) - (x1 * z2);
|
||||
float xy = (x1 * y2) - (y1 * x2);
|
||||
float invPyth = 1.0f / (float)(Math.Sqrt((yz * yz) + (xz * xz) + (xy * xy)));
|
||||
|
||||
Normal.X = yz * invPyth;
|
||||
Normal.Y = xz * invPyth;
|
||||
Normal.Z = xy * invPyth;
|
||||
D = -((Normal.X * point1.X) + (Normal.Y * point1.Y) + (Normal.Z * point1.Z));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="math.Plane"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="values">The values to assign to the A, B, C, and D components of the plane. This must be an array with four elements.</param>
|
||||
/// <exception cref="ArgumentNullException">Thrown when <paramref name="values"/> is <c>null</c>.</exception>
|
||||
/// <exception cref="ArgumentOutOfRangeException">Thrown when <paramref name="values"/> contains more or less than four elements.</exception>
|
||||
public Plane(float[] values)
|
||||
{
|
||||
if (values == null)
|
||||
throw new ArgumentNullException("values");
|
||||
if (values.Length != 4)
|
||||
throw new ArgumentOutOfRangeException("values", "There must be four and only four input values for Plane.");
|
||||
|
||||
Normal.X = values[0];
|
||||
Normal.Y = values[1];
|
||||
Normal.Z = values[2];
|
||||
D = values[3];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the component at the specified index.
|
||||
/// </summary>
|
||||
/// <value>The value of the A, B, C, or D component, depending on the index.</value>
|
||||
/// <param name="index">The index of the component to access. Use 0 for the A component, 1 for the B component, 2 for the C component, and 3 for the D component.</param>
|
||||
/// <returns>The value of the component at the specified index.</returns>
|
||||
/// <exception cref="System.ArgumentOutOfRangeException">Thrown when the <paramref name="index"/> is out of the range [0, 3].</exception>
|
||||
public float this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0: return Normal.X;
|
||||
case 1: return Normal.Y;
|
||||
case 2: return Normal.Z;
|
||||
case 3: return D;
|
||||
}
|
||||
|
||||
throw new ArgumentOutOfRangeException("index", "Indices for Plane run from 0 to 3, inclusive.");
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0: Normal.X = value; break;
|
||||
case 1: Normal.Y = value; break;
|
||||
case 2: Normal.Z = value; break;
|
||||
case 3: D = value; break;
|
||||
default: throw new ArgumentOutOfRangeException("index", "Indices for Plane run from 0 to 3, inclusive.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Negates a plane by negating all its coefficients, which result in a plane in opposite direction.
|
||||
/// </summary>
|
||||
public void Negate()
|
||||
{
|
||||
Normal.X = -Normal.X;
|
||||
Normal.Y = -Normal.Y;
|
||||
Normal.Z = -Normal.Z;
|
||||
D = -D;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes the coefficients of the normal vector of the plane to make it of unit length.
|
||||
/// </summary>
|
||||
public void Normalize()
|
||||
{
|
||||
float magnitude = 1.0f / (float)(Math.Sqrt((Normal.X * Normal.X) + (Normal.Y * Normal.Y) + (Normal.Z * Normal.Z)));
|
||||
|
||||
Normal.X *= magnitude;
|
||||
Normal.Y *= magnitude;
|
||||
Normal.Z *= magnitude;
|
||||
D *= magnitude;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an array containing the elements of the plane.
|
||||
/// </summary>
|
||||
/// <returns>A four-element array containing the components of the plane.</returns>
|
||||
public float[] ToArray()
|
||||
{
|
||||
return new float[] { Normal.X, Normal.Y, Normal.Z, D };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if there is an intersection between the current object and a point.
|
||||
/// </summary>
|
||||
/// <param name="point">The point to test.</param>
|
||||
/// <returns>Whether the two objects intersected.</returns>
|
||||
public PlaneIntersectionType Intersects(ref Vector3 point)
|
||||
{
|
||||
return CollisionHelper.PlaneIntersectsPoint(ref this, ref point);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if there is an intersection between the current object and a <see cref="math.Ray"/>.
|
||||
/// </summary>
|
||||
/// <param name="ray">The ray to test.</param>
|
||||
/// <returns>Whether the two objects intersected.</returns>
|
||||
public bool Intersects(ref Ray ray)
|
||||
{
|
||||
float distance;
|
||||
return CollisionHelper.RayIntersectsPlane(ref ray, ref this, out distance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if there is an intersection between the current object and a <see cref="math.Ray"/>.
|
||||
/// </summary>
|
||||
/// <param name="ray">The ray to test.</param>
|
||||
/// <param name="distance">When the method completes, contains the distance of the intersection,
|
||||
/// or 0 if there was no intersection.</param>
|
||||
/// <returns>Whether the two objects intersected.</returns>
|
||||
public bool Intersects(ref Ray ray, out float distance)
|
||||
{
|
||||
return CollisionHelper.RayIntersectsPlane(ref ray, ref this, out distance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if there is an intersection between the current object and a <see cref="math.Ray"/>.
|
||||
/// </summary>
|
||||
/// <param name="ray">The ray to test.</param>
|
||||
/// <param name="point">When the method completes, contains the point of intersection,
|
||||
/// or <see cref="math.Vector3.Zero"/> if there was no intersection.</param>
|
||||
/// <returns>Whether the two objects intersected.</returns>
|
||||
public bool Intersects(ref Ray ray, out Vector3 point)
|
||||
{
|
||||
return CollisionHelper.RayIntersectsPlane(ref ray, ref this, out point);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if there is an intersection between the current object and a <see cref="math.Plane"/>.
|
||||
/// </summary>
|
||||
/// <param name="plane">The plane to test.</param>
|
||||
/// <returns>Whether the two objects intersected.</returns>
|
||||
public bool Intersects(ref Plane plane)
|
||||
{
|
||||
return CollisionHelper.PlaneIntersectsPlane(ref this, ref plane);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if there is an intersection between the current object and a <see cref="math.Plane"/>.
|
||||
/// </summary>
|
||||
/// <param name="plane">The plane to test.</param>
|
||||
/// <param name="line">When the method completes, contains the line of intersection
|
||||
/// as a <see cref="math.Ray"/>, or a zero ray if there was no intersection.</param>
|
||||
/// <returns>Whether the two objects intersected.</returns>
|
||||
public bool Intersects(ref Plane plane, out Ray line)
|
||||
{
|
||||
return CollisionHelper.PlaneIntersectsPlane(ref this, ref plane, out line);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if there is an intersection between the current object and a triangle.
|
||||
/// </summary>
|
||||
/// <param name="vertex1">The first vertex of the triangle to test.</param>
|
||||
/// <param name="vertex2">The second vertex of the triagnle to test.</param>
|
||||
/// <param name="vertex3">The third vertex of the triangle to test.</param>
|
||||
/// <returns>Whether the two objects intersected.</returns>
|
||||
public PlaneIntersectionType Intersects(ref Vector3 vertex1, ref Vector3 vertex2, ref Vector3 vertex3)
|
||||
{
|
||||
return CollisionHelper.PlaneIntersectsTriangle(ref this, ref vertex1, ref vertex2, ref vertex3);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if there is an intersection between the current object and a <see cref="math.BoundingBox"/>.
|
||||
/// </summary>
|
||||
/// <param name="box">The box to test.</param>
|
||||
/// <returns>Whether the two objects intersected.</returns>
|
||||
public PlaneIntersectionType Intersects(ref BoundingBox box)
|
||||
{
|
||||
return CollisionHelper.PlaneIntersectsBox(ref this, ref box);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if there is an intersection between the current object and a <see cref="math.BoundingSphere"/>.
|
||||
/// </summary>
|
||||
/// <param name="sphere">The sphere to test.</param>
|
||||
/// <returns>Whether the two objects intersected.</returns>
|
||||
public PlaneIntersectionType Intersects(ref BoundingSphere sphere)
|
||||
{
|
||||
return CollisionHelper.PlaneIntersectsSphere(ref this, ref sphere);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scales the plane by the given scaling factor.
|
||||
/// </summary>
|
||||
/// <param name="value">The plane to scale.</param>
|
||||
/// <param name="scale">The amount by which to scale the plane.</param>
|
||||
/// <param name="result">When the method completes, contains the scaled plane.</param>
|
||||
public static void Multiply(ref Plane value, float scale, out Plane result)
|
||||
{
|
||||
result.Normal.X = value.Normal.X * scale;
|
||||
result.Normal.Y = value.Normal.Y * scale;
|
||||
result.Normal.Z = value.Normal.Z * scale;
|
||||
result.D = value.D * scale;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scales the plane by the given scaling factor.
|
||||
/// </summary>
|
||||
/// <param name="value">The plane to scale.</param>
|
||||
/// <param name="scale">The amount by which to scale the plane.</param>
|
||||
/// <returns>The scaled plane.</returns>
|
||||
public static Plane Multiply(Plane value, float scale)
|
||||
{
|
||||
return new Plane(value.Normal.X * scale, value.Normal.Y * scale, value.Normal.Z * scale, value.D * scale);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the dot product of the specified vector and plane.
|
||||
/// </summary>
|
||||
/// <param name="left">The source plane.</param>
|
||||
/// <param name="right">The source vector.</param>
|
||||
/// <param name="result">When the method completes, contains the dot product of the specified plane and vector.</param>
|
||||
public static void Dot(ref Plane left, ref Vector4 right, out float result)
|
||||
{
|
||||
result = (left.Normal.X * right.X) + (left.Normal.Y * right.Y) + (left.Normal.Z * right.Z) + (left.D * right.W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the dot product of the specified vector and plane.
|
||||
/// </summary>
|
||||
/// <param name="left">The source plane.</param>
|
||||
/// <param name="right">The source vector.</param>
|
||||
/// <returns>The dot product of the specified plane and vector.</returns>
|
||||
public static float Dot(Plane left, Vector4 right)
|
||||
{
|
||||
return (left.Normal.X * right.X) + (left.Normal.Y * right.Y) + (left.Normal.Z * right.Z) + (left.D * right.W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the dot product of a specified vector and the normal of the plane plus the distance value of the plane.
|
||||
/// </summary>
|
||||
/// <param name="left">The source plane.</param>
|
||||
/// <param name="right">The source vector.</param>
|
||||
/// <param name="result">When the method completes, contains the dot product of a specified vector and the normal of the Plane plus the distance value of the plane.</param>
|
||||
public static void DotCoordinate(ref Plane left, ref Vector3 right, out float result)
|
||||
{
|
||||
result = (left.Normal.X * right.X) + (left.Normal.Y * right.Y) + (left.Normal.Z * right.Z) + left.D;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the dot product of a specified vector and the normal of the plane plus the distance value of the plane.
|
||||
/// </summary>
|
||||
/// <param name="left">The source plane.</param>
|
||||
/// <param name="right">The source vector.</param>
|
||||
/// <returns>The dot product of a specified vector and the normal of the Plane plus the distance value of the plane.</returns>
|
||||
public static float DotCoordinate(Plane left, Vector3 right)
|
||||
{
|
||||
return (left.Normal.X * right.X) + (left.Normal.Y * right.Y) + (left.Normal.Z * right.Z) + left.D;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the dot product of the specified vector and the normal of the plane.
|
||||
/// </summary>
|
||||
/// <param name="left">The source plane.</param>
|
||||
/// <param name="right">The source vector.</param>
|
||||
/// <param name="result">When the method completes, contains the dot product of the specified vector and the normal of the plane.</param>
|
||||
public static void DotNormal(ref Plane left, ref Vector3 right, out float result)
|
||||
{
|
||||
result = (left.Normal.X * right.X) + (left.Normal.Y * right.Y) + (left.Normal.Z * right.Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the dot product of the specified vector and the normal of the plane.
|
||||
/// </summary>
|
||||
/// <param name="left">The source plane.</param>
|
||||
/// <param name="right">The source vector.</param>
|
||||
/// <returns>The dot product of the specified vector and the normal of the plane.</returns>
|
||||
public static float DotNormal(Plane left, Vector3 right)
|
||||
{
|
||||
return (left.Normal.X * right.X) + (left.Normal.Y * right.Y) + (left.Normal.Z * right.Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Projects a point onto a plane.
|
||||
/// </summary>
|
||||
/// <param name="plane">The plane to project the point to.</param>
|
||||
/// <param name="point">The point to project.</param>
|
||||
/// <param name="result">The projected point.</param>
|
||||
public static void Project(ref Plane plane, ref Vector3 point, out Vector3 result)
|
||||
{
|
||||
float distance;
|
||||
DotCoordinate(ref plane, ref point, out distance);
|
||||
|
||||
// compute: point - distance * plane.Normal
|
||||
Vector3.Multiply(ref plane.Normal, distance, out result);
|
||||
Vector3.Subtract(ref point, ref result, out result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Projects a point onto a plane.
|
||||
/// </summary>
|
||||
/// <param name="plane">The plane to project the point to.</param>
|
||||
/// <param name="point">The point to project.</param>
|
||||
/// <returns>The projected point.</returns>
|
||||
public static Vector3 Project(Plane plane, Vector3 point)
|
||||
{
|
||||
Vector3 result;
|
||||
Project(ref plane, ref point, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes the coefficients of the normal vector of the plane to make it of unit length.
|
||||
/// </summary>
|
||||
/// <param name="plane">The source plane.</param>
|
||||
/// <param name="result">When the method completes, contains the normalized plane.</param>
|
||||
public static void Normalize(ref Plane plane, out Plane result)
|
||||
{
|
||||
float magnitude = 1.0f / (float)(Math.Sqrt((plane.Normal.X * plane.Normal.X) + (plane.Normal.Y * plane.Normal.Y) + (plane.Normal.Z * plane.Normal.Z)));
|
||||
|
||||
result.Normal.X = plane.Normal.X * magnitude;
|
||||
result.Normal.Y = plane.Normal.Y * magnitude;
|
||||
result.Normal.Z = plane.Normal.Z * magnitude;
|
||||
result.D = plane.D * magnitude;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Changes the coefficients of the normal vector of the plane to make it of unit length.
|
||||
/// </summary>
|
||||
/// <param name="plane">The source plane.</param>
|
||||
/// <returns>The normalized plane.</returns>
|
||||
public static Plane Normalize(Plane plane)
|
||||
{
|
||||
float magnitude = 1.0f / (float)(Math.Sqrt((plane.Normal.X * plane.Normal.X) + (plane.Normal.Y * plane.Normal.Y) + (plane.Normal.Z * plane.Normal.Z)));
|
||||
return new Plane(plane.Normal.X * magnitude, plane.Normal.Y * magnitude, plane.Normal.Z * magnitude, plane.D * magnitude);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Negates a plane by negating all its coefficients, which result in a plane in opposite direction.
|
||||
/// </summary>
|
||||
/// <param name="plane">The source plane.</param>
|
||||
/// <param name="result">When the method completes, contains the flipped plane.</param>
|
||||
public static void Negate(ref Plane plane, out Plane result)
|
||||
{
|
||||
result.Normal.X = -plane.Normal.X;
|
||||
result.Normal.Y = -plane.Normal.Y;
|
||||
result.Normal.Z = -plane.Normal.Z;
|
||||
result.D = -plane.D;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Negates a plane by negating all its coefficients, which result in a plane in opposite direction.
|
||||
/// </summary>
|
||||
/// <param name="plane">The source plane.</param>
|
||||
/// <returns>The flipped plane.</returns>
|
||||
public static Plane Negate(Plane plane)
|
||||
{
|
||||
float magnitude = 1.0f / (float)(Math.Sqrt((plane.Normal.X * plane.Normal.X) + (plane.Normal.Y * plane.Normal.Y) + (plane.Normal.Z * plane.Normal.Z)));
|
||||
return new Plane(plane.Normal.X * magnitude, plane.Normal.Y * magnitude, plane.Normal.Z * magnitude, plane.D * magnitude);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transforms a normalized plane by a quaternion rotation.
|
||||
/// </summary>
|
||||
/// <param name="plane">The normalized source plane.</param>
|
||||
/// <param name="rotation">The quaternion rotation.</param>
|
||||
/// <param name="result">When the method completes, contains the transformed plane.</param>
|
||||
public static void Transform(ref Plane plane, ref Quaternion rotation, out Plane result)
|
||||
{
|
||||
float x2 = rotation.X + rotation.X;
|
||||
float y2 = rotation.Y + rotation.Y;
|
||||
float z2 = rotation.Z + rotation.Z;
|
||||
float wx = rotation.W * x2;
|
||||
float wy = rotation.W * y2;
|
||||
float wz = rotation.W * z2;
|
||||
float xx = rotation.X * x2;
|
||||
float xy = rotation.X * y2;
|
||||
float xz = rotation.X * z2;
|
||||
float yy = rotation.Y * y2;
|
||||
float yz = rotation.Y * z2;
|
||||
float zz = rotation.Z * z2;
|
||||
|
||||
float x = plane.Normal.X;
|
||||
float y = plane.Normal.Y;
|
||||
float z = plane.Normal.Z;
|
||||
|
||||
result.Normal.X = ((x * ((1.0f - yy) - zz)) + (y * (xy - wz))) + (z * (xz + wy));
|
||||
result.Normal.Y = ((x * (xy + wz)) + (y * ((1.0f - xx) - zz))) + (z * (yz - wx));
|
||||
result.Normal.Z = ((x * (xz - wy)) + (y * (yz + wx))) + (z * ((1.0f - xx) - yy));
|
||||
result.D = plane.D;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transforms a normalized plane by a quaternion rotation.
|
||||
/// </summary>
|
||||
/// <param name="plane">The normalized source plane.</param>
|
||||
/// <param name="rotation">The quaternion rotation.</param>
|
||||
/// <returns>The transformed plane.</returns>
|
||||
public static Plane Transform(Plane plane, Quaternion rotation)
|
||||
{
|
||||
Plane result;
|
||||
float x2 = rotation.X + rotation.X;
|
||||
float y2 = rotation.Y + rotation.Y;
|
||||
float z2 = rotation.Z + rotation.Z;
|
||||
float wx = rotation.W * x2;
|
||||
float wy = rotation.W * y2;
|
||||
float wz = rotation.W * z2;
|
||||
float xx = rotation.X * x2;
|
||||
float xy = rotation.X * y2;
|
||||
float xz = rotation.X * z2;
|
||||
float yy = rotation.Y * y2;
|
||||
float yz = rotation.Y * z2;
|
||||
float zz = rotation.Z * z2;
|
||||
|
||||
float x = plane.Normal.X;
|
||||
float y = plane.Normal.Y;
|
||||
float z = plane.Normal.Z;
|
||||
|
||||
result.Normal.X = ((x * ((1.0f - yy) - zz)) + (y * (xy - wz))) + (z * (xz + wy));
|
||||
result.Normal.Y = ((x * (xy + wz)) + (y * ((1.0f - xx) - zz))) + (z * (yz - wx));
|
||||
result.Normal.Z = ((x * (xz - wy)) + (y * (yz + wx))) + (z * ((1.0f - xx) - yy));
|
||||
result.D = plane.D;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transforms an array of normalized planes by a quaternion rotation.
|
||||
/// </summary>
|
||||
/// <param name="planes">The array of normalized planes to transform.</param>
|
||||
/// <param name="rotation">The quaternion rotation.</param>
|
||||
/// <exception cref="ArgumentNullException">Thrown when <paramref name="planes"/> is <c>null</c>.</exception>
|
||||
public static void Transform(Plane[] planes, ref Quaternion rotation)
|
||||
{
|
||||
if (planes == null)
|
||||
throw new ArgumentNullException("planes");
|
||||
|
||||
float x2 = rotation.X + rotation.X;
|
||||
float y2 = rotation.Y + rotation.Y;
|
||||
float z2 = rotation.Z + rotation.Z;
|
||||
float wx = rotation.W * x2;
|
||||
float wy = rotation.W * y2;
|
||||
float wz = rotation.W * z2;
|
||||
float xx = rotation.X * x2;
|
||||
float xy = rotation.X * y2;
|
||||
float xz = rotation.X * z2;
|
||||
float yy = rotation.Y * y2;
|
||||
float yz = rotation.Y * z2;
|
||||
float zz = rotation.Z * z2;
|
||||
|
||||
for (int i = 0; i < planes.Length; ++i)
|
||||
{
|
||||
float x = planes[i].Normal.X;
|
||||
float y = planes[i].Normal.Y;
|
||||
float z = planes[i].Normal.Z;
|
||||
|
||||
/*
|
||||
* Note:
|
||||
* Factor common arithmetic out of loop.
|
||||
*/
|
||||
planes[i].Normal.X = ((x * ((1.0f - yy) - zz)) + (y * (xy - wz))) + (z * (xz + wy));
|
||||
planes[i].Normal.Y = ((x * (xy + wz)) + (y * ((1.0f - xx) - zz))) + (z * (yz - wx));
|
||||
planes[i].Normal.Z = ((x * (xz - wy)) + (y * (yz + wx))) + (z * ((1.0f - xx) - yy));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transforms a normalized plane by a matrix.
|
||||
/// </summary>
|
||||
/// <param name="plane">The normalized source plane.</param>
|
||||
/// <param name="transformation">The transformation matrix.</param>
|
||||
/// <param name="result">When the method completes, contains the transformed plane.</param>
|
||||
public static void Transform(ref Plane plane, ref Matrix transformation, out Plane result)
|
||||
{
|
||||
float x = plane.Normal.X;
|
||||
float y = plane.Normal.Y;
|
||||
float z = plane.Normal.Z;
|
||||
float d = plane.D;
|
||||
|
||||
Matrix inverse;
|
||||
Matrix.Invert(ref transformation, out inverse);
|
||||
|
||||
result.Normal.X = (((x * inverse.M11) + (y * inverse.M12)) + (z * inverse.M13)) + (d * inverse.M14);
|
||||
result.Normal.Y = (((x * inverse.M21) + (y * inverse.M22)) + (z * inverse.M23)) + (d * inverse.M24);
|
||||
result.Normal.Z = (((x * inverse.M31) + (y * inverse.M32)) + (z * inverse.M33)) + (d * inverse.M34);
|
||||
result.D = (((x * inverse.M41) + (y * inverse.M42)) + (z * inverse.M43)) + (d * inverse.M44);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transforms a normalized plane by a matrix.
|
||||
/// </summary>
|
||||
/// <param name="plane">The normalized source plane.</param>
|
||||
/// <param name="transformation">The transformation matrix.</param>
|
||||
/// <returns>When the method completes, contains the transformed plane.</returns>
|
||||
public static Plane Transform(Plane plane, Matrix transformation)
|
||||
{
|
||||
Plane result;
|
||||
float x = plane.Normal.X;
|
||||
float y = plane.Normal.Y;
|
||||
float z = plane.Normal.Z;
|
||||
float d = plane.D;
|
||||
|
||||
transformation.Invert();
|
||||
result.Normal.X = (((x * transformation.M11) + (y * transformation.M12)) + (z * transformation.M13)) + (d * transformation.M14);
|
||||
result.Normal.Y = (((x * transformation.M21) + (y * transformation.M22)) + (z * transformation.M23)) + (d * transformation.M24);
|
||||
result.Normal.Z = (((x * transformation.M31) + (y * transformation.M32)) + (z * transformation.M33)) + (d * transformation.M34);
|
||||
result.D = (((x * transformation.M41) + (y * transformation.M42)) + (z * transformation.M43)) + (d * transformation.M44);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Transforms an array of normalized planes by a matrix.
|
||||
/// </summary>
|
||||
/// <param name="planes">The array of normalized planes to transform.</param>
|
||||
/// <param name="transformation">The transformation matrix.</param>
|
||||
/// <exception cref="ArgumentNullException">Thrown when <paramref name="planes"/> is <c>null</c>.</exception>
|
||||
public static void Transform(Plane[] planes, ref Matrix transformation)
|
||||
{
|
||||
if (planes == null)
|
||||
throw new ArgumentNullException("planes");
|
||||
|
||||
Matrix inverse;
|
||||
Matrix.Invert(ref transformation, out inverse);
|
||||
|
||||
for (int i = 0; i < planes.Length; ++i)
|
||||
{
|
||||
Transform(ref planes[i], ref transformation, out planes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scales a plane by the given value.
|
||||
/// </summary>
|
||||
/// <param name="scale">The amount by which to scale the plane.</param>
|
||||
/// <param name="plane">The plane to scale.</param>
|
||||
/// <returns>The scaled plane.</returns>
|
||||
public static Plane operator *(float scale, Plane plane)
|
||||
{
|
||||
return new Plane(plane.Normal.X * scale, plane.Normal.Y * scale, plane.Normal.Z * scale, plane.D * scale);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scales a plane by the given value.
|
||||
/// </summary>
|
||||
/// <param name="plane">The plane to scale.</param>
|
||||
/// <param name="scale">The amount by which to scale the plane.</param>
|
||||
/// <returns>The scaled plane.</returns>
|
||||
public static Plane operator *(Plane plane, float scale)
|
||||
{
|
||||
return new Plane(plane.Normal.X * scale, plane.Normal.Y * scale, plane.Normal.Z * scale, plane.D * scale);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Negates a plane by negating all its coefficients, which result in a plane in opposite direction.
|
||||
/// </summary>
|
||||
/// <returns>The negated plane.</returns>
|
||||
public static Plane operator -(Plane plane)
|
||||
{
|
||||
return new Plane(-plane.Normal.X, -plane.Normal.Y, -plane.Normal.Z, -plane.D);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests for equality between two objects.
|
||||
/// </summary>
|
||||
/// <param name="left">The first value to compare.</param>
|
||||
/// <param name="right">The second value to compare.</param>
|
||||
/// <returns><c>true</c> if <paramref name="left"/> has the same value as <paramref name="right"/>; otherwise, <c>false</c>.</returns>
|
||||
public static bool operator ==(Plane left, Plane right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests for inequality between two objects.
|
||||
/// </summary>
|
||||
/// <param name="left">The first value to compare.</param>
|
||||
/// <param name="right">The second value to compare.</param>
|
||||
/// <returns><c>true</c> if <paramref name="left"/> has a different value than <paramref name="right"/>; otherwise, <c>false</c>.</returns>
|
||||
public static bool operator !=(Plane left, Plane right)
|
||||
{
|
||||
return !left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="string"/> that represents this instance.
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, "A:{0} B:{1} C:{2} D:{3}", Normal.X, Normal.Y, Normal.Z, D);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <param name="format">The format.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="string"/> that represents this instance.
|
||||
/// </returns>
|
||||
public string ToString(string format)
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, "A:{0} B:{1} C:{2} D:{3}", Normal.X.ToString(format, CultureInfo.CurrentCulture),
|
||||
Normal.Y.ToString(format, CultureInfo.CurrentCulture), Normal.Z.ToString(format, CultureInfo.CurrentCulture), D.ToString(format, CultureInfo.CurrentCulture));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <param name="formatProvider">The format provider.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="string"/> that represents this instance.
|
||||
/// </returns>
|
||||
public string ToString(IFormatProvider formatProvider)
|
||||
{
|
||||
return string.Format(formatProvider, "A:{0} B:{1} C:{2} D:{3}", Normal.X, Normal.Y, Normal.Z, D);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <param name="format">The format.</param>
|
||||
/// <param name="formatProvider">The format provider.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="string"/> that represents this instance.
|
||||
/// </returns>
|
||||
public string ToString(string format, IFormatProvider formatProvider)
|
||||
{
|
||||
return string.Format(formatProvider, "A:{0} B:{1} C:{2} D:{3}", Normal.X.ToString(format, formatProvider),
|
||||
Normal.Y.ToString(format, formatProvider), Normal.Z.ToString(format, formatProvider), D.ToString(format, formatProvider));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a hash code for this instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
|
||||
/// </returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Normal.GetHashCode() + D.GetHashCode();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="math.Vector4"/> is equal to this instance.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="math.Vector4"/> to compare with this instance.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the specified <see cref="math.Vector4"/> is equal to this instance; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public bool Equals(Plane value)
|
||||
{
|
||||
return Normal == value.Normal && D == value.D;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="object"/> is equal to this instance.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="object"/> to compare with this instance.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the specified <see cref="object"/> is equal to this instance; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
if (value == null)
|
||||
return false;
|
||||
|
||||
if (value.GetType() != GetType())
|
||||
return false;
|
||||
|
||||
return Equals((Plane)value);
|
||||
}
|
||||
|
||||
#if SlimDX1xInterop
|
||||
/// <summary>
|
||||
/// Performs an implicit conversion from <see cref="math.Plane"/> to <see cref="SlimDX.Plane"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator SlimDX.Plane(Plane value)
|
||||
{
|
||||
return new SlimDX.Plane(value.Normal, value.D);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an implicit conversion from <see cref="SlimDX.Plane"/> to <see cref="math.Plane"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator Plane(SlimDX.Plane value)
|
||||
{
|
||||
return new Plane(value.Normal, value.D);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if XnaInterop
|
||||
/// <summary>
|
||||
/// Performs an implicit conversion from <see cref="math.Plane"/> to <see cref="Microsoft.Xna.Framework.Plane"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator Microsoft.Xna.Framework.Plane(Plane value)
|
||||
{
|
||||
return new Microsoft.Xna.Framework.Plane(value.Normal, value.D);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an implicit conversion from <see cref="Microsoft.Xna.Framework.Plane"/> to <see cref="math.Plane"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator Plane(Microsoft.Xna.Framework.Plane value)
|
||||
{
|
||||
return new Plane(value.Normal, value.D);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
57
math/PlaneIntersectionType.cs
Normal file
57
math/PlaneIntersectionType.cs
Normal file
@ -0,0 +1,57 @@
|
||||
// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
|
||||
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// Original code from SlimMath project. http://code.google.com/p/slimmath/
|
||||
// Greetings to SlimDX Group. Original code published with the following license:
|
||||
// -----------------------------------------------------------------------------
|
||||
/*
|
||||
* Copyright (c) 2007-2011 SlimDX Group
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
namespace math
|
||||
{
|
||||
/*
|
||||
* The enumerations defined in this file are in alphabetical order. When
|
||||
* adding new enumerations or renaming existing ones, please make sure
|
||||
* the ordering is maintained.
|
||||
*/
|
||||
|
||||
/// <summary>
|
||||
/// Describes the result of an intersection with a plane in three dimensions.
|
||||
/// </summary>
|
||||
public enum PlaneIntersectionType
|
||||
{
|
||||
/// <summary>
|
||||
/// The object is behind the plane.
|
||||
/// </summary>
|
||||
Back,
|
||||
|
||||
/// <summary>
|
||||
/// The object is in front of the plane.
|
||||
/// </summary>
|
||||
Front,
|
||||
|
||||
/// <summary>
|
||||
/// The object is intersecting the plane.
|
||||
/// </summary>
|
||||
Intersecting,
|
||||
}
|
||||
}
|
||||
147
math/Point.cs
Normal file
147
math/Point.cs
Normal file
@ -0,0 +1,147 @@
|
||||
// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
|
||||
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
|
||||
//
|
||||
// Copyright (c) 2010-2013 SharpDX - Alexandre Mutel
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Xenko.Core.Serialization;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace math
|
||||
{
|
||||
/// <summary>
|
||||
/// A 2D point.
|
||||
/// </summary>
|
||||
[DataContract]
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
||||
public struct Point : IEquatable<Point>
|
||||
{
|
||||
/// <summary>
|
||||
/// A point with (0,0) coordinates.
|
||||
/// </summary>
|
||||
public static readonly Point Zero = new Point(0, 0);
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Point"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="x">The x.</param>
|
||||
/// <param name="y">The y.</param>
|
||||
public Point(int x, int y)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Left coordinate.
|
||||
/// </summary>
|
||||
[DataMember( Order = 0 )]
|
||||
public int X;
|
||||
|
||||
/// <summary>
|
||||
/// Top coordinate.
|
||||
/// </summary>
|
||||
[DataMember( Order = 1 )]
|
||||
public int Y;
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="object"/> is equal to this instance.
|
||||
/// </summary>
|
||||
/// <param name="other">The <see cref="object"/> to compare with this instance.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the specified <see cref="object"/> is equal to this instance; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public bool Equals(Point other)
|
||||
{
|
||||
return other.X == X && other.Y == Y;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj)) return false;
|
||||
if (obj.GetType() != typeof(Point)) return false;
|
||||
return Equals((Point)obj);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
return (X * 397) ^ Y;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements the operator ==.
|
||||
/// </summary>
|
||||
/// <param name="left">The left.</param>
|
||||
/// <param name="right">The right.</param>
|
||||
/// <returns>
|
||||
/// The result of the operator.
|
||||
/// </returns>
|
||||
public static bool operator ==(Point left, Point right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements the operator !=.
|
||||
/// </summary>
|
||||
/// <param name="left">The left.</param>
|
||||
/// <param name="right">The right.</param>
|
||||
/// <returns>
|
||||
/// The result of the operator.
|
||||
/// </returns>
|
||||
public static bool operator !=(Point left, Point right)
|
||||
{
|
||||
return !left.Equals(right);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("({0},{1})", X, Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an implicit conversion from <see cref="Vec2"/> to <see cref="Point"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static explicit operator Point(Vec2 value)
|
||||
{
|
||||
return new Point((int)value.X, (int)value.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an explicit conversion from <see cref="Point"/> to <see cref="Vec2"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator Vec2(Point value)
|
||||
{
|
||||
return new Vec2(value.X, value.Y);
|
||||
}
|
||||
}
|
||||
}
|
||||
8
math/Properties/AssemblyInfo.cs
Normal file
8
math/Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,8 @@
|
||||
// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
|
||||
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
#pragma warning disable 436 // Xenko.PublicKeys is defined in multiple assemblies
|
||||
|
||||
[assembly: InternalsVisibleTo("math.Serializers" + Xenko.PublicKeys.Default)]
|
||||
1424
math/Quaternion.cs
Normal file
1424
math/Quaternion.cs
Normal file
File diff suppressed because it is too large
Load Diff
61
math/RandomSeed.cs
Normal file
61
math/RandomSeed.cs
Normal file
@ -0,0 +1,61 @@
|
||||
// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
|
||||
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
|
||||
|
||||
// Random numbers which also allow creation of random values in the shaders and are deterministic
|
||||
// Based on this article:
|
||||
// http://martindevans.me/game-development/2015/02/22/Random-Gibberish/
|
||||
|
||||
using System;
|
||||
|
||||
namespace math
|
||||
{
|
||||
/// <summary>
|
||||
/// The <see cref="RandomSeed"/> is a structure for deterministically acquiring random values.
|
||||
/// One <see cref="RandomSeed"/> should be able to reproduce the same pseudo-random value for a fixed offset, but
|
||||
/// provide enough random distribution for different offsets or different random seeds
|
||||
/// Although other methods exist, the current implementation can easily be replicated in the shaders if required
|
||||
/// </summary>
|
||||
public struct RandomSeed
|
||||
{
|
||||
private const double GelfondConst = 23.1406926327792690; // e to the power of Pi = (-1) to the power of -i
|
||||
private const double GelfondSchneiderConst = 2.6651441426902251; // 2 to the power of sqrt(2)
|
||||
private const double Numerator = 123456789;
|
||||
|
||||
// When casting uint to double it works fine, but when casting it to float it might cause underflow errors (loss of precision)
|
||||
// We want to limit the maximum settable value to prevent such errors.
|
||||
private const uint UnderflowGuard = 0xFFFF;
|
||||
|
||||
private readonly uint seed;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RandomSeed"/> struct from a target uint.
|
||||
/// </summary>
|
||||
/// <param name="seed">The seed value to initialize the deterministic random generator.</param>
|
||||
public RandomSeed(uint seed)
|
||||
{
|
||||
this.seed = (seed & UnderflowGuard);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a deterministic double value between 0 and 1 based on the seed
|
||||
/// </summary>
|
||||
/// <returns>Deterministic pseudo-random value between 0 and 1</returns>
|
||||
public double GetDouble(uint offset)
|
||||
{
|
||||
var dRand = (double)(unchecked(seed + offset)); // We want it to overflow
|
||||
|
||||
var dotProduct = Math.Cos(dRand) * GelfondConst + Math.Sin(dRand) * GelfondSchneiderConst;
|
||||
var denominator = 1e-7 + 256 * dotProduct;
|
||||
var remainder = Numerator % denominator;
|
||||
|
||||
return (remainder - Math.Floor(remainder));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a deterministic float value between 0 and 1 based on the seed
|
||||
/// The calculations are still made as doubles to prevent underflow errors.
|
||||
/// </summary>
|
||||
/// <returns>Deterministic pseudo-random value between 0 and 1</returns>
|
||||
public float GetFloat(uint offset) => (float)GetDouble(offset);
|
||||
}
|
||||
}
|
||||
400
math/Ray.cs
Normal file
400
math/Ray.cs
Normal file
@ -0,0 +1,400 @@
|
||||
// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
|
||||
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// Original code from SlimMath project. http://code.google.com/p/slimmath/
|
||||
// Greetings to SlimDX Group. Original code published with the following license:
|
||||
// -----------------------------------------------------------------------------
|
||||
/*
|
||||
* Copyright (c) 2007-2011 SlimDX Group
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace math
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a three dimensional line based on a point in space and a direction.
|
||||
/// </summary>
|
||||
[DataContract]
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
||||
public struct Ray : IEquatable<Ray>, IFormattable
|
||||
{
|
||||
/// <summary>
|
||||
/// The position in three dimensional space where the ray starts.
|
||||
/// </summary>
|
||||
public Vector3 Position;
|
||||
|
||||
/// <summary>
|
||||
/// The normalized direction in which the ray points.
|
||||
/// </summary>
|
||||
public Vector3 Direction;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="math.Ray"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="position">The position in three dimensional space of the origin of the ray.</param>
|
||||
/// <param name="direction">The normalized direction of the ray.</param>
|
||||
public Ray(Vector3 position, Vector3 direction)
|
||||
{
|
||||
this.Position = position;
|
||||
this.Direction = direction;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if there is an intersection between the current object and a point.
|
||||
/// </summary>
|
||||
/// <param name="point">The point to test.</param>
|
||||
/// <returns>Whether the two objects intersected.</returns>
|
||||
public bool Intersects(ref Vector3 point)
|
||||
{
|
||||
return CollisionHelper.RayIntersectsPoint(ref this, ref point);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if there is an intersection between the current object and a <see cref="math.Ray"/>.
|
||||
/// </summary>
|
||||
/// <param name="ray">The ray to test.</param>
|
||||
/// <returns>Whether the two objects intersected.</returns>
|
||||
public bool Intersects(ref Ray ray)
|
||||
{
|
||||
Vector3 point;
|
||||
return CollisionHelper.RayIntersectsRay(ref this, ref ray, out point);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if there is an intersection between the current object and a <see cref="math.Ray"/>.
|
||||
/// </summary>
|
||||
/// <param name="ray">The ray to test.</param>
|
||||
/// <param name="point">When the method completes, contains the point of intersection,
|
||||
/// or <see cref="math.Vector3.Zero"/> if there was no intersection.</param>
|
||||
/// <returns>Whether the two objects intersected.</returns>
|
||||
public bool Intersects(ref Ray ray, out Vector3 point)
|
||||
{
|
||||
return CollisionHelper.RayIntersectsRay(ref this, ref ray, out point);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if there is an intersection between the current object and a <see cref="math.Plane"/>.
|
||||
/// </summary>
|
||||
/// <param name="plane">The plane to test</param>
|
||||
/// <returns>Whether the two objects intersected.</returns>
|
||||
public bool Intersects(ref Plane plane)
|
||||
{
|
||||
float distance;
|
||||
return CollisionHelper.RayIntersectsPlane(ref this, ref plane, out distance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if there is an intersection between the current object and a <see cref="math.Plane"/>.
|
||||
/// </summary>
|
||||
/// <param name="plane">The plane to test.</param>
|
||||
/// <param name="distance">When the method completes, contains the distance of the intersection,
|
||||
/// or 0 if there was no intersection.</param>
|
||||
/// <returns>Whether the two objects intersected.</returns>
|
||||
public bool Intersects(ref Plane plane, out float distance)
|
||||
{
|
||||
return CollisionHelper.RayIntersectsPlane(ref this, ref plane, out distance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if there is an intersection between the current object and a <see cref="math.Plane"/>.
|
||||
/// </summary>
|
||||
/// <param name="plane">The plane to test.</param>
|
||||
/// <param name="point">When the method completes, contains the point of intersection,
|
||||
/// or <see cref="math.Vector3.Zero"/> if there was no intersection.</param>
|
||||
/// <returns>Whether the two objects intersected.</returns>
|
||||
public bool Intersects(ref Plane plane, out Vector3 point)
|
||||
{
|
||||
return CollisionHelper.RayIntersectsPlane(ref this, ref plane, out point);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if there is an intersection between the current object and a triangle.
|
||||
/// </summary>
|
||||
/// <param name="vertex1">The first vertex of the triangle to test.</param>
|
||||
/// <param name="vertex2">The second vertex of the triangle to test.</param>
|
||||
/// <param name="vertex3">The third vertex of the triangle to test.</param>
|
||||
/// <returns>Whether the two objects intersected.</returns>
|
||||
public bool Intersects(ref Vector3 vertex1, ref Vector3 vertex2, ref Vector3 vertex3)
|
||||
{
|
||||
float distance;
|
||||
return CollisionHelper.RayIntersectsTriangle(ref this, ref vertex1, ref vertex2, ref vertex3, out distance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if there is an intersection between the current object and a triangle.
|
||||
/// </summary>
|
||||
/// <param name="vertex1">The first vertex of the triangle to test.</param>
|
||||
/// <param name="vertex2">The second vertex of the triangle to test.</param>
|
||||
/// <param name="vertex3">The third vertex of the triangle to test.</param>
|
||||
/// <param name="distance">When the method completes, contains the distance of the intersection,
|
||||
/// or 0 if there was no intersection.</param>
|
||||
/// <returns>Whether the two objects intersected.</returns>
|
||||
public bool Intersects(ref Vector3 vertex1, ref Vector3 vertex2, ref Vector3 vertex3, out float distance)
|
||||
{
|
||||
return CollisionHelper.RayIntersectsTriangle(ref this, ref vertex1, ref vertex2, ref vertex3, out distance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if there is an intersection between the current object and a triangle.
|
||||
/// </summary>
|
||||
/// <param name="vertex1">The first vertex of the triangle to test.</param>
|
||||
/// <param name="vertex2">The second vertex of the triangle to test.</param>
|
||||
/// <param name="vertex3">The third vertex of the triangle to test.</param>
|
||||
/// <param name="point">When the method completes, contains the point of intersection,
|
||||
/// or <see cref="math.Vector3.Zero"/> if there was no intersection.</param>
|
||||
/// <returns>Whether the two objects intersected.</returns>
|
||||
public bool Intersects(ref Vector3 vertex1, ref Vector3 vertex2, ref Vector3 vertex3, out Vector3 point)
|
||||
{
|
||||
return CollisionHelper.RayIntersectsTriangle(ref this, ref vertex1, ref vertex2, ref vertex3, out point);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if there is an intersection between the current object and a <see cref="math.BoundingBox"/>.
|
||||
/// </summary>
|
||||
/// <param name="box">The box to test.</param>
|
||||
/// <returns>Whether the two objects intersected.</returns>
|
||||
public bool Intersects(ref BoundingBox box)
|
||||
{
|
||||
float distance;
|
||||
return CollisionHelper.RayIntersectsBox(ref this, ref box, out distance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if there is an intersection between the current object and a <see cref="math.BoundingBox"/>.
|
||||
/// </summary>
|
||||
/// <param name="box">The box to test.</param>
|
||||
/// <param name="distance">When the method completes, contains the distance of the intersection,
|
||||
/// or 0 if there was no intersection.</param>
|
||||
/// <returns>Whether the two objects intersected.</returns>
|
||||
public bool Intersects(ref BoundingBox box, out float distance)
|
||||
{
|
||||
return CollisionHelper.RayIntersectsBox(ref this, ref box, out distance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if there is an intersection between the current object and a <see cref="math.BoundingBox"/>.
|
||||
/// </summary>
|
||||
/// <param name="box">The box to test.</param>
|
||||
/// <param name="point">When the method completes, contains the point of intersection,
|
||||
/// or <see cref="math.Vector3.Zero"/> if there was no intersection.</param>
|
||||
/// <returns>Whether the two objects intersected.</returns>
|
||||
public bool Intersects(ref BoundingBox box, out Vector3 point)
|
||||
{
|
||||
return CollisionHelper.RayIntersectsBox(ref this, ref box, out point);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if there is an intersection between the current object and a <see cref="math.BoundingSphere"/>.
|
||||
/// </summary>
|
||||
/// <param name="sphere">The sphere to test.</param>
|
||||
/// <returns>Whether the two objects intersected.</returns>
|
||||
public bool Intersects(ref BoundingSphere sphere)
|
||||
{
|
||||
float distance;
|
||||
return CollisionHelper.RayIntersectsSphere(ref this, ref sphere, out distance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if there is an intersection between the current object and a <see cref="math.BoundingSphere"/>.
|
||||
/// </summary>
|
||||
/// <param name="sphere">The sphere to test.</param>
|
||||
/// <param name="distance">When the method completes, contains the distance of the intersection,
|
||||
/// or 0 if there was no intersection.</param>
|
||||
/// <returns>Whether the two objects intersected.</returns>
|
||||
public bool Intersects(ref BoundingSphere sphere, out float distance)
|
||||
{
|
||||
return CollisionHelper.RayIntersectsSphere(ref this, ref sphere, out distance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if there is an intersection between the current object and a <see cref="math.BoundingSphere"/>.
|
||||
/// </summary>
|
||||
/// <param name="sphere">The sphere to test.</param>
|
||||
/// <param name="point">When the method completes, contains the point of intersection,
|
||||
/// or <see cref="math.Vector3.Zero"/> if there was no intersection.</param>
|
||||
/// <returns>Whether the two objects intersected.</returns>
|
||||
public bool Intersects(ref BoundingSphere sphere, out Vector3 point)
|
||||
{
|
||||
return CollisionHelper.RayIntersectsSphere(ref this, ref sphere, out point);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests for equality between two objects.
|
||||
/// </summary>
|
||||
/// <param name="left">The first value to compare.</param>
|
||||
/// <param name="right">The second value to compare.</param>
|
||||
/// <returns><c>true</c> if <paramref name="left"/> has the same value as <paramref name="right"/>; otherwise, <c>false</c>.</returns>
|
||||
public static bool operator ==(Ray left, Ray right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests for inequality between two objects.
|
||||
/// </summary>
|
||||
/// <param name="left">The first value to compare.</param>
|
||||
/// <param name="right">The second value to compare.</param>
|
||||
/// <returns><c>true</c> if <paramref name="left"/> has a different value than <paramref name="right"/>; otherwise, <c>false</c>.</returns>
|
||||
public static bool operator !=(Ray left, Ray right)
|
||||
{
|
||||
return !left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="string"/> that represents this instance.
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, "Position:{0} Direction:{1}", Position.ToString(), Direction.ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <param name="format">The format.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="string"/> that represents this instance.
|
||||
/// </returns>
|
||||
public string ToString(string format)
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, "Position:{0} Direction:{1}", Position.ToString(format, CultureInfo.CurrentCulture),
|
||||
Direction.ToString(format, CultureInfo.CurrentCulture));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <param name="formatProvider">The format provider.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="string"/> that represents this instance.
|
||||
/// </returns>
|
||||
public string ToString(IFormatProvider formatProvider)
|
||||
{
|
||||
return string.Format(formatProvider, "Position:{0} Direction:{1}", Position.ToString(), Direction.ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="string"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <param name="format">The format.</param>
|
||||
/// <param name="formatProvider">The format provider.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="string"/> that represents this instance.
|
||||
/// </returns>
|
||||
public string ToString(string format, IFormatProvider formatProvider)
|
||||
{
|
||||
return string.Format(formatProvider, "Position:{0} Direction:{1}", Position.ToString(format, formatProvider),
|
||||
Direction.ToString(format, formatProvider));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a hash code for this instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
|
||||
/// </returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Position.GetHashCode() + Direction.GetHashCode();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="math.Vector4"/> is equal to this instance.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="math.Vector4"/> to compare with this instance.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the specified <see cref="math.Vector4"/> is equal to this instance; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public bool Equals(Ray value)
|
||||
{
|
||||
return Position == value.Position && Direction == value.Direction;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="object"/> is equal to this instance.
|
||||
/// </summary>
|
||||
/// <param name="value">The <see cref="object"/> to compare with this instance.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the specified <see cref="object"/> is equal to this instance; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
if (value == null)
|
||||
return false;
|
||||
|
||||
if (value.GetType() != GetType())
|
||||
return false;
|
||||
|
||||
return Equals((Ray)value);
|
||||
}
|
||||
|
||||
#if SlimDX1xInterop
|
||||
/// <summary>
|
||||
/// Performs an implicit conversion from <see cref="math.Ray"/> to <see cref="SlimDX.Ray"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator SlimDX.Ray(Ray value)
|
||||
{
|
||||
return new SlimDX.Ray(value.Position, value.Direction);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an implicit conversion from <see cref="SlimDX.Ray"/> to <see cref="math.Ray"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator Ray(SlimDX.Ray value)
|
||||
{
|
||||
return new Ray(value.Position, value.Direction);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if XnaInterop
|
||||
/// <summary>
|
||||
/// Performs an implicit conversion from <see cref="math.Ray"/> to <see cref="Microsoft.Xna.Framework.Ray"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator Microsoft.Xna.Framework.Ray(Ray value)
|
||||
{
|
||||
return new Microsoft.Xna.Framework.Ray(value.Position, value.Direction);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an implicit conversion from <see cref="Microsoft.Xna.Framework.Ray"/> to <see cref="math.Ray"/>.
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator Ray(Microsoft.Xna.Framework.Ray value)
|
||||
{
|
||||
return new Ray(value.Position, value.Direction);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
502
math/Rectangle.cs
Normal file
502
math/Rectangle.cs
Normal file
@ -0,0 +1,502 @@
|
||||
// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
|
||||
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
|
||||
//
|
||||
// Copyright (c) 2010-2013 SharpDX - Alexandre Mutel
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace math
|
||||
{
|
||||
/// <summary>
|
||||
/// A rectangle structure defining X,Y,Width,Height.
|
||||
/// </summary>
|
||||
[DataContract( Name = "Rectangle")]
|
||||
[DataStyle(DataStyle.Compact)]
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
||||
public struct Rectangle : IEquatable<Rectangle>
|
||||
{
|
||||
/// <summary>
|
||||
/// An empty rectangle.
|
||||
/// </summary>
|
||||
public static readonly Rectangle Empty;
|
||||
|
||||
static Rectangle()
|
||||
{
|
||||
Empty = new Rectangle();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Rectangle"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="x">The left.</param>
|
||||
/// <param name="y">The top.</param>
|
||||
/// <param name="width">The width.</param>
|
||||
/// <param name="height">The height.</param>
|
||||
public Rectangle(int x, int y, int width, int height)
|
||||
{
|
||||
this.X = x;
|
||||
this.Y = y;
|
||||
this.Width = width;
|
||||
this.Height = height;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the left.
|
||||
/// </summary>
|
||||
/// <value>The left.</value>
|
||||
[DataMemberIgnore]
|
||||
public int Left
|
||||
{
|
||||
get { return X; }
|
||||
set { X = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the top.
|
||||
/// </summary>
|
||||
/// <value>The top.</value>
|
||||
[DataMemberIgnore]
|
||||
public int Top
|
||||
{
|
||||
get { return Y; }
|
||||
set { Y = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the right.
|
||||
/// </summary>
|
||||
/// <value>The right.</value>
|
||||
[DataMemberIgnore]
|
||||
public int Right
|
||||
{
|
||||
get { return X + Width; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the bottom.
|
||||
/// </summary>
|
||||
/// <value>The bottom.</value>
|
||||
[DataMemberIgnore]
|
||||
public int Bottom
|
||||
{
|
||||
get { return Y + Height; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the X position.
|
||||
/// </summary>
|
||||
/// <value>The X position.</value>
|
||||
[DataMember( Order = 0 )]
|
||||
public int X;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Y position.
|
||||
/// </summary>
|
||||
/// <value>The Y position.</value>
|
||||
[DataMember( Order = 1 )]
|
||||
public int Y;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the width.
|
||||
/// </summary>
|
||||
/// <value>The width.</value>
|
||||
[DataMember( Order = 2 )]
|
||||
public int Width;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the height.
|
||||
/// </summary>
|
||||
/// <value>The height.</value>
|
||||
[DataMember( Order = 3 )]
|
||||
public int Height;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the location.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The location.
|
||||
/// </value>
|
||||
[DataMemberIgnore]
|
||||
public Point Location
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Point(X, Y);
|
||||
}
|
||||
set
|
||||
{
|
||||
X = value.X;
|
||||
Y = value.Y;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Point that specifies the center of the rectangle.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The center.
|
||||
/// </value>
|
||||
[DataMemberIgnore]
|
||||
public Point Center
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Point(X + (Width / 2), Y + (Height / 2));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value that indicates whether the rectangle is empty.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if [is empty]; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool IsEmpty
|
||||
{
|
||||
get
|
||||
{
|
||||
return (Width == 0) && (Height == 0) && (X == 0) && (Y == 0);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the size of the rectangle.
|
||||
/// </summary>
|
||||
/// <value>The size of the rectangle.</value>
|
||||
[DataMemberIgnore]
|
||||
public Size2 Size
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Size2(Width, Height);
|
||||
}
|
||||
set
|
||||
{
|
||||
Width = value.Width;
|
||||
Height = value.Height;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the position of the top-left corner of the rectangle.
|
||||
/// </summary>
|
||||
/// <value>The top-left corner of the rectangle.</value>
|
||||
public Point TopLeft { get { return new Point(Left, Top); } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the position of the top-right corner of the rectangle.
|
||||
/// </summary>
|
||||
/// <value>The top-right corner of the rectangle.</value>
|
||||
public Point TopRight { get { return new Point(Right, Top); } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the position of the bottom-left corner of the rectangle.
|
||||
/// </summary>
|
||||
/// <value>The bottom-left corner of the rectangle.</value>
|
||||
public Point BottomLeft { get { return new Point(Left, Bottom); } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the position of the bottom-right corner of the rectangle.
|
||||
/// </summary>
|
||||
/// <value>The bottom-right corner of the rectangle.</value>
|
||||
public Point BottomRight { get { return new Point(Right, Bottom); } }
|
||||
|
||||
/// <summary>Changes the position of the rectangle.</summary>
|
||||
/// <param name="amount">The values to adjust the position of the rectangle by.</param>
|
||||
public void Offset(Point amount)
|
||||
{
|
||||
Offset(amount.X, amount.Y);
|
||||
}
|
||||
|
||||
/// <summary>Changes the position of the rectangle.</summary>
|
||||
/// <param name="offsetX">Change in the x-position.</param>
|
||||
/// <param name="offsetY">Change in the y-position.</param>
|
||||
public void Offset(int offsetX, int offsetY)
|
||||
{
|
||||
X += offsetX;
|
||||
Y += offsetY;
|
||||
}
|
||||
|
||||
/// <summary>Pushes the edges of the rectangle out by the horizontal and vertical values specified.</summary>
|
||||
/// <param name="horizontalAmount">Value to push the sides out by.</param>
|
||||
/// <param name="verticalAmount">Value to push the top and bottom out by.</param>
|
||||
public void Inflate(int horizontalAmount, int verticalAmount)
|
||||
{
|
||||
X -= horizontalAmount;
|
||||
Y -= verticalAmount;
|
||||
Width += horizontalAmount * 2;
|
||||
Height += verticalAmount * 2;
|
||||
}
|
||||
|
||||
/// <summary>Determines whether this rectangle contains a specified point represented by its x- and y-coordinates.</summary>
|
||||
/// <param name="x">The x-coordinate of the specified point.</param>
|
||||
/// <param name="y">The y-coordinate of the specified point.</param>
|
||||
public bool Contains(int x, int y)
|
||||
{
|
||||
return (X <= x) && (x < Right) && (Y <= y) && (y < Bottom);
|
||||
}
|
||||
|
||||
/// <summary>Determines whether this rectangle contains a specified Point.</summary>
|
||||
/// <param name="value">The Point to evaluate.</param>
|
||||
public bool Contains(Point value)
|
||||
{
|
||||
bool result;
|
||||
Contains(ref value, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>Determines whether this rectangle contains a specified Point.</summary>
|
||||
/// <param name="value">The Point to evaluate.</param>
|
||||
/// <param name="result">[OutAttribute] true if the specified Point is contained within this rectangle; false otherwise.</param>
|
||||
public void Contains(ref Point value, out bool result)
|
||||
{
|
||||
result = (X <= value.X) && (value.X < Right) && (Y <= value.Y) && (value.Y < Bottom);
|
||||
}
|
||||
|
||||
/// <summary>Determines whether this rectangle entirely contains a specified rectangle.</summary>
|
||||
/// <param name="value">The rectangle to evaluate.</param>
|
||||
public bool Contains(Rectangle value)
|
||||
{
|
||||
bool result;
|
||||
Contains(ref value, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>Determines whether this rectangle entirely contains a specified rectangle.</summary>
|
||||
/// <param name="value">The rectangle to evaluate.</param>
|
||||
/// <param name="result">[OutAttribute] On exit, is true if this rectangle entirely contains the specified rectangle, or false if not.</param>
|
||||
public void Contains(ref Rectangle value, out bool result)
|
||||
{
|
||||
result = (X <= value.X) && (value.Right <= Right) && (Y <= value.Y) && (value.Bottom <= Bottom);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks, if specified point is inside <see cref="Rectangle"/>.
|
||||
/// </summary>
|
||||
/// <param name="x">X point coordinate.</param>
|
||||
/// <param name="y">Y point coordinate.</param>
|
||||
/// <returns><c>true</c> if point is inside <see cref="Rectangle"/>, otherwise <c>false</c>.</returns>
|
||||
public bool Contains(float x, float y)
|
||||
{
|
||||
return (x >= this.X && x <= Right && y >= this.Y && y <= Bottom);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks, if specified <see cref="Vec2"/> is inside <see cref="Rectangle"/>.
|
||||
/// </summary>
|
||||
/// <param name="vector2D">Coordinate <see cref="Vec2"/>.</param>
|
||||
/// <returns><c>true</c> if <see cref="Vec2"/> is inside <see cref="Rectangle"/>, otherwise <c>false</c>.</returns>
|
||||
public bool Contains(Vec2 vector2D)
|
||||
{
|
||||
return Contains(vector2D.X, vector2D.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks, if specified <see cref="Int2"/> is inside <see cref="Rectangle"/>.
|
||||
/// </summary>
|
||||
/// <param name="int2">Coordinate <see cref="Int2"/>.</param>
|
||||
/// <returns><c>true</c> if <see cref="Int2"/> is inside <see cref="Rectangle"/>, otherwise <c>false</c>.</returns>
|
||||
public bool Contains(Int2 int2)
|
||||
{
|
||||
return Contains(int2.X, int2.Y);
|
||||
}
|
||||
|
||||
/// <summary>Determines whether a specified rectangle intersects with this rectangle.</summary>
|
||||
/// <param name="value">The rectangle to evaluate.</param>
|
||||
public bool Intersects(Rectangle value)
|
||||
{
|
||||
bool result;
|
||||
Intersects(ref value, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether a specified rectangle intersects with this rectangle.
|
||||
/// </summary>
|
||||
/// <param name="value">The rectangle to evaluate</param>
|
||||
/// <param name="result">[OutAttribute] true if the specified rectangle intersects with this one; false otherwise.</param>
|
||||
public void Intersects(ref Rectangle value, out bool result)
|
||||
{
|
||||
result = (value.X < Right) && (X < value.Right) && (value.Y < Bottom) && (Y < value.Bottom);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a rectangle defining the area where one rectangle overlaps with another rectangle.
|
||||
/// </summary>
|
||||
/// <param name="value1">The first rectangle to compare.</param>
|
||||
/// <param name="value2">The second rectangle to compare.</param>
|
||||
/// <returns>The intersection rectangle.</returns>
|
||||
public static Rectangle Intersect(Rectangle value1, Rectangle value2)
|
||||
{
|
||||
Rectangle result;
|
||||
Intersect(ref value1, ref value2, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>Creates a rectangle defining the area where one rectangle overlaps with another rectangle.</summary>
|
||||
/// <param name="value1">The first rectangle to compare.</param>
|
||||
/// <param name="value2">The second rectangle to compare.</param>
|
||||
/// <param name="result">[OutAttribute] The area where the two first parameters overlap.</param>
|
||||
public static void Intersect(ref Rectangle value1, ref Rectangle value2, out Rectangle result)
|
||||
{
|
||||
int newLeft = (value1.X > value2.X) ? value1.X : value2.X;
|
||||
int newTop = (value1.Y > value2.Y) ? value1.Y : value2.Y;
|
||||
int newRight = (value1.Right < value2.Right) ? value1.Right : value2.Right;
|
||||
int newBottom = (value1.Bottom < value2.Bottom) ? value1.Bottom : value2.Bottom;
|
||||
if ((newRight > newLeft) && (newBottom > newTop))
|
||||
{
|
||||
result = new Rectangle(newLeft, newTop, newRight - newLeft, newBottom - newTop);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = Empty;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new rectangle that incorporate the provided point to the given rectangle.
|
||||
/// </summary>
|
||||
/// <param name="rectangle">The original rectangle.</param>
|
||||
/// <param name="point">The point to incorporate.</param>
|
||||
/// <returns>The union rectangle.</returns>
|
||||
public static Rectangle Union(Rectangle rectangle, Int2 point)
|
||||
{
|
||||
Rectangle result;
|
||||
var rect = new Rectangle(point.X, point.Y, 1, 1);
|
||||
Union(ref rectangle, ref rect, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new rectangle that exactly contains two other rectangles.
|
||||
/// </summary>
|
||||
/// <param name="value1">The first rectangle to contain.</param>
|
||||
/// <param name="value2">The second rectangle to contain.</param>
|
||||
/// <returns>The union rectangle.</returns>
|
||||
public static Rectangle Union(Rectangle value1, Rectangle value2)
|
||||
{
|
||||
Rectangle result;
|
||||
Union(ref value1, ref value2, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new rectangle that exactly contains two other rectangles.
|
||||
/// </summary>
|
||||
/// <param name="value1">The first rectangle to contain.</param>
|
||||
/// <param name="value2">The second rectangle to contain.</param>
|
||||
/// <param name="result">[OutAttribute] The rectangle that must be the union of the first two rectangles.</param>
|
||||
public static void Union(ref Rectangle value1, ref Rectangle value2, out Rectangle result)
|
||||
{
|
||||
var left = Math.Min(value1.Left, value2.Left);
|
||||
var right = Math.Max(value1.Right, value2.Right);
|
||||
var top = Math.Min(value1.Top, value2.Top);
|
||||
var bottom = Math.Max(value1.Bottom, value2.Bottom);
|
||||
result = new Rectangle(left, top, right - left, bottom - top);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="object"/> is equal to this instance.
|
||||
/// </summary>
|
||||
/// <param name="obj">The <see cref="object"/> to compare with this instance.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the specified <see cref="object"/> is equal to this instance; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj)) return false;
|
||||
if (obj.GetType() != typeof(Rectangle)) return false;
|
||||
return Equals((Rectangle)obj);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="Rectangle"/> is equal to this instance.
|
||||
/// </summary>
|
||||
/// <param name="other">The <see cref="Rectangle"/> to compare with this instance.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the specified <see cref="Rectangle"/> is equal to this instance; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public bool Equals(Rectangle other)
|
||||
{
|
||||
return other.X == this.X && other.Y == this.Y && other.Width == Width && other.Height == Height;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a hash code for this instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
|
||||
/// </returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
int result = X;
|
||||
result = (result * 397) ^ Y;
|
||||
result = (result * 397) ^ Width;
|
||||
result = (result * 397) ^ Height;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements the operator ==.
|
||||
/// </summary>
|
||||
/// <param name="left">The left.</param>
|
||||
/// <param name="right">The right.</param>
|
||||
/// <returns>The result of the operator.</returns>
|
||||
public static bool operator ==(Rectangle left, Rectangle right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements the operator !=.
|
||||
/// </summary>
|
||||
/// <param name="left">The left.</param>
|
||||
/// <param name="right">The right.</param>
|
||||
/// <returns>The result of the operator.</returns>
|
||||
public static bool operator !=(Rectangle left, Rectangle right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an implicit conversion to the <see cref="RectangleF"/> structure.
|
||||
/// </summary>
|
||||
/// <remarks>Performs direct converstion from int to float.</remarks>
|
||||
/// <param name="value">The source <see cref="Rectangle"/> value.</param>
|
||||
/// <returns>The converted structure.</returns>
|
||||
public static implicit operator RectangleF(Rectangle value)
|
||||
{
|
||||
return new RectangleF(value.X, value.Y, value.Width, value.Height);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, "X:{0} Y:{1} Width:{2} Height:{3}", X, Y, Width, Height);
|
||||
}
|
||||
}
|
||||
}
|
||||
492
math/RectangleF.cs
Normal file
492
math/RectangleF.cs
Normal file
@ -0,0 +1,492 @@
|
||||
// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
|
||||
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
|
||||
//
|
||||
// Copyright (c) 2010-2013 SharpDX - Alexandre Mutel
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace math
|
||||
{
|
||||
/// <summary>
|
||||
/// Define a RectangleF.
|
||||
/// </summary>
|
||||
[DataContract( Name = "RectangleF")]
|
||||
[DataStyle(DataStyle.Compact)]
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
||||
public struct RectangleF : IEquatable<RectangleF>
|
||||
{
|
||||
/// <summary>
|
||||
/// An empty rectangle
|
||||
/// </summary>
|
||||
public static readonly RectangleF Empty;
|
||||
|
||||
static RectangleF()
|
||||
{
|
||||
Empty = new RectangleF();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RectangleF"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="x">The left.</param>
|
||||
/// <param name="y">The top.</param>
|
||||
/// <param name="width">The width.</param>
|
||||
/// <param name="height">The height.</param>
|
||||
public RectangleF(float x, float y, float width, float height)
|
||||
{
|
||||
this.X = x;
|
||||
this.Y = y;
|
||||
this.Width = width;
|
||||
this.Height = height;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the X position of the left edge.
|
||||
/// </summary>
|
||||
/// <value>The left.</value>
|
||||
[DataMemberIgnore]
|
||||
public float Left
|
||||
{
|
||||
get { return X; }
|
||||
set { X = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the top.
|
||||
/// </summary>
|
||||
/// <value>The top.</value>
|
||||
[DataMemberIgnore]
|
||||
public float Top
|
||||
{
|
||||
get { return Y; }
|
||||
set { Y = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the right.
|
||||
/// </summary>
|
||||
/// <value>The right.</value>
|
||||
[DataMemberIgnore]
|
||||
public float Right
|
||||
{
|
||||
get
|
||||
{
|
||||
return X + Width;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the bottom.
|
||||
/// </summary>
|
||||
/// <value>The bottom.</value>
|
||||
public float Bottom
|
||||
{
|
||||
get
|
||||
{
|
||||
return Y + Height;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the X position.
|
||||
/// </summary>
|
||||
/// <value>The X position.</value>
|
||||
/// <userdoc>The beginning of the rectangle along the Ox axis.</userdoc>
|
||||
[DataMember( Order = 0 )]
|
||||
public float X;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Y position.
|
||||
/// </summary>
|
||||
/// <value>The Y position.</value>
|
||||
/// <userdoc>The beginning of the rectangle along the Oy axis.</userdoc>
|
||||
[DataMember( Order = 1 )]
|
||||
public float Y;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the width.
|
||||
/// </summary>
|
||||
/// <value>The width.</value>
|
||||
/// <userdoc>The width of the rectangle.</userdoc>
|
||||
[DataMember( Order = 2 )]
|
||||
public float Width;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the height.
|
||||
/// </summary>
|
||||
/// <value>The height.</value>
|
||||
/// <userdoc>The height of the rectangle.</userdoc>
|
||||
[DataMember( Order = 3 )]
|
||||
public float Height;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the location.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The location.
|
||||
/// </value>
|
||||
[DataMemberIgnore]
|
||||
public Vec2 Location
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Vec2(X, Y);
|
||||
}
|
||||
set
|
||||
{
|
||||
X = value.X;
|
||||
Y = value.Y;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Point that specifies the center of the rectangle.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The center.
|
||||
/// </value>
|
||||
[DataMemberIgnore]
|
||||
public Vec2 Center
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Vec2(X + (Width / 2), Y + (Height / 2));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value that indicates whether the rectangle is empty.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <c>true</c> if [is empty]; otherwise, <c>false</c>.
|
||||
/// </value>
|
||||
public bool IsEmpty
|
||||
{
|
||||
get
|
||||
{
|
||||
return (Width == 0.0f) && (Height == 0.0f) && (X == 0.0f) && (Y == 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the size of the rectangle.
|
||||
/// </summary>
|
||||
/// <value>The size of the rectangle.</value>
|
||||
[DataMemberIgnore]
|
||||
public Size2F Size
|
||||
{
|
||||
get
|
||||
{
|
||||
return new Size2F(Width, Height);
|
||||
}
|
||||
set
|
||||
{
|
||||
Width = value.Width;
|
||||
Height = value.Height;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the position of the top-left corner of the rectangle.
|
||||
/// </summary>
|
||||
/// <value>The top-left corner of the rectangle.</value>
|
||||
public Vec2 TopLeft { get { return new Vec2(X, Y); } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the position of the top-right corner of the rectangle.
|
||||
/// </summary>
|
||||
/// <value>The top-right corner of the rectangle.</value>
|
||||
public Vec2 TopRight { get { return new Vec2(Right, Y); } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the position of the bottom-left corner of the rectangle.
|
||||
/// </summary>
|
||||
/// <value>The bottom-left corner of the rectangle.</value>
|
||||
public Vec2 BottomLeft { get { return new Vec2(X, Bottom); } }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the position of the bottom-right corner of the rectangle.
|
||||
/// </summary>
|
||||
/// <value>The bottom-right corner of the rectangle.</value>
|
||||
public Vec2 BottomRight { get { return new Vec2(Right, Bottom); } }
|
||||
|
||||
/// <summary>Changes the position of the rectangle.</summary>
|
||||
/// <param name="amount">The values to adjust the position of the rectangle by.</param>
|
||||
public void Offset(Point amount)
|
||||
{
|
||||
Offset(amount.X, amount.Y);
|
||||
}
|
||||
|
||||
/// <summary>Changes the position of the rectangle.</summary>
|
||||
/// <param name="amount">The values to adjust the position of the rectangle by.</param>
|
||||
public void Offset(Vec2 amount)
|
||||
{
|
||||
Offset(amount.X, amount.Y);
|
||||
}
|
||||
|
||||
/// <summary>Changes the position of the rectangle.</summary>
|
||||
/// <param name="offsetX">Change in the x-position.</param>
|
||||
/// <param name="offsetY">Change in the y-position.</param>
|
||||
public void Offset(float offsetX, float offsetY)
|
||||
{
|
||||
X += offsetX;
|
||||
Y += offsetY;
|
||||
}
|
||||
|
||||
/// <summary>Pushes the edges of the rectangle out by the horizontal and vertical values specified.</summary>
|
||||
/// <param name="horizontalAmount">Value to push the sides out by.</param>
|
||||
/// <param name="verticalAmount">Value to push the top and bottom out by.</param>
|
||||
public void Inflate(float horizontalAmount, float verticalAmount)
|
||||
{
|
||||
X -= horizontalAmount;
|
||||
Y -= verticalAmount;
|
||||
Width += horizontalAmount * 2;
|
||||
Height += verticalAmount * 2;
|
||||
}
|
||||
|
||||
/// <summary>Determines whether this rectangle contains a specified Point.</summary>
|
||||
/// <param name="value">The Point to evaluate.</param>
|
||||
/// <param name="result">[OutAttribute] true if the specified Point is contained within this rectangle; false otherwise.</param>
|
||||
public void Contains(ref Vec2 value, out bool result)
|
||||
{
|
||||
result = (X <= value.X) && (value.X < Right) && (Y <= value.Y) && (value.Y < Bottom);
|
||||
}
|
||||
|
||||
/// <summary>Determines whether this rectangle entirely contains a specified rectangle.</summary>
|
||||
/// <param name="value">The rectangle to evaluate.</param>
|
||||
public bool Contains(Rectangle value)
|
||||
{
|
||||
return (X <= value.X) && (value.Right <= Right) && (Y <= value.Y) && (value.Bottom <= Bottom);
|
||||
}
|
||||
|
||||
/// <summary>Determines whether this rectangle entirely contains a specified rectangle.</summary>
|
||||
/// <param name="value">The rectangle to evaluate.</param>
|
||||
/// <param name="result">[OutAttribute] On exit, is true if this rectangle entirely contains the specified rectangle, or false if not.</param>
|
||||
public void Contains(ref RectangleF value, out bool result)
|
||||
{
|
||||
result = (X <= value.X) && (value.Right <= Right) && (Y <= value.Y) && (value.Bottom <= Bottom);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks, if specified point is inside <see cref="RectangleF"/>.
|
||||
/// </summary>
|
||||
/// <param name="x">X point coordinate.</param>
|
||||
/// <param name="y">Y point coordinate.</param>
|
||||
/// <returns><c>true</c> if point is inside <see cref="RectangleF"/>, otherwise <c>false</c>.</returns>
|
||||
public bool Contains(float x, float y)
|
||||
{
|
||||
return (x >= this.X && x <= Right && y >= this.Y && y <= Bottom);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks, if specified <see cref="Vec2"/> is inside <see cref="RectangleF"/>.
|
||||
/// </summary>
|
||||
/// <param name="vector2D">Coordinate <see cref="Vec2"/>.</param>
|
||||
/// <returns><c>true</c> if <see cref="Vec2"/> is inside <see cref="RectangleF"/>, otherwise <c>false</c>.</returns>
|
||||
public bool Contains(Vec2 vector2D)
|
||||
{
|
||||
return Contains(vector2D.X, vector2D.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks, if specified <see cref="Int2"/> is inside <see cref="Rectangle"/>.
|
||||
/// </summary>
|
||||
/// <param name="int2">Coordinate <see cref="Int2"/>.</param>
|
||||
/// <returns><c>true</c> if <see cref="Int2"/> is inside <see cref="Rectangle"/>, otherwise <c>false</c>.</returns>
|
||||
public bool Contains(Int2 int2)
|
||||
{
|
||||
return Contains(int2.X, int2.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks, if specified <see cref="Point"/> is inside <see cref="RectangleF"/>.
|
||||
/// </summary>
|
||||
/// <param name="point">Coordinate <see cref="Point"/>.</param>
|
||||
/// <returns><c>true</c> if <see cref="Point"/> is inside <see cref="RectangleF"/>, otherwise <c>false</c>.</returns>
|
||||
public bool Contains(Point point)
|
||||
{
|
||||
return Contains(point.X, point.Y);
|
||||
}
|
||||
|
||||
/// <summary>Determines whether a specified rectangle intersects with this rectangle.</summary>
|
||||
/// <param name="value">The rectangle to evaluate.</param>
|
||||
public bool Intersects(RectangleF value)
|
||||
{
|
||||
bool result;
|
||||
Intersects(ref value, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether a specified rectangle intersects with this rectangle.
|
||||
/// </summary>
|
||||
/// <param name="value">The rectangle to evaluate</param>
|
||||
/// <param name="result">[OutAttribute] true if the specified rectangle intersects with this one; false otherwise.</param>
|
||||
public void Intersects(ref RectangleF value, out bool result)
|
||||
{
|
||||
result = (value.X < Right) && (X < value.Right) && (value.Y < Bottom) && (Y < value.Bottom);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a rectangle defining the area where one rectangle overlaps with another rectangle.
|
||||
/// </summary>
|
||||
/// <param name="value1">The first Rectangle to compare.</param>
|
||||
/// <param name="value2">The second Rectangle to compare.</param>
|
||||
/// <returns>The intersection rectangle.</returns>
|
||||
public static RectangleF Intersect(RectangleF value1, RectangleF value2)
|
||||
{
|
||||
RectangleF result;
|
||||
Intersect(ref value1, ref value2, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>Creates a rectangle defining the area where one rectangle overlaps with another rectangle.</summary>
|
||||
/// <param name="value1">The first rectangle to compare.</param>
|
||||
/// <param name="value2">The second rectangle to compare.</param>
|
||||
/// <param name="result">[OutAttribute] The area where the two first parameters overlap.</param>
|
||||
public static void Intersect(ref RectangleF value1, ref RectangleF value2, out RectangleF result)
|
||||
{
|
||||
float newLeft = (value1.X > value2.X) ? value1.X : value2.X;
|
||||
float newTop = (value1.Y > value2.Y) ? value1.Y : value2.Y;
|
||||
float newRight = (value1.Right < value2.Right) ? value1.Right : value2.Right;
|
||||
float newBottom = (value1.Bottom < value2.Bottom) ? value1.Bottom : value2.Bottom;
|
||||
if ((newRight > newLeft) && (newBottom > newTop))
|
||||
{
|
||||
result = new RectangleF(newLeft, newTop, newRight - newLeft, newBottom - newTop);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = Empty;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new rectangle that exactly contains two other rectangles.
|
||||
/// </summary>
|
||||
/// <param name="value1">The first rectangle to contain.</param>
|
||||
/// <param name="value2">The second rectangle to contain.</param>
|
||||
/// <returns>The union rectangle.</returns>
|
||||
public static RectangleF Union(RectangleF value1, RectangleF value2)
|
||||
{
|
||||
RectangleF result;
|
||||
Union(ref value1, ref value2, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new rectangle that exactly contains two other rectangles.
|
||||
/// </summary>
|
||||
/// <param name="value1">The first rectangle to contain.</param>
|
||||
/// <param name="value2">The second rectangle to contain.</param>
|
||||
/// <param name="result">[OutAttribute] The rectangle that must be the union of the first two rectangles.</param>
|
||||
public static void Union(ref RectangleF value1, ref RectangleF value2, out RectangleF result)
|
||||
{
|
||||
var left = Math.Min(value1.Left, value2.Left);
|
||||
var right = Math.Max(value1.Right, value2.Right);
|
||||
var top = Math.Min(value1.Top, value2.Top);
|
||||
var bottom = Math.Max(value1.Bottom, value2.Bottom);
|
||||
result = new RectangleF(left, top, right - left, bottom - top);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="object"/> is equal to this instance.
|
||||
/// </summary>
|
||||
/// <param name="obj">The <see cref="object"/> to compare with this instance.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the specified <see cref="object"/> is equal to this instance; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj)) return false;
|
||||
if (obj.GetType() != typeof(RectangleF)) return false;
|
||||
return Equals((RectangleF)obj);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Equals(RectangleF other)
|
||||
{
|
||||
return MathUtil.NearEqual(other.Left, Left) &&
|
||||
MathUtil.NearEqual(other.Right, Right) &&
|
||||
MathUtil.NearEqual(other.Top, Top) &&
|
||||
MathUtil.NearEqual(other.Bottom, Bottom);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a hash code for this instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
|
||||
/// </returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
int result = X.GetHashCode();
|
||||
result = (result * 397) ^ Y.GetHashCode();
|
||||
result = (result * 397) ^ Width.GetHashCode();
|
||||
result = (result * 397) ^ Height.GetHashCode();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements the operator ==.
|
||||
/// </summary>
|
||||
/// <param name="left">The left.</param>
|
||||
/// <param name="right">The right.</param>
|
||||
/// <returns>The result of the operator.</returns>
|
||||
public static bool operator ==(RectangleF left, RectangleF right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements the operator !=.
|
||||
/// </summary>
|
||||
/// <param name="left">The left.</param>
|
||||
/// <param name="right">The right.</param>
|
||||
/// <returns>The result of the operator.</returns>
|
||||
public static bool operator !=(RectangleF left, RectangleF right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an explicit conversion to <see cref="Rectangle"/> structure.
|
||||
/// </summary>
|
||||
/// <remarks>Performs direct float to int conversion, any fractional data is truncated.</remarks>
|
||||
/// <param name="value">The source <see cref="RectangleF"/> value.</param>
|
||||
/// <returns>A converted <see cref="Rectangle"/> structure.</returns>
|
||||
public static explicit operator Rectangle(RectangleF value)
|
||||
{
|
||||
return new Rectangle((int)value.X, (int)value.Y, (int)value.Width, (int)value.Height);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, "X:{0} Y:{1} Width:{2} Height:{3}", X, Y, Width, Height);
|
||||
}
|
||||
}
|
||||
}
|
||||
132
math/Size2.cs
Normal file
132
math/Size2.cs
Normal file
@ -0,0 +1,132 @@
|
||||
// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
|
||||
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
|
||||
//
|
||||
// Copyright (c) 2010-2013 SharpDX - Alexandre Mutel
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace math
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a 2D rectangular size (width,height).
|
||||
/// </summary>
|
||||
[DataContract( Name = "!Size2")]
|
||||
[DataStyle(DataStyle.Compact)]
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
||||
public struct Size2 : IEquatable<Size2>
|
||||
{
|
||||
/// <summary>
|
||||
/// A zero size with (width, height) = (0,0)
|
||||
/// </summary>
|
||||
public static readonly Size2 Zero = new Size2(0, 0);
|
||||
|
||||
/// <summary>
|
||||
/// A zero size with (width, height) = (0,0)
|
||||
/// </summary>
|
||||
public static readonly Size2 Empty = Zero;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Size2"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="width">The x.</param>
|
||||
/// <param name="height">The y.</param>
|
||||
public Size2(int width, int height)
|
||||
{
|
||||
Width = width;
|
||||
Height = height;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Width.
|
||||
/// </summary>
|
||||
[DataMember( Order = 0 )]
|
||||
public int Width;
|
||||
|
||||
/// <summary>
|
||||
/// Height.
|
||||
/// </summary>
|
||||
[DataMember( Order = 1 )]
|
||||
public int Height;
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="object"/> is equal to this instance.
|
||||
/// </summary>
|
||||
/// <param name="other">The <see cref="object"/> to compare with this instance.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the specified <see cref="object"/> is equal to this instance; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public bool Equals(Size2 other)
|
||||
{
|
||||
return other.Width == Width && other.Height == Height;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj)) return false;
|
||||
if (obj.GetType() != typeof(Size2)) return false;
|
||||
return Equals((Size2)obj);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
return (Width * 397) ^ Height;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements the operator ==.
|
||||
/// </summary>
|
||||
/// <param name="left">The left.</param>
|
||||
/// <param name="right">The right.</param>
|
||||
/// <returns>
|
||||
/// The result of the operator.
|
||||
/// </returns>
|
||||
public static bool operator ==(Size2 left, Size2 right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements the operator !=.
|
||||
/// </summary>
|
||||
/// <param name="left">The left.</param>
|
||||
/// <param name="right">The right.</param>
|
||||
/// <returns>
|
||||
/// The result of the operator.
|
||||
/// </returns>
|
||||
public static bool operator !=(Size2 left, Size2 right)
|
||||
{
|
||||
return !left.Equals(right);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("({0},{1})", Width, Height);
|
||||
}
|
||||
}
|
||||
}
|
||||
132
math/Size2F.cs
Normal file
132
math/Size2F.cs
Normal file
@ -0,0 +1,132 @@
|
||||
// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
|
||||
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
|
||||
//
|
||||
// Copyright (c) 2010-2013 SharpDX - Alexandre Mutel
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace math
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a 2D rectangular size (width,height).
|
||||
/// </summary>
|
||||
[DataContract( Name = "Size2F")]
|
||||
[DataStyle(DataStyle.Compact)]
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
||||
public struct Size2F : IEquatable<Size2F>
|
||||
{
|
||||
/// <summary>
|
||||
/// A zero size with (width, height) = (0,0)
|
||||
/// </summary>
|
||||
public static readonly Size2F Zero = new Size2F(0, 0);
|
||||
|
||||
/// <summary>
|
||||
/// A zero size with (width, height) = (0,0)
|
||||
/// </summary>
|
||||
public static readonly Size2F Empty = Zero;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Size2F"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="width">The x.</param>
|
||||
/// <param name="height">The y.</param>
|
||||
public Size2F(float width, float height)
|
||||
{
|
||||
Width = width;
|
||||
Height = height;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Width.
|
||||
/// </summary>
|
||||
[DataMember( Order = 0 )]
|
||||
public float Width;
|
||||
|
||||
/// <summary>
|
||||
/// Height.
|
||||
/// </summary>
|
||||
[DataMember( Order = 1 )]
|
||||
public float Height;
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="object"/> is equal to this instance.
|
||||
/// </summary>
|
||||
/// <param name="other">The <see cref="object"/> to compare with this instance.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the specified <see cref="object"/> is equal to this instance; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public bool Equals(Size2F other)
|
||||
{
|
||||
return other.Width == Width && other.Height == Height;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj)) return false;
|
||||
if (obj.GetType() != typeof(Size2F)) return false;
|
||||
return Equals((Size2F)obj);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
return (Width.GetHashCode() * 397) ^ Height.GetHashCode();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements the operator ==.
|
||||
/// </summary>
|
||||
/// <param name="left">The left.</param>
|
||||
/// <param name="right">The right.</param>
|
||||
/// <returns>
|
||||
/// The result of the operator.
|
||||
/// </returns>
|
||||
public static bool operator ==(Size2F left, Size2F right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements the operator !=.
|
||||
/// </summary>
|
||||
/// <param name="left">The left.</param>
|
||||
/// <param name="right">The right.</param>
|
||||
/// <returns>
|
||||
/// The result of the operator.
|
||||
/// </returns>
|
||||
public static bool operator !=(Size2F left, Size2F right)
|
||||
{
|
||||
return !left.Equals(right);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("({0},{1})", Width, Height);
|
||||
}
|
||||
}
|
||||
}
|
||||
237
math/Size3.cs
Normal file
237
math/Size3.cs
Normal file
@ -0,0 +1,237 @@
|
||||
// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
|
||||
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
|
||||
//
|
||||
// Copyright (c) 2010-2013 SharpDX - Alexandre Mutel
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace math
|
||||
{
|
||||
/// <summary>
|
||||
/// Structure providing Width, Height and Depth.
|
||||
/// </summary>
|
||||
[DataContract( Name = "!Size3")]
|
||||
[DataStyle(DataStyle.Compact)]
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct Size3 : IEquatable<Size3>, IComparable<Size3>
|
||||
{
|
||||
/// <summary>
|
||||
/// A zero size with (width, height, depth) = (0,0,0)
|
||||
/// </summary>
|
||||
public static readonly Size3 Zero = new Size3(0, 0, 0);
|
||||
|
||||
/// <summary>
|
||||
/// A one size with (width, height, depth) = (1,1,1)
|
||||
/// </summary>
|
||||
public static readonly Size3 One = new Size3(1, 1, 1);
|
||||
|
||||
/// <summary>
|
||||
/// A zero size with (width, height, depth) = (0,0,0)
|
||||
/// </summary>
|
||||
public static readonly Size3 Empty = Zero;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Size3" /> struct.
|
||||
/// </summary>
|
||||
/// <param name="width">The x.</param>
|
||||
/// <param name="height">The y.</param>
|
||||
/// <param name="depth">The depth.</param>
|
||||
public Size3(int width, int height, int depth)
|
||||
{
|
||||
Width = width;
|
||||
Height = height;
|
||||
Depth = depth;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Width.
|
||||
/// </summary>
|
||||
[DataMember( Order = 0 )]
|
||||
public int Width;
|
||||
|
||||
/// <summary>
|
||||
/// Height.
|
||||
/// </summary>
|
||||
[DataMember( Order = 1 )]
|
||||
public int Height;
|
||||
|
||||
/// <summary>
|
||||
/// Height.
|
||||
/// </summary>
|
||||
[DataMember( Order = 2 )]
|
||||
public int Depth;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a volume size.
|
||||
/// </summary>
|
||||
private long VolumeSize
|
||||
{
|
||||
get
|
||||
{
|
||||
return (long)Width * Height * Depth;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Equals(Size3 other)
|
||||
{
|
||||
return Width == other.Width && Height == other.Height && Depth == other.Depth;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj)) return false;
|
||||
return obj is Size3 && Equals((Size3)obj);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
int hashCode = Width;
|
||||
hashCode = (hashCode * 397) ^ Height;
|
||||
hashCode = (hashCode * 397) ^ Depth;
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public int CompareTo(Size3 other)
|
||||
{
|
||||
return Math.Sign(this.VolumeSize - other.VolumeSize);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("({0},{1},{2})", Width, Height, Depth);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements the <.
|
||||
/// </summary>
|
||||
/// <param name="left">The left.</param>
|
||||
/// <param name="right">The right.</param>
|
||||
/// <returns>The result of the operator.</returns>
|
||||
public static bool operator <(Size3 left, Size3 right)
|
||||
{
|
||||
return left.CompareTo(right) < 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements the <.
|
||||
/// </summary>
|
||||
/// <param name="left">The left.</param>
|
||||
/// <param name="right">The right.</param>
|
||||
/// <returns>The result of the operator.</returns>
|
||||
public static bool operator <=(Size3 left, Size3 right)
|
||||
{
|
||||
return left.CompareTo(right) <= 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements the < or ==.
|
||||
/// </summary>
|
||||
/// <param name="left">The left.</param>
|
||||
/// <param name="right">The right.</param>
|
||||
/// <returns>The result of the operator.</returns>
|
||||
public static bool operator >(Size3 left, Size3 right)
|
||||
{
|
||||
return left.CompareTo(right) > 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements the > or ==.
|
||||
/// </summary>
|
||||
/// <param name="left">The left.</param>
|
||||
/// <param name="right">The right.</param>
|
||||
/// <returns>The result of the operator.</returns>
|
||||
public static bool operator >=(Size3 left, Size3 right)
|
||||
{
|
||||
return left.CompareTo(right) >= 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements the ==.
|
||||
/// </summary>
|
||||
/// <param name="left">The left.</param>
|
||||
/// <param name="right">The right.</param>
|
||||
/// <returns>The result of the operator.</returns>
|
||||
public static bool operator ==(Size3 left, Size3 right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implements the !=.
|
||||
/// </summary>
|
||||
/// <param name="left">The left.</param>
|
||||
/// <param name="right">The right.</param>
|
||||
/// <returns>The result of the operator.</returns>
|
||||
public static bool operator !=(Size3 left, Size3 right)
|
||||
{
|
||||
return !left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the next up mip-level (*2) of this size.
|
||||
/// </summary>
|
||||
/// <returns>A next up mip-level Size3.</returns>
|
||||
public Size3 Up2(int count = 1)
|
||||
{
|
||||
if (count < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("count", "Must be >= 0");
|
||||
}
|
||||
|
||||
return new Size3(Math.Max(1, Width << count), Math.Max(1, Height << count), Math.Max(1, Depth << count));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the next down mip-level (/2) of this size.
|
||||
/// </summary>
|
||||
/// <param name="count">The count.</param>
|
||||
/// <returns>A next down mip-level Size3.</returns>
|
||||
public Size3 Down2(int count = 1)
|
||||
{
|
||||
if (count < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("count", "Must be >= 0");
|
||||
}
|
||||
|
||||
return new Size3(Math.Max(1, Width >> count), Math.Max(1, Height >> count), Math.Max(1, Depth >> count));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the mip size based on a direction.
|
||||
/// </summary>
|
||||
/// <param name="direction">The direction < 0 then <see cref="Down2"/>, > 0 then <see cref="Up2"/>, else this unchanged.</param>
|
||||
/// <returns>Size3.</returns>
|
||||
public Size3 Mip(int direction)
|
||||
{
|
||||
return direction == 0 ? this : direction < 0 ? Down2() : Up2();
|
||||
}
|
||||
}
|
||||
}
|
||||
250
math/SphericalHarmonics.cs
Normal file
250
math/SphericalHarmonics.cs
Normal file
@ -0,0 +1,250 @@
|
||||
// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
|
||||
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
|
||||
#pragma warning disable SA1003 // Symbols must be spaced correctly
|
||||
#pragma warning disable SA1008 // Opening parenthesis must be spaced correctly
|
||||
#pragma warning disable SA1009 // Closing parenthesis must be spaced correctly
|
||||
#pragma warning disable SA1010 // Opening square brackets must be spaced correctly
|
||||
#pragma warning disable SA1025 // Code must not contain multiple whitespace in a row
|
||||
#pragma warning disable SA1119 // Statement must not use unnecessary parenthesis
|
||||
#pragma warning disable SA1402 // File may only contain a single class
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace math
|
||||
{
|
||||
/// <summary>
|
||||
/// A representation of a sphere of values via Spherical Harmonics (SH).
|
||||
/// </summary>
|
||||
/// <typeparam name="TDataType">The type of data contained by the sphere</typeparam>
|
||||
[DataContract( Name = "SphericalHarmonicsGeneric")]
|
||||
public abstract class SphericalHarmonics<TDataType>
|
||||
{
|
||||
/// <summary>
|
||||
/// The maximum order supported.
|
||||
/// </summary>
|
||||
public const int MaximumOrder = 5;
|
||||
|
||||
private int order;
|
||||
|
||||
/// <summary>
|
||||
/// The order of calculation of the spherical harmonic.
|
||||
/// </summary>
|
||||
[DataMember( Order = 0 )]
|
||||
public int Order
|
||||
{
|
||||
get { return order; }
|
||||
internal set
|
||||
{
|
||||
if (order>5)
|
||||
throw new NotSupportedException("Only orders inferior or equal to 5 are supported");
|
||||
|
||||
order = Math.Max(1, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the coefficients defining the spherical harmonics (the spherical coordinates x{l,m} multiplying the spherical base Y{l,m}).
|
||||
/// </summary>
|
||||
[DataMember( Order = 1 )]
|
||||
public TDataType[] Coefficients { get; internal set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SphericalHarmonics{TDataType}"/> class (null, for serialization).
|
||||
/// </summary>
|
||||
internal SphericalHarmonics()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SphericalHarmonics{TDataType}"/> class.
|
||||
/// </summary>
|
||||
/// <param name="order">The order of the harmonics</param>
|
||||
protected SphericalHarmonics(int order)
|
||||
{
|
||||
this.order = order;
|
||||
Coefficients = new TDataType[order * order];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Evaluate the value of the spherical harmonics in the provided direction.
|
||||
/// </summary>
|
||||
/// <param name="direction">The direction</param>
|
||||
/// <returns>The value of the spherical harmonics in the direction</returns>
|
||||
public abstract TDataType Evaluate(Vector3 direction);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the coefficient x{l,m} of the spherical harmonics (the {l,m} spherical coordinate corresponding to the spherical base Y{l,m}).
|
||||
/// </summary>
|
||||
/// <param name="l">the l index of the coefficient</param>
|
||||
/// <param name="m">the m index of the coefficient</param>
|
||||
/// <returns>the value of the coefficient</returns>
|
||||
public TDataType this[int l, int m]
|
||||
{
|
||||
get
|
||||
{
|
||||
CheckIndicesValidity(l, m, order);
|
||||
return Coefficients[LmToCoefficientIndex(l, m)];
|
||||
}
|
||||
set
|
||||
{
|
||||
CheckIndicesValidity(l, m, order);
|
||||
Coefficients[LmToCoefficientIndex(l, m)] = value;
|
||||
}
|
||||
}
|
||||
|
||||
// ReSharper disable UnusedParameter.Local
|
||||
private static void CheckIndicesValidity(int l, int m, int maxOrder)
|
||||
// ReSharper restore UnusedParameter.Local
|
||||
{
|
||||
if (l > maxOrder - 1)
|
||||
throw new IndexOutOfRangeException("'l' parameter should be between '0' and '{0}' (order-1).".ToFormat(maxOrder-1));
|
||||
|
||||
if (Math.Abs(m) > l)
|
||||
throw new IndexOutOfRangeException("'m' parameter should be between '-l' and '+l'.");
|
||||
}
|
||||
|
||||
private static int LmToCoefficientIndex(int l, int m)
|
||||
{
|
||||
return l * l + l + m;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A spherical harmonics representation of a cubemap.
|
||||
/// </summary>
|
||||
[DataContract( Name = "SphericalHarmonics")]
|
||||
public class SphericalHarmonics : SphericalHarmonics<Color3>
|
||||
{
|
||||
private readonly float[] baseValues;
|
||||
|
||||
private const float Pi4 = 4 * MathUtil.Pi;
|
||||
private const float Pi16 = 16 * MathUtil.Pi;
|
||||
private const float Pi64 = 64 * MathUtil.Pi;
|
||||
private static readonly float SqrtPi = (float)Math.Sqrt(MathUtil.Pi);
|
||||
|
||||
/// <summary>
|
||||
/// Base coefficients for SH.
|
||||
/// </summary>
|
||||
public static readonly float[] BaseCoefficients =
|
||||
{
|
||||
(float)(1.0/(2.0*SqrtPi)),
|
||||
|
||||
(float)(-Math.Sqrt(3.0/Pi4)),
|
||||
(float)(Math.Sqrt(3.0/Pi4)),
|
||||
(float)(-Math.Sqrt(3.0/Pi4)),
|
||||
|
||||
(float)(Math.Sqrt(15.0/Pi4)),
|
||||
(float)(-Math.Sqrt(15.0/Pi4)),
|
||||
(float)(Math.Sqrt(5.0/Pi16)),
|
||||
(float)(-Math.Sqrt(15.0/Pi4)),
|
||||
(float)(Math.Sqrt(15.0/Pi16)),
|
||||
|
||||
-(float)Math.Sqrt(70/Pi64),
|
||||
(float)Math.Sqrt(105/Pi4),
|
||||
-(float)Math.Sqrt(42/Pi64),
|
||||
(float)Math.Sqrt(7/Pi16),
|
||||
-(float)Math.Sqrt(42/Pi64),
|
||||
(float)Math.Sqrt(105/Pi16),
|
||||
-(float)Math.Sqrt(70/Pi64),
|
||||
|
||||
3*(float)Math.Sqrt(35/Pi16),
|
||||
-3*(float)Math.Sqrt(70/Pi64),
|
||||
3*(float)Math.Sqrt(5/Pi16),
|
||||
-3*(float)Math.Sqrt(10/Pi64),
|
||||
(float)(1.0/(16.0*SqrtPi)),
|
||||
-3*(float)Math.Sqrt(10/Pi64),
|
||||
3*(float)Math.Sqrt(5/Pi64),
|
||||
-3*(float)Math.Sqrt(70/Pi64),
|
||||
3*(float)Math.Sqrt(35/(4*Pi64)),
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SphericalHarmonics"/> class (null, for serialization).
|
||||
/// </summary>
|
||||
internal SphericalHarmonics()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SphericalHarmonics"/> class.
|
||||
/// </summary>
|
||||
/// <param name="order">The order of the harmonics</param>
|
||||
public SphericalHarmonics(int order)
|
||||
: base(order)
|
||||
{
|
||||
baseValues = new float[order * order];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Evaluates the color for the specified direction.
|
||||
/// </summary>
|
||||
/// <param name="direction">The direction to evaluate.</param>
|
||||
/// <returns>The color computed for this direction.</returns>
|
||||
public override Color3 Evaluate(Vector3 direction)
|
||||
{
|
||||
var x = direction.X;
|
||||
var y = direction.Y;
|
||||
var z = direction.Z;
|
||||
|
||||
var x2 = x*x;
|
||||
var y2 = y*y;
|
||||
var z2 = z*z;
|
||||
|
||||
var z3 = (float)Math.Pow(z, 3.0);
|
||||
|
||||
var x4 = (float)Math.Pow(x, 4.0);
|
||||
var y4 = (float)Math.Pow(y, 4.0);
|
||||
var z4 = (float)Math.Pow(z, 4.0);
|
||||
|
||||
//Equations based on data from: http://ppsloan.org/publications/StupidSH36.pdf
|
||||
baseValues[ 0] = 1/(2*SqrtPi);
|
||||
|
||||
if (Order > 1)
|
||||
{
|
||||
baseValues[ 1] = -(float)Math.Sqrt(3/Pi4)*y;
|
||||
baseValues[ 2] = (float)Math.Sqrt(3/Pi4)*z;
|
||||
baseValues[ 3] = -(float)Math.Sqrt(3/Pi4)*x;
|
||||
|
||||
if (Order > 2)
|
||||
{
|
||||
baseValues[ 4] = (float)Math.Sqrt(15/Pi4)*y*x;
|
||||
baseValues[ 5] = -(float)Math.Sqrt(15/Pi4)*y*z;
|
||||
baseValues[ 6] = (float)Math.Sqrt(5/Pi16)*(3*z2-1);
|
||||
baseValues[ 7] = -(float)Math.Sqrt(15/Pi4)*x*z;
|
||||
baseValues[ 8] = (float)Math.Sqrt(15/Pi16)*(x2-y2);
|
||||
|
||||
if (Order > 3)
|
||||
{
|
||||
baseValues[ 9] = -(float)Math.Sqrt( 70/Pi64)*y*(3*x2-y2);
|
||||
baseValues[10] = (float)Math.Sqrt(105/ Pi4)*y*x*z;
|
||||
baseValues[11] = -(float)Math.Sqrt( 42/Pi64)*y*(-1+5*z2);
|
||||
baseValues[12] = (float)Math.Sqrt( 7/Pi16)*(5*z3-3*z);
|
||||
baseValues[13] = -(float)Math.Sqrt( 42/Pi64)*x*(-1+5*z2);
|
||||
baseValues[14] = (float)Math.Sqrt(105/Pi16)*(x2-y2)*z;
|
||||
baseValues[15] = -(float)Math.Sqrt( 70/Pi64)*x*(x2-3*y2);
|
||||
|
||||
if (Order > 4)
|
||||
{
|
||||
baseValues[16] = 3*(float)Math.Sqrt(35/Pi16)*x*y*(x2-y2);
|
||||
baseValues[17] = -3*(float)Math.Sqrt(70/Pi64)*y*z*(3*x2-y2);
|
||||
baseValues[18] = 3*(float)Math.Sqrt( 5/Pi16)*y*x*(-1+7*z2);
|
||||
baseValues[19] = -3*(float)Math.Sqrt(10/Pi64)*y*z*(-3+7*z2);
|
||||
baseValues[20] = (105*z4-90*z2+9)/(16*SqrtPi);
|
||||
baseValues[21] = -3*(float)Math.Sqrt(10/Pi64)*x*z*(-3+7*z2);
|
||||
baseValues[22] = 3*(float)Math.Sqrt( 5/Pi64)*(x2-y2)*(-1+7*z2);
|
||||
baseValues[23] = -3*(float)Math.Sqrt(70/Pi64)*x*z*(x2-3*y2);
|
||||
baseValues[24] = 3*(float)Math.Sqrt(35/(4*Pi64))*(x4-6*y2*x2+y4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var data = new Color3();
|
||||
|
||||
for (int i = 0; i < baseValues.Length; i++)
|
||||
data += Coefficients[i] * baseValues[i];
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
}
|
||||
640
math/UInt4.cs
Normal file
640
math/UInt4.cs
Normal file
@ -0,0 +1,640 @@
|
||||
// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
|
||||
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
|
||||
//
|
||||
// Copyright (c) 2010-2011 SharpDX - Alexandre Mutel
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Runtime.InteropServices;
|
||||
using Xenko.Core.Serialization;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace math
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a four dimensional mathematical vector.
|
||||
/// </summary>
|
||||
[DataContract]
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
||||
public struct UInt4 : IEquatable<UInt4>, IFormattable
|
||||
{
|
||||
/// <summary>
|
||||
/// The size of the <see cref = "UInt4" /> type, in bytes.
|
||||
/// </summary>
|
||||
public static readonly int SizeInBytes = Utilities.SizeOf<UInt4>();
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref = "UInt4" /> with all of its components set to zero.
|
||||
/// </summary>
|
||||
public static readonly UInt4 Zero = new UInt4();
|
||||
|
||||
/// <summary>
|
||||
/// The X unit <see cref = "UInt4" /> (1, 0, 0, 0).
|
||||
/// </summary>
|
||||
public static readonly UInt4 UnitX = new UInt4(1, 0, 0, 0);
|
||||
|
||||
/// <summary>
|
||||
/// The Y unit <see cref = "UInt4" /> (0, 1, 0, 0).
|
||||
/// </summary>
|
||||
public static readonly UInt4 UnitY = new UInt4(0, 1, 0, 0);
|
||||
|
||||
/// <summary>
|
||||
/// The Z unit <see cref = "UInt4" /> (0, 0, 1, 0).
|
||||
/// </summary>
|
||||
public static readonly UInt4 UnitZ = new UInt4(0, 0, 1, 0);
|
||||
|
||||
/// <summary>
|
||||
/// The W unit <see cref = "UInt4" /> (0, 0, 0, 1).
|
||||
/// </summary>
|
||||
public static readonly UInt4 UnitW = new UInt4(0, 0, 0, 1);
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref = "UInt4" /> with all of its components set to one.
|
||||
/// </summary>
|
||||
public static readonly UInt4 One = new UInt4(1, 1, 1, 1);
|
||||
|
||||
/// <summary>
|
||||
/// The X component of the vector.
|
||||
/// </summary>
|
||||
public uint X;
|
||||
|
||||
/// <summary>
|
||||
/// The Y component of the vector.
|
||||
/// </summary>
|
||||
public uint Y;
|
||||
|
||||
/// <summary>
|
||||
/// The Z component of the vector.
|
||||
/// </summary>
|
||||
public uint Z;
|
||||
|
||||
/// <summary>
|
||||
/// The W component of the vector.
|
||||
/// </summary>
|
||||
public uint W;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref = "UInt4" /> struct.
|
||||
/// </summary>
|
||||
/// <param name = "value">The value that will be assigned to all components.</param>
|
||||
public UInt4(uint value)
|
||||
{
|
||||
X = value;
|
||||
Y = value;
|
||||
Z = value;
|
||||
W = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref = "UInt4" /> struct.
|
||||
/// </summary>
|
||||
/// <param name = "x">Initial value for the X component of the vector.</param>
|
||||
/// <param name = "y">Initial value for the Y component of the vector.</param>
|
||||
/// <param name = "z">Initial value for the Z component of the vector.</param>
|
||||
/// <param name = "w">Initial value for the W component of the vector.</param>
|
||||
public UInt4(uint x, uint y, uint z, uint w)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
Z = z;
|
||||
W = w;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref = "UInt4" /> struct.
|
||||
/// </summary>
|
||||
/// <param name = "values">The values to assign to the X, Y, Z, and W components of the vector. This must be an array with four elements.</param>
|
||||
/// <exception cref = "ArgumentNullException">Thrown when <paramref name = "values" /> is <c>null</c>.</exception>
|
||||
/// <exception cref = "ArgumentOutOfRangeException">Thrown when <paramref name = "values" /> contains more or less than four elements.</exception>
|
||||
public UInt4(uint[] values)
|
||||
{
|
||||
if (values == null)
|
||||
throw new ArgumentNullException("values");
|
||||
if (values.Length != 4)
|
||||
throw new ArgumentOutOfRangeException("values", "There must be four and only four input values for UInt4.");
|
||||
|
||||
X = values[0];
|
||||
Y = values[1];
|
||||
Z = values[2];
|
||||
W = values[3];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the component at the specified index.
|
||||
/// </summary>
|
||||
/// <value>The value of the X, Y, Z, or W component, depending on the index.</value>
|
||||
/// <param name = "index">The index of the component to access. Use 0 for the X component, 1 for the Y component, 2 for the Z component, and 3 for the W component.</param>
|
||||
/// <returns>The value of the component at the specified index.</returns>
|
||||
/// <exception cref = "System.ArgumentOutOfRangeException">Thrown when the <paramref name = "index" /> is out of the range [0, 3].</exception>
|
||||
public uint this[uint index]
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
return X;
|
||||
case 1:
|
||||
return Y;
|
||||
case 2:
|
||||
return Z;
|
||||
case 3:
|
||||
return W;
|
||||
}
|
||||
|
||||
throw new ArgumentOutOfRangeException("index", "Indices for UInt4 run from 0 to 3, inclusive.");
|
||||
}
|
||||
|
||||
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 ArgumentOutOfRangeException("index", "Indices for UInt4 run from 0 to 3, inclusive.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an array containing the elements of the vector.
|
||||
/// </summary>
|
||||
/// <returns>A four-element array containing the components of the vector.</returns>
|
||||
public uint[] ToArray()
|
||||
{
|
||||
return new uint[] { X, Y, Z, W };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds two vectors.
|
||||
/// </summary>
|
||||
/// <param name = "left">The first vector to add.</param>
|
||||
/// <param name = "right">The second vector to add.</param>
|
||||
/// <param name = "result">When the method completes, contains the sum of the two vectors.</param>
|
||||
public static void Add(ref UInt4 left, ref UInt4 right, out UInt4 result)
|
||||
{
|
||||
result = new UInt4(left.X + right.X, left.Y + right.Y, left.Z + right.Z, left.W + right.W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds two vectors.
|
||||
/// </summary>
|
||||
/// <param name = "left">The first vector to add.</param>
|
||||
/// <param name = "right">The second vector to add.</param>
|
||||
/// <returns>The sum of the two vectors.</returns>
|
||||
public static UInt4 Add(UInt4 left, UInt4 right)
|
||||
{
|
||||
return new UInt4(left.X + right.X, left.Y + right.Y, left.Z + right.Z, left.W + right.W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subtracts two vectors.
|
||||
/// </summary>
|
||||
/// <param name = "left">The first vector to subtract.</param>
|
||||
/// <param name = "right">The second vector to subtract.</param>
|
||||
/// <param name = "result">When the method completes, contains the difference of the two vectors.</param>
|
||||
public static void Subtract(ref UInt4 left, ref UInt4 right, out UInt4 result)
|
||||
{
|
||||
result = new UInt4(left.X - right.X, left.Y - right.Y, left.Z - right.Z, left.W - right.W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subtracts two vectors.
|
||||
/// </summary>
|
||||
/// <param name = "left">The first vector to subtract.</param>
|
||||
/// <param name = "right">The second vector to subtract.</param>
|
||||
/// <returns>The difference of the two vectors.</returns>
|
||||
public static UInt4 Subtract(UInt4 left, UInt4 right)
|
||||
{
|
||||
return new UInt4(left.X - right.X, left.Y - right.Y, left.Z - right.Z, left.W - right.W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scales a vector by the given value.
|
||||
/// </summary>
|
||||
/// <param name = "value">The vector to scale.</param>
|
||||
/// <param name = "scale">The amount by which to scale the vector.</param>
|
||||
/// <param name = "result">When the method completes, contains the scaled vector.</param>
|
||||
public static void Multiply(ref UInt4 value, uint scale, out UInt4 result)
|
||||
{
|
||||
result = new UInt4(value.X * scale, value.Y * scale, value.Z * scale, value.W * scale);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scales a vector by the given value.
|
||||
/// </summary>
|
||||
/// <param name = "value">The vector to scale.</param>
|
||||
/// <param name = "scale">The amount by which to scale the vector.</param>
|
||||
/// <returns>The scaled vector.</returns>
|
||||
public static UInt4 Multiply(UInt4 value, uint scale)
|
||||
{
|
||||
return new UInt4(value.X * scale, value.Y * scale, value.Z * scale, value.W * scale);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Modulates a vector with another by performing component-wise multiplication.
|
||||
/// </summary>
|
||||
/// <param name = "left">The first vector to modulate.</param>
|
||||
/// <param name = "right">The second vector to modulate.</param>
|
||||
/// <param name = "result">When the method completes, contains the modulated vector.</param>
|
||||
public static void Modulate(ref UInt4 left, ref UInt4 right, out UInt4 result)
|
||||
{
|
||||
result = new UInt4(left.X * right.X, left.Y * right.Y, left.Z * right.Z, left.W * right.W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Modulates a vector with another by performing component-wise multiplication.
|
||||
/// </summary>
|
||||
/// <param name = "left">The first vector to modulate.</param>
|
||||
/// <param name = "right">The second vector to modulate.</param>
|
||||
/// <returns>The modulated vector.</returns>
|
||||
public static UInt4 Modulate(UInt4 left, UInt4 right)
|
||||
{
|
||||
return new UInt4(left.X * right.X, left.Y * right.Y, left.Z * right.Z, left.W * right.W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scales a vector by the given value.
|
||||
/// </summary>
|
||||
/// <param name = "value">The vector to scale.</param>
|
||||
/// <param name = "scale">The amount by which to scale the vector.</param>
|
||||
/// <param name = "result">When the method completes, contains the scaled vector.</param>
|
||||
public static void Divide(ref UInt4 value, uint scale, out UInt4 result)
|
||||
{
|
||||
result = new UInt4(value.X / scale, value.Y / scale, value.Z / scale, value.W / scale);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scales a vector by the given value.
|
||||
/// </summary>
|
||||
/// <param name = "value">The vector to scale.</param>
|
||||
/// <param name = "scale">The amount by which to scale the vector.</param>
|
||||
/// <returns>The scaled vector.</returns>
|
||||
public static UInt4 Divide(UInt4 value, uint scale)
|
||||
{
|
||||
return new UInt4(value.X / scale, value.Y / scale, value.Z / scale, value.W / scale);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restricts a value to be within a specified range.
|
||||
/// </summary>
|
||||
/// <param name = "value">The value to clamp.</param>
|
||||
/// <param name = "min">The minimum value.</param>
|
||||
/// <param name = "max">The maximum value.</param>
|
||||
/// <param name = "result">When the method completes, contains the clamped value.</param>
|
||||
public static void Clamp(ref UInt4 value, ref UInt4 min, ref UInt4 max, out UInt4 result)
|
||||
{
|
||||
uint x = value.X;
|
||||
x = (x > max.X) ? max.X : x;
|
||||
x = (x < min.X) ? min.X : x;
|
||||
|
||||
uint y = value.Y;
|
||||
y = (y > max.Y) ? max.Y : y;
|
||||
y = (y < min.Y) ? min.Y : y;
|
||||
|
||||
uint z = value.Z;
|
||||
z = (z > max.Z) ? max.Z : z;
|
||||
z = (z < min.Z) ? min.Z : z;
|
||||
|
||||
uint w = value.W;
|
||||
w = (w > max.W) ? max.W : w;
|
||||
w = (w < min.W) ? min.W : w;
|
||||
|
||||
result = new UInt4(x, y, z, w);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restricts a value to be within a specified range.
|
||||
/// </summary>
|
||||
/// <param name = "value">The value to clamp.</param>
|
||||
/// <param name = "min">The minimum value.</param>
|
||||
/// <param name = "max">The maximum value.</param>
|
||||
/// <returns>The clamped value.</returns>
|
||||
public static UInt4 Clamp(UInt4 value, UInt4 min, UInt4 max)
|
||||
{
|
||||
UInt4 result;
|
||||
Clamp(ref value, ref min, ref max, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a vector containing the smallest components of the specified vectors.
|
||||
/// </summary>
|
||||
/// <param name = "left">The first source vector.</param>
|
||||
/// <param name = "right">The second source vector.</param>
|
||||
/// <param name = "result">When the method completes, contains an new vector composed of the largest components of the source vectors.</param>
|
||||
public static void Max(ref UInt4 left, ref UInt4 right, out UInt4 result)
|
||||
{
|
||||
result.X = (left.X > right.X) ? left.X : right.X;
|
||||
result.Y = (left.Y > right.Y) ? left.Y : right.Y;
|
||||
result.Z = (left.Z > right.Z) ? left.Z : right.Z;
|
||||
result.W = (left.W > right.W) ? left.W : right.W;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a vector containing the largest components of the specified vectors.
|
||||
/// </summary>
|
||||
/// <param name = "left">The first source vector.</param>
|
||||
/// <param name = "right">The second source vector.</param>
|
||||
/// <returns>A vector containing the largest components of the source vectors.</returns>
|
||||
public static UInt4 Max(UInt4 left, UInt4 right)
|
||||
{
|
||||
UInt4 result;
|
||||
Max(ref left, ref right, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a vector containing the smallest components of the specified vectors.
|
||||
/// </summary>
|
||||
/// <param name = "left">The first source vector.</param>
|
||||
/// <param name = "right">The second source vector.</param>
|
||||
/// <param name = "result">When the method completes, contains an new vector composed of the smallest components of the source vectors.</param>
|
||||
public static void Min(ref UInt4 left, ref UInt4 right, out UInt4 result)
|
||||
{
|
||||
result.X = (left.X < right.X) ? left.X : right.X;
|
||||
result.Y = (left.Y < right.Y) ? left.Y : right.Y;
|
||||
result.Z = (left.Z < right.Z) ? left.Z : right.Z;
|
||||
result.W = (left.W < right.W) ? left.W : right.W;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a vector containing the smallest components of the specified vectors.
|
||||
/// </summary>
|
||||
/// <param name = "left">The first source vector.</param>
|
||||
/// <param name = "right">The second source vector.</param>
|
||||
/// <returns>A vector containing the smallest components of the source vectors.</returns>
|
||||
public static UInt4 Min(UInt4 left, UInt4 right)
|
||||
{
|
||||
UInt4 result;
|
||||
Min(ref left, ref right, out result);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds two vectors.
|
||||
/// </summary>
|
||||
/// <param name = "left">The first vector to add.</param>
|
||||
/// <param name = "right">The second vector to add.</param>
|
||||
/// <returns>The sum of the two vectors.</returns>
|
||||
public static UInt4 operator +(UInt4 left, UInt4 right)
|
||||
{
|
||||
return new UInt4(left.X + right.X, left.Y + right.Y, left.Z + right.Z, left.W + right.W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assert a vector (return it unchanged).
|
||||
/// </summary>
|
||||
/// <param name = "value">The vector to assert (unchange).</param>
|
||||
/// <returns>The asserted (unchanged) vector.</returns>
|
||||
public static UInt4 operator +(UInt4 value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subtracts two vectors.
|
||||
/// </summary>
|
||||
/// <param name = "left">The first vector to subtract.</param>
|
||||
/// <param name = "right">The second vector to subtract.</param>
|
||||
/// <returns>The difference of the two vectors.</returns>
|
||||
public static UInt4 operator -(UInt4 left, UInt4 right)
|
||||
{
|
||||
return new UInt4(left.X - right.X, left.Y - right.Y, left.Z - right.Z, left.W - right.W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scales a vector by the given value.
|
||||
/// </summary>
|
||||
/// <param name = "value">The vector to scale.</param>
|
||||
/// <param name = "scale">The amount by which to scale the vector.</param>
|
||||
/// <returns>The scaled vector.</returns>
|
||||
public static UInt4 operator *(uint scale, UInt4 value)
|
||||
{
|
||||
return new UInt4(value.X * scale, value.Y * scale, value.Z * scale, value.W * scale);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scales a vector by the given value.
|
||||
/// </summary>
|
||||
/// <param name = "value">The vector to scale.</param>
|
||||
/// <param name = "scale">The amount by which to scale the vector.</param>
|
||||
/// <returns>The scaled vector.</returns>
|
||||
public static UInt4 operator *(UInt4 value, uint scale)
|
||||
{
|
||||
return new UInt4(value.X * scale, value.Y * scale, value.Z * scale, value.W * scale);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scales a vector by the given value.
|
||||
/// </summary>
|
||||
/// <param name = "value">The vector to scale.</param>
|
||||
/// <param name = "scale">The amount by which to scale the vector.</param>
|
||||
/// <returns>The scaled vector.</returns>
|
||||
public static UInt4 operator /(UInt4 value, uint scale)
|
||||
{
|
||||
return new UInt4(value.X / scale, value.Y / scale, value.Z / scale, value.W / scale);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests for equality between two objects.
|
||||
/// </summary>
|
||||
/// <param name = "left">The first value to compare.</param>
|
||||
/// <param name = "right">The second value to compare.</param>
|
||||
/// <returns><c>true</c> if <paramref name = "left" /> has the same value as <paramref name = "right" />; otherwise, <c>false</c>.</returns>
|
||||
public static bool operator ==(UInt4 left, UInt4 right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests for inequality between two objects.
|
||||
/// </summary>
|
||||
/// <param name = "left">The first value to compare.</param>
|
||||
/// <param name = "right">The second value to compare.</param>
|
||||
/// <returns><c>true</c> if <paramref name = "left" /> has a different value than <paramref name = "right" />; otherwise, <c>false</c>.</returns>
|
||||
public static bool operator !=(UInt4 left, UInt4 right)
|
||||
{
|
||||
return !left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an explicit conversion from <see cref = "UInt4" /> to <see cref = "Vec2" />.
|
||||
/// </summary>
|
||||
/// <param name = "value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static explicit operator Vec2(UInt4 value)
|
||||
{
|
||||
return new Vec2(value.X, value.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an explicit conversion from <see cref = "UInt4" /> to <see cref = "Vector3" />.
|
||||
/// </summary>
|
||||
/// <param name = "value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static explicit operator Vector3(UInt4 value)
|
||||
{
|
||||
return new Vector3(value.X, value.Y, value.Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an explicit conversion from <see cref = "UInt4" /> to <see cref = "Vector4" />.
|
||||
/// </summary>
|
||||
/// <param name = "value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static explicit operator Vector4(UInt4 value)
|
||||
{
|
||||
return new Vector4(value.X, value.Y, value.Z, value.W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref = "string" /> that represents this instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref = "string" /> that represents this instance.
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, "X:{0} Y:{1} Z:{2} W:{3}", X, Y, Z, W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref = "string" /> that represents this instance.
|
||||
/// </summary>
|
||||
/// <param name = "format">The format.</param>
|
||||
/// <returns>
|
||||
/// A <see cref = "string" /> that represents this instance.
|
||||
/// </returns>
|
||||
public string ToString(string format)
|
||||
{
|
||||
if (format == null)
|
||||
return ToString();
|
||||
|
||||
return string.Format(CultureInfo.CurrentCulture, "X:{0} Y:{1} Z:{2} W:{3}",
|
||||
X.ToString(format, CultureInfo.CurrentCulture),
|
||||
Y.ToString(format, CultureInfo.CurrentCulture),
|
||||
Z.ToString(format, CultureInfo.CurrentCulture),
|
||||
W.ToString(format, CultureInfo.CurrentCulture));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref = "string" /> that represents this instance.
|
||||
/// </summary>
|
||||
/// <param name = "formatProvider">The format provider.</param>
|
||||
/// <returns>
|
||||
/// A <see cref = "string" /> that represents this instance.
|
||||
/// </returns>
|
||||
public string ToString(IFormatProvider formatProvider)
|
||||
{
|
||||
return string.Format(formatProvider, "X:{0} Y:{1} Z:{2} W:{3}", X, Y, Z, W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref = "string" /> that represents this instance.
|
||||
/// </summary>
|
||||
/// <param name = "format">The format.</param>
|
||||
/// <param name = "formatProvider">The format provider.</param>
|
||||
/// <returns>
|
||||
/// A <see cref = "string" /> that represents this instance.
|
||||
/// </returns>
|
||||
public string ToString(string format, IFormatProvider formatProvider)
|
||||
{
|
||||
if (format == null)
|
||||
ToString(formatProvider);
|
||||
|
||||
return string.Format(formatProvider, "X:{0} Y:{1} Z:{2} W:{3}", X.ToString(format, formatProvider),
|
||||
Y.ToString(format, formatProvider), Z.ToString(format, formatProvider),
|
||||
W.ToString(format, formatProvider));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a hash code for this instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
|
||||
/// </returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return X.GetHashCode() + Y.GetHashCode() + Z.GetHashCode() + W.GetHashCode();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref = "UInt4" /> is equal to this instance.
|
||||
/// </summary>
|
||||
/// <param name = "other">The <see cref = "UInt4" /> to compare with this instance.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the specified <see cref = "UInt4" /> is equal to this instance; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public bool Equals(UInt4 other)
|
||||
{
|
||||
return other.X == X && other.Y == Y && other.Z == Z && other.W == W;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref = "object" /> is equal to this instance.
|
||||
/// </summary>
|
||||
/// <param name = "value">The <see cref = "object" /> to compare with this instance.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the specified <see cref = "object" /> is equal to this instance; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public override bool Equals(object value)
|
||||
{
|
||||
if (value == null)
|
||||
return false;
|
||||
|
||||
if (value.GetType() != GetType())
|
||||
return false;
|
||||
|
||||
return Equals((UInt4)value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an implicit conversion from <see cref="uint"/> array to <see cref="math.UInt4"/>.
|
||||
/// </summary>
|
||||
/// <param name="input">The input.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator UInt4(uint[] input)
|
||||
{
|
||||
return new UInt4(input);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs an implicit conversion from <see cref="math.UInt4"/> to <see cref="int"/> array.
|
||||
/// </summary>
|
||||
/// <param name="input">The input.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator uint[](UInt4 input)
|
||||
{
|
||||
return input.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
1462
math/Vector2.cs
Normal file
1462
math/Vector2.cs
Normal file
File diff suppressed because it is too large
Load Diff
1737
math/Vector3.cs
Normal file
1737
math/Vector3.cs
Normal file
File diff suppressed because it is too large
Load Diff
1410
math/Vector4.cs
Normal file
1410
math/Vector4.cs
Normal file
File diff suppressed because it is too large
Load Diff
64
math/VectorExtensions.cs
Normal file
64
math/VectorExtensions.cs
Normal file
@ -0,0 +1,64 @@
|
||||
// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
|
||||
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
|
||||
namespace math
|
||||
{
|
||||
/// <summary>
|
||||
/// Extensions methods of the vector classes.
|
||||
/// </summary>
|
||||
public static class VectorExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Return the Y/X components of the vector in the inverse order.
|
||||
/// </summary>
|
||||
/// <param name="vector">the input vector</param>
|
||||
public static Vec2 YX(this Vec2 vector)
|
||||
{
|
||||
return new Vec2(vector.Y, vector.X);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the X/Y components of the vector.
|
||||
/// </summary>
|
||||
/// <param name="vector">the input vector</param>
|
||||
public static Vec2 XY(this Vector3 vector)
|
||||
{
|
||||
return new Vec2(vector.X, vector.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the X/Z components of the vector.
|
||||
/// </summary>
|
||||
/// <param name="vector">the input vector</param>
|
||||
public static Vec2 XZ(this Vector3 vector)
|
||||
{
|
||||
return new Vec2(vector.X, vector.Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the Y/Z components of the vector.
|
||||
/// </summary>
|
||||
/// <param name="vector">the input vector</param>
|
||||
public static Vec2 YZ(this Vector3 vector)
|
||||
{
|
||||
return new Vec2(vector.Y, vector.Z);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the X/Y components of the vector.
|
||||
/// </summary>
|
||||
/// <param name="vector">the input vector</param>
|
||||
public static Vec2 XY(this Vector4 vector)
|
||||
{
|
||||
return new Vec2(vector.X, vector.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the X/Y/Z components of the vector.
|
||||
/// </summary>
|
||||
/// <param name="vector">the input vector</param>
|
||||
public static Vector3 XYZ(this Vector4 vector)
|
||||
{
|
||||
return new Vector3(vector.X, vector.Y, vector.Z);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user