mirror of
https://github.com/TechplexEngineer/plexview.git
synced 2026-07-28 06:22:14 +00:00
Initial commit
I wish I could figure out how to have PlexVie be out of the LibOMV tree but its just not working die to a DLL not found exception about libopenjpeg. (Yes the dll is in the bin folder) This will do for now
This commit is contained in:
@@ -0,0 +1,554 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2014, openmetaverse.org
|
||||
* All rights reserved.
|
||||
*
|
||||
* - Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* - Neither the name of the openmetaverse.org nor the names
|
||||
* of its contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Globalization;
|
||||
|
||||
namespace OpenMetaverse
|
||||
{
|
||||
[Serializable]
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct Vector4 : IComparable<Vector4>, IEquatable<Vector4>
|
||||
{
|
||||
/// <summary>X value</summary>
|
||||
public float X;
|
||||
/// <summary>Y value</summary>
|
||||
public float Y;
|
||||
/// <summary>Z value</summary>
|
||||
public float Z;
|
||||
/// <summary>W value</summary>
|
||||
public float W;
|
||||
|
||||
#region Constructors
|
||||
|
||||
public Vector4(float x, float y, float z, float w)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
Z = z;
|
||||
W = w;
|
||||
}
|
||||
|
||||
public Vector4(Vector2 value, float z, float w)
|
||||
{
|
||||
X = value.X;
|
||||
Y = value.Y;
|
||||
Z = z;
|
||||
W = w;
|
||||
}
|
||||
|
||||
public Vector4(Vector3 value, float w)
|
||||
{
|
||||
X = value.X;
|
||||
Y = value.Y;
|
||||
Z = value.Z;
|
||||
W = w;
|
||||
}
|
||||
|
||||
public Vector4(float value)
|
||||
{
|
||||
X = value;
|
||||
Y = value;
|
||||
Z = value;
|
||||
W = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor, builds a vector from a byte array
|
||||
/// </summary>
|
||||
/// <param name="byteArray">Byte array containing four four-byte floats</param>
|
||||
/// <param name="pos">Beginning position in the byte array</param>
|
||||
public Vector4(byte[] byteArray, int pos)
|
||||
{
|
||||
X = Y = Z = W = 0f;
|
||||
FromBytes(byteArray, pos);
|
||||
}
|
||||
|
||||
public Vector4(Vector4 value)
|
||||
{
|
||||
X = value.X;
|
||||
Y = value.Y;
|
||||
Z = value.Z;
|
||||
W = value.W;
|
||||
}
|
||||
|
||||
#endregion Constructors
|
||||
|
||||
#region Public Methods
|
||||
|
||||
public float Length()
|
||||
{
|
||||
return (float)Math.Sqrt(DistanceSquared(this, Zero));
|
||||
}
|
||||
|
||||
public float LengthSquared()
|
||||
{
|
||||
return DistanceSquared(this, Zero);
|
||||
}
|
||||
|
||||
public void Normalize()
|
||||
{
|
||||
this = Normalize(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test if this vector is equal to another vector, within a given
|
||||
/// tolerance range
|
||||
/// </summary>
|
||||
/// <param name="vec">Vector to test against</param>
|
||||
/// <param name="tolerance">The acceptable magnitude of difference
|
||||
/// between the two vectors</param>
|
||||
/// <returns>True if the magnitude of difference between the two vectors
|
||||
/// is less than the given tolerance, otherwise false</returns>
|
||||
public bool ApproxEquals(Vector4 vec, float tolerance)
|
||||
{
|
||||
Vector4 diff = this - vec;
|
||||
return (diff.LengthSquared() <= tolerance * tolerance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// IComparable.CompareTo implementation
|
||||
/// </summary>
|
||||
public int CompareTo(Vector4 vector)
|
||||
{
|
||||
return Length().CompareTo(vector.Length());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test if this vector is composed of all finite numbers
|
||||
/// </summary>
|
||||
public bool IsFinite()
|
||||
{
|
||||
return (Utils.IsFinite(X) && Utils.IsFinite(Y) && Utils.IsFinite(Z) && Utils.IsFinite(W));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Builds a vector from a byte array
|
||||
/// </summary>
|
||||
/// <param name="byteArray">Byte array containing a 16 byte vector</param>
|
||||
/// <param name="pos">Beginning position in the byte array</param>
|
||||
public void FromBytes(byte[] byteArray, int pos)
|
||||
{
|
||||
if (!BitConverter.IsLittleEndian)
|
||||
{
|
||||
// Big endian architecture
|
||||
byte[] conversionBuffer = new byte[16];
|
||||
|
||||
Buffer.BlockCopy(byteArray, pos, conversionBuffer, 0, 16);
|
||||
|
||||
Array.Reverse(conversionBuffer, 0, 4);
|
||||
Array.Reverse(conversionBuffer, 4, 4);
|
||||
Array.Reverse(conversionBuffer, 8, 4);
|
||||
Array.Reverse(conversionBuffer, 12, 4);
|
||||
|
||||
X = BitConverter.ToSingle(conversionBuffer, 0);
|
||||
Y = BitConverter.ToSingle(conversionBuffer, 4);
|
||||
Z = BitConverter.ToSingle(conversionBuffer, 8);
|
||||
W = BitConverter.ToSingle(conversionBuffer, 12);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Little endian architecture
|
||||
X = BitConverter.ToSingle(byteArray, pos);
|
||||
Y = BitConverter.ToSingle(byteArray, pos + 4);
|
||||
Z = BitConverter.ToSingle(byteArray, pos + 8);
|
||||
W = BitConverter.ToSingle(byteArray, pos + 12);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the raw bytes for this vector
|
||||
/// </summary>
|
||||
/// <returns>A 16 byte array containing X, Y, Z, and W</returns>
|
||||
public byte[] GetBytes()
|
||||
{
|
||||
byte[] byteArray = new byte[16];
|
||||
ToBytes(byteArray, 0);
|
||||
return byteArray;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the raw bytes for this vector to a byte array
|
||||
/// </summary>
|
||||
/// <param name="dest">Destination byte array</param>
|
||||
/// <param name="pos">Position in the destination array to start
|
||||
/// writing. Must be at least 16 bytes before the end of the array</param>
|
||||
public void ToBytes(byte[] dest, int pos)
|
||||
{
|
||||
Buffer.BlockCopy(BitConverter.GetBytes(X), 0, dest, pos + 0, 4);
|
||||
Buffer.BlockCopy(BitConverter.GetBytes(Y), 0, dest, pos + 4, 4);
|
||||
Buffer.BlockCopy(BitConverter.GetBytes(Z), 0, dest, pos + 8, 4);
|
||||
Buffer.BlockCopy(BitConverter.GetBytes(W), 0, dest, pos + 12, 4);
|
||||
|
||||
if (!BitConverter.IsLittleEndian)
|
||||
{
|
||||
Array.Reverse(dest, pos + 0, 4);
|
||||
Array.Reverse(dest, pos + 4, 4);
|
||||
Array.Reverse(dest, pos + 8, 4);
|
||||
Array.Reverse(dest, pos + 12, 4);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
|
||||
#region Static Methods
|
||||
|
||||
public static Vector4 Add(Vector4 value1, Vector4 value2)
|
||||
{
|
||||
value1.W += value2.W;
|
||||
value1.X += value2.X;
|
||||
value1.Y += value2.Y;
|
||||
value1.Z += value2.Z;
|
||||
return value1;
|
||||
}
|
||||
|
||||
public static Vector4 Clamp(Vector4 value1, Vector4 min, Vector4 max)
|
||||
{
|
||||
return new Vector4(
|
||||
Utils.Clamp(value1.X, min.X, max.X),
|
||||
Utils.Clamp(value1.Y, min.Y, max.Y),
|
||||
Utils.Clamp(value1.Z, min.Z, max.Z),
|
||||
Utils.Clamp(value1.W, min.W, max.W));
|
||||
}
|
||||
|
||||
public static float Distance(Vector4 value1, Vector4 value2)
|
||||
{
|
||||
return (float)Math.Sqrt(DistanceSquared(value1, value2));
|
||||
}
|
||||
|
||||
public static float DistanceSquared(Vector4 value1, Vector4 value2)
|
||||
{
|
||||
return
|
||||
(value1.W - value2.W) * (value1.W - value2.W) +
|
||||
(value1.X - value2.X) * (value1.X - value2.X) +
|
||||
(value1.Y - value2.Y) * (value1.Y - value2.Y) +
|
||||
(value1.Z - value2.Z) * (value1.Z - value2.Z);
|
||||
}
|
||||
|
||||
public static Vector4 Divide(Vector4 value1, Vector4 value2)
|
||||
{
|
||||
value1.W /= value2.W;
|
||||
value1.X /= value2.X;
|
||||
value1.Y /= value2.Y;
|
||||
value1.Z /= value2.Z;
|
||||
return value1;
|
||||
}
|
||||
|
||||
public static Vector4 Divide(Vector4 value1, float divider)
|
||||
{
|
||||
float factor = 1f / divider;
|
||||
value1.W *= factor;
|
||||
value1.X *= factor;
|
||||
value1.Y *= factor;
|
||||
value1.Z *= factor;
|
||||
return value1;
|
||||
}
|
||||
|
||||
public static float Dot(Vector4 vector1, Vector4 vector2)
|
||||
{
|
||||
return vector1.X * vector2.X + vector1.Y * vector2.Y + vector1.Z * vector2.Z + vector1.W * vector2.W;
|
||||
}
|
||||
|
||||
public static Vector4 Lerp(Vector4 value1, Vector4 value2, float amount)
|
||||
{
|
||||
return new Vector4(
|
||||
Utils.Lerp(value1.X, value2.X, amount),
|
||||
Utils.Lerp(value1.Y, value2.Y, amount),
|
||||
Utils.Lerp(value1.Z, value2.Z, amount),
|
||||
Utils.Lerp(value1.W, value2.W, amount));
|
||||
}
|
||||
|
||||
public static Vector4 Max(Vector4 value1, Vector4 value2)
|
||||
{
|
||||
return new Vector4(
|
||||
Math.Max(value1.X, value2.X),
|
||||
Math.Max(value1.Y, value2.Y),
|
||||
Math.Max(value1.Z, value2.Z),
|
||||
Math.Max(value1.W, value2.W));
|
||||
}
|
||||
|
||||
public static Vector4 Min(Vector4 value1, Vector4 value2)
|
||||
{
|
||||
return new Vector4(
|
||||
Math.Min(value1.X, value2.X),
|
||||
Math.Min(value1.Y, value2.Y),
|
||||
Math.Min(value1.Z, value2.Z),
|
||||
Math.Min(value1.W, value2.W));
|
||||
}
|
||||
|
||||
public static Vector4 Multiply(Vector4 value1, Vector4 value2)
|
||||
{
|
||||
value1.W *= value2.W;
|
||||
value1.X *= value2.X;
|
||||
value1.Y *= value2.Y;
|
||||
value1.Z *= value2.Z;
|
||||
return value1;
|
||||
}
|
||||
|
||||
public static Vector4 Multiply(Vector4 value1, float scaleFactor)
|
||||
{
|
||||
value1.W *= scaleFactor;
|
||||
value1.X *= scaleFactor;
|
||||
value1.Y *= scaleFactor;
|
||||
value1.Z *= scaleFactor;
|
||||
return value1;
|
||||
}
|
||||
|
||||
public static Vector4 Negate(Vector4 value)
|
||||
{
|
||||
value.X = -value.X;
|
||||
value.Y = -value.Y;
|
||||
value.Z = -value.Z;
|
||||
value.W = -value.W;
|
||||
return value;
|
||||
}
|
||||
|
||||
public static Vector4 Normalize(Vector4 vector)
|
||||
{
|
||||
const float MAG_THRESHOLD = 0.0000001f;
|
||||
float factor = DistanceSquared(vector, Zero);
|
||||
if (factor > MAG_THRESHOLD)
|
||||
{
|
||||
factor = 1f / (float)Math.Sqrt(factor);
|
||||
vector.X *= factor;
|
||||
vector.Y *= factor;
|
||||
vector.Z *= factor;
|
||||
vector.W *= factor;
|
||||
}
|
||||
else
|
||||
{
|
||||
vector.X = 0f;
|
||||
vector.Y = 0f;
|
||||
vector.Z = 0f;
|
||||
vector.W = 0f;
|
||||
}
|
||||
return vector;
|
||||
}
|
||||
|
||||
public static Vector4 SmoothStep(Vector4 value1, Vector4 value2, float amount)
|
||||
{
|
||||
return new Vector4(
|
||||
Utils.SmoothStep(value1.X, value2.X, amount),
|
||||
Utils.SmoothStep(value1.Y, value2.Y, amount),
|
||||
Utils.SmoothStep(value1.Z, value2.Z, amount),
|
||||
Utils.SmoothStep(value1.W, value2.W, amount));
|
||||
}
|
||||
|
||||
public static Vector4 Subtract(Vector4 value1, Vector4 value2)
|
||||
{
|
||||
value1.W -= value2.W;
|
||||
value1.X -= value2.X;
|
||||
value1.Y -= value2.Y;
|
||||
value1.Z -= value2.Z;
|
||||
return value1;
|
||||
}
|
||||
|
||||
public static Vector4 Transform(Vector2 position, Matrix4 matrix)
|
||||
{
|
||||
return new Vector4(
|
||||
(position.X * matrix.M11) + (position.Y * matrix.M21) + matrix.M41,
|
||||
(position.X * matrix.M12) + (position.Y * matrix.M22) + matrix.M42,
|
||||
(position.X * matrix.M13) + (position.Y * matrix.M23) + matrix.M43,
|
||||
(position.X * matrix.M14) + (position.Y * matrix.M24) + matrix.M44);
|
||||
}
|
||||
|
||||
public static Vector4 Transform(Vector3 position, Matrix4 matrix)
|
||||
{
|
||||
return new Vector4(
|
||||
(position.X * matrix.M11) + (position.Y * matrix.M21) + (position.Z * matrix.M31) + matrix.M41,
|
||||
(position.X * matrix.M12) + (position.Y * matrix.M22) + (position.Z * matrix.M32) + matrix.M42,
|
||||
(position.X * matrix.M13) + (position.Y * matrix.M23) + (position.Z * matrix.M33) + matrix.M43,
|
||||
(position.X * matrix.M14) + (position.Y * matrix.M24) + (position.Z * matrix.M34) + matrix.M44);
|
||||
}
|
||||
|
||||
public static Vector4 Transform(Vector4 vector, Matrix4 matrix)
|
||||
{
|
||||
return new Vector4(
|
||||
(vector.X * matrix.M11) + (vector.Y * matrix.M21) + (vector.Z * matrix.M31) + (vector.W * matrix.M41),
|
||||
(vector.X * matrix.M12) + (vector.Y * matrix.M22) + (vector.Z * matrix.M32) + (vector.W * matrix.M42),
|
||||
(vector.X * matrix.M13) + (vector.Y * matrix.M23) + (vector.Z * matrix.M33) + (vector.W * matrix.M43),
|
||||
(vector.X * matrix.M14) + (vector.Y * matrix.M24) + (vector.Z * matrix.M34) + (vector.W * matrix.M44));
|
||||
}
|
||||
|
||||
public static Vector4 Parse(string val)
|
||||
{
|
||||
char[] splitChar = { ',' };
|
||||
string[] split = val.Replace("<", String.Empty).Replace(">", String.Empty).Split(splitChar);
|
||||
return new Vector4(
|
||||
float.Parse(split[0].Trim(), Utils.EnUsCulture),
|
||||
float.Parse(split[1].Trim(), Utils.EnUsCulture),
|
||||
float.Parse(split[2].Trim(), Utils.EnUsCulture),
|
||||
float.Parse(split[3].Trim(), Utils.EnUsCulture));
|
||||
}
|
||||
|
||||
public static bool TryParse(string val, out Vector4 result)
|
||||
{
|
||||
try
|
||||
{
|
||||
result = Parse(val);
|
||||
return true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
result = new Vector4();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Static Methods
|
||||
|
||||
#region Overrides
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return (obj is Vector4) ? this == (Vector4)obj : false;
|
||||
}
|
||||
|
||||
public bool Equals(Vector4 other)
|
||||
{
|
||||
return W == other.W
|
||||
&& X == other.X
|
||||
&& Y == other.Y
|
||||
&& Z == other.Z;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return X.GetHashCode() ^ Y.GetHashCode() ^ Z.GetHashCode() ^ W.GetHashCode();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format(Utils.EnUsCulture, "<{0}, {1}, {2}, {3}>", X, Y, Z, W);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a string representation of the vector elements with up to three
|
||||
/// decimal digits and separated by spaces only
|
||||
/// </summary>
|
||||
/// <returns>Raw string representation of the vector</returns>
|
||||
public string ToRawString()
|
||||
{
|
||||
CultureInfo enUs = new CultureInfo("en-us");
|
||||
enUs.NumberFormat.NumberDecimalDigits = 3;
|
||||
|
||||
return String.Format(enUs, "{0} {1} {2} {3}", X, Y, Z, W);
|
||||
}
|
||||
|
||||
#endregion Overrides
|
||||
|
||||
#region Operators
|
||||
|
||||
public static bool operator ==(Vector4 value1, Vector4 value2)
|
||||
{
|
||||
return value1.W == value2.W
|
||||
&& value1.X == value2.X
|
||||
&& value1.Y == value2.Y
|
||||
&& value1.Z == value2.Z;
|
||||
}
|
||||
|
||||
public static bool operator !=(Vector4 value1, Vector4 value2)
|
||||
{
|
||||
return !(value1 == value2);
|
||||
}
|
||||
|
||||
public static Vector4 operator +(Vector4 value1, Vector4 value2)
|
||||
{
|
||||
value1.W += value2.W;
|
||||
value1.X += value2.X;
|
||||
value1.Y += value2.Y;
|
||||
value1.Z += value2.Z;
|
||||
return value1;
|
||||
}
|
||||
|
||||
public static Vector4 operator -(Vector4 value)
|
||||
{
|
||||
return new Vector4(-value.X, -value.Y, -value.Z, -value.W);
|
||||
}
|
||||
|
||||
public static Vector4 operator -(Vector4 value1, Vector4 value2)
|
||||
{
|
||||
value1.W -= value2.W;
|
||||
value1.X -= value2.X;
|
||||
value1.Y -= value2.Y;
|
||||
value1.Z -= value2.Z;
|
||||
return value1;
|
||||
}
|
||||
|
||||
public static Vector4 operator *(Vector4 value1, Vector4 value2)
|
||||
{
|
||||
value1.W *= value2.W;
|
||||
value1.X *= value2.X;
|
||||
value1.Y *= value2.Y;
|
||||
value1.Z *= value2.Z;
|
||||
return value1;
|
||||
}
|
||||
|
||||
public static Vector4 operator *(Vector4 value1, float scaleFactor)
|
||||
{
|
||||
value1.W *= scaleFactor;
|
||||
value1.X *= scaleFactor;
|
||||
value1.Y *= scaleFactor;
|
||||
value1.Z *= scaleFactor;
|
||||
return value1;
|
||||
}
|
||||
|
||||
public static Vector4 operator /(Vector4 value1, Vector4 value2)
|
||||
{
|
||||
value1.W /= value2.W;
|
||||
value1.X /= value2.X;
|
||||
value1.Y /= value2.Y;
|
||||
value1.Z /= value2.Z;
|
||||
return value1;
|
||||
}
|
||||
|
||||
public static Vector4 operator /(Vector4 value1, float divider)
|
||||
{
|
||||
float factor = 1f / divider;
|
||||
value1.W *= factor;
|
||||
value1.X *= factor;
|
||||
value1.Y *= factor;
|
||||
value1.Z *= factor;
|
||||
return value1;
|
||||
}
|
||||
|
||||
#endregion Operators
|
||||
|
||||
/// <summary>A vector with a value of 0,0,0,0</summary>
|
||||
public readonly static Vector4 Zero = new Vector4();
|
||||
/// <summary>A vector with a value of 1,1,1,1</summary>
|
||||
public readonly static Vector4 One = new Vector4(1f, 1f, 1f, 1f);
|
||||
/// <summary>A vector with a value of 1,0,0,0</summary>
|
||||
public readonly static Vector4 UnitX = new Vector4(1f, 0f, 0f, 0f);
|
||||
/// <summary>A vector with a value of 0,1,0,0</summary>
|
||||
public readonly static Vector4 UnitY = new Vector4(0f, 1f, 0f, 0f);
|
||||
/// <summary>A vector with a value of 0,0,1,0</summary>
|
||||
public readonly static Vector4 UnitZ = new Vector4(0f, 0f, 1f, 0f);
|
||||
/// <summary>A vector with a value of 0,0,0,1</summary>
|
||||
public readonly static Vector4 UnitW = new Vector4(0f, 0f, 0f, 1f);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user