summaryrefslogtreecommitdiff
path: root/Runtime/Export/Math.txt
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2019-08-14 22:50:43 +0800
committerchai <chaifix@163.com>2019-08-14 22:50:43 +0800
commit15740faf9fe9fe4be08965098bbf2947e096aeeb (patch)
treea730ec236656cc8cab5b13f088adfaed6bb218fb /Runtime/Export/Math.txt
+Unity Runtime codeHEADmaster
Diffstat (limited to 'Runtime/Export/Math.txt')
-rw-r--r--Runtime/Export/Math.txt2391
1 files changed, 2391 insertions, 0 deletions
diff --git a/Runtime/Export/Math.txt b/Runtime/Export/Math.txt
new file mode 100644
index 0000000..6dbd21f
--- /dev/null
+++ b/Runtime/Export/Math.txt
@@ -0,0 +1,2391 @@
+C++RAW
+
+#include "UnityPrefix.h"
+#include "Runtime/Math/Quaternion.h"
+#include "Runtime/Utilities/Utility.h"
+#include "Runtime/Geometry/AABB.h"
+#include "Runtime/Geometry/Ray.h"
+#include "Runtime/Geometry/Ray2D.h"
+#include "Runtime/Geometry/Intersection.h"
+#include <vector>
+#include "Runtime/Utilities/BitUtility.h"
+#include "Runtime/Terrain/PerlinNoise.h"
+#include "Runtime/Camera/CameraUtil.h"
+#include "Runtime/Math/Color.h"
+#include "Runtime/Math/ColorSpaceConversion.h"
+#include "Runtime/Scripting/ScriptingUtility.h"
+
+CSRAW
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+namespace UnityEngine
+{
+
+// Representation of 2D vectors and points.
+THREAD_SAFE
+STRUCT Vector2
+ // X component of the vector.
+ CSRAW public float x;
+ // Y component of the vector.
+ CSRAW public float y;
+
+ // Access the /x/ or /y/ component using [0] or [1] respectively.
+ CSRAW public float this [int index]
+ {
+ get
+ {
+ switch(index)
+ {
+ case 0: return x;
+ case 1: return y;
+ default:
+ throw new IndexOutOfRangeException("Invalid Vector2 index!");
+ }
+ }
+
+ set
+ {
+ switch(index)
+ {
+ case 0: x = value; break;
+ case 1: y = value; break;
+ default:
+ throw new IndexOutOfRangeException("Invalid Vector2 index!");
+ }
+ }
+ }
+
+ // Constructs a new vector with given x, y components.
+ public Vector2 (float x, float y) { this.x = x; this.y = y; }
+
+ // Set x and y components of an existing Vector2.
+ CSRAW public void Set (float new_x, float new_y) { x = new_x; y = new_y; }
+
+ // Linearly interpolates between two vectors.
+ CSRAW public static Vector2 Lerp (Vector2 from, Vector2 to, float t)
+ {
+ t = Mathf.Clamp01 (t);
+ return new Vector2(
+ from.x + (to.x - from.x)*t,
+ from.y + (to.y - from.y)*t
+ );
+ }
+
+ // Moves a point /current/ towards /target/.
+ CSRAW static public Vector2 MoveTowards (Vector2 current, Vector2 target, float maxDistanceDelta)
+ {
+ Vector2 toVector = target - current;
+ float dist = toVector.magnitude;
+ if (dist <= maxDistanceDelta || dist == 0)
+ return target;
+ return current + toVector / dist * maxDistanceDelta;
+ }
+
+ // Multiplies two vectors component-wise.
+ CSRAW public static Vector2 Scale (Vector2 a, Vector2 b) { return new Vector2 (a.x*b.x, a.y*b.y); }
+
+ // Multiplies every component of this vector by the same component of /scale/.
+ CSRAW public void Scale (Vector2 scale) { x *= scale.x; y *= scale.y; }
+
+ // Makes this vector have a ::ref::magnitude of 1.
+ CSRAW public void Normalize ()
+ {
+ float mag = this.magnitude;
+ if (mag > kEpsilon)
+ this = this / mag;
+ else
+ this = zero;
+ }
+
+ // Returns this vector with a ::ref::magnitude of 1 (RO).
+ CSRAW public Vector2 normalized { get {
+ Vector2 v = new Vector2(x, y);
+ v.Normalize();
+ return v;
+ } }
+
+ /// *listonly*
+ CSRAW override public string ToString() { return UnityString.Format("({0:F1}, {1:F1})", x, y); }
+ // Returns a nicely formatted string for this vector.
+ CSRAW public string ToString(string format) {
+ return UnityString.Format("({0}, {1})", x.ToString(format), y.ToString(format));
+ }
+
+ // used to allow Vector2s to be used as keys in hash tables
+ public override int GetHashCode() {
+ return x.GetHashCode() ^ (y.GetHashCode()<<2);
+ }
+
+ // also required for being able to use Vector2s as keys in hash tables
+ public override bool Equals(object other) {
+ if(!(other is Vector2)) return false;
+
+ Vector2 rhs=(Vector2)other;
+ return x.Equals(rhs.x) && y.Equals(rhs.y);
+ }
+
+ // Dot Product of two vectors.
+ public static float Dot (Vector2 lhs, Vector2 rhs) { return lhs.x*rhs.x + lhs.y*rhs.y; }
+
+ // Returns the length of this vector (RO).
+ CSRAW public float magnitude { get { return Mathf.Sqrt (x*x + y*y); } }
+ // Returns the squared length of this vector (RO).
+ CSRAW public float sqrMagnitude { get { return x*x + y*y; } }
+
+ // Returns the angle in degrees between /from/ and /to/.
+ CSRAW public static float Angle(Vector2 from, Vector2 to) { return Mathf.Acos(Mathf.Clamp (Vector2.Dot (from.normalized, to.normalized), -1F, 1F)) * Mathf.Rad2Deg; }
+
+ // Returns the distance between /a/ and /b/.
+ CSRAW public static float Distance (Vector2 a, Vector2 b) { return (a-b).magnitude; }
+
+ // Returns a copy of /vector/ with its magnitude clamped to /maxLength/.
+ CSRAW public static Vector2 ClampMagnitude (Vector2 vector, float maxLength)
+ {
+ if (vector.sqrMagnitude > maxLength * maxLength)
+ return vector.normalized * maxLength;
+ return vector;
+ }
+
+ OBSOLETE planned Use Vector2.sqrMagnitude
+ CSRAW public static float SqrMagnitude (Vector2 a) { return a.x*a.x + a.y*a.y; }
+ OBSOLETE planned Use .sqrMagnitude
+ CSRAW public float SqrMagnitude () { return x*x + y*y; }
+
+ // Returns a vector that is made from the smallest components of two vectors.
+ CSRAW public static Vector2 Min (Vector2 lhs, Vector2 rhs) { return new Vector2 (Mathf.Min(lhs.x,rhs.x), Mathf.Min(lhs.y,rhs.y)); }
+
+ // Returns a vector that is made from the largest components of two vectors.
+ CSRAW public static Vector2 Max (Vector2 lhs, Vector2 rhs) { return new Vector2 (Mathf.Max(lhs.x,rhs.x), Mathf.Max(lhs.y,rhs.y)); }
+
+ // Adds two vectors.
+ CSRAW public static Vector2 operator + (Vector2 a, Vector2 b) { return new Vector2 (a.x+b.x, a.y+b.y); }
+ // Subtracts one vector from another.
+ CSRAW public static Vector2 operator - (Vector2 a, Vector2 b) { return new Vector2 (a.x-b.x, a.y-b.y); }
+ // Negates a vector.
+ CSRAW public static Vector2 operator - (Vector2 a) { return new Vector2 (-a.x, -a.y); }
+ // Multiplies a vector by a number.
+ CSRAW public static Vector2 operator * (Vector2 a, float d) { return new Vector2 (a.x*d, a.y*d); }
+ // Multiplies a vector by a number.
+ CSRAW public static Vector2 operator * (float d, Vector2 a) { return new Vector2 (a.x*d, a.y*d); }
+ // Divides a vector by a number.
+ CSRAW public static Vector2 operator / (Vector2 a, float d) { return new Vector2 (a.x/d, a.y/d); }
+ // Returns true if the vectors are equal.
+ CSRAW public static bool operator == (Vector2 lhs, Vector2 rhs) {
+ return SqrMagnitude (lhs - rhs) < kEpsilon * kEpsilon;
+ }
+ // Returns true if vectors different.
+ CSRAW public static bool operator != (Vector2 lhs, Vector2 rhs)
+ {
+ return SqrMagnitude (lhs - rhs) >= kEpsilon * kEpsilon;
+ }
+
+ // Converts a [[Vector3]] to a Vector2.
+ CSRAW public static implicit operator Vector2(Vector3 v) {
+ return new Vector2(v.x, v.y);
+ }
+ // Converts a Vector2 to a [[Vector3]].
+ CSRAW public static implicit operator Vector3(Vector2 v) {
+ return new Vector3(v.x, v.y, 0);
+ }
+
+ // Shorthand for writing @@Vector2(0, 0)@@
+ CSRAW public static Vector2 zero { get { return new Vector2 (0.0F, 0.0F); } }
+ // Shorthand for writing @@Vector2(1, 1)@@
+ CSRAW public static Vector2 one { get { return new Vector2 (1.0F, 1.0F); } }
+ // Shorthand for writing @@Vector2(0, 1)@@
+ CSRAW public static Vector2 up { get { return new Vector2 (0.0F, 1.0F); } }
+ // Shorthand for writing @@Vector2(1, 0)@@
+ CSRAW public static Vector2 right { get { return new Vector2 (1.0F, 0.0F); } }
+
+ // *Undocumented*
+ CSRAW public const float kEpsilon = 0.00001F;
+END
+
+
+// Representation of 3D vectors and points.
+CSRAW
+THREAD_SAFE
+STRUCT Vector3
+
+ // *undocumented*
+ CSRAW public const float kEpsilon = 0.00001F;
+
+ // X component of the vector.
+ CSRAW public float x;
+ // Y component of the vector.
+ CSRAW public float y;
+ // Z component of the vector.
+ CSRAW public float z;
+
+
+ // Linearly interpolates between two vectors.
+ CSRAW public static Vector3 Lerp (Vector3 from, Vector3 to, float t)
+ {
+ t = Mathf.Clamp01 (t);
+ return new Vector3(
+ from.x + (to.x - from.x)*t,
+ from.y + (to.y - from.y)*t,
+ from.z + (to.z - from.z)*t
+ );
+ }
+
+
+ // Spherically interpolates between two vectors.
+ CUSTOM static Vector3 Slerp (Vector3 from, Vector3 to, float t) { return Slerp (from, to, clamp01 (t)); }
+
+
+ CUSTOM private static void Internal_OrthoNormalize2 (ref Vector3 a, ref Vector3 b) { OrthoNormalize (&a, &b); }
+ CUSTOM private static void Internal_OrthoNormalize3 (ref Vector3 a, ref Vector3 b, ref Vector3 c) { OrthoNormalize (&a, &b, &c); }
+
+ // Makes vectors normalized and orthogonal to each other.
+ CSRAW static public void OrthoNormalize (ref Vector3 normal, ref Vector3 tangent) { Internal_OrthoNormalize2 (ref normal, ref tangent); }
+ // Makes vectors normalized and orthogonal to each other.
+ CSRAW static public void OrthoNormalize (ref Vector3 normal, ref Vector3 tangent, ref Vector3 binormal) { Internal_OrthoNormalize3 (ref normal, ref tangent, ref binormal); }
+
+
+ // Moves a point /current/ in a straight line towards a /target/ point.
+ CSRAW static public Vector3 MoveTowards (Vector3 current, Vector3 target, float maxDistanceDelta)
+ {
+ Vector3 toVector = target - current;
+ float dist = toVector.magnitude;
+ if (dist <= maxDistanceDelta || dist == 0)
+ return target;
+ return current + toVector / dist * maxDistanceDelta;
+ }
+
+ // Rotates a vector /current/ towards /target/.
+ CUSTOM static Vector3 RotateTowards (Vector3 current, Vector3 target, float maxRadiansDelta, float maxMagnitudeDelta) { return RotateTowards (current, target, maxRadiansDelta, maxMagnitudeDelta); }
+
+ // Gradually changes a vector towards a desired goal over time.
+ CSRAW public static Vector3 SmoothDamp (Vector3 current, Vector3 target, ref Vector3 currentVelocity, float smoothTime, float maxSpeed = Mathf.Infinity, float deltaTime = Time.deltaTime)
+ {
+ // Based on Game Programming Gems 4 Chapter 1.10
+ smoothTime = Mathf.Max(0.0001F, smoothTime);
+ float omega = 2F / smoothTime;
+
+ float x = omega * deltaTime;
+ float exp = 1F / (1F + x + 0.48F*x*x + 0.235F*x*x*x);
+ Vector3 change = current - target;
+ Vector3 originalTo = target;
+
+ // Clamp maximum speed
+ float maxChange = maxSpeed * smoothTime;
+ change = Vector3.ClampMagnitude(change, maxChange);
+ target = current - change;
+
+ Vector3 temp = (currentVelocity + omega * change) * deltaTime;
+ currentVelocity = (currentVelocity - omega * temp) * exp;
+ Vector3 output = target + (change + temp) * exp;
+
+ // Prevent overshooting
+ if (Vector3.Dot(originalTo - current, output - originalTo) > 0)
+ {
+ output = originalTo;
+ currentVelocity = (output - originalTo) / deltaTime;
+ }
+
+ return output;
+ }
+
+ // Access the x, y, z components using [0], [1], [2] respectively.
+ CSRAW public float this [int index]
+ {
+ get
+ {
+ switch(index)
+ {
+ case 0: return x;
+ case 1: return y;
+ case 2: return z;
+ default:
+ throw new IndexOutOfRangeException("Invalid Vector3 index!");
+ }
+ }
+
+ set
+ {
+ switch(index)
+ {
+ case 0: x = value; break;
+ case 1: y = value; break;
+ case 2: z = value; break;
+ default:
+ throw new IndexOutOfRangeException("Invalid Vector3 index!");
+ }
+ }
+ }
+
+ // Creates a new vector with given x, y, z components.
+ public Vector3 (float x, float y, float z) { this.x = x; this.y = y; this.z = z; }
+ // Creates a new vector with given x, y components and sets /z/ to zero.
+ public Vector3 (float x, float y) { this.x = x; this.y = y; z = 0F; }
+
+ // Set x, y and z components of an existing Vector3.
+ CSRAW public void Set (float new_x, float new_y, float new_z) { x = new_x; y = new_y; z = new_z; }
+
+ // Multiplies two vectors component-wise.
+ CSRAW public static Vector3 Scale (Vector3 a, Vector3 b) { return new Vector3 (a.x*b.x, a.y*b.y, a.z*b.z); }
+
+ // Multiplies every component of this vector by the same component of /scale/.
+ CSRAW public void Scale (Vector3 scale) { x *= scale.x; y *= scale.y; z *= scale.z; }
+
+ // Cross Product of two vectors.
+ CSRAW public static Vector3 Cross (Vector3 lhs, Vector3 rhs)
+ {
+ return new Vector3 (
+ lhs.y * rhs.z - lhs.z * rhs.y,
+ lhs.z * rhs.x - lhs.x * rhs.z,
+ lhs.x * rhs.y - lhs.y * rhs.x);
+ }
+
+ // used to allow Vector3s to be used as keys in hash tables
+ public override int GetHashCode() {
+ return x.GetHashCode() ^ (y.GetHashCode()<<2) ^ (z.GetHashCode()>>2);
+ }
+
+ // also required for being able to use Vector3s as keys in hash tables
+ public override bool Equals(object other) {
+ if(!(other is Vector3)) return false;
+
+ Vector3 rhs=(Vector3)other;
+ return x.Equals(rhs.x) && y.Equals(rhs.y) && z.Equals(rhs.z);
+ }
+
+ // Reflects a vector off the plane defined by a normal.
+ CSRAW public static Vector3 Reflect (Vector3 inDirection, Vector3 inNormal)
+ {
+ return -2F * Dot (inNormal, inDirection) * inNormal + inDirection;
+ }
+
+ // *undoc* --- we have normalized property now
+ CSRAW public static Vector3 Normalize (Vector3 value)
+ {
+ float mag = Magnitude (value);
+ if (mag > kEpsilon)
+ return value / mag;
+ else
+ return zero;
+ }
+
+ // Makes this vector have a ::ref::magnitude of 1.
+ CSRAW public void Normalize ()
+ {
+ float mag = Magnitude (this);
+ if (mag > kEpsilon)
+ this = this / mag;
+ else
+ this = zero;
+ }
+
+ // Returns this vector with a ::ref::magnitude of 1 (RO).
+ CSRAW public Vector3 normalized { get { return Vector3.Normalize (this); } }
+
+ /// *listonly*
+ CSRAW override public string ToString() { return UnityString.Format("({0:F1}, {1:F1}, {2:F1})", x, y, z); }
+ // Returns a nicely formatted string for this vector.
+ CSRAW public string ToString(string format) {
+ return UnityString.Format("({0}, {1}, {2})", x.ToString(format), y.ToString(format), z.ToString(format));
+ }
+
+ // Dot Product of two vectors.
+ public static float Dot (Vector3 lhs, Vector3 rhs) { return lhs.x*rhs.x + lhs.y*rhs.y + lhs.z*rhs.z; }
+
+ // Projects a vector onto another vector.
+ public static Vector3 Project (Vector3 vector, Vector3 onNormal) {
+ float sqrMag = Dot(onNormal,onNormal);
+ if (sqrMag < Mathf.Epsilon)
+ return zero;
+ else
+ return onNormal * Dot (vector, onNormal) / sqrMag;
+ }
+
+ //*undocumented* --------------------------- TODO is this generally useful? What is the intention? I know i understood it once upon a time but it evaded my mind.
+ CSRAW public static Vector3 Exclude (Vector3 excludeThis, Vector3 fromThat) {
+ return fromThat - Project (fromThat, excludeThis);
+ }
+
+ // Returns the angle in degrees between /from/ and /to/. This is always the smallest
+ CSRAW public static float Angle(Vector3 from, Vector3 to) { return Mathf.Acos(Mathf.Clamp (Vector3.Dot (from.normalized, to.normalized), -1F, 1F)) * Mathf.Rad2Deg; }
+
+ // Returns the distance between /a/ and /b/.
+ public static float Distance (Vector3 a, Vector3 b) { Vector3 vec = new Vector3 (a.x - b.x, a.y - b.y, a.z - b.z); return Mathf.Sqrt (vec.x * vec.x + vec.y * vec.y + vec.z * vec.z); }
+
+ // Returns a copy of /vector/ with its magnitude clamped to /maxLength/.
+ CSRAW public static Vector3 ClampMagnitude (Vector3 vector, float maxLength)
+ {
+ if (vector.sqrMagnitude > maxLength * maxLength)
+ return vector.normalized * maxLength;
+ return vector;
+ }
+
+ // *undoc* --- there's a property now
+ CSRAW public static float Magnitude (Vector3 a) { return Mathf.Sqrt (a.x*a.x + a.y*a.y + a.z*a.z); }
+
+ // Returns the length of this vector (RO).
+ CSRAW public float magnitude { get { return Mathf.Sqrt (x*x + y*y + z*z); } }
+
+ // *undoc* --- there's a property now
+ CSRAW public static float SqrMagnitude (Vector3 a) { return a.x*a.x + a.y*a.y + a.z*a.z; }
+
+ // Returns the squared length of this vector (RO).
+ CSRAW public float sqrMagnitude { get { return x * x + y * y + z * z; } }
+
+
+ // Returns a vector that is made from the smallest components of two vectors.
+ CSRAW public static Vector3 Min (Vector3 lhs, Vector3 rhs) { return new Vector3 (Mathf.Min(lhs.x,rhs.x), Mathf.Min(lhs.y,rhs.y), Mathf.Min(lhs.z,rhs.z)); }
+
+ // Returns a vector that is made from the largest components of two vectors.
+ CSRAW public static Vector3 Max (Vector3 lhs, Vector3 rhs) { return new Vector3 (Mathf.Max(lhs.x,rhs.x), Mathf.Max(lhs.y,rhs.y), Mathf.Max(lhs.z,rhs.z)); }
+
+ // Shorthand for writing @@Vector3(0, 0, 0)@@
+ CSRAW public static Vector3 zero { get { return new Vector3 (0F, 0F, 0F); } }
+ // Shorthand for writing @@Vector3(1, 1, 1)@@
+ CSRAW public static Vector3 one { get { return new Vector3 (1F, 1F, 1F); } }
+ // Shorthand for writing @@Vector3(0, 0, 1)@@
+ CSRAW public static Vector3 forward { get { return new Vector3 (0F, 0F, 1F); } }
+ OBSOLETE planned Use -Vector3.forward
+ CSRAW public static Vector3 back { get { return new Vector3 (0F, 0F, -1F); } }
+ // Shorthand for writing @@Vector3(0, 1, 0)@@
+ CSRAW public static Vector3 up { get { return new Vector3 (0F, 1F, 0F); } }
+ OBSOLETE planned Use -Vector3.up
+ CSRAW public static Vector3 down { get { return new Vector3 (0F, -1F, 0F); } }
+ OBSOLETE planned Use -Vector3.right
+ CSRAW public static Vector3 left { get { return new Vector3 (-1F, 0F, 0F); } }
+ // Shorthand for writing @@Vector3(1, 0, 0)@@
+ CSRAW public static Vector3 right { get { return new Vector3 (1F, 0F, 0F); } }
+
+
+ // Adds two vectors.
+ CSRAW public static Vector3 operator + (Vector3 a, Vector3 b) { return new Vector3 (a.x+b.x, a.y+b.y, a.z+b.z); }
+ // Subtracts one vector from another.
+ CSRAW public static Vector3 operator - (Vector3 a, Vector3 b) { return new Vector3 (a.x-b.x, a.y-b.y, a.z-b.z); }
+ // Negates a vector.
+ CSRAW public static Vector3 operator - (Vector3 a) { return new Vector3 (-a.x, -a.y, -a.z); }
+ // Multiplies a vector by a number.
+ CSRAW public static Vector3 operator * (Vector3 a, float d) { return new Vector3 (a.x*d, a.y*d, a.z*d); }
+ // Multiplies a vector by a number.
+ CSRAW public static Vector3 operator * (float d, Vector3 a) { return new Vector3 (a.x*d, a.y*d, a.z*d); }
+ // Divides a vector by a number.
+ CSRAW public static Vector3 operator / (Vector3 a, float d) { return new Vector3 (a.x/d, a.y/d, a.z/d); }
+
+ // Returns true if the vectors are equal.
+ CSRAW public static bool operator == (Vector3 lhs, Vector3 rhs)
+ {
+ return SqrMagnitude (lhs - rhs) < kEpsilon * kEpsilon;
+ }
+
+ // Returns true if vectors different.
+ CSRAW public static bool operator != (Vector3 lhs, Vector3 rhs)
+ {
+ return SqrMagnitude (lhs - rhs) >= kEpsilon * kEpsilon;
+ }
+
+ OBSOLETE warning Use Vector3.forward instead.
+ CSRAW public static Vector3 fwd { get { return new Vector3 (0F, 0F, 1F); } }
+
+ OBSOLETE warning Use Vector3.Angle instead. AngleBetween uses radians instead of degrees and was deprecated for this reason
+ CSRAW public static float AngleBetween(Vector3 from, Vector3 to) { return Mathf.Acos(Mathf.Clamp (Vector3.Dot (from.normalized, to.normalized), -1F, 1F)); }
+END
+
+
+// Representation of RGBA colors.
+
+THREAD_SAFE
+STRUCT Color
+ // Red component of the color.
+ CSRAW public float r;
+
+ // Green component of the color.
+ CSRAW public float g;
+
+ // Blue component of the color.
+ CSRAW public float b;
+
+ // Alpha component of the color.
+ CSRAW public float a;
+
+
+ // Constructs a new Color with given r,g,b,a components.
+ CSRAW public Color (float r, float g, float b, float a)
+ {
+ this.r = r; this.g = g; this.b = b; this.a = a;
+ }
+
+ // Constructs a new Color with given r,g,b components and sets /a/ to 1.
+ CSRAW public Color (float r, float g, float b)
+ {
+ this.r = r; this.g = g; this.b = b; this.a = 1.0F;
+ }
+
+ /// *listonly*
+ CSRAW override public string ToString() {
+ return UnityString.Format("RGBA({0:F3}, {1:F3}, {2:F3}, {3:F3})", r, g, b, a);
+ }
+ // Returns a nicely formatted string of this color.
+ CSRAW public string ToString(string format) {
+ return UnityString.Format("RGBA({0}, {1}, {2}, {3})", r.ToString(format), g.ToString(format), b.ToString(format), a.ToString(format));
+ }
+
+ // used to allow Colors to be used as keys in hash tables
+ public override int GetHashCode() {
+ return ((Vector4)this).GetHashCode();
+ }
+
+ // also required for being able to use Colors as keys in hash tables
+ public override bool Equals(object other) {
+ if (!(other is Color)) return false;
+ Color rhs = (Color)other;
+ return r.Equals(rhs.r) && g.Equals(rhs.g) && b.Equals(rhs.b) && a.Equals(rhs.a);
+ }
+
+ // Adds two colors together. Each component is added separately.
+ CSRAW public static Color operator + (Color a, Color b) { return new Color (a.r+b.r, a.g+b.g, a.b+b.b, a.a+b.a); }
+
+ // Subtracts color /b/ from color /a/. Each component is subtracted separately.
+ CSRAW public static Color operator - (Color a, Color b) { return new Color (a.r-b.r, a.g-b.g, a.b-b.b, a.a-b.a); }
+
+ // Multiplies two colors together. Each component is multiplied separately.
+ CSRAW public static Color operator * (Color a, Color b) { return new Color (a.r*b.r, a.g*b.g, a.b*b.b, a.a*b.a); }
+
+ // Multiplies color /a/ by the float /b/. Each color component is scaled separately.
+ CSRAW public static Color operator * (Color a, float b) { return new Color (a.r*b, a.g*b, a.b*b, a.a*b); }
+
+ // Multiplies color /a/ by the float /b/. Each color component is scaled separately.
+ CSRAW public static Color operator * (float b, Color a) { return new Color (a.r*b, a.g*b, a.b*b, a.a*b); }
+
+ // Divides color /a/ by the float /b/. Each color component is scaled separately.
+ CSRAW public static Color operator / (Color a, float b) { return new Color (a.r/b, a.g/b, a.b/b, a.a/b); }
+
+ //*undoc*
+ CSRAW public static bool operator == (Color lhs, Color rhs)
+ {
+ return ((Vector4)lhs == (Vector4)rhs);
+ }
+ //*undoc*
+ CSRAW public static bool operator != (Color lhs, Color rhs)
+ {
+ return ((Vector4)lhs != (Vector4)rhs);
+ }
+
+ // Interpolates between colors /a/ and /b/ by /t/.
+ CSRAW public static Color Lerp (Color a, Color b, float t)
+ {
+ t = Mathf.Clamp01 (t);
+ return new Color(
+ a.r + (b.r - a.r)*t,
+ a.g + (b.g - a.g)*t,
+ a.b + (b.b - a.b)*t,
+ a.a + (b.a - a.a)*t
+ );
+ }
+
+ // Returns new color that has RGB components multiplied, but leaving alpha untouched.
+ CSRAW internal Color RGBMultiplied (float multiplier) { return new Color (r * multiplier, g * multiplier, b * multiplier, a); }
+ // Returns new color that has RGB components multiplied, but leaving alpha untouched.
+ CSRAW internal Color AlphaMultiplied (float multiplier) { return new Color (r,g,b,a * multiplier); }
+ // Returns new color that has RGB components multiplied, but leaving alpha untouched.
+ CSRAW internal Color RGBMultiplied (Color multiplier) { return new Color (r * multiplier.r, g * multiplier.g, b * multiplier.b, a); }
+
+ // Solid red. RGBA is (1, 0, 0, 1).
+ CSRAW public static Color red { get { return new Color (1F, 0F, 0F, 1F); } }
+ // Solid green. RGBA is (0, 1, 0, 1).
+ CSRAW public static Color green { get { return new Color (0F, 1F, 0F, 1F); } }
+ // Solid blue. RGBA is (0, 0, 1, 1).
+ CSRAW public static Color blue { get { return new Color (0F, 0F, 1F, 1F); } }
+ // Solid white. RGBA is (1, 1, 1, 1).
+ CSRAW public static Color white { get { return new Color (1F, 1F, 1F, 1F); } }
+ // Solid black. RGBA is (0, 0, 0, 1).
+ CSRAW public static Color black { get { return new Color (0F, 0F, 0F, 1F); } }
+ // Yellow. RGBA is (1, 0.92, 0.016, 1), but the color is nice to look at!
+ CSRAW public static Color yellow { get { return new Color (1F, 235F / 255F, 4F / 255F, 1F); } }
+ // Cyan. RGBA is (0, 1, 1, 1).
+ CSRAW public static Color cyan { get { return new Color (0F, 1F, 1F, 1F); } }
+ // Magenta. RGBA is (1, 0, 1, 1).
+ CSRAW public static Color magenta { get { return new Color (1F, 0F, 1F, 1F); } }
+ // Gray. RGBA is (0.5, 0.5, 0.5, 1).
+ CSRAW public static Color gray { get { return new Color (.5F, .5F, .5F, 1F); } }
+ // English spelling for ::ref::gray. RGBA is the same (0.5, 0.5, 0.5, 1).
+ CSRAW public static Color grey { get { return new Color (.5F, .5F, .5F, 1F); } }
+ // Completely transparent. RGBA is (0, 0, 0, 0).
+ CSRAW public static Color clear { get { return new Color (0F, 0F, 0F, 0F); } }
+
+ // The grayscale value of the color (RO)
+ CSRAW public float grayscale { get { return 0.299F * r + 0.587F * g + 0.114F * b; } }
+
+ // A version of the color that has had the inverse gamma curve applied
+ CSRAW public Color linear
+ {
+ get {
+ return new Color (Mathf.GammaToLinearSpace(r), Mathf.GammaToLinearSpace(g), Mathf.GammaToLinearSpace(b), a);
+ }
+ }
+
+ // A version of the color that has had the gamma curve applied
+ CSRAW public Color gamma
+ {
+ get {
+ return new Color (Mathf.LinearToGammaSpace(r), Mathf.LinearToGammaSpace(g), Mathf.LinearToGammaSpace(b), a);
+ }
+ }
+
+ // Colors can be implicitly converted to and from [[Vector4]].
+ CSRAW public static implicit operator Vector4(Color c) {
+ return new Vector4(c.r, c.g, c.b, c.a);
+ }
+ // Colors can be implicitly converted to and from [[Vector4]].
+ CSRAW public static implicit operator Color(Vector4 v) {
+ return new Color(v.x, v.y, v.z, v.w);
+ }
+
+ // Access the r, g, b,a components using [0], [1], [2], [3] respectively.
+ CSRAW public float this [int index]
+ {
+ get
+ {
+ switch(index)
+ {
+ case 0: return r;
+ case 1: return g;
+ case 2: return b;
+ case 3: return a;
+ default:
+ throw new IndexOutOfRangeException("Invalid Vector3 index!");
+ }
+ }
+
+ 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 IndexOutOfRangeException("Invalid Vector3 index!");
+ }
+ }
+ }
+
+
+END
+
+
+// Representation of RGBA colors in 32 bit format
+THREAD_SAFE
+STRUCT Color32
+ // Red component of the color.
+ CSRAW public byte r;
+
+ // Green component of the color.
+ CSRAW public byte g;
+
+ // Blue component of the color.
+ CSRAW public byte b;
+
+ // Alpha component of the color.
+ CSRAW public byte a;
+
+ // Constructs a new Color with given r, g, b, a components.
+ CSRAW public Color32(byte r, byte g, byte b, byte a) {
+ this.r = r; this.g = g; this.b = b; this.a = a;
+ }
+
+ // Color32 can be implicitly converted to and from [[Color]].
+ CSRAW public static implicit operator Color32(Color c) {
+ return new Color32((byte)(Mathf.Clamp01(c.r) * 255), (byte)(Mathf.Clamp01(c.g) * 255), (byte)(Mathf.Clamp01(c.b) * 255), (byte)(Mathf.Clamp01(c.a) * 255));
+ }
+
+ // Color32 can be implicitly converted to and from [[Color]].
+ CSRAW public static implicit operator Color (Color32 c) {
+ return new Color(c.r / 255f, c.g / 255f, c.b / 255f, c.a / 255f);
+ }
+
+ /// *listonly*
+ CSRAW override public string ToString() {
+ return UnityString.Format("RGBA({0}, {1}, {2}, {3})", r, g, b, a);
+ }
+ // Returns a nicely formatted string of this color.
+ CSRAW public string ToString(string format) {
+ return UnityString.Format("RGBA({0}, {1}, {2}, {3})", r.ToString(format), g.ToString(format), b.ToString(format), a.ToString(format));
+ }
+
+ // Interpolates between colors /a/ and /b/ by /t/.
+ CSRAW public static Color32 Lerp (Color32 a, Color32 b, float t)
+ {
+ t = Mathf.Clamp01 (t);
+ return new Color32(
+ (byte)(a.r + (b.r - a.r)*t),
+ (byte)(a.g + (b.g - a.g)*t),
+ (byte)(a.b + (b.b - a.b)*t),
+ (byte)(a.a + (b.a - a.a)*t)
+ );
+ }
+END
+
+
+// Quaternions are used to represent rotations.
+
+CSRAW
+THREAD_SAFE
+STRUCT Quaternion
+
+ // X component of the Quaternion. Don't modify this directly unless you know quaternions inside out.
+ CSRAW public float x;
+ // Y component of the Quaternion. Don't modify this directly unless you know quaternions inside out.
+ CSRAW public float y;
+ // Z component of the Quaternion. Don't modify this directly unless you know quaternions inside out.
+ CSRAW public float z;
+ // W component of the Quaternion. Don't modify this directly unless you know quaternions inside out.
+ CSRAW public float w;
+
+ // Access the x, y, z, w components using [0], [1], [2], [3] respectively.
+ CSRAW public float this [int index]
+ {
+ get
+ {
+ switch(index)
+ {
+ case 0: return x;
+ case 1: return y;
+ case 2: return z;
+ case 3: return w;
+ default:
+ throw new IndexOutOfRangeException("Invalid Quaternion index!");
+ }
+ }
+
+ set
+ {
+ switch(index)
+ {
+ case 0: x = value; break;
+ case 1: y = value; break;
+ case 2: z = value; break;
+ case 3: w = value; break;
+ default:
+ throw new IndexOutOfRangeException("Invalid Quaternion index!");
+ }
+ }
+ }
+
+
+ // Constructs new Quaternion with given x,y,z,w components.
+ CSRAW public Quaternion (float x, float y, float z, float w) { this.x = x; this.y = y; this.z = z; this.w = w; }
+
+ // Set x, y, z and w components of an existing Quaternion.
+ CSRAW public void Set (float new_x, float new_y, float new_z, float new_w) { x = new_x; y = new_y; z = new_z; w = new_w; }
+
+ // The identity rotation (RO). This quaternion corresponds to "no rotation": the object
+ CSRAW public static Quaternion identity { get { return new Quaternion (0F, 0F, 0F, 1F); } }
+
+ // Combines rotations /lhs/ and /rhs/.
+ CSRAW public static Quaternion operator * (Quaternion lhs, Quaternion rhs)
+ {
+ return new Quaternion (
+ lhs.w*rhs.x + lhs.x*rhs.w + lhs.y*rhs.z - lhs.z*rhs.y,
+ lhs.w*rhs.y + lhs.y*rhs.w + lhs.z*rhs.x - lhs.x*rhs.z,
+ lhs.w*rhs.z + lhs.z*rhs.w + lhs.x*rhs.y - lhs.y*rhs.x,
+ lhs.w*rhs.w - lhs.x*rhs.x - lhs.y*rhs.y - lhs.z*rhs.z);
+ }
+
+ // Rotates the point /point/ with /rotation/.
+ CSRAW public static Vector3 operator * (Quaternion rotation, Vector3 point)
+ {
+ float x = rotation.x * 2F;
+ float y = rotation.y * 2F;
+ float z = rotation.z * 2F;
+ float xx = rotation.x * x;
+ float yy = rotation.y * y;
+ float zz = rotation.z * z;
+ float xy = rotation.x * y;
+ float xz = rotation.x * z;
+ float yz = rotation.y * z;
+ float wx = rotation.w * x;
+ float wy = rotation.w * y;
+ float wz = rotation.w * z;
+
+ Vector3 res;
+ res.x = (1F - (yy + zz)) * point.x + (xy - wz) * point.y + (xz + wy) * point.z;
+ res.y = (xy + wz) * point.x + (1F - (xx + zz)) * point.y + (yz - wx) * point.z;
+ res.z = (xz - wy) * point.x + (yz + wx) * point.y + (1F - (xx + yy)) * point.z;
+ return res;
+ }
+
+ // *undocumented*
+ CSRAW public const float kEpsilon = 0.000001F;
+
+ // Are two quaternions equal to each other?
+ CSRAW public static bool operator == (Quaternion lhs, Quaternion rhs)
+ {
+ return Dot (lhs, rhs) > 1.0f-kEpsilon;
+ }
+
+ // Are two quaternions different from each other?
+ CSRAW public static bool operator != (Quaternion lhs, Quaternion rhs)
+ {
+ return Dot (lhs, rhs) <= 1.0f-kEpsilon;
+ }
+
+ // The dot product between two rotations.
+ CSRAW public static float Dot (Quaternion a, Quaternion b) { return a.x*b.x + a.y*b.y + a.z*b.z + a.w*b.w; }
+
+ // Creates a rotation which rotates /angle/ degrees around /axis/.
+ CUSTOM static Quaternion AngleAxis (float angle, Vector3 axis) { return AxisAngleToQuaternionSafe (axis, Deg2Rad(angle)); }
+
+ // Converts a rotation to angle-axis representation.
+ CSRAW public void ToAngleAxis (out float angle, out Vector3 axis) { Internal_ToAxisAngleRad (this, out axis, out angle); angle *= Mathf.Rad2Deg; }
+
+ // Creates a rotation which rotates from /fromDirection/ to /toDirection/.
+ CUSTOM static Quaternion FromToRotation (Vector3 fromDirection, Vector3 toDirection) { return FromToQuaternionSafe (fromDirection, toDirection); }
+
+ // Creates a rotation which rotates from /fromDirection/ to /toDirection/.
+ CSRAW public void SetFromToRotation (Vector3 fromDirection, Vector3 toDirection) { this = FromToRotation (fromDirection, toDirection); }
+
+ // Creates a rotation with the specified /forward/ and /upwards/ directions.
+ CUSTOM static Quaternion LookRotation (Vector3 forward, Vector3 upwards = Vector3.up)
+ {
+ Quaternionf q = Quaternionf::identity ();
+ if (!LookRotationToQuaternion (forward, upwards, &q))
+ {
+ float mag = Magnitude (forward);
+ if (mag > Vector3f::epsilon)
+ {
+ Matrix3x3f m;
+ m.SetFromToRotation (Vector3f::zAxis, forward / mag);
+ MatrixToQuaternion (m, q);
+ }
+ else
+ {
+ LogString ("Look rotation viewing vector is zero");
+ }
+ }
+ return q;
+ }
+
+ // Creates a rotation with the specified /forward/ and /upwards/ directions.
+ CSRAW public void SetLookRotation (Vector3 view, Vector3 up = Vector3.up) { this = LookRotation (view, up); }
+
+ // Spherically interpolates between /from/ and /to/ by t.
+ CUSTOM static Quaternion Slerp (Quaternion from, Quaternion to, float t) { return Slerp (from, to, clamp01 (t)); }
+
+ // Interpolates between /from/ and /to/ by /t/ and normalizes the result afterwards.
+ CUSTOM static Quaternion Lerp (Quaternion from, Quaternion to, float t) { return Lerp (from, to, clamp01 (t)); }
+
+ // Rotates a rotation /from/ towards /to/.
+ CSRAW public static Quaternion RotateTowards (Quaternion from, Quaternion to, float maxDegreesDelta)
+ {
+ float angle = Quaternion.Angle(from, to);
+ if (angle == 0.0f)
+ return to;
+ float slerpValue = Mathf.Min(1.0f, maxDegreesDelta / angle);
+ return UnclampedSlerp(from, to, slerpValue);
+ }
+
+ CUSTOM private static Quaternion UnclampedSlerp (Quaternion from, Quaternion to, float t) { return Slerp (from, to, t); }
+
+ // Returns the Inverse of /rotation/.
+ CUSTOM static Quaternion Inverse (Quaternion rotation) { return Inverse (rotation); }
+
+
+ /// *listonly*
+ CSRAW override public string ToString() {
+ return UnityString.Format("({0:F1}, {1:F1}, {2:F1}, {3:F1})", x, y, z, w);
+ }
+ // Returns a nicely formatted string of the Quaternion
+ CSRAW public string ToString(string format) {
+ return UnityString.Format("({0}, {1}, {2}, {3})", x.ToString(format), y.ToString(format), z.ToString(format), w.ToString(format));
+ }
+
+ // Returns the angle in degrees between two rotations /a/ and /b/.
+ CSRAW static public float Angle (Quaternion a, Quaternion b)
+ {
+ float dot = Dot(a, b);
+ return Mathf.Acos(Mathf.Min(Mathf.Abs(dot), 1.0F)) * 2.0F * Mathf.Rad2Deg;
+ }
+
+ // Returns the euler angle representation of the rotation.
+ CSRAW public Vector3 eulerAngles { get { return Internal_ToEulerRad(this) * Mathf.Rad2Deg; } set { this=Internal_FromEulerRad(value * Mathf.Deg2Rad); } }
+
+ // Returns a rotation that rotates z degrees around the z axis, x degrees around the x axis, and y degrees around the y axis (in that order).
+ CSRAW static public Quaternion Euler (float x, float y, float z) { return Internal_FromEulerRad (new Vector3 (x, y, z) * Mathf.Deg2Rad); }
+
+ // Returns a rotation that rotates z degrees around the z axis, x degrees around the x axis, and y degrees around the y axis (in that order).
+ CSRAW static public Quaternion Euler (Vector3 euler) { return Internal_FromEulerRad (euler * Mathf.Deg2Rad); }
+
+
+ // Internal implementation. Note Rad suffix that indicates that this method works in radians.
+ CUSTOM static private Vector3 Internal_ToEulerRad (Quaternion rotation)
+ {
+ Quaternionf outRotation = NormalizeSafe (rotation);
+ return QuaternionToEuler (outRotation);
+ }
+
+ // Internal implementation. Note Rad suffix that indicates that this method works in radians.
+ CUSTOM static private Quaternion Internal_FromEulerRad (Vector3 euler) {
+ return EulerToQuaternion (euler);
+ }
+
+ // Internal implementation. Note Rad suffix that indicates that this method works in radians.
+ CUSTOM private static void Internal_ToAxisAngleRad (Quaternion q, out Vector3 axis, out float angle) {
+ QuaternionToAxisAngle (NormalizeSafe (q), axis, angle);
+ }
+
+
+ // Old obsolete radians-based Euler functions:
+ OBSOLETE warning Use Quaternion.Euler instead. This function was deprecated because it uses radians instead of degrees
+ CSRAW static public Quaternion EulerRotation (float x, float y, float z) { return Internal_FromEulerRad (new Vector3 (x, y, z)); }
+ OBSOLETE warning Use Quaternion.Euler instead. This function was deprecated because it uses radians instead of degrees
+ CSRAW public static Quaternion EulerRotation (Vector3 euler) { return Internal_FromEulerRad (euler); }
+ OBSOLETE warning Use Quaternion.Euler instead. This function was deprecated because it uses radians instead of degrees
+ CSRAW public void SetEulerRotation (float x, float y, float z) { this = Internal_FromEulerRad (new Vector3 (x, y, z)); }
+ OBSOLETE warning Use Quaternion.Euler instead. This function was deprecated because it uses radians instead of degrees
+ CSRAW public void SetEulerRotation (Vector3 euler) { this = Internal_FromEulerRad (euler); }
+ OBSOLETE warning Use Quaternion.eulerAngles instead. This function was deprecated because it uses radians instead of degrees
+ CSRAW public Vector3 ToEuler () { return Internal_ToEulerRad (this); }
+
+ OBSOLETE warning Use Quaternion.Euler instead. This function was deprecated because it uses radians instead of degrees
+ CSRAW static public Quaternion EulerAngles (float x, float y, float z) { return Internal_FromEulerRad (new Vector3 (x, y, z)); }
+ OBSOLETE warning Use Quaternion.Euler instead. This function was deprecated because it uses radians instead of degrees
+ CSRAW public static Quaternion EulerAngles (Vector3 euler) { return Internal_FromEulerRad (euler); }
+
+ OBSOLETE warning Use Quaternion.ToAngleAxis instead. This function was deprecated because it uses radians instead of degrees
+ CSRAW public void ToAxisAngle (out Vector3 axis, out float angle) { Internal_ToAxisAngleRad (this, out axis, out angle); }
+
+ OBSOLETE warning Use Quaternion.Euler instead. This function was deprecated because it uses radians instead of degrees
+ CSRAW public void SetEulerAngles (float x, float y, float z) { SetEulerRotation (new Vector3 (x, y, z)); }
+ OBSOLETE warning Use Quaternion.Euler instead. This function was deprecated because it uses radians instead of degrees
+ CSRAW public void SetEulerAngles (Vector3 euler) { this = EulerRotation (euler); }
+ OBSOLETE warning Use Quaternion.eulerAngles instead. This function was deprecated because it uses radians instead of degrees
+ CSRAW public static Vector3 ToEulerAngles (Quaternion rotation) { return Quaternion.Internal_ToEulerRad (rotation); }
+ OBSOLETE warning Use Quaternion.eulerAngles instead. This function was deprecated because it uses radians instead of degrees
+ CSRAW public Vector3 ToEulerAngles () { return Quaternion.Internal_ToEulerRad (this); }
+
+ OBSOLETE warning Use Quaternion.AngleAxis instead. This function was deprecated because it uses radians instead of degrees
+ CUSTOM static Quaternion AxisAngle (Vector3 axis, float angle) { return AxisAngleToQuaternionSafe (axis, angle); }
+
+ OBSOLETE warning Use Quaternion.AngleAxis instead. This function was deprecated because it uses radians instead of degrees
+ CSRAW public void SetAxisAngle (Vector3 axis, float angle) { this = AxisAngle (axis, angle); }
+
+ // used to allow Quaternions to be used as keys in hash tables
+ CSRAW public override int GetHashCode() {
+ return x.GetHashCode() ^ (y.GetHashCode()<<2) ^ (z.GetHashCode()>>2) ^ (w.GetHashCode()>>1);
+ }
+
+ // also required for being able to use Quaternions as keys in hash tables
+ public override bool Equals(object other) {
+ if(!(other is Quaternion)) return false;
+
+ Quaternion rhs=(Quaternion)other;
+ return x.Equals(rhs.x) && y.Equals(rhs.y) && z.Equals(rhs.z) && w.Equals(rhs.w);
+ }
+
+END
+
+
+// A 2D Rectangle defined by x, y position and width, height
+THREAD_SAFE
+STRUCT Rect
+ CSRAW private float m_XMin, m_YMin, m_Width, m_Height;
+
+ // Creates a new rectangle.
+ CSRAW public Rect (float left, float top, float width, float height) {
+ m_XMin = left;
+ m_YMin = top;
+ m_Width = width;
+ m_Height = height;
+ }
+
+ //*undocumented*
+ CSRAW public Rect (Rect source) {
+ m_XMin = source.m_XMin;
+ m_YMin = source.m_YMin;
+ m_Width = source.m_Width;
+ m_Height= source.m_Height;
+ }
+
+ // Creates a rectangle from min/max coordinate values.
+ static public Rect MinMaxRect (float left, float top, float right, float bottom)
+ {
+ return new Rect (left, top, right - left, bottom - top);
+ }
+
+ // Set components of an existing Rect.
+ CSRAW public void Set (float left, float top, float width, float height) {
+ m_XMin = left;
+ m_YMin = top;
+ m_Width = width;
+ m_Height = height;
+ }
+
+ // Left coordinate of the rectangle.
+ CSRAW public float x { get { return m_XMin; } set { m_XMin = value; } }
+
+ // Top coordinate of the rectangle.
+ CSRAW public float y { get { return m_YMin; } set { m_YMin = value; } }
+
+ // Center coordinate of the rectangle.
+ CSRAW public Vector2 center { get { return new Vector2 (x + m_Width / 2f, y + m_Height / 2f); } set { m_XMin = value.x - m_Width / 2f; m_YMin = value.y - m_Height / 2f; } }
+
+ // Width of the rectangle.
+ CSRAW public float width { get { return m_Width; } set { m_Width = value; } }
+
+ // Height of the rectangle.
+ CSRAW public float height { get { return m_Height; } set { m_Height = value; } }
+
+ OBSOLETE warning use xMin
+ CSRAW public float left { get { return m_XMin; } }
+ OBSOLETE warning use xMax
+ CSRAW public float right { get { return m_XMin + m_Width; } }
+ OBSOLETE warning use yMin
+ CSRAW public float top { get { return m_YMin; } }
+ OBSOLETE warning use yMax
+ CSRAW public float bottom { get { return m_YMin + m_Height; } }
+
+ // Left coordinate of the rectangle.
+ CSRAW public float xMin { get { return m_XMin; } set { float oldxmax = xMax; m_XMin = value; m_Width = oldxmax - m_XMin; } }
+ // Top coordinate of the rectangle.
+ CSRAW public float yMin { get { return m_YMin; } set { float oldymax = yMax; m_YMin = value; m_Height = oldymax - m_YMin; } }
+ // Right coordinate of the rectangle.
+ CSRAW public float xMax { get { return m_Width + m_XMin; } set { m_Width = value - m_XMin; } }
+ // Bottom coordinate of the rectangle.
+ CSRAW public float yMax { get { return m_Height + m_YMin; } set { m_Height = value - m_YMin; } }
+
+ /// *listonly*
+ CSRAW override public string ToString() { return UnityString.Format("(x:{0:F2}, y:{1:F2}, width:{2:F2}, height:{3:F2})", x, y, width, height); }
+ // Returns a nicely formatted string for this Rect.
+ CSRAW public string ToString(string format) {
+ return UnityString.Format("(x:{0}, y:{1}, width:{2}, height:{3})", x.ToString(format), y.ToString(format), width.ToString(format), height.ToString(format));
+ }
+
+ /// *listonly*
+ CSRAW public bool Contains (Vector2 point)
+ {
+ return (point.x >= xMin) && (point.x < xMax) && (point.y >= yMin) && (point.y < yMax);
+ }
+ // Returns true if the /x/ and /y/ components of /point/ is a point inside this rectangle.
+ public bool Contains (Vector3 point)
+ {
+ return (point.x >= xMin) && (point.x < xMax) && (point.y >= yMin) && (point.y < yMax);
+ }
+ public bool Contains(Vector3 point, bool allowInverse)
+ {
+ if (!allowInverse)
+ {
+ return Contains(point);
+ }
+ bool xAxis = false;
+ if (width < 0f && (point.x <= xMin) && (point.x > xMax) || width >= 0f && (point.x >= xMin) && (point.x < xMax))
+ xAxis = true;
+ if (xAxis && (height < 0f && (point.y <= yMin) && (point.y > yMax) || height >= 0f && (point.y >= yMin) && (point.y < yMax)))
+ return true;
+ return false;
+ }
+ // removed for 2.0
+ // Clamp a point to be within a rectangle.
+// CSRAW public Vector2 Clamp (Vector2 point) {
+// return new Vector2 (Mathf.Clamp (point.x, left, xMax-1), Mathf.Clamp (point.y, yMin, yMax-1));
+// }
+
+ // Swaps min and max if min was greater than max.
+ private static Rect OrderMinMax (Rect rect)
+ {
+ if (rect.xMin > rect.xMax)
+ {
+ float temp = rect.xMin;
+ rect.xMin = rect.xMax;
+ rect.xMax = temp;
+ }
+ if (rect.yMin > rect.yMax)
+ {
+ float temp = rect.yMin;
+ rect.yMin = rect.yMax;
+ rect.yMax = temp;
+ }
+ return rect;
+ }
+
+ CSRAW public bool Overlaps (Rect other)
+ {
+ return (other.xMax > xMin &&
+ other.xMin < xMax &&
+ other.yMax > yMin &&
+ other.yMin < yMax);
+ }
+
+ CSRAW public bool Overlaps (Rect other, bool allowInverse)
+ {
+ Rect self = this;
+ if (allowInverse)
+ {
+ self = OrderMinMax (self);
+ other = OrderMinMax (other);
+ }
+ return self.Overlaps (other);
+ }
+
+ // Returns true if the rectangles are different.
+ CSRAW public static bool operator != (Rect lhs, Rect rhs)
+ {
+ return lhs.x != rhs.x || lhs.y != rhs.y || lhs.width != rhs.width || lhs.height != rhs.height;
+ }
+
+ // Returns true if the rectangles are the same.
+ CSRAW public static bool operator == (Rect lhs, Rect rhs) {
+ return lhs.x == rhs.x && lhs.y == rhs.y && lhs.width == rhs.width && lhs.height == rhs.height;
+ }
+
+ public override int GetHashCode() {
+ return x.GetHashCode() ^ (width.GetHashCode()<<2) ^ (y.GetHashCode()>>2) ^ (height.GetHashCode()>>1);
+ }
+
+ public override bool Equals(object other) {
+ if(!(other is Rect)) return false;
+
+ Rect rhs=(Rect)other;
+ return x.Equals(rhs.x) && y.Equals(rhs.y) && width.Equals(rhs.width) && height.Equals(rhs.height);
+ }
+END
+
+
+// A standard 4x4 transformation matrix.
+THREAD_SAFE
+STRUCT Matrix4x4
+ CSRAW
+ ///*undocumented*
+ public float m00;
+ ///*undocumented*
+ public float m10;
+ ///*undocumented*
+ public float m20;
+ ///*undocumented*
+ public float m30;
+
+ ///*undocumented*
+ public float m01;
+ ///*undocumented*
+ public float m11;
+ ///*undocumented*
+ public float m21;
+ ///*undocumented*
+ public float m31;
+
+ ///*undocumented*
+ public float m02;
+ ///*undocumented*
+ public float m12;
+ ///*undocumented*
+ public float m22;
+ ///*undocumented*
+ public float m32;
+
+ ///*undocumented*
+ public float m03;
+ ///*undocumented*
+ public float m13;
+ ///*undocumented*
+ public float m23;
+ ///*undocumented*
+ public float m33;
+
+
+ CSRAW
+ // Access element at [row, column].
+ public float this [int row, int column]
+ {
+ get
+ {
+ return this [ row + column*4 ];
+ }
+
+ set
+ {
+ this [ row + column*4 ] = value;
+ }
+ }
+
+ // Access element at sequential index (0..15 inclusive).
+ CSRAW public float this [int index]
+ {
+ get
+ {
+ switch(index)
+ {
+ case 0: return m00;
+ case 1: return m10;
+ case 2: return m20;
+ case 3: return m30;
+ case 4: return m01;
+ case 5: return m11;
+ case 6: return m21;
+ case 7: return m31;
+ case 8: return m02;
+ case 9: return m12;
+ case 10:return m22;
+ case 11:return m32;
+ case 12:return m03;
+ case 13:return m13;
+ case 14:return m23;
+ case 15:return m33;
+ default:
+ throw new IndexOutOfRangeException("Invalid matrix index!");
+ }
+ }
+
+ set
+ {
+ switch(index)
+ {
+ case 0: m00 = value; break;
+ case 1: m10 = value; break;
+ case 2: m20 = value; break;
+ case 3: m30 = value; break;
+ case 4: m01 = value; break;
+ case 5: m11 = value; break;
+ case 6: m21 = value; break;
+ case 7: m31 = value; break;
+ case 8: m02 = value; break;
+ case 9: m12 = value; break;
+ case 10:m22 = value; break;
+ case 11:m32 = value; break;
+ case 12:m03 = value; break;
+ case 13:m13 = value; break;
+ case 14:m23 = value; break;
+ case 15:m33 = value; break;
+
+ default:
+ throw new IndexOutOfRangeException("Invalid matrix index!");
+ }
+ }
+ }
+
+ // used to allow Matrix4x4s to be used as keys in hash tables
+ public override int GetHashCode() {
+ return GetColumn( 0 ).GetHashCode() ^ (GetColumn( 1 ).GetHashCode()<<2) ^ (GetColumn( 2 ).GetHashCode()>>2) ^ (GetColumn( 3 ).GetHashCode()>>1);
+ }
+
+ // also required for being able to use Matrix4x4s as keys in hash tables
+ public override bool Equals(object other) {
+ if(!(other is Matrix4x4)) return false;
+
+ Matrix4x4 rhs=(Matrix4x4)other;
+ return GetColumn( 0 ).Equals(rhs.GetColumn( 0 ))
+ && GetColumn( 1 ).Equals(rhs.GetColumn( 1 ))
+ && GetColumn( 2 ).Equals(rhs.GetColumn( 2 ))
+ && GetColumn( 3 ).Equals(rhs.GetColumn( 3 ));
+ }
+
+ // Multiplies two matrices.
+ CSRAW static public Matrix4x4 operator * (Matrix4x4 lhs, Matrix4x4 rhs)
+ {
+ Matrix4x4 res = new Matrix4x4();
+ res.m00 = lhs.m00 * rhs.m00 + lhs.m01 * rhs.m10 + lhs.m02 * rhs.m20 + lhs.m03 * rhs.m30;
+ res.m01 = lhs.m00 * rhs.m01 + lhs.m01 * rhs.m11 + lhs.m02 * rhs.m21 + lhs.m03 * rhs.m31;
+ res.m02 = lhs.m00 * rhs.m02 + lhs.m01 * rhs.m12 + lhs.m02 * rhs.m22 + lhs.m03 * rhs.m32;
+ res.m03 = lhs.m00 * rhs.m03 + lhs.m01 * rhs.m13 + lhs.m02 * rhs.m23 + lhs.m03 * rhs.m33;
+
+ res.m10 = lhs.m10 * rhs.m00 + lhs.m11 * rhs.m10 + lhs.m12 * rhs.m20 + lhs.m13 * rhs.m30;
+ res.m11 = lhs.m10 * rhs.m01 + lhs.m11 * rhs.m11 + lhs.m12 * rhs.m21 + lhs.m13 * rhs.m31;
+ res.m12 = lhs.m10 * rhs.m02 + lhs.m11 * rhs.m12 + lhs.m12 * rhs.m22 + lhs.m13 * rhs.m32;
+ res.m13 = lhs.m10 * rhs.m03 + lhs.m11 * rhs.m13 + lhs.m12 * rhs.m23 + lhs.m13 * rhs.m33;
+
+ res.m20 = lhs.m20 * rhs.m00 + lhs.m21 * rhs.m10 + lhs.m22 * rhs.m20 + lhs.m23 * rhs.m30;
+ res.m21 = lhs.m20 * rhs.m01 + lhs.m21 * rhs.m11 + lhs.m22 * rhs.m21 + lhs.m23 * rhs.m31;
+ res.m22 = lhs.m20 * rhs.m02 + lhs.m21 * rhs.m12 + lhs.m22 * rhs.m22 + lhs.m23 * rhs.m32;
+ res.m23 = lhs.m20 * rhs.m03 + lhs.m21 * rhs.m13 + lhs.m22 * rhs.m23 + lhs.m23 * rhs.m33;
+
+ res.m30 = lhs.m30 * rhs.m00 + lhs.m31 * rhs.m10 + lhs.m32 * rhs.m20 + lhs.m33 * rhs.m30;
+ res.m31 = lhs.m30 * rhs.m01 + lhs.m31 * rhs.m11 + lhs.m32 * rhs.m21 + lhs.m33 * rhs.m31;
+ res.m32 = lhs.m30 * rhs.m02 + lhs.m31 * rhs.m12 + lhs.m32 * rhs.m22 + lhs.m33 * rhs.m32;
+ res.m33 = lhs.m30 * rhs.m03 + lhs.m31 * rhs.m13 + lhs.m32 * rhs.m23 + lhs.m33 * rhs.m33;
+
+ return res;
+ }
+
+ // Transforms a [[Vector4]] by a matrix.
+ CSRAW static public Vector4 operator * (Matrix4x4 lhs, Vector4 v)
+ {
+ Vector4 res;
+ res.x = lhs.m00 * v.x + lhs.m01 * v.y + lhs.m02 * v.z + lhs.m03 * v.w;
+ res.y = lhs.m10 * v.x + lhs.m11 * v.y + lhs.m12 * v.z + lhs.m13 * v.w;
+ res.z = lhs.m20 * v.x + lhs.m21 * v.y + lhs.m22 * v.z + lhs.m23 * v.w;
+ res.w = lhs.m30 * v.x + lhs.m31 * v.y + lhs.m32 * v.z + lhs.m33 * v.w;
+ return res;
+ }
+
+ //*undoc*
+ CSRAW public static bool operator == (Matrix4x4 lhs, Matrix4x4 rhs)
+ {
+ return lhs.GetColumn( 0 ) == rhs.GetColumn( 0 )
+ && lhs.GetColumn( 1 ) == rhs.GetColumn( 1 )
+ && lhs.GetColumn( 2 ) == rhs.GetColumn( 2 )
+ && lhs.GetColumn( 3 ) == rhs.GetColumn( 3 );
+ }
+ //*undoc*
+ CSRAW public static bool operator != (Matrix4x4 lhs, Matrix4x4 rhs)
+ {
+ return !(lhs == rhs);
+ }
+
+ //*undocumented* --- have a property now
+ CUSTOM static Matrix4x4 Inverse (Matrix4x4 m) { Matrix4x4f output (m); output.Invert_Full(); return output; }
+ //*undocumented* --- have a property now
+ CUSTOM static Matrix4x4 Transpose (Matrix4x4 m) { Matrix4x4f output (m); output.Transpose(); return output; }
+
+ // Invert a matrix and return the success code.
+ CUSTOM internal static bool Invert (Matrix4x4 inMatrix, out Matrix4x4 dest) { return Matrix4x4f::Invert_Full(inMatrix, *dest); }
+
+ // The inverse of this matrix (RO).
+ CSRAW public Matrix4x4 inverse { get { return Matrix4x4.Inverse (this); } }
+
+ // Returns the transpose of this matrix (RO).
+ CSRAW public Matrix4x4 transpose { get { return Matrix4x4.Transpose (this); } }
+
+ // Is this the identity matrix?
+ CUSTOM_PROP bool isIdentity { return self.IsIdentity(); }
+
+ // Get a column of the matrix.
+ CSRAW public Vector4 GetColumn (int i) { return new Vector4 (this[0, i], this[1, i], this[2, i], this[3, i]); }
+ // Returns a row of the matrix.
+ CSRAW public Vector4 GetRow (int i) { return new Vector4 (this[i, 0], this[i, 1], this[i, 2], this[i, 3]); }
+ // Sets a column of the matrix.
+ CSRAW public void SetColumn (int i, Vector4 v) { this[0, i] = v.x; this[1, i] = v.y; this[2, i] = v.z; this[3, i] = v.w; }
+ // Sets a row of the matrix.
+ CSRAW public void SetRow (int i, Vector4 v){ this[i, 0] = v.x; this[i, 1] = v.y; this[i, 2] = v.z; this[i, 3] = v.w; }
+
+
+ // Transforms a position by this matrix (generic).
+ CSRAW public Vector3 MultiplyPoint (Vector3 v)
+ {
+ Vector3 res;
+ float w;
+ res.x = this.m00 * v.x + this.m01 * v.y + this.m02 * v.z + this.m03;
+ res.y = this.m10 * v.x + this.m11 * v.y + this.m12 * v.z + this.m13;
+ res.z = this.m20 * v.x + this.m21 * v.y + this.m22 * v.z + this.m23;
+ w = this.m30 * v.x + this.m31 * v.y + this.m32 * v.z + this.m33;
+
+ w = 1F / w;
+ res.x *= w;
+ res.y *= w;
+ res.z *= w;
+ return res;
+ }
+
+ // Transforms a position by this matrix (fast).
+ CSRAW public Vector3 MultiplyPoint3x4 (Vector3 v)
+ {
+ Vector3 res;
+ res.x = this.m00 * v.x + this.m01 * v.y + this.m02 * v.z + this.m03;
+ res.y = this.m10 * v.x + this.m11 * v.y + this.m12 * v.z + this.m13;
+ res.z = this.m20 * v.x + this.m21 * v.y + this.m22 * v.z + this.m23;
+ return res;
+ }
+
+ // Transforms a direction by this matrix.
+ CSRAW public Vector3 MultiplyVector (Vector3 v)
+ {
+ Vector3 res;
+ res.x = this.m00 * v.x + this.m01 * v.y + this.m02 * v.z;
+ res.y = this.m10 * v.x + this.m11 * v.y + this.m12 * v.z;
+ res.z = this.m20 * v.x + this.m21 * v.y + this.m22 * v.z;
+ return res;
+ }
+
+ // Creates a scaling matrix.
+ CSRAW static public Matrix4x4 Scale (Vector3 v)
+ {
+ Matrix4x4 m = new Matrix4x4();
+ m.m00 = v.x; m.m01 = 0F; m.m02 = 0F; m.m03 = 0F;
+ m.m10 = 0F; m.m11 = v.y; m.m12 = 0F; m.m13 = 0F;
+ m.m20 = 0F; m.m21 = 0F; m.m22 = v.z; m.m23 = 0F;
+ m.m30 = 0F; m.m31 = 0F; m.m32 = 0F; m.m33 = 1F;
+ return m;
+ }
+
+ // Returns a matrix with all elements set to zero (RO).
+ CSRAW public static Matrix4x4 zero {
+ get
+ {
+ Matrix4x4 m = new Matrix4x4();
+ m.m00 = 0F; m.m01 = 0F; m.m02 = 0F; m.m03 = 0F;
+ m.m10 = 0F; m.m11 = 0F; m.m12 = 0F; m.m13 = 0F;
+ m.m20 = 0F; m.m21 = 0F; m.m22 = 0F; m.m23 = 0F;
+ m.m30 = 0F; m.m31 = 0F; m.m32 = 0F; m.m33 = 0F;
+ return m;
+ }
+ }
+
+ // Returns the identity matrix (RO).
+ CSRAW public static Matrix4x4 identity {
+ get
+ {
+ Matrix4x4 m = new Matrix4x4();
+ m.m00 = 1F; m.m01 = 0F; m.m02 = 0F; m.m03 = 0F;
+ m.m10 = 0F; m.m11 = 1F; m.m12 = 0F; m.m13 = 0F;
+ m.m20 = 0F; m.m21 = 0F; m.m22 = 1F; m.m23 = 0F;
+ m.m30 = 0F; m.m31 = 0F; m.m32 = 0F; m.m33 = 1F;
+ return m;
+ }
+ }
+
+ // Sets this matrix to a translation, rotation and scaling matrix.
+ CSRAW public void SetTRS(Vector3 pos, Quaternion q, Vector3 s)
+ {
+ this = Matrix4x4.TRS(pos, q, s);
+ }
+
+ // Creates a translation, rotation and scaling matrix.
+ CUSTOM static Matrix4x4 TRS(Vector3 pos, Quaternion q, Vector3 s)
+ {
+ Matrix4x4f temp;
+ temp.SetTRS(pos,q,s);
+ return temp;
+ }
+
+ /// *listonly*
+ CSRAW override public string ToString() {
+ return UnityString.Format("{0:F5}\t{1:F5}\t{2:F5}\t{3:F5}\n{4:F5}\t{5:F5}\t{6:F5}\t{7:F5}\n{8:F5}\t{9:F5}\t{10:F5}\t{11:F5}\n{12:F5}\t{13:F5}\t{14:F5}\t{15:F5}\n", m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33);
+ }
+ // Returns a nicely formatted string for this matrix.
+ CSRAW public string ToString(string format) {
+ return UnityString.Format("{0}\t{1}\t{2}\t{3}\n{4}\t{5}\t{6}\t{7}\n{8}\t{9}\t{10}\t{11}\n{12}\t{13}\t{14}\t{15}\n",
+ m00.ToString(format), m01.ToString(format), m02.ToString(format), m03.ToString(format),
+ m10.ToString(format), m11.ToString(format), m12.ToString(format), m13.ToString(format),
+ m20.ToString(format), m21.ToString(format), m22.ToString(format), m23.ToString(format),
+ m30.ToString(format), m31.ToString(format), m32.ToString(format), m33.ToString(format));
+ }
+
+ // Creates an orthogonal projection matrix.
+ CUSTOM static public Matrix4x4 Ortho (float left, float right, float bottom, float top, float zNear, float zFar) {
+ Matrix4x4f m;
+ m.SetOrtho(left, right, bottom, top, zNear, zFar);
+ return m;
+ }
+
+ // Creates a perspective projection matrix.
+ CUSTOM static public Matrix4x4 Perspective (float fov, float aspect, float zNear, float zFar) {
+ Matrix4x4f m;
+ m.SetPerspective( fov, aspect, zNear, zFar );
+ return m;
+ }
+END
+
+
+// Represents an axis aligned bounding box.
+THREAD_SAFE
+STRUCT Bounds
+
+ CSRAW private Vector3 m_Center;
+ CSRAW private Vector3 m_Extents;
+
+ // Creates new Bounds with a given /center/ and total /size/. Bound ::ref::extents will be half the given size.
+ CSRAW public Bounds (Vector3 center, Vector3 size)
+ {
+ m_Center = center;
+ m_Extents = size * 0.5F;
+ }
+
+ // used to allow Bounds to be used as keys in hash tables
+ public override int GetHashCode() {
+ return center.GetHashCode() ^ (extents.GetHashCode()<<2);
+ }
+
+ // also required for being able to use Vector4s as keys in hash tables
+ public override bool Equals(object other) {
+ if(!(other is Bounds)) return false;
+
+ Bounds rhs=(Bounds)other;
+ return center.Equals(rhs.center) && extents.Equals(rhs.extents);
+ }
+
+ // The center of the bounding box.
+ CSRAW public Vector3 center { get { return m_Center; } set { m_Center = value; } }
+
+ // The total size of the box. This is always twice as large as the ::ref::extents.
+ CSRAW public Vector3 size { get { return m_Extents * 2.0F; } set { m_Extents = value * 0.5F; } }
+
+ // The extents of the box. This is always half of the ::ref::size.
+ CSRAW public Vector3 extents { get { return m_Extents; } set { m_Extents = value; } }
+
+ // The minimal point of the box. This is always equal to ''center-extents''.
+ CSRAW public Vector3 min { get { return center - extents; } set { SetMinMax (value, max); } }
+ // The maximal point of the box. This is always equal to ''center+extents''.
+ CSRAW public Vector3 max { get { return center + extents; } set { SetMinMax (min, value); } }
+
+ //*undoc*
+ CSRAW public static bool operator == (Bounds lhs, Bounds rhs)
+ {
+ return (lhs.center == rhs.center && lhs.extents == rhs.extents);
+ }
+ //*undoc*
+ CSRAW public static bool operator != (Bounds lhs, Bounds rhs)
+ {
+ return !(lhs == rhs);
+ }
+
+ // Sets the bounds to the /min/ and /max/ value of the box.
+ CSRAW public void SetMinMax (Vector3 min, Vector3 max)
+ {
+ extents = (max - min) * 0.5F;
+ center = min + extents;
+ }
+
+ // Grows the Bounds to include the /point/.
+ CSRAW public void Encapsulate (Vector3 point)
+ {
+ SetMinMax(Vector3.Min (min, point), Vector3.Max (max, point));
+ }
+
+ // Grow the bounds to encapsulate the bounds.
+ CSRAW public void Encapsulate (Bounds bounds) {
+ Encapsulate (bounds.center - bounds.extents);
+ Encapsulate (bounds.center + bounds.extents);
+ }
+
+ // Expand the bounds by increasing its /size/ by /amount/ along each side.
+ CSRAW public void Expand (float amount) {
+ amount *= .5f;
+ extents += new Vector3 (amount, amount, amount);
+ }
+
+ // Expand the bounds by increasing its /size/ by /amount/ along each side.
+ CSRAW public void Expand (Vector3 amount) {
+ extents += amount * .5f;
+ }
+
+ // Does another bounding box intersect with this bounding box?
+ CSRAW public bool Intersects (Bounds bounds) {
+ return (min.x <= bounds.max.x) && (max.x >= bounds.min.x) &&
+ (min.y <= bounds.max.y) && (max.y >= bounds.min.y) &&
+ (min.z <= bounds.max.z) && (max.z >= bounds.min.z);
+ }
+
+ CUSTOM private static bool Internal_Contains (Bounds m, Vector3 point) { return m.IsInside (point); }
+ // Is /point/ contained in the bounding box?
+ CSRAW public bool Contains (Vector3 point) { return Internal_Contains (this, point); }
+
+ CUSTOM private static float Internal_SqrDistance (Bounds m, Vector3 point) { return CalculateSqrDistance(point, m); }
+
+ // The smallest squared distance between the point and this bounding box.
+ CSRAW public float SqrDistance (Vector3 point) { return Internal_SqrDistance(this, point); }
+
+ CUSTOM private static bool Internal_IntersectRay (ref Ray ray, ref Bounds bounds, out float distance) { return IntersectRayAABB(ray, bounds, distance); }
+
+ // Does /ray/ intersect this bounding box?
+ CSRAW public bool IntersectRay (Ray ray) { float dist; return Internal_IntersectRay (ref ray, ref this, out dist); }
+
+ // Does /ray/ intersect this bounding box?
+ CSRAW public bool IntersectRay (Ray ray, out float distance) { return Internal_IntersectRay (ref ray, ref this, out distance); }
+
+ /// *listonly*
+ CSRAW override public string ToString() {
+ return UnityString.Format("Center: {0}, Extents: {1}", m_Center, m_Extents);
+ }
+ // Returns a nicely formatted string for the bounds.
+ CSRAW public string ToString(string format) {
+ return UnityString.Format("Center: {0}, Extents: {1}", m_Center.ToString(format), m_Extents.ToString(format));
+ }
+
+
+END
+
+
+
+// Representation of four-dimensional vectors.
+THREAD_SAFE
+STRUCT Vector4
+
+ // *undocumented*
+ CSRAW public const float kEpsilon = 0.00001F;
+
+ // X component of the vector.
+ CSRAW public float x;
+ // Y component of the vector.
+ CSRAW public float y;
+ // Z component of the vector.
+ CSRAW public float z;
+ // W component of the vector.
+ CSRAW public float w;
+
+ // Access the x, y, z, w components using [0], [1], [2], [3] respectively.
+ CSRAW public float this [int index]
+ {
+ get
+ {
+ switch(index)
+ {
+ case 0: return x;
+ case 1: return y;
+ case 2: return z;
+ case 3: return w;
+ default:
+ throw new IndexOutOfRangeException("Invalid Vector4 index!");
+ }
+ }
+
+ set
+ {
+ switch(index)
+ {
+ case 0: x = value; break;
+ case 1: y = value; break;
+ case 2: z = value; break;
+ case 3: w = value; break;
+ default:
+ throw new IndexOutOfRangeException("Invalid Vector4 index!");
+ }
+ }
+ }
+
+ // Creates a new vector with given x, y, z, w components.
+ CSRAW public Vector4 (float x, float y, float z, float w) { this.x = x; this.y = y; this.z = z; this.w = w; }
+ // Creates a new vector with given x, y, z components and sets /w/ to zero.
+ CSRAW public Vector4 (float x, float y, float z) { this.x = x; this.y = y; this.z = z; this.w = 0F; }
+ // Creates a new vector with given x, y components and sets /z/ and /w/ to zero.
+ CSRAW public Vector4 (float x, float y) { this.x = x; this.y = y; this.z = 0F; this.w = 0F; }
+
+ // Set x, y, z and w components of an existing Vector4.
+ CSRAW public void Set (float new_x, float new_y, float new_z, float new_w) { x = new_x; y = new_y; z = new_z; w = new_w; }
+
+ // Linearly interpolates between two vectors.
+ CSRAW public static Vector4 Lerp (Vector4 from, Vector4 to, float t)
+ {
+ t = Mathf.Clamp01 (t);
+ return new Vector4(
+ from.x + (to.x - from.x)*t,
+ from.y + (to.y - from.y)*t,
+ from.z + (to.z - from.z)*t,
+ from.w + (to.w - from.w)*t
+ );
+ }
+
+ // Moves a point /current/ towards /target/.
+ CSRAW static public Vector4 MoveTowards (Vector4 current, Vector4 target, float maxDistanceDelta)
+ {
+ Vector4 toVector = target - current;
+ float dist = toVector.magnitude;
+ if (dist <= maxDistanceDelta || dist == 0)
+ return target;
+ return current + toVector / dist * maxDistanceDelta;
+ }
+
+ // Multiplies two vectors component-wise.
+ CSRAW public static Vector4 Scale (Vector4 a, Vector4 b) { return new Vector4 (a.x*b.x, a.y*b.y, a.z*b.z, a.w*b.w); }
+ // Multiplies every component of this vector by the same component of /scale/.
+ CSRAW public void Scale (Vector4 scale) { x *= scale.x; y *= scale.y; z *= scale.z; w *= scale.w; }
+
+
+ // used to allow Vector4s to be used as keys in hash tables
+ public override int GetHashCode() {
+ return x.GetHashCode() ^ (y.GetHashCode()<<2) ^ (z.GetHashCode()>>2) ^ (w.GetHashCode()>>1);
+ }
+
+ // also required for being able to use Vector4s as keys in hash tables
+ public override bool Equals(object other) {
+ if(!(other is Vector4)) return false;
+
+ Vector4 rhs=(Vector4)other;
+ return x.Equals(rhs.x) && y.Equals(rhs.y) && z.Equals(rhs.z) && w.Equals(rhs.w);
+ }
+
+ // *undoc* --- we have normalized property now
+ CSRAW public static Vector4 Normalize (Vector4 a)
+ {
+ float mag = Magnitude (a);
+ if (mag > kEpsilon)
+ return a / mag;
+ else
+ return zero;
+ }
+
+ // Makes this vector have a ::ref::magnitude of 1.
+ CSRAW public void Normalize ()
+ {
+ float mag = Magnitude (this);
+ if (mag > kEpsilon)
+ this = this / mag;
+ else
+ this = zero;
+ }
+
+ // Returns this vector with a ::ref::magnitude of 1 (RO).
+ CSRAW public Vector4 normalized { get { return Vector4.Normalize(this); } }
+
+
+ /// *listonly*
+ CSRAW override public string ToString() {
+ return UnityString.Format("({0:F1}, {1:F1}, {2:F1}, {3:F1})", x, y, z, w);
+ }
+ // Returns a nicely formatted string for this vector.
+ CSRAW public string ToString(string format) {
+ return UnityString.Format("({0}, {1}, {2}, {3})", x.ToString(format), y.ToString(format), z.ToString(format), w.ToString(format));
+ }
+
+
+ // Dot Product of two vectors.
+ CSRAW public static float Dot (Vector4 a, Vector4 b) { return a.x*b.x + a.y*b.y + a.z*b.z + a.w*b.w; }
+
+ // Projects a vector onto another vector.
+ CSRAW public static Vector4 Project (Vector4 a, Vector4 b) { return b * Dot (a, b) / Dot (b, b); }
+
+ // Returns the distance between /a/ and /b/.
+ CSRAW public static float Distance (Vector4 a, Vector4 b) { return Magnitude (a-b); }
+
+ // *undoc* --- there's a property now
+ CSRAW public static float Magnitude (Vector4 a) { return Mathf.Sqrt (Dot (a, a)); }
+
+ // Returns the length of this vector (RO).
+ CSRAW public float magnitude { get { return Mathf.Sqrt (Dot (this, this)); } }
+
+ // *undoc* --- there's a property now
+ CSRAW public static float SqrMagnitude (Vector4 a) { return Vector4.Dot (a, a); }
+ // *undoc* --- there's a property now
+ CSRAW public float SqrMagnitude () { return Dot (this, this); }
+
+ // Returns the squared length of this vector (RO).
+ CSRAW public float sqrMagnitude { get { return Dot (this, this); } }
+
+
+ // Returns a vector that is made from the smallest components of two vectors.
+ CSRAW public static Vector4 Min (Vector4 lhs, Vector4 rhs) { return new Vector4 (Mathf.Min(lhs.x,rhs.x), Mathf.Min(lhs.y,rhs.y), Mathf.Min(lhs.z,rhs.z), Mathf.Min(lhs.w,rhs.w)); }
+
+ // Returns a vector that is made from the largest components of two vectors.
+ CSRAW public static Vector4 Max (Vector4 lhs, Vector4 rhs) { return new Vector4 (Mathf.Max(lhs.x,rhs.x), Mathf.Max(lhs.y,rhs.y), Mathf.Max(lhs.z,rhs.z), Mathf.Max(lhs.w,rhs.w)); }
+
+ // Shorthand for writing @@Vector4(0,0,0,0)@@
+ CSRAW public static Vector4 zero { get { return new Vector4 (0F, 0F, 0F, 0F); } }
+ // Shorthand for writing @@Vector4(1,1,1,1)@@
+ CSRAW public static Vector4 one { get { return new Vector4 (1F, 1F, 1F, 1F); } }
+
+
+ // Adds two vectors.
+ CSRAW public static Vector4 operator + (Vector4 a, Vector4 b) { return new Vector4 (a.x+b.x, a.y+b.y, a.z+b.z, a.w+b.w); }
+ // Subtracts one vector from another.
+ CSRAW public static Vector4 operator - (Vector4 a, Vector4 b) { return new Vector4 (a.x-b.x, a.y-b.y, a.z-b.z, a.w-b.w); }
+ // Negates a vector.
+ CSRAW public static Vector4 operator - (Vector4 a) { return new Vector4 (-a.x, -a.y, -a.z, -a.w); }
+ // Multiplies a vector by a number.
+ CSRAW public static Vector4 operator * (Vector4 a, float d) { return new Vector4 (a.x*d, a.y*d, a.z*d, a.w*d); }
+ // Multiplies a vector by a number.
+ CSRAW public static Vector4 operator * (float d, Vector4 a) { return new Vector4 (a.x*d, a.y*d, a.z*d, a.w*d); }
+ // Divides a vector by a number.
+ CSRAW public static Vector4 operator / (Vector4 a, float d) { return new Vector4 (a.x/d, a.y/d, a.z/d, a.w/d); }
+
+ // Returns true if the vectors are equal.
+ CSRAW public static bool operator == (Vector4 lhs, Vector4 rhs)
+ {
+ return SqrMagnitude (lhs - rhs) < kEpsilon * kEpsilon;
+ }
+ // Returns true if vectors different.
+ CSRAW public static bool operator != (Vector4 lhs, Vector4 rhs)
+ {
+ return SqrMagnitude (lhs - rhs) >= kEpsilon * kEpsilon;
+ }
+
+ // Converts a [[Vector3]] to a Vector4.
+ CSRAW public static implicit operator Vector4(Vector3 v) {
+ return new Vector4(v.x, v.y, v.z, 0.0F);
+ }
+
+ // Converts a Vector4 to a [[Vector3]].
+ CSRAW public static implicit operator Vector3(Vector4 v) {
+ return new Vector3(v.x, v.y, v.z);
+ }
+
+ // Converts a [[Vector2]] to a Vector4.
+ CSRAW public static implicit operator Vector4(Vector2 v) {
+ return new Vector4(v.x, v.y, 0.0F, 0.0F);
+ }
+
+ // Converts a Vector4 to a [[Vector2]].
+ CSRAW public static implicit operator Vector2(Vector4 v) {
+ return new Vector2(v.x, v.y);
+ }
+
+END
+
+
+// Representation of rays.
+THREAD_SAFE
+STRUCT Ray
+ CSRAW private Vector3 m_Origin;
+ CSRAW private Vector3 m_Direction;
+
+ // Creates a ray starting at /origin/ along /direction/.
+ CSRAW public Ray (Vector3 origin, Vector3 direction) { m_Origin = origin; m_Direction = direction.normalized; }
+
+ // The origin point of the ray.
+ CSRAW public Vector3 origin { get { return m_Origin; } set { m_Origin = value; } }
+ // The direction of the ray.
+ CSRAW public Vector3 direction { get { return m_Direction; } set { m_Direction = value.normalized; } }
+
+ // Returns a point at /distance/ units along the ray.
+ CSRAW public Vector3 GetPoint (float distance) { return m_Origin + m_Direction * distance; }
+
+ /// *listonly*
+ CSRAW override public string ToString() { return UnityString.Format("Origin: {0}, Dir: {1}", m_Origin, m_Direction); }
+ // Returns a nicely formatted string for this ray.
+ CSRAW public string ToString(string format) {
+ return UnityString.Format("Origin: {0}, Dir: {1}", m_Origin.ToString(format), m_Direction.ToString(format));
+ }
+
+END
+
+// Representation of 2D rays.
+THREAD_SAFE
+STRUCT Ray2D
+ CSRAW private Vector2 m_Origin;
+ CSRAW private Vector2 m_Direction;
+
+ // Creates a ray starting at /origin/ along /direction/.
+ CSRAW public Ray2D (Vector2 origin, Vector2 direction) { m_Origin = origin; m_Direction = direction.normalized; }
+
+ // The origin point of the ray.
+ CSRAW public Vector2 origin { get { return m_Origin; } set { m_Origin = value; } }
+
+ // The direction of the ray.
+ CSRAW public Vector2 direction { get { return m_Direction; } set { m_Direction = value.normalized; } }
+
+ // Returns a point at /distance/ units along the ray.
+ CSRAW public Vector2 GetPoint (float distance) { return m_Origin + m_Direction * distance; }
+
+ /// *listonly*
+ CSRAW override public string ToString() { return UnityString.Format("Origin: {0}, Dir: {1}", m_Origin, m_Direction); }
+
+ // Returns a nicely formatted string for this ray.
+ CSRAW public string ToString(string format) {
+ return UnityString.Format("Origin: {0}, Dir: {1}", m_Origin.ToString(format), m_Direction.ToString(format));
+ }
+
+END
+
+// Representation of planes.
+THREAD_SAFE
+STRUCT Plane
+ CSRAW Vector3 m_Normal;
+ CSRAW float m_Distance;
+
+ // Normal vector of the plane.
+ CSRAW public Vector3 normal { get { return m_Normal; } set { m_Normal = value; } }
+ // Distance from the origin to the plane.
+ CSRAW public float distance { get { return m_Distance; } set { m_Distance = value; } }
+
+ // Creates a plane.
+ public Plane (Vector3 inNormal, Vector3 inPoint) {
+ m_Normal = Vector3.Normalize (inNormal);
+ m_Distance = -Vector3.Dot (inNormal, inPoint);
+ }
+
+ // Creates a plane.
+ public Plane (Vector3 inNormal, float d) {
+ m_Normal = Vector3.Normalize (inNormal);
+ m_Distance = d;
+ }
+
+ // Creates a plane.
+ public Plane (Vector3 a, Vector3 b, Vector3 c) {
+ m_Normal = Vector3.Normalize (Vector3.Cross (b - a, c - a));
+ m_Distance = -Vector3.Dot (m_Normal, a);
+ }
+
+ // Sets a plane using a point that lies within it plus a normal to orient it (note that the normal must be a normalised vector).
+ public void SetNormalAndPosition (Vector3 inNormal, Vector3 inPoint) {
+ normal = Vector3.Normalize (inNormal);
+ distance = -Vector3.Dot (inNormal, inPoint);
+ }
+
+ // Sets a plane using three points that lie within it. The points go around clockwise as you look down on the top surface of the plane.
+ public void Set3Points (Vector3 a, Vector3 b, Vector3 c) {
+ normal = Vector3.Normalize (Vector3.Cross (b - a, c - a));
+ distance = -Vector3.Dot (normal, a);
+ }
+
+ // Returns a signed distance from plane to point.
+ public float GetDistanceToPoint (Vector3 inPt) { return Vector3.Dot (normal, inPt) + distance; }
+
+ // Is a point on the positive side of the plane?
+ public bool GetSide (Vector3 inPt) { return Vector3.Dot (normal, inPt) + distance > 0.0F; }
+
+ // Are two points on the same side of the plane?
+ public bool SameSide (Vector3 inPt0, Vector3 inPt1) {
+ float d0 = GetDistanceToPoint(inPt0);
+ float d1 = GetDistanceToPoint(inPt1);
+ if (d0 > 0.0f && d1 > 0.0f)
+ return true;
+ else if (d0 <= 0.0f && d1 <= 0.0f)
+ return true;
+ else
+ return false;
+ }
+
+ // Intersects a ray with the plane.
+ public bool Raycast (Ray ray, out float enter) {
+ float vdot = Vector3.Dot (ray.direction, normal);
+ float ndot = -Vector3.Dot (ray.origin, normal) - distance;
+
+ // is line parallel to the plane? if so, even if the line is
+ // at the plane it is not considered as intersection because
+ // it would be impossible to determine the point of intersection
+ if ( Mathf.Approximately (vdot, 0.0f) ) {
+ enter = 0.0F;
+ return false;
+ }
+
+ // the resulting intersection is behind the origin of the ray
+ // if the result is negative ( enter < 0 )
+ enter = ndot / vdot;
+
+ return enter > 0.0F;
+ }
+
+END
+
+
+// A collection of common math functions.
+THREAD_SAFE
+STRUCT Mathf
+ CSRAW
+
+ // Returns the sine of angle /f/ in radians.
+ CSRAW public static float Sin (float f) { return (float)Math.Sin (f); }
+
+ // Returns the cosine of angle /f/ in radians.
+ CSRAW public static float Cos (float f) { return (float)Math.Cos (f); }
+
+ // Returns the tangent of angle /f/ in radians.
+ CSRAW public static float Tan (float f) { return (float)Math.Tan (f); }
+
+ // Returns the arc-sine of /f/ - the angle in radians whose sine is /f/.
+ CSRAW public static float Asin (float f) { return (float)Math.Asin (f); }
+
+ // Returns the arc-cosine of /f/ - the angle in radians whose cosine is /f/.
+ CSRAW public static float Acos (float f) { return (float)Math.Acos (f); }
+
+ // Returns the arc-tangent of /f/ - the angle in radians whose tangent is /f/.
+ CSRAW public static float Atan (float f) { return (float)Math.Atan (f); }
+
+ // Returns the angle in radians whose ::ref::Tan is @@y/x@@.
+ CSRAW public static float Atan2 (float y, float x) { return (float)Math.Atan2 (y,x); }
+
+ // Returns square root of /f/.
+ CSRAW public static float Sqrt (float f) { return (float)Math.Sqrt (f); }
+
+ // Returns the absolute value of /f/.
+ CSRAW public static float Abs (float f) { return (float)Math.Abs (f); }
+
+ // Returns the absolute value of /value/.
+ CSRAW public static int Abs (int value) { return Math.Abs (value); }
+
+ /// *listonly*
+ CSRAW public static float Min (float a, float b) { return a < b ? a : b; }
+ // Returns the smallest of two or more values.
+ CSRAW public static float Min (params float[] values)
+ {
+ int len = values.Length; // cache the length
+ if (len == 0)
+ return 0;
+ float m = values[0];
+ for (int i=1; i<len; i++)
+ {
+ if (values[i] < m)
+ m = values[i];
+ }
+ return m;
+ }
+
+ /// *listonly*
+ CSRAW public static int Min (int a, int b) { return a < b ? a : b; }
+ // Returns the smallest of two or more values.
+ CSRAW public static int Min (params int[] values)
+ {
+ int len = values.Length; // cache the length
+ if (len == 0)
+ return 0;
+ int m = values[0];
+ for (int i=1; i<len; i++)
+ {
+ if (values[i] < m)
+ m = values[i];
+ }
+ return m;
+ }
+
+ /// *listonly*
+ CSRAW public static float Max (float a, float b) { return a > b ? a : b; }
+ // Returns largest of two or more values.
+ CSRAW public static float Max (params float[] values)
+ {
+ int len = values.Length; // cache the length
+ if (len == 0)
+ return 0;
+ float m = values[0];
+ for (int i=1; i<len; i++)
+ {
+ if (values[i] > m)
+ m = values[i];
+ }
+ return m;
+ }
+
+ /// *listonly*
+ CSRAW public static int Max (int a, int b) { return a > b ? a : b; }
+ // Returns the largest of two or more values.
+ CSRAW public static int Max (params int[] values)
+ {
+ int len = values.Length; // cache the length
+ if (len == 0)
+ return 0;
+ int m = values[0];
+ for (int i=1; i<len; i++)
+ {
+ if (values[i] > m)
+ m = values[i];
+ }
+ return m;
+ }
+
+ // Returns /f/ raised to power /p/.
+ CSRAW public static float Pow (float f, float p) { return (float)Math.Pow (f, p); }
+
+ // Returns e raised to the specified power.
+ CSRAW public static float Exp (float power) { return (float)Math.Exp (power); }
+
+ // Returns the logarithm of a specified number in a specified base.
+ CSRAW public static float Log (float f, float p) { return (float)Math.Log (f, p); }
+
+ // Returns the natural (base e) logarithm of a specified number.
+ CSRAW public static float Log (float f) { return (float)Math.Log (f); }
+
+ // Returns the base 10 logarithm of a specified number.
+ CSRAW public static float Log10 (float f) { return (float)Math.Log10 (f); }
+
+ // Returns the smallest integer greater to or equal to /f/.
+ CSRAW public static float Ceil (float f) { return (float)Math.Ceiling (f); }
+
+ // Returns the largest integer smaller to or equal to /f/.
+ CSRAW public static float Floor (float f) { return (float)Math.Floor (f); }
+
+ // Returns /f/ rounded to the nearest integer.
+ CSRAW public static float Round (float f) { return (float)Math.Round (f); }
+
+ // Returns the smallest integer greater to or equal to /f/.
+ CSRAW public static int CeilToInt (float f) { return (int)Math.Ceiling (f); }
+
+ // Returns the largest integer smaller to or equal to /f/.
+ CSRAW public static int FloorToInt (float f) { return (int)Math.Floor (f); }
+
+ // Returns /f/ rounded to the nearest integer.
+ CSRAW public static int RoundToInt (float f) { return (int)Math.Round (f); }
+
+ // Returns the sign of /f/.
+ CSRAW public static float Sign (float f) { return f >= 0F ? 1F : -1F; }
+
+ // The infamous ''3.14159265358979...'' value (RO).
+ CSRAW public const float PI = (float)Math.PI;
+
+
+ // A representation of positive infinity (RO).
+ CSRAW public const float Infinity = Single.PositiveInfinity;
+
+
+ // A representation of negative infinity (RO).
+ CSRAW public const float NegativeInfinity = Single.NegativeInfinity;
+
+
+ // Degrees-to-radians conversion constant (RO).
+ CSRAW public const float Deg2Rad = PI * 2F / 360F;
+
+ // Radians-to-degrees conversion constant (RO).
+ CSRAW public const float Rad2Deg = 1F / Deg2Rad;
+
+ // A tiny floating point value (RO).
+ #if UNITY_IPHONE || UNITY_BB10 || UNITY_TIZEN
+ CSRAW public const float Epsilon = 1.17549435E-38f; // VFP rounds de-normlized values to 0, unfortunatelly Single.Epsilon is de-normalized value!
+ #else
+ CSRAW public const float Epsilon = Single.Epsilon;
+ #endif
+
+
+ // Clamps a value between a minimum float and maximum float value.
+ CSRAW public static float Clamp (float value, float min, float max)
+ {
+ if (value < min)
+ value = min;
+ else if (value > max)
+ value = max;
+ return value;
+ }
+
+ // Clamps value between min and max and returns value.
+ // Set the position of the transform to be that of the time
+ // but never less than 1 or more than 3
+ //
+ CSRAW public static int Clamp (int value, int min, int max)
+ {
+ if (value < min)
+ value = min;
+ else if (value > max)
+ value = max;
+ return value;
+ }
+
+ // Clamps value between 0 and 1 and returns value
+ CSRAW public static float Clamp01 (float value)
+ {
+ if (value < 0F)
+ return 0F;
+ else if (value > 1F)
+ return 1F;
+ else
+ return value;
+ }
+
+ // Interpolates between /a/ and /b/ by /t/. /t/ is clamped between 0 and 1.
+ CSRAW public static float Lerp (float from, float to, float t)
+ {
+ return from + (to - from) * Clamp01 (t);
+ }
+
+ // Same as ::ref::Lerp but makes sure the values interpolate correctly when they wrap around 360 degrees.
+ CSRAW public static float LerpAngle (float a, float b, float t)
+ {
+ float delta = Repeat ((b - a), 360);
+ if (delta > 180)
+ delta -= 360;
+ return a + delta * Clamp01 (t);
+ }
+
+ // Moves a value /current/ towards /target/.
+ CSRAW static public float MoveTowards (float current, float target, float maxDelta)
+ {
+ if (Mathf.Abs(target - current) <= maxDelta)
+ return target;
+ return current + Mathf.Sign(target - current) * maxDelta;
+ }
+
+ // Same as ::ref::MoveTowards but makes sure the values interpolate correctly when they wrap around 360 degrees.
+ CSRAW static public float MoveTowardsAngle (float current, float target, float maxDelta)
+ {
+ target = current + DeltaAngle(current, target);
+ return MoveTowards(current, target, maxDelta);
+ }
+
+ // Interpolates between /min/ and /max/ with smoothing at the limits.
+ CSRAW public static float SmoothStep (float from, float to, float t)
+ {
+ t = Mathf.Clamp01(t);
+ t = -2.0F * t*t*t + 3.0F * t*t;
+ return to * t + from * (1F - t);
+ }
+
+ //*undocumented
+ CSRAW public static float Gamma (float value, float absmax, float gamma)
+ {
+ bool negative = false;
+ if (value < 0F)
+ negative = true;
+ float absval = Abs(value);
+ if (absval > absmax)
+ return negative ? -absval : absval;
+
+ float result = Pow(absval / absmax, gamma) * absmax;
+ return negative ? -result : result;
+ }
+
+ // Compares two floating point values if they are similar.
+ CSRAW public static bool Approximately (float a, float b)
+ {
+ // If a or b is zero, compare that the other is less or equal to epsilon.
+ // If neither a or b are 0, then find an epsilon that is good for
+ // comparing numbers at the maximum magnitude of a and b.
+ // Floating points have about 7 significant digits, so
+ // 1.000001f can be represented while 1.0000001f is rounded to zero,
+ // thus we could use an epsilon of 0.000001f for comparing values close to 1.
+ // We multiply this epsilon by the biggest magnitude of a and b.
+ return Abs(b - a) < Max( 0.000001f * Max(Abs(a), Abs(b)), Epsilon*8);
+ }
+
+ // Gradually changes a value towards a desired goal over time.
+ CSRAW public static float SmoothDamp (float current, float target, ref float currentVelocity, float smoothTime, float maxSpeed = Mathf.Infinity, float deltaTime = Time.deltaTime)
+ {
+ // Based on Game Programming Gems 4 Chapter 1.10
+ smoothTime = Mathf.Max(0.0001F, smoothTime);
+ float omega = 2F / smoothTime;
+
+ float x = omega * deltaTime;
+ float exp = 1F / (1F + x + 0.48F*x*x + 0.235F*x*x*x);
+ float change = current - target;
+ float originalTo = target;
+
+ // Clamp maximum speed
+ float maxChange = maxSpeed * smoothTime;
+ change = Mathf.Clamp(change, -maxChange, maxChange);
+ target = current - change;
+
+ float temp = (currentVelocity + omega * change) * deltaTime;
+ currentVelocity = (currentVelocity - omega * temp) * exp;
+ float output = target + (change + temp) * exp;
+
+ // Prevent overshooting
+ if (originalTo - current > 0.0F == output > originalTo)
+ {
+ output = originalTo;
+ currentVelocity = (output - originalTo) / deltaTime;
+ }
+
+ return output;
+ }
+
+
+ // Gradually changes an angle given in degrees towards a desired goal angle over time.
+ CSRAW public static float SmoothDampAngle (float current, float target, ref float currentVelocity, float smoothTime, float maxSpeed = Mathf.Infinity, float deltaTime = Time.deltaTime)
+ {
+ // Normalize angles
+ target = current + DeltaAngle(current, target);
+ return SmoothDamp(current, target, ref currentVelocity, smoothTime, maxSpeed, deltaTime);
+ }
+
+ // Loops the value t, so that it is never larger than length and never smaller than 0.
+ CSRAW public static float Repeat (float t, float length)
+ {
+ return t - Mathf.Floor (t / length) * length;
+ }
+
+ // PingPongs the value t, so that it is never larger than length and never smaller than 0.
+ CSRAW public static float PingPong (float t, float length)
+ {
+ t = Repeat (t, length * 2F);
+ return length - Mathf.Abs (t - length);
+ }
+
+ // Calculates the ::ref::Lerp parameter between of two values.
+ CSRAW public static float InverseLerp (float from, float to, float value)
+ {
+ if (from < to)
+ {
+ if (value < from)
+ return 0.0F;
+ else if (value > to)
+ return 1.0F;
+ else
+ {
+ value -= from;
+ value /= (to - from);
+ return value;
+ }
+ }
+ else if (from > to)
+ {
+ if (value < to)
+ return 1.0F;
+ else if (value > from)
+ return 0.0F;
+ else
+ {
+ return 1.0F - ((value - to) / (from - to));
+ }
+ }
+ else
+ {
+ return 0.0F;
+ }
+ }
+
+ // Returns the closest power of two value.
+ CUSTOM static int ClosestPowerOfTwo (int value)
+ {
+ return ClosestPowerOfTwo(value);
+ }
+
+ // Converts the given value from gamma to linear color space.
+ CUSTOM static float GammaToLinearSpace (float value)
+ {
+ return GammaToLinearSpace (value);
+ }
+
+ // Converts the given value from linear to gamma color space.
+ CUSTOM static float LinearToGammaSpace (float value)
+ {
+ return LinearToGammaSpace (value);
+ }
+
+ // Returns true if the value is power of two.
+ CUSTOM static bool IsPowerOfTwo (int value)
+ {
+ return IsPowerOfTwo(value);
+ }
+
+ // Returns the next power of two value
+ CUSTOM static int NextPowerOfTwo (int value)
+ {
+ return NextPowerOfTwo(value);
+ }
+
+ // Calculates the shortest difference between two given angles.
+ CSRAW public static float DeltaAngle (float current, float target)
+ {
+ float delta = Mathf.Repeat ((target - current), 360.0F);
+ if (delta > 180.0F)
+ delta -= 360.0F;
+ return delta;
+ }
+
+ // Generate 2D Perlin noise.
+ CUSTOM static float PerlinNoise (float x, float y)
+ {
+ return PerlinNoise::NoiseNormalized (x,y);
+ }
+
+
+ // Infinite Line Intersection (line1 is p1-p2 and line2 is p3-p4)
+ CSRAW internal static bool LineIntersection (Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, ref Vector2 result)
+ {
+ float bx = p2.x - p1.x;
+ float by = p2.y - p1.y;
+ float dx = p4.x - p3.x;
+ float dy = p4.y - p3.y;
+ float bDotDPerp = bx * dy - by * dx;
+ if (bDotDPerp == 0)
+ {
+ return false;
+ }
+ float cx = p3.x - p1.x;
+ float cy = p3.y - p1.y;
+ float t = (cx * dy - cy * dx) / bDotDPerp;
+
+ result = new Vector2 (p1.x + t * bx, p1.y + t * by);
+ return true;
+ }
+
+ // Line Segment Intersection (line1 is p1-p2 and line2 is p3-p4)
+ CSRAW internal static bool LineSegmentIntersection(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, ref Vector2 result)
+ {
+ float bx = p2.x - p1.x;
+ float by = p2.y - p1.y;
+ float dx = p4.x - p3.x;
+ float dy = p4.y - p3.y;
+ float bDotDPerp = bx * dy - by * dx;
+ if (bDotDPerp == 0)
+ {
+ return false;
+ }
+ float cx = p3.x - p1.x;
+ float cy = p3.y - p1.y;
+ float t = (cx * dy - cy * dx) / bDotDPerp;
+ if (t < 0 || t > 1)
+ {
+ return false;
+ }
+ float u = (cx * by - cy * bx) / bDotDPerp;
+ if (u < 0 || u > 1)
+ {
+ return false;
+ }
+ result = new Vector2(p1.x + t * bx, p1.y + t * by);
+ return true;
+ }
+END
+CSRAW
+}