Repository: Scrawk/2D-Deformable-body-in-Unity
Branch: master
Commit: af26a1a84715
Files: 116
Total size: 425.4 KB
Directory structure:
gitextract_fo5zd9vd/
├── .gitignore
├── Assets/
│ ├── Common/
│ │ ├── Decomposition/
│ │ │ ├── Decomposition2x2d.cs
│ │ │ ├── Decomposition2x2d.cs.meta
│ │ │ ├── Decomposition2x2f.cs
│ │ │ ├── Decomposition2x2f.cs.meta
│ │ │ ├── Decomposition3x3d.cs
│ │ │ ├── Decomposition3x3d.cs.meta
│ │ │ ├── Decomposition3x3f.cs
│ │ │ └── Decomposition3x3f.cs.meta
│ │ ├── Decomposition.meta
│ │ ├── LinearAlgebra/
│ │ │ ├── Matrix2x2d.cs
│ │ │ ├── Matrix2x2d.cs.meta
│ │ │ ├── Matrix2x2f.cs
│ │ │ ├── Matrix2x2f.cs.meta
│ │ │ ├── Matrix3x3d.cs
│ │ │ ├── Matrix3x3d.cs.meta
│ │ │ ├── Matrix3x3f.cs
│ │ │ ├── Matrix3x3f.cs.meta
│ │ │ ├── Matrix4x4d.cs
│ │ │ ├── Matrix4x4d.cs.meta
│ │ │ ├── Matrix4x4f.cs
│ │ │ ├── Matrix4x4f.cs.meta
│ │ │ ├── MatrixMxN.cs
│ │ │ ├── MatrixMxN.cs.meta
│ │ │ ├── Quaternion3d.cs
│ │ │ ├── Quaternion3d.cs.meta
│ │ │ ├── Quaternion3f.cs
│ │ │ ├── Quaternion3f.cs.meta
│ │ │ ├── Vector2d.cs
│ │ │ ├── Vector2d.cs.meta
│ │ │ ├── Vector2f.cs
│ │ │ ├── Vector2f.cs.meta
│ │ │ ├── Vector2i.cs
│ │ │ ├── Vector2i.cs.meta
│ │ │ ├── Vector3d.cs
│ │ │ ├── Vector3d.cs.meta
│ │ │ ├── Vector3f.cs
│ │ │ ├── Vector3f.cs.meta
│ │ │ ├── Vector3i.cs
│ │ │ ├── Vector3i.cs.meta
│ │ │ ├── Vector4d.cs
│ │ │ ├── Vector4d.cs.meta
│ │ │ ├── Vector4f.cs
│ │ │ ├── Vector4f.cs.meta
│ │ │ ├── Vector4i.cs
│ │ │ └── Vector4i.cs.meta
│ │ ├── LinearAlgebra.meta
│ │ ├── Mathematics/
│ │ │ ├── DMath.cs
│ │ │ ├── DMath.cs.meta
│ │ │ ├── FMath.cs
│ │ │ ├── FMath.cs.meta
│ │ │ ├── IMath.cs
│ │ │ └── IMath.cs.meta
│ │ └── Mathematics.meta
│ ├── Common.meta
│ ├── FEM2D/
│ │ ├── Demo.unity
│ │ ├── Demo.unity.meta
│ │ ├── Materials/
│ │ │ ├── TextureMaterial.mat
│ │ │ ├── TextureMaterial.mat.meta
│ │ │ ├── TextureShader.shader
│ │ │ └── TextureShader.shader.meta
│ │ ├── Materials.meta
│ │ ├── Scripts/
│ │ │ ├── CreateCantileverBeam.cs
│ │ │ ├── CreateCantileverBeam.cs.meta
│ │ │ ├── CreateFromImage.cs
│ │ │ ├── CreateFromImage.cs.meta
│ │ │ ├── CreateRandomConvex.cs
│ │ │ ├── CreateRandomConvex.cs.meta
│ │ │ ├── CreateTorus.cs
│ │ │ ├── CreateTorus.cs.meta
│ │ │ ├── DelaunayTriangulation.cs
│ │ │ ├── DelaunayTriangulation.cs.meta
│ │ │ ├── FEMDemo.cs
│ │ │ ├── FEMDemo.cs.meta
│ │ │ ├── FEMElement.cs
│ │ │ ├── FEMElement.cs.meta
│ │ │ ├── FEMFractureEvent.cs
│ │ │ ├── FEMFractureEvent.cs.meta
│ │ │ ├── FEMParticle.cs
│ │ │ ├── FEMParticle.cs.meta
│ │ │ ├── FEMScene.cs
│ │ │ ├── FEMScene.cs.meta
│ │ │ ├── Mesher.cs
│ │ │ ├── Mesher.cs.meta
│ │ │ ├── Triangle.cs
│ │ │ └── Triangle.cs.meta
│ │ ├── Scripts.meta
│ │ ├── Textures/
│ │ │ ├── armadillo.png.meta
│ │ │ ├── bunny.png.meta
│ │ │ └── donut1.png.meta
│ │ └── Textures.meta
│ └── FEM2D.meta
├── LICENSE
├── Packages/
│ ├── manifest.json
│ └── packages-lock.json
├── ProjectSettings/
│ ├── AudioManager.asset
│ ├── ClusterInputManager.asset
│ ├── DynamicsManager.asset
│ ├── EditorBuildSettings.asset
│ ├── EditorSettings.asset
│ ├── GraphicsSettings.asset
│ ├── InputManager.asset
│ ├── NavMeshAreas.asset
│ ├── PackageManagerSettings.asset
│ ├── Physics2DSettings.asset
│ ├── PresetManager.asset
│ ├── ProjectSettings.asset
│ ├── ProjectVersion.txt
│ ├── QualitySettings.asset
│ ├── TagManager.asset
│ ├── TimeManager.asset
│ ├── UnityConnectSettings.asset
│ ├── VFXManager.asset
│ ├── VersionControlSettings.asset
│ └── XRSettings.asset
└── README.md
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
################################################################################
# This .gitignore file was automatically created by Microsoft(R) Visual Studio.
################################################################################
/Temp
/.vs/2D-Deformable-body-in-Unity/v16
/Library
/Logs
/obj/Debug
================================================
FILE: Assets/Common/Decomposition/Decomposition2x2d.cs
================================================
using System;
using System.Collections.Generic;
using Common.Core.LinearAlgebra;
namespace Common.Mathematics.Decomposition
{
public static class Decomposition2x2d
{
public static Matrix2x2d QRDecomposition(Matrix2x2d m)
{
Vector2d a = m.GetColumn(0).Normalized;
Matrix2x2d q = new Matrix2x2d();
q.SetColumn(0, a);
q.SetColumn(1, a.PerpendicularCCW);
return q;
}
public static Matrix2x2d PolarDecomposition(Matrix2x2d m)
{
Matrix2x2d q = m + new Matrix2x2d(m.m11, -m.m10, -m.m01, m.m00);
Vector2d c0 = q.GetColumn(0);
Vector2d c1 = q.GetColumn(1);
double s = c0.Magnitude;
q.SetColumn(0, c0 / s);
q.SetColumn(1, c1 / s);
return q;
}
public static void EigenDecomposition(Matrix2x2d m, out double e1, out double e2)
{
// solve the characteristic polynomial
double a = 1.0;
double b = -(m.m00 + m.m11);
double c = m.m00 * m.m11 - m.m01 * m.m10;
SolveQuadratic(a, b, c, out e1, out e2);
}
private static bool SolveQuadratic(double a, double b, double c, out double min, out double max)
{
min = max = 0.0;
if (a == 0.0 && b == 0.0)
return true;
double discriminant = b * b - 4.0 * a * c;
if (discriminant < 0.0)
return false;
// numerical receipes 5.6 (this method ensures numerical accuracy is preserved)
double t = -0.5 * (b + Math.Sign(b) * Math.Sqrt(discriminant));
min = t / a;
max = c / t;
if (min > max)
{
double tmp = min;
min = max;
max = tmp;
}
return true;
}
}
}
================================================
FILE: Assets/Common/Decomposition/Decomposition2x2d.cs.meta
================================================
fileFormatVersion: 2
guid: 60689437f1f73d04da8380919053e6e8
timeCreated: 1514536270
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Common/Decomposition/Decomposition2x2f.cs
================================================
using System;
using System.Collections.Generic;
using Common.Core.LinearAlgebra;
namespace Common.Mathematics.Decomposition
{
public static class Decomposition2x2f
{
public static Matrix2x2f QRDecomposition(Matrix2x2f m)
{
Vector2f a = m.GetColumn(0).Normalized;
Matrix2x2f q = new Matrix2x2f();
q.SetColumn(0, a);
q.SetColumn(1, a.PerpendicularCCW);
return q;
}
public static Matrix2x2f PolarDecomposition(Matrix2x2f m)
{
Matrix2x2f q = m + new Matrix2x2f(m.m11, -m.m10, -m.m01, m.m00);
Vector2f c0 = q.GetColumn(0);
Vector2f c1 = q.GetColumn(1);
float s = c0.Magnitude;
q.SetColumn(0, c0 / s);
q.SetColumn(1, c1 / s);
return q;
}
public static void EigenDecomposition(Matrix2x2f m, out float e1, out float e2)
{
// solve the characteristic polynomial
float a = 1.0f;
float b = -(m.m00 + m.m11);
float c = m.m00 * m.m11 - m.m01 * m.m10;
SolveQuadratic(a, b, c, out e1, out e2);
}
private static bool SolveQuadratic(float a, float b, float c, out float min, out float max)
{
min = max = 0.0f;
if (a == 0.0f && b == 0.0f)
return true;
float discriminant = b * b - 4.0f * a * c;
if (discriminant < 0.0f)
return false;
// numerical receipes 5.6 (this method ensures numerical accuracy is preserved)
float t = (float)(-0.5 * (b + Math.Sign(b) * Math.Sqrt(discriminant)));
min = t / a;
max = c / t;
if (min > max)
{
float tmp = min;
min = max;
max = tmp;
}
return true;
}
}
}
================================================
FILE: Assets/Common/Decomposition/Decomposition2x2f.cs.meta
================================================
fileFormatVersion: 2
guid: 677436b12b96e754eb23bb58733959f9
timeCreated: 1514536270
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Common/Decomposition/Decomposition3x3d.cs
================================================
using System;
using Common.Core.LinearAlgebra;
namespace Common.Mathematics.Decomposition
{
public static class Decomposition3x3d
{
///
/// Rotates A through phi in pq-plane to set A(p,q) = 0
/// Rotation stored in R whose columns are eigenvectors of A
///
public static void JacobiRotate(ref Matrix3x3d A, ref Matrix3x3d R, int p, int q)
{
if (A[p, q] == 0.0f)
return;
double d = (A[p, p] - A[q, q]) / (2.0f * A[p, q]);
double t = 1.0 / (Math.Abs(d) + Math.Sqrt(d * d + 1.0));
if (d < 0.0f) t = -t;
double c = 1.0 / Math.Sqrt(t * t + 1);
double s = t * c;
A[p, p] += t * A[p, q];
A[q, q] -= t * A[p, q];
A[p, q] = A[q, p] = 0.0f;
// transform A
int k;
for (k = 0; k < 3; k++)
{
if (k != p && k != q)
{
double Akp = c * A[k, p] + s * A[k, q];
double Akq = -s * A[k, p] + c * A[k, q];
A[k, p] = A[p, k] = Akp;
A[k, q] = A[q, k] = Akq;
}
}
// store rotation in R
for (k = 0; k < 3; k++)
{
double Rkp = c * R[k, p] + s * R[k, q];
double Rkq = -s * R[k, p] + c * R[k, q];
R[k, p] = Rkp;
R[k, q] = Rkq;
}
}
public static void EigenDecomposition(Matrix3x3d A, out Matrix3x3d eigenVecs, out Vector3d eigenVals)
{
const int numJacobiIterations = 10;
const double epsilon = 1e-15;
Matrix3x3d D = A;
// only for symmetric matrices!
eigenVecs = Matrix3x3d.Identity; // unit matrix
int iter = 0;
while (iter < numJacobiIterations)
{
// 3 off diagonal elements
// find off diagonal element with maximum modulus
int p, q;
double a, max;
max = Math.Abs(D.m01);
p = 0; q = 1;
a = Math.Abs(D.m02);
if (a > max) { p = 0; q = 2; max = a; }
a = Math.Abs(D.m12);
if (a > max) { p = 1; q = 2; max = a; }
// all small enough -> done
if (max < epsilon) break;
// rotate matrix with respect to that element
JacobiRotate(ref D, ref eigenVecs, p, q);
iter++;
}
eigenVals = new Vector3d(D.m00, D.m11, D.m22);
}
///
/// Perform polar decomposition A = (U D U^T) R
///
public static void PolarDecomposition(Matrix3x3d A, out Matrix3x3d R, out Matrix3x3d U, out Matrix3x3d D)
{
// A = SR, where S is symmetric and R is orthonormal
// -> S = (A A^T)^(1/2)
// A = U D U^T R
Matrix3x3d AAT = new Matrix3x3d();
AAT.m00 = A.m00 * A.m00 + A.m01 * A.m01 + A.m02 * A.m02;
AAT.m11 = A.m10 * A.m10 + A.m11 * A.m11 + A.m12 * A.m12;
AAT.m22 = A.m20 * A.m20 + A.m21 * A.m21 + A.m22 * A.m22;
AAT.m01 = A.m00 * A.m10 + A.m01 * A.m11 + A.m02 * A.m12;
AAT.m02 = A.m00 * A.m20 + A.m01 * A.m21 + A.m02 * A.m22;
AAT.m12 = A.m10 * A.m20 + A.m11 * A.m21 + A.m12 * A.m22;
AAT.m10 = AAT.m01;
AAT.m20 = AAT.m02;
AAT.m21 = AAT.m12;
R = Matrix3x3d.Identity;
Vector3d eigenVals;
EigenDecomposition(AAT, out U, out eigenVals);
double d0 = Math.Sqrt(eigenVals.x);
double d1 = Math.Sqrt(eigenVals.y);
double d2 = Math.Sqrt(eigenVals.z);
D = new Matrix3x3d();
D.m00 = d0;
D.m11 = d1;
D.m22 = d2;
const double eps = 1e-15;
double l0 = eigenVals.x; if (l0 <= eps) l0 = 0.0; else l0 = 1.0 / d0;
double l1 = eigenVals.y; if (l1 <= eps) l1 = 0.0; else l1 = 1.0 / d1;
double l2 = eigenVals.z; if (l2 <= eps) l2 = 0.0; else l2 = 1.0 / d2;
Matrix3x3d S1 = new Matrix3x3d();
S1.m00 = l0 * U.m00 * U.m00 + l1 * U.m01 * U.m01 + l2 * U.m02 * U.m02;
S1.m11 = l0 * U.m10 * U.m10 + l1 * U.m11 * U.m11 + l2 * U.m12 * U.m12;
S1.m22 = l0 * U.m20 * U.m20 + l1 * U.m21 * U.m21 + l2 * U.m22 * U.m22;
S1.m01 = l0 * U.m00 * U.m10 + l1 * U.m01 * U.m11 + l2 * U.m02 * U.m12;
S1.m02 = l0 * U.m00 * U.m20 + l1 * U.m01 * U.m21 + l2 * U.m02 * U.m22;
S1.m12 = l0 * U.m10 * U.m20 + l1 * U.m11 * U.m21 + l2 * U.m12 * U.m22;
S1.m10 = S1.m01;
S1.m20 = S1.m02;
S1.m21 = S1.m12;
R = S1 * A;
// stabilize
Vector3d c0, c1, c2;
c0 = R.GetColumn(0);
c1 = R.GetColumn(1);
c2 = R.GetColumn(2);
if (c0.SqrMagnitude < eps)
c0 = c1.Cross(c2);
else if (c1.SqrMagnitude < eps)
c1 = c2.Cross(c0);
else
c2 = c0.Cross(c1);
R.SetColumn(0, c0);
R.SetColumn(1, c1);
R.SetColumn(2, c2);
}
///
/// Return the one norm of the matrix.
///
public static double OneNorm(Matrix3x3d A)
{
double sum1 = Math.Abs(A.m00) + Math.Abs(A.m10) + Math.Abs(A.m20);
double sum2 = Math.Abs(A.m01) + Math.Abs(A.m11) + Math.Abs(A.m21);
double sum3 = Math.Abs(A.m02) + Math.Abs(A.m12) + Math.Abs(A.m22);
double maxSum = sum1;
if (sum2 > maxSum)
maxSum = sum2;
if (sum3 > maxSum)
maxSum = sum3;
return maxSum;
}
///
/// Return the inf norm of the matrix.
///
public static double InfNorm(Matrix3x3d A)
{
double sum1 = Math.Abs(A.m00) + Math.Abs(A.m01) + Math.Abs(A.m02);
double sum2 = Math.Abs(A.m10) + Math.Abs(A.m11) + Math.Abs(A.m12);
double sum3 = Math.Abs(A.m20) + Math.Abs(A.m21) + Math.Abs(A.m22);
double maxSum = sum1;
if (sum2 > maxSum)
maxSum = sum2;
if (sum3 > maxSum)
maxSum = sum3;
return maxSum;
}
///
/// Perform a polar decomposition of matrix M and return the rotation matrix R. This method handles the degenerated cases.
/// am>
public static void PolarDecompositionStable(Matrix3x3d M, double tolerance, out Matrix3x3d R)
{
Matrix3x3d Mt = M.Transpose;
double Mone = OneNorm(M);
double Minf = InfNorm(M);
double Eone;
Matrix3x3d MadjTt = new Matrix3x3d();
Matrix3x3d Et = new Matrix3x3d();
const double eps = 1.0e-15;
do
{
MadjTt.SetRow(0, Mt.GetRow(1).Cross(Mt.GetRow(2)));
MadjTt.SetRow(1, Mt.GetRow(2).Cross(Mt.GetRow(0)));
MadjTt.SetRow(2, Mt.GetRow(0).Cross(Mt.GetRow(1)));
double det = Mt.m00 * MadjTt.m00 + Mt.m01 * MadjTt.m01 + Mt.m02 * MadjTt.m02;
if (Math.Abs(det) < eps)
{
int index = int.MaxValue;
for (int i = 0; i < 3; i++)
{
double len = MadjTt.GetRow(i).SqrMagnitude;
if (len > eps)
{
// index of valid cross product
// => is also the index of the vector in Mt that must be exchanged
index = i;
break;
}
}
if (index == int.MaxValue)
{
R = Matrix3x3d.Identity;
return;
}
else
{
Mt.SetRow(index, Mt.GetRow((index + 1) % 3).Cross(Mt.GetRow((index + 2) % 3)));
MadjTt.SetRow((index + 1) % 3, Mt.GetRow((index + 2) % 3).Cross(Mt.GetRow(index)));
MadjTt.SetRow((index + 2) % 3, Mt.GetRow(index).Cross(Mt.GetRow((index + 1) % 3)));
Matrix3x3d M2 = Mt.Transpose;
Mone = OneNorm(M2);
Minf = InfNorm(M2);
det = Mt.m00 * MadjTt.m00 + Mt.m01 * MadjTt.m01 + Mt.m02 * MadjTt.m02;
}
}
double MadjTone = OneNorm(MadjTt);
double MadjTinf = InfNorm(MadjTt);
double gamma = Math.Sqrt(Math.Sqrt((MadjTone * MadjTinf) / (Mone * Minf)) / Math.Abs(det));
double g1 = gamma * 0.5;
double g2 = 0.5 / (gamma * det);
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
Et[i, j] = Mt[i, j];
Mt[i, j] = g1 * Mt[i, j] + g2 * MadjTt[i, j];
Et[i, j] -= Mt[i, j];
}
}
Eone = OneNorm(Et);
Mone = OneNorm(Mt);
Minf = InfNorm(Mt);
}
while (Eone > Mone * tolerance);
// Q = Mt^T
R = Mt.Transpose;
//end of function
}
///
/// Perform a singular value decomposition of matrix A: A = U * sigma * V^T.
/// This function returns two proper rotation matrices U and V^T which do not
/// contain a reflection. Reflections are corrected by the inversion handling
/// proposed by Irving et al. 2004.
///
public static void SVDWithInversionHandling(Matrix3x3d A, out Vector3d sigma, out Matrix3x3d U, out Matrix3x3d VT)
{
Vector3d S;
Matrix3x3d AT_A, V;
AT_A = A.Transpose * A;
// Eigen decomposition of A^T * A
EigenDecomposition(AT_A, out V, out S);
int pos;
// Detect if V is a reflection .
// Make a rotation out of it by multiplying one column with -1.
double detV = V.Determinant;
if (detV < 0.0f)
{
double minLambda = double.PositiveInfinity;
pos = 0;
for (int l = 0; l < 3; l++)
{
if (S[l] < minLambda)
{
pos = l;
minLambda = S[l];
}
}
V[0, pos] = -V[0, pos];
V[1, pos] = -V[1, pos];
V[2, pos] = -V[2, pos];
}
if (S.x < 0.0f) S.x = 0.0f; // safety for sqrt
if (S.y < 0.0f) S.y = 0.0f;
if (S.z < 0.0f) S.z = 0.0f;
sigma.x = Math.Sqrt(S.x);
sigma.y = Math.Sqrt(S.y);
sigma.z = Math.Sqrt(S.z);
VT = V.Transpose;
// Check for values of hatF near zero
int chk = 0;
pos = 0;
for (int l = 0; l < 3; l++)
{
if (Math.Abs(sigma[l]) < 1.0e-4)
{
pos = l;
chk++;
}
}
if (chk > 0)
{
if (chk > 1)
{
U = Matrix3x3d.Identity;
}
else
{
U = A * V;
for (int l = 0; l < 3; l++)
{
if (l != pos)
{
for (int m = 0; m < 3; m++)
{
U[m, l] *= 1.0f / sigma[l];
}
}
}
Vector3d[] v = new Vector3d[2];
int index = 0;
for (int l = 0; l < 3; l++)
{
if (l != pos)
{
v[index++] = new Vector3d(U[0, l], U[1, l], U[2, l]);
}
}
Vector3d vec = v[0].Cross(v[1]);
vec.Normalize();
U[0, pos] = vec[0];
U[1, pos] = vec[1];
U[2, pos] = vec[2];
}
}
else
{
Vector3d sigmaInv = new Vector3d(1.0 / sigma.x, 1.0 / sigma.y, 1.0 / sigma.z);
U = A * V;
for (int l = 0; l < 3; l++)
{
for (int m = 0; m < 3; m++)
{
U[m, l] *= sigmaInv[l];
}
}
}
double detU = U.Determinant;
// U is a reflection => inversion
if (detU < 0.0)
{
//std::cout << "Inversion!\n";
double minLambda = double.PositiveInfinity;
pos = 0;
for (int l = 0; l < 3; l++)
{
if (sigma[l] < minLambda)
{
pos = l;
minLambda = sigma[l];
}
}
// invert values of smallest singular value
sigma[pos] = -sigma[pos];
U[0, pos] = -U[0, pos];
U[1, pos] = -U[1, pos];
U[2, pos] = -U[2, pos];
}
//end of function
}
}
}
================================================
FILE: Assets/Common/Decomposition/Decomposition3x3d.cs.meta
================================================
fileFormatVersion: 2
guid: 4c6eedd17e5c16345a731cb65b62ab3c
timeCreated: 1514536270
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Common/Decomposition/Decomposition3x3f.cs
================================================
using System;
using Common.Core.LinearAlgebra;
namespace Common.Mathematics.Decomposition
{
public static class Decomposition3x3f
{
///
/// Rotates A through phi in pq-plane to set A(p,q) = 0
/// Rotation stored in R whose columns are eigenvectors of A
///
public static void JacobiRotate(ref Matrix3x3f A, ref Matrix3x3f R, int p, int q)
{
if (A[p, q] == 0.0f)
return;
float d = (A[p, p] - A[q, q]) / (2.0f*A[p, q]);
float t = 1.0f / (Math.Abs(d) + (float)Math.Sqrt(d*d + 1.0f));
if (d < 0.0f) t = -t;
float c = 1.0f / (float)Math.Sqrt(t*t + 1);
float s = t*c;
A[p, p] += t*A[p, q];
A[q, q] -= t*A[p, q];
A[p, q] = A[q, p] = 0.0f;
// transform A
int k;
for (k = 0; k < 3; k++)
{
if (k != p && k != q)
{
float Akp = c*A[k, p] + s*A[k, q];
float Akq = -s*A[k, p] + c*A[k, q];
A[k, p] = A[p, k] = Akp;
A[k, q] = A[q, k] = Akq;
}
}
// store rotation in R
for (k = 0; k < 3; k++)
{
float Rkp = c*R[k, p] + s*R[k, q];
float Rkq = -s*R[k, p] + c*R[k, q];
R[k, p] = Rkp;
R[k, q] = Rkq;
}
}
public static void EigenDecomposition(Matrix3x3f A, out Matrix3x3f eigenVecs, out Vector3f eigenVals)
{
const int numJacobiIterations = 10;
const float epsilon = 1e-15f;
Matrix3x3f D = A;
// only for symmetric matrices!
eigenVecs = Matrix3x3f.Identity; // unit matrix
int iter = 0;
while (iter < numJacobiIterations)
{
// 3 off diagonal elements
// find off diagonal element with maximum modulus
int p, q;
float a, max;
max = Math.Abs(D.m01);
p = 0; q = 1;
a = Math.Abs(D.m02);
if (a > max) { p = 0; q = 2; max = a; }
a = Math.Abs(D.m12);
if (a > max) { p = 1; q = 2; max = a; }
// all small enough -> done
if (max < epsilon) break;
// rotate matrix with respect to that element
JacobiRotate(ref D, ref eigenVecs, p, q);
iter++;
}
eigenVals = new Vector3f(D.m00, D.m11, D.m22);
}
///
/// Perform polar decomposition A = (U D U^T) R
///
public static void PolarDecomposition(Matrix3x3f A, out Matrix3x3f R, out Matrix3x3f U, out Matrix3x3f D)
{
// A = SR, where S is symmetric and R is orthonormal
// -> S = (A A^T)^(1/2)
// A = U D U^T R
Matrix3x3f AAT = new Matrix3x3f();
AAT.m00 = A.m00*A.m00 + A.m01*A.m01 + A.m02*A.m02;
AAT.m11 = A.m10*A.m10 + A.m11*A.m11 + A.m12*A.m12;
AAT.m22 = A.m20*A.m20 + A.m21*A.m21 + A.m22*A.m22;
AAT.m01 = A.m00*A.m10 + A.m01*A.m11 + A.m02*A.m12;
AAT.m02 = A.m00*A.m20 + A.m01*A.m21 + A.m02*A.m22;
AAT.m12 = A.m10*A.m20 + A.m11*A.m21 + A.m12*A.m22;
AAT.m10 = AAT.m01;
AAT.m20 = AAT.m02;
AAT.m21 = AAT.m12;
R = Matrix3x3f.Identity;
Vector3f eigenVals;
EigenDecomposition(AAT, out U, out eigenVals);
float d0 = (float)Math.Sqrt(eigenVals.x);
float d1 = (float)Math.Sqrt(eigenVals.y);
float d2 = (float)Math.Sqrt(eigenVals.z);
D = new Matrix3x3f();
D.m00 = d0;
D.m11 = d1;
D.m22 = d2;
const float eps = 1e-15f;
float l0 = eigenVals.x; if (l0 <= eps) l0 = 0.0f; else l0 = 1.0f / d0;
float l1 = eigenVals.y; if (l1 <= eps) l1 = 0.0f; else l1 = 1.0f / d1;
float l2 = eigenVals.z; if (l2 <= eps) l2 = 0.0f; else l2 = 1.0f / d2;
Matrix3x3f S1 = new Matrix3x3f();
S1.m00 = l0*U.m00*U.m00 + l1*U.m01*U.m01 + l2*U.m02*U.m02;
S1.m11 = l0*U.m10*U.m10 + l1*U.m11*U.m11 + l2*U.m12*U.m12;
S1.m22 = l0*U.m20*U.m20 + l1*U.m21*U.m21 + l2*U.m22*U.m22;
S1.m01 = l0*U.m00*U.m10 + l1*U.m01*U.m11 + l2*U.m02*U.m12;
S1.m02 = l0*U.m00*U.m20 + l1*U.m01*U.m21 + l2*U.m02*U.m22;
S1.m12 = l0*U.m10*U.m20 + l1*U.m11*U.m21 + l2*U.m12*U.m22;
S1.m10 = S1.m01;
S1.m20 = S1.m02;
S1.m21 = S1.m12;
R = S1*A;
// stabilize
Vector3f c0, c1, c2;
c0 = R.GetColumn(0);
c1 = R.GetColumn(1);
c2 = R.GetColumn(2);
if (c0.SqrMagnitude < eps)
c0 = c1.Cross(c2);
else if (c1.SqrMagnitude < eps)
c1 = c2.Cross(c0);
else
c2 = c0.Cross(c1);
R.SetColumn(0, c0);
R.SetColumn(1, c1);
R.SetColumn(2, c2);
}
///
/// Return the one norm of the matrix.
///
private static float OneNorm(Matrix3x3f A)
{
float sum1 = Math.Abs(A.m00) + Math.Abs(A.m10) + Math.Abs(A.m20);
float sum2 = Math.Abs(A.m01) + Math.Abs(A.m11) + Math.Abs(A.m21);
float sum3 = Math.Abs(A.m02) + Math.Abs(A.m12) + Math.Abs(A.m22);
float maxSum = sum1;
if (sum2 > maxSum)
maxSum = sum2;
if (sum3 > maxSum)
maxSum = sum3;
return maxSum;
}
///
/// Return the inf norm of the matrix.
///
private static float InfNorm(Matrix3x3f A)
{
float sum1 = Math.Abs(A.m00) + Math.Abs(A.m01) + Math.Abs(A.m02);
float sum2 = Math.Abs(A.m10) + Math.Abs(A.m11) + Math.Abs(A.m12);
float sum3 = Math.Abs(A.m20) + Math.Abs(A.m21) + Math.Abs(A.m22);
float maxSum = sum1;
if (sum2 > maxSum)
maxSum = sum2;
if (sum3 > maxSum)
maxSum = sum3;
return maxSum;
}
///
/// Perform a polar decomposition of matrix M and return the rotation matrix R. This method handles the degenerated cases.
/// am>
public static void PolarDecompositionStable(Matrix3x3f M, float tolerance, out Matrix3x3f R)
{
Matrix3x3f Mt = M.Transpose;
float Mone = OneNorm(M);
float Minf = InfNorm(M);
float Eone;
Matrix3x3f MadjTt = new Matrix3x3f();
Matrix3x3f Et = new Matrix3x3f();
do
{
MadjTt.SetRow(0, Mt.GetRow(1).Cross(Mt.GetRow(2)));
MadjTt.SetRow(1, Mt.GetRow(2).Cross(Mt.GetRow(0)));
MadjTt.SetRow(2, Mt.GetRow(0).Cross(Mt.GetRow(1)));
float det = Mt.m00 * MadjTt.m00 + Mt.m01 * MadjTt.m01 + Mt.m02 * MadjTt.m02;
if (Math.Abs(det) < 1.0e-12f)
{
int index = int.MaxValue;
for (int i = 0; i < 3; i++)
{
float len = MadjTt.GetRow(i).SqrMagnitude;
if (len > 1.0e-12f)
{
// index of valid cross product
// => is also the index of the vector in Mt that must be exchanged
index = i;
break;
}
}
if (index == int.MaxValue)
{
R = Matrix3x3f.Identity;
return;
}
else
{
Mt.SetRow(index, Mt.GetRow((index + 1) % 3).Cross(Mt.GetRow((index + 2) % 3)));
MadjTt.SetRow((index + 1) % 3, Mt.GetRow((index + 2) % 3).Cross(Mt.GetRow(index)));
MadjTt.SetRow((index + 2) % 3, Mt.GetRow(index).Cross(Mt.GetRow((index + 1) % 3)));
Matrix3x3f M2 = Mt.Transpose;
Mone = OneNorm(M2);
Minf = InfNorm(M2);
det = Mt.m00 * MadjTt.m00 + Mt.m01 * MadjTt.m01 + Mt.m02 * MadjTt.m02;
}
}
float MadjTone = OneNorm(MadjTt);
float MadjTinf = InfNorm(MadjTt);
float gamma = (float)Math.Sqrt(Math.Sqrt((MadjTone*MadjTinf) / (Mone*Minf)) / Math.Abs(det));
float g1 = gamma*0.5f;
float g2 = 0.5f / (gamma*det);
for(int i = 0; i < 3; i++)
{
for(int j = 0; j < 3; j++)
{
Et[i,j] = Mt[i,j];
Mt[i,j] = g1*Mt[i,j] + g2*MadjTt[i,j];
Et[i,j] -= Mt[i,j];
}
}
Eone = OneNorm(Et);
Mone = OneNorm(Mt);
Minf = InfNorm(Mt);
}
while (Eone > Mone * tolerance);
// Q = Mt^T
R = Mt.Transpose;
//end of function
}
///
/// Perform a singular value decomposition of matrix A: A = U * sigma * V^T.
/// This function returns two proper rotation matrices U and V^T which do not
/// contain a reflection. Reflections are corrected by the inversion handling
/// proposed by Irving et al. 2004.
///
public static void SVDWithInversionHandling(Matrix3x3f A, out Vector3f sigma, out Matrix3x3f U, out Matrix3x3f VT)
{
Vector3f S;
Matrix3x3f AT_A, V;
AT_A = A.Transpose * A;
// Eigen decomposition of A^T * A
EigenDecomposition(AT_A, out V, out S);
int pos;
// Detect if V is a reflection .
// Make a rotation out of it by multiplying one column with -1.
float detV = V.Determinant;
if (detV < 0.0f)
{
float minLambda = float.PositiveInfinity;
pos = 0;
for (int l = 0; l < 3; l++)
{
if (S[l] < minLambda)
{
pos = l;
minLambda = S[l];
}
}
V[0, pos] = -V[0, pos];
V[1, pos] = -V[1, pos];
V[2, pos] = -V[2, pos];
}
if (S.x < 0.0f) S.x = 0.0f; // safety for sqrt
if (S.y < 0.0f) S.y = 0.0f;
if (S.z < 0.0f) S.z = 0.0f;
sigma.x = (float)Math.Sqrt(S.x);
sigma.y = (float)Math.Sqrt(S.y);
sigma.z = (float)Math.Sqrt(S.z);
VT = V.Transpose;
// Check for values of hatF near zero
int chk = 0;
pos = 0;
for (int l = 0; l < 3; l++)
{
if (Math.Abs(sigma[l]) < 1.0e-4f)
{
pos = l;
chk++;
}
}
if (chk > 0)
{
if (chk > 1)
{
U = Matrix3x3f.Identity;
}
else
{
U = A * V;
for (int l = 0; l < 3; l++)
{
if (l != pos)
{
for (int m = 0; m < 3; m++)
{
U[m, l] *= 1.0f / sigma[l];
}
}
}
Vector3f[] v = new Vector3f[2];
int index = 0;
for (int l = 0; l < 3; l++)
{
if (l != pos)
{
v[index++] = new Vector3f(U[0, l], U[1, l], U[2, l]);
}
}
Vector3f vec = v[0].Cross(v[1]);
vec.Normalize();
U[0, pos] = vec[0];
U[1, pos] = vec[1];
U[2, pos] = vec[2];
}
}
else
{
Vector3f sigmaInv = new Vector3f(1.0f / sigma.x, 1.0f / sigma.y, 1.0f / sigma.z);
U = A * V;
for (int l = 0; l < 3; l++)
{
for (int m = 0; m < 3; m++)
{
U[m, l] *= sigmaInv[l];
}
}
}
float detU = U.Determinant;
// U is a reflection => inversion
if (detU < 0.0f)
{
//std::cout << "Inversion!\n";
float minLambda = float.PositiveInfinity;
pos = 0;
for(int l = 0; l < 3; l++)
{
if (sigma[l] < minLambda)
{
pos = l;
minLambda = sigma[l];
}
}
// invert values of smallest singular value
sigma[pos] = -sigma[pos];
U[0, pos] = -U[0, pos];
U[1, pos] = -U[1, pos];
U[2, pos] = -U[2, pos];
}
//end of function
}
}
}
================================================
FILE: Assets/Common/Decomposition/Decomposition3x3f.cs.meta
================================================
fileFormatVersion: 2
guid: c51f4ad5b0f26454b81446d12138e40d
timeCreated: 1514536270
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Common/Decomposition.meta
================================================
fileFormatVersion: 2
guid: ca3a86e2d1148ce4a9d75690faa7ade4
folderAsset: yes
timeCreated: 1514536270
licenseType: Free
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Common/LinearAlgebra/Matrix2x2d.cs
================================================
using System;
using System.Collections;
using System.Runtime.InteropServices;
using Common.Core.Mathematics;
namespace Common.Core.LinearAlgebra
{
///
/// A single precision 2 dimension matrix
///
[StructLayout(LayoutKind.Sequential)]
public struct Matrix2x2d
{
///
/// The matrix
///
public double m00, m01, m10, m11;
///
/// The Matrix Idenity.
///
static readonly public Matrix2x2d Identity = new Matrix2x2d(1, 0, 0, 1);
///
/// A matrix from the following varibles.
///
public Matrix2x2d(double m00, double m01, double m10, double m11)
{
this.m00 = m00; this.m01 = m01;
this.m10 = m10; this.m11 = m11;
}
///
/// A matrix from the following varibles.
///
public Matrix2x2d(double v)
{
m00 = v; m01 = v;
m10 = v; m11 = v;
}
///
/// A matrix copied from a array of varibles.
///
public Matrix2x2d(double[,] m)
{
m00 = m[0,0]; m01 = m[0,1];
m10 = m[1,0]; m11 = m[1,1];
}
///
/// A matrix copied from a array of varibles.
///
public Matrix2x2d(double[] m)
{
m00 = m[0 + 0 * 2]; m01 = m[0 + 1 * 2];
m10 = m[1 + 0 * 2]; m11 = m[1 + 1 * 2];
}
///
/// Access the varible at index i
///
public double this[int i]
{
get
{
switch (i)
{
case 0: return m00;
case 1: return m10;
case 2: return m01;
case 3: return m11;
default: throw new IndexOutOfRangeException("Matrix2x2d index out of range: " + i);
}
}
set
{
switch (i)
{
case 0: m00 = value; break;
case 1: m10 = value; break;
case 2: m01 = value; break;
case 3: m11 = value; break;
default: throw new IndexOutOfRangeException("Matrix2x2d index out of range: " + i);
}
}
}
///
/// Access the varible at index i,j.
///
public double this[int i, int j]
{
get
{
int k = i + j * 2;
switch (k)
{
case 0: return m00;
case 1: return m10;
case 2: return m01;
case 3: return m11;
default: throw new IndexOutOfRangeException("Matrix2x2d index out of range: " + k);
}
}
set
{
int k = i + j * 2;
switch (k)
{
case 0: m00 = value; break;
case 1: m10 = value; break;
case 2: m01 = value; break;
case 3: m11 = value; break;
default: throw new IndexOutOfRangeException("Matrix2x2d index out of range: " + k);
}
}
}
///
/// The transpose of the matrix. The rows and columns are flipped.
///
public Matrix2x2d Transpose
{
get
{
Matrix2x2d kTranspose = new Matrix2x2d();
kTranspose.m00 = m00;
kTranspose.m10 = m01;
kTranspose.m01 = m10;
kTranspose.m11 = m11;
return kTranspose;
}
}
///
/// The determinate of a matrix.
///
public double Determinant
{
get
{
return m00 * m11 - m10 * m01;
}
}
///
/// The inverse of the matrix.
/// A matrix multipled by its inverse is the idenity.
///
public Matrix2x2d Inverse
{
get
{
Matrix2x2d kInverse = Identity;
TryInverse(ref kInverse);
return kInverse;
}
}
public double Trace
{
get
{
return m00 + m11;
}
}
///
/// Add two matrices.
///
public static Matrix2x2d operator +(Matrix2x2d m1, Matrix2x2d m2)
{
Matrix2x2d kSum = new Matrix2x2d();
kSum.m00 = m1.m00 + m2.m00;
kSum.m10 = m1.m10 + m2.m10;
kSum.m01 = m1.m01 + m2.m01;
kSum.m11 = m1.m11 + m2.m11;
return kSum;
}
///
/// Subtract two matrices.
///
public static Matrix2x2d operator -(Matrix2x2d m1, Matrix2x2d m2)
{
Matrix2x2d kSum = new Matrix2x2d();
kSum.m00 = m1.m00 - m2.m00;
kSum.m10 = m1.m10 - m2.m10;
kSum.m01 = m1.m01 - m2.m01;
kSum.m11 = m1.m11 - m2.m11;
return kSum;
}
///
/// Multiply two matrices.
///
public static Matrix2x2d operator *(Matrix2x2d m1, Matrix2x2d m2)
{
Matrix2x2d kProd = new Matrix2x2d();
kProd.m00 = m1.m00 * m2.m00 + m1.m01 * m2.m10;
kProd.m10 = m1.m10 * m2.m00 + m1.m11 * m2.m10;
kProd.m01 = m1.m00 * m2.m01 + m1.m01 * m2.m11;
kProd.m11 = m1.m10 * m2.m01 + m1.m11 * m2.m11;
return kProd;
}
///
/// Multiply a vector by a matrix.
///
public static Vector2d operator *(Matrix2x2d m, Vector2d v)
{
Vector2d kProd = new Vector2d();
kProd.x = m.m00 * v.x + m.m01 * v.y;
kProd.y = m.m10 * v.x + m.m11 * v.y;
return kProd;
}
///
/// Multiply a matrix by a scalar.
///
public static Matrix2x2d operator *(Matrix2x2d m, double s)
{
Matrix2x2d kProd = new Matrix2x2d();
kProd.m00 = m.m00 * s;
kProd.m10 = m.m10 * s;
kProd.m01 = m.m01 * s;
kProd.m11 = m.m11 * s;
return kProd;
}
///
/// Multiply a matrix by a scalar.
///
public static Matrix2x2d operator *(double s, Matrix2x2d m)
{
Matrix2x2d kProd = new Matrix2x2d();
kProd.m00 = m.m00 * s;
kProd.m10 = m.m10 * s;
kProd.m01 = m.m01 * s;
kProd.m11 = m.m11 * s;
return kProd;
}
///
/// Are these matrices equal.
///
public static bool operator ==(Matrix2x2d m1, Matrix2x2d m2)
{
if (m1.m00 != m2.m00) return false;
if (m1.m10 != m2.m10) return false;
if (m1.m01 != m2.m01) return false;
if (m1.m11 != m2.m11) return false;
return true;
}
///
/// Are these matrices not equal.
///
public static bool operator !=(Matrix2x2d m1, Matrix2x2d m2)
{
if (m1.m00 != m2.m00) return true;
if (m1.m10 != m2.m10) return true;
if (m1.m01 != m2.m01) return true;
if (m1.m11 != m2.m11) return true;
return false;
}
///
/// Are these matrices equal.
///
public override bool Equals (object obj)
{
if(!(obj is Matrix2x2d)) return false;
Matrix2x2d mat = (Matrix2x2d)obj;
return this == mat;
}
///
/// Are these matrices equal.
///
public bool Equals(Matrix2x2d mat)
{
return this == mat;
}
///
/// Are these matrices equal.
///
public bool EqualsWithError(Matrix2x2d m, double eps)
{
if (Math.Abs(m00 - m.m00) > eps) return false;
if (Math.Abs(m10 - m.m10) > eps) return false;
if (Math.Abs(m01 - m.m01) > eps) return false;
if (Math.Abs(m11 - m.m11) > eps) return false;
return true;
}
///
/// Matrices hash code.
///
public override int GetHashCode()
{
int hash = 0;
for(int i = 0; i < 4; i++)
hash ^= this[i].GetHashCode();
return hash;
}
///
/// A matrix as a string.
///
public override string ToString()
{
return this[0, 0] + "," + this[0, 1] + "\n" + this[1, 0] + "," + this[1, 1];
}
///
/// The Inverse of the matrix copied into mInv.
/// Returns false if the matrix has no inverse.
/// A matrix multipled by its inverse is the idenity.
///
public bool TryInverse(ref Matrix2x2d mInv)
{
double det = Determinant;
if (DMath.IsZero(det))
return false;
double invDet = 1.0 / det;
mInv.m00 = m11 * invDet;
mInv.m01 = -m01 * invDet;
mInv.m10 = -m10 * invDet;
mInv.m11 = m00 * invDet;
return true;
}
///
/// Get the ith column as a vector.
///
public Vector2d GetColumn(int iCol)
{
return new Vector2d(this[0, iCol], this[1, iCol]);
}
///
/// Set the ith column from avector.
///
public void SetColumn(int iCol, Vector2d v)
{
this[0, iCol] = v.x;
this[1, iCol] = v.y;
}
///
/// Get the ith row as a vector.
///
/// Set the ith row from avector.
///
public void SetRow(int iRow, Vector2d v)
{
this[iRow, 0] = v.x;
this[iRow, 1] = v.y;
}
///
/// Create a rotation out of a angle.
///
static public Matrix2x2d Rotate(double angle)
{
double ca = Math.Cos(angle * Math.PI / 180.0);
double sa = Math.Sin(angle * Math.PI / 180.0);
return new Matrix2x2d(ca, -sa,
sa, ca);
}
///
/// Convert to a float precision 3 dimension matrix.
///
public Matrix3x3d ToMatrix3x3d()
{
return new Matrix3x3d(m00, m01, 0.0,
m10, m11, 0.0,
0.0, 0.0, 0.0);
}
}
}
================================================
FILE: Assets/Common/LinearAlgebra/Matrix2x2d.cs.meta
================================================
fileFormatVersion: 2
guid: 84b9e005a3c7e82429bbb49ae4ad0119
timeCreated: 1514536270
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Common/LinearAlgebra/Matrix2x2f.cs
================================================
using System;
using System.Collections;
using System.Runtime.InteropServices;
using Common.Core.Mathematics;
namespace Common.Core.LinearAlgebra
{
///
/// A single precision 2 dimension matrix
///
[StructLayout(LayoutKind.Sequential)]
public struct Matrix2x2f
{
///
/// The matrix
///
public float m00, m10, m01, m11;
///
/// The Matrix Idenity.
///
static readonly public Matrix2x2f Identity = new Matrix2x2f(1, 0, 0, 1);
///
/// A matrix from the following varibles.
///
public Matrix2x2f(float m00, float m01, float m10, float m11)
{
this.m00 = m00; this.m01 = m01;
this.m10 = m10; this.m11 = m11;
}
///
/// A matrix from the following varibles.
///
public Matrix2x2f(float v)
{
m00 = v; m01 = v;
m10 = v; m11 = v;
}
///
/// A matrix copied from a array of varibles.
///
public Matrix2x2f(float[,] m)
{
m00 = m[0,0]; m01 = m[0,1];
m10 = m[1,0]; m11 = m[1,1];
}
///
/// A matrix copied from a array of varibles.
///
public Matrix2x2f(float[] m)
{
m00 = m[0 + 0 * 2]; m01 = m[0 + 1 * 2];
m10 = m[1 + 0 * 2]; m11 = m[1 + 1 * 2];
}
///
/// Access the varible at index i
///
public float this[int i]
{
get
{
switch (i)
{
case 0: return m00;
case 1: return m10;
case 2: return m01;
case 3: return m11;
default: throw new IndexOutOfRangeException("Matrix2x2f index out of range: " + i);
}
}
set
{
switch (i)
{
case 0: m00 = value; break;
case 1: m10 = value; break;
case 2: m01 = value; break;
case 3: m11 = value; break;
default: throw new IndexOutOfRangeException("Matrix2x2f index out of range: " + i);
}
}
}
///
/// The transpose of the matrix. The rows and columns are flipped.
///
public Matrix2x2f Transpose
{
get
{
Matrix2x2f kTranspose = new Matrix2x2f();
kTranspose.m00 = m00;
kTranspose.m10 = m01;
kTranspose.m01 = m10;
kTranspose.m11 = m11;
return kTranspose;
}
}
///
/// The determinate of a matrix.
///
public float Determinant
{
get
{
return m00 * m11 - m10 * m01;
}
}
///
/// The inverse of the matrix.
/// A matrix multipled by its inverse is the idenity.
///
public Matrix2x2f Inverse
{
get
{
Matrix2x2f kInverse = Identity;
TryInverse(ref kInverse);
return kInverse;
}
}
public float Trace
{
get
{
return m00 + m11;
}
}
///
/// Access the varible at index i,j.
///
public float this[int i, int j]
{
get
{
int k = i + j * 2;
switch (k)
{
case 0: return m00;
case 1: return m10;
case 2: return m01;
case 3: return m11;
default: throw new IndexOutOfRangeException("Matrix2x2f index out of range: " + k);
}
}
set
{
int k = i + j * 2;
switch (k)
{
case 0: m00 = value; break;
case 1: m10 = value; break;
case 2: m01 = value; break;
case 3: m11 = value; break;
default: throw new IndexOutOfRangeException("Matrix2x2f index out of range: " + k);
}
}
}
///
/// Add two matrices.
///
public static Matrix2x2f operator +(Matrix2x2f m1, Matrix2x2f m2)
{
Matrix2x2f kSum = new Matrix2x2f();
kSum.m00 = m1.m00 + m2.m00;
kSum.m10 = m1.m10 + m2.m10;
kSum.m01 = m1.m01 + m2.m01;
kSum.m11 = m1.m11 + m2.m11;
return kSum;
}
///
/// Subtract two matrices.
///
public static Matrix2x2f operator -(Matrix2x2f m1, Matrix2x2f m2)
{
Matrix2x2f kSum = new Matrix2x2f();
kSum.m00 = m1.m00 - m2.m00;
kSum.m10 = m1.m10 - m2.m10;
kSum.m01 = m1.m01 - m2.m01;
kSum.m11 = m1.m11 - m2.m11;
return kSum;
}
///
/// Multiply two matrices.
///
public static Matrix2x2f operator *(Matrix2x2f m1, Matrix2x2f m2)
{
Matrix2x2f kProd = new Matrix2x2f();
kProd.m00 = m1.m00 * m2.m00 + m1.m01 * m2.m10;
kProd.m10 = m1.m10 * m2.m00 + m1.m11 * m2.m10;
kProd.m01 = m1.m00 * m2.m01 + m1.m01 * m2.m11;
kProd.m11 = m1.m10 * m2.m01 + m1.m11 * m2.m11;
return kProd;
}
///
/// Multiply a vector by a matrix.
///
public static Vector2f operator *(Matrix2x2f m, Vector2f v)
{
Vector2f kProd = new Vector2f();
kProd.x = m.m00 * v.x + m.m01 * v.y;
kProd.y = m.m10 * v.x + m.m11 * v.y;
return kProd;
}
///
/// Multiply a matrix by a scalar.
///
public static Matrix2x2f operator *(Matrix2x2f m, float s)
{
Matrix2x2f kProd = new Matrix2x2f();
kProd.m00 = m.m00 * s;
kProd.m10 = m.m10 * s;
kProd.m01 = m.m01 * s;
kProd.m11 = m.m11 * s;
return kProd;
}
///
/// Multiply a matrix by a scalar.
///
public static Matrix2x2f operator *(float s, Matrix2x2f m)
{
Matrix2x2f kProd = new Matrix2x2f();
kProd.m00 = m.m00 * s;
kProd.m10 = m.m10 * s;
kProd.m01 = m.m01 * s;
kProd.m11 = m.m11 * s;
return kProd;
}
///
/// Are these matrices equal.
///
public static bool operator ==(Matrix2x2f m1, Matrix2x2f m2)
{
if (m1.m00 != m2.m00) return false;
if (m1.m10 != m2.m10) return false;
if (m1.m01 != m2.m01) return false;
if (m1.m11 != m2.m11) return false;
return true;
}
///
/// Are these matrices not equal.
///
public static bool operator !=(Matrix2x2f m1, Matrix2x2f m2)
{
if (m1.m00 != m2.m00) return true;
if (m1.m10 != m2.m10) return true;
if (m1.m01 != m2.m01) return true;
if (m1.m11 != m2.m11) return true;
return false;
}
///
/// Are these matrices equal.
///
public override bool Equals (object obj)
{
if(!(obj is Matrix2x2f)) return false;
Matrix2x2f mat = (Matrix2x2f)obj;
return this == mat;
}
///
/// Are these matrices equal.
///
public bool Equals(Matrix2x2f mat)
{
return this == mat;
}
///
/// Are these matrices equal.
///
public bool EqualsWithError(Matrix2x2f m, float eps)
{
if (Math.Abs(m00 - m.m00) > eps) return false;
if (Math.Abs(m10 - m.m10) > eps) return false;
if (Math.Abs(m01 - m.m01) > eps) return false;
if (Math.Abs(m11 - m.m11) > eps) return false;
return true;
}
///
/// Matrices hash code.
///
public override int GetHashCode()
{
int hash = 0;
for(int i = 0; i < 4; i++)
hash ^= this[i].GetHashCode();
return hash;
}
///
/// A matrix as a string.
///
public override string ToString()
{
return this[0, 0] + "," + this[0, 1] + "\n" + this[1, 0] + "," + this[1, 1];
}
///
/// The Inverse of the matrix copied into mInv.
/// Returns false if the matrix has no inverse.
/// A matrix multipled by its inverse is the idenity.
///
public bool TryInverse(ref Matrix2x2f mInv)
{
float det = Determinant;
if (FMath.IsZero(det))
return false;
float invDet = 1.0f / det;
mInv.m00 = m11 * invDet;
mInv.m01 = -m01 * invDet;
mInv.m10 = -m10 * invDet;
mInv.m11 = m00 * invDet;
return true;
}
///
/// Get the ith column as a vector.
///
public Vector2f GetColumn(int iCol)
{
return new Vector2f(this[0, iCol], this[1, iCol]);
}
///
/// Set the ith column from avector.
///
public void SetColumn(int iCol, Vector2f v)
{
this[0, iCol] = v.x;
this[1, iCol] = v.y;
}
///
/// Get the ith row as a vector.
///
public Vector2f GetRow(int iRow)
{
return new Vector2f(this[iRow, 0], this[iRow, 1]);
}
///
/// Set the ith row from avector.
///
public void SetRow(int iRow, Vector2f v)
{
this[iRow, 0 ] = v.x;
this[iRow, 1 ] = v.y;
}
///
/// Create a rotation out of a angle.
///
static public Matrix2x2f Rotate(float angle)
{
float ca = (float)Math.Cos(angle * Math.PI / 180.0);
float sa = (float)Math.Sin(angle * Math.PI / 180.0);
return new Matrix2x2f(ca, -sa,
sa, ca);
}
///
/// Convert to a single precision 3 dimension matrix.
///
public Matrix3x3f ToMatrix3x3f()
{
return new Matrix3x3f(m00, m01, 0.0f,
m10, m11, 0.0f,
0.0f, 0.0f, 0.0f);
}
}
}
================================================
FILE: Assets/Common/LinearAlgebra/Matrix2x2f.cs.meta
================================================
fileFormatVersion: 2
guid: 5552436bd5f193c4c8a224e34dc6e321
timeCreated: 1514536270
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Common/LinearAlgebra/Matrix3x3d.cs
================================================
using System;
using System.Collections;
using System.Runtime.InteropServices;
using Common.Core.Mathematics;
namespace Common.Core.LinearAlgebra
{
///
/// A single precision 3 dimension matrix
///
[StructLayout(LayoutKind.Sequential)]
public struct Matrix3x3d
{
///
/// The matrix
///
public double m00, m01, m02;
public double m10, m11, m12;
public double m20, m21, m22;
///
/// The Matrix Idenity.
///
static readonly public Matrix3x3d Identity = new Matrix3x3d(1, 0, 0, 0, 1, 0, 0, 0, 1);
///
/// A matrix from the following varibles.
///
public Matrix3x3d(double m00, double m01, double m02,
double m10, double m11, double m12,
double m20, double m21, double m22)
{
this.m00 = m00; this.m01 = m01; this.m02 = m02;
this.m10 = m10; this.m11 = m11; this.m12 = m12;
this.m20 = m20; this.m21 = m21; this.m22 = m22;
}
///
/// A matrix from the following varibles.
///
public Matrix3x3d(double v)
{
m00 = v; m01 = v; m02 = v;
m10 = v; m11 = v; m12 = v;
m20 = v; m21 = v; m22 = v;
}
///
/// A matrix copied from a array of varibles.
///
public Matrix3x3d(double[,] m)
{
m00 = m[0, 0]; m01 = m[0, 1]; m02 = m[0, 2];
m10 = m[1, 0]; m11 = m[1, 1]; m12 = m[1, 2];
m20 = m[2, 0]; m21 = m[2, 1]; m22 = m[2, 2];
}
///
/// A matrix copied from a array of varibles.
///
public Matrix3x3d(double[] m)
{
m00 = m[0 + 0 * 3]; m01 = m[0 + 1 * 3]; m02 = m[0 + 2 * 3];
m10 = m[1 + 0 * 3]; m11 = m[1 + 1 * 3]; m12 = m[1 + 2 * 3];
m20 = m[2 + 0 * 3]; m21 = m[2 + 1 * 3]; m22 = m[2 + 2 * 3];
}
///
/// Access the varible at index i
///
public double this[int i]
{
get
{
switch (i)
{
case 0: return m00;
case 1: return m10;
case 2: return m20;
case 3: return m01;
case 4: return m11;
case 5: return m21;
case 6: return m02;
case 7: return m12;
case 8: return m22;
default: throw new IndexOutOfRangeException("Matrix3x3d index out of range: " + i);
}
}
set
{
switch (i)
{
case 0: m00 = value; break;
case 1: m10 = value; break;
case 2: m20 = value; break;
case 3: m01 = value; break;
case 4: m11 = value; break;
case 5: m21 = value; break;
case 6: m02 = value; break;
case 7: m12 = value; break;
case 8: m22 = value; break;
default: throw new IndexOutOfRangeException("Matrix3x3d index out of range: " + i);
}
}
}
///
/// Access the varible at index ij
///
public double this[int i, int j]
{
get
{
int k = i + j * 3;
switch (k)
{
case 0: return m00;
case 1: return m10;
case 2: return m20;
case 3: return m01;
case 4: return m11;
case 5: return m21;
case 6: return m02;
case 7: return m12;
case 8: return m22;
default: throw new IndexOutOfRangeException("Matrix3x3d index out of range: " + k);
}
}
set
{
int k = i + j * 3;
switch (k)
{
case 0: m00 = value; break;
case 1: m10 = value; break;
case 2: m20 = value; break;
case 3: m01 = value; break;
case 4: m11 = value; break;
case 5: m21 = value; break;
case 6: m02 = value; break;
case 7: m12 = value; break;
case 8: m22 = value; break;
default: throw new IndexOutOfRangeException("Matrix3x3d index out of range: " + k);
}
}
}
///
/// The transpose of the matrix. The rows and columns are flipped.
///
public Matrix3x3d Transpose
{
get
{
Matrix3x3d transpose = new Matrix3x3d();
transpose.m00 = m00;
transpose.m01 = m10;
transpose.m02 = m20;
transpose.m10 = m01;
transpose.m11 = m11;
transpose.m12 = m21;
transpose.m20 = m02;
transpose.m21 = m12;
transpose.m22 = m22;
return transpose;
}
}
///
/// The determinate of a matrix.
///
public double Determinant
{
get
{
double cofactor00 = m11 * m22 - m12 * m21;
double cofactor10 = m12 * m20 - m10 * m22;
double cofactor20 = m10 * m21 - m11 * m20;
double det = m00 * cofactor00 + m01 * cofactor10 + m02 * cofactor20;
return det;
}
}
///
/// The inverse of the matrix.
/// A matrix multipled by its inverse is the idenity.
///
public Matrix3x3d Inverse
{
get
{
Matrix3x3d inverse = Identity;
TryInverse(out inverse);
return inverse;
}
}
public double Trace
{
get
{
return m00 + m11 + m22;
}
}
///
/// Add two matrices.
///
public static Matrix3x3d operator +(Matrix3x3d m1, Matrix3x3d m2)
{
Matrix3x3d kSum = new Matrix3x3d();
kSum.m00 = m1.m00 + m2.m00;
kSum.m01 = m1.m01 + m2.m01;
kSum.m02 = m1.m02 + m2.m02;
kSum.m10 = m1.m10 + m2.m10;
kSum.m11 = m1.m11 + m2.m11;
kSum.m12 = m1.m12 + m2.m12;
kSum.m20 = m1.m20 + m2.m20;
kSum.m21 = m1.m21 + m2.m21;
kSum.m22 = m1.m22 + m2.m22;
return kSum;
}
///
/// Subtract two matrices.
///
public static Matrix3x3d operator -(Matrix3x3d m1, Matrix3x3d m2)
{
Matrix3x3d kSum = new Matrix3x3d();
kSum.m00 = m1.m00 - m2.m00;
kSum.m01 = m1.m01 - m2.m01;
kSum.m02 = m1.m02 - m2.m02;
kSum.m10 = m1.m10 - m2.m10;
kSum.m11 = m1.m11 - m2.m11;
kSum.m12 = m1.m12 - m2.m12;
kSum.m20 = m1.m20 - m2.m20;
kSum.m21 = m1.m21 - m2.m21;
kSum.m22 = m1.m22 - m2.m22;
return kSum;
}
///
/// Multiply two matrices.
///
public static Matrix3x3d operator *(Matrix3x3d m1, Matrix3x3d m2)
{
Matrix3x3d kProd = new Matrix3x3d();
kProd.m00 = m1.m00 * m2.m00 + m1.m01 * m2.m10 + m1.m02 * m2.m20;
kProd.m01 = m1.m00 * m2.m01 + m1.m01 * m2.m11 + m1.m02 * m2.m21;
kProd.m02 = m1.m00 * m2.m02 + m1.m01 * m2.m12 + m1.m02 * m2.m22;
kProd.m10 = m1.m10 * m2.m00 + m1.m11 * m2.m10 + m1.m12 * m2.m20;
kProd.m11 = m1.m10 * m2.m01 + m1.m11 * m2.m11 + m1.m12 * m2.m21;
kProd.m12 = m1.m10 * m2.m02 + m1.m11 * m2.m12 + m1.m12 * m2.m22;
kProd.m20 = m1.m20 * m2.m00 + m1.m21 * m2.m10 + m1.m22 * m2.m20;
kProd.m21 = m1.m20 * m2.m01 + m1.m21 * m2.m11 + m1.m22 * m2.m21;
kProd.m22 = m1.m20 * m2.m02 + m1.m21 * m2.m12 + m1.m22 * m2.m22;
return kProd;
}
///
/// Multiply a vector by a matrix.
///
public static Vector3d operator *(Matrix3x3d m, Vector3d v)
{
Vector3d kProd = new Vector3d();
kProd.x = m.m00 * v.x + m.m01 * v.y + m.m02 * v.z;
kProd.y = m.m10 * v.x + m.m11 * v.y + m.m12 * v.z;
kProd.z = m.m20 * v.x + m.m21 * v.y + m.m22 * v.z;
return kProd;
}
///
/// Multiply a matrix by a scalar.
///
public static Matrix3x3d operator *(Matrix3x3d m1, double s)
{
Matrix3x3d kProd = new Matrix3x3d();
kProd.m00 = m1.m00 * s;
kProd.m01 = m1.m01 * s;
kProd.m02 = m1.m02 * s;
kProd.m10 = m1.m10 * s;
kProd.m11 = m1.m11 * s;
kProd.m12 = m1.m12 * s;
kProd.m20 = m1.m20 * s;
kProd.m21 = m1.m21 * s;
kProd.m22 = m1.m22 * s;
return kProd;
}
///
/// Multiply a matrix by a scalar.
///
public static Matrix3x3d operator *(double s, Matrix3x3d m1)
{
Matrix3x3d kProd = new Matrix3x3d();
kProd.m00 = m1.m00 * s;
kProd.m01 = m1.m01 * s;
kProd.m02 = m1.m02 * s;
kProd.m10 = m1.m10 * s;
kProd.m11 = m1.m11 * s;
kProd.m12 = m1.m12 * s;
kProd.m20 = m1.m20 * s;
kProd.m21 = m1.m21 * s;
kProd.m22 = m1.m22 * s;
return kProd;
}
///
/// Are these matrices equal.
///
public static bool operator ==(Matrix3x3d m1, Matrix3x3d m2)
{
if (m1.m00 != m2.m00) return false;
if (m1.m01 != m2.m01) return false;
if (m1.m02 != m2.m02) return false;
if (m1.m10 != m2.m10) return false;
if (m1.m11 != m2.m11) return false;
if (m1.m12 != m2.m12) return false;
if (m1.m20 != m2.m20) return false;
if (m1.m21 != m2.m21) return false;
if (m1.m22 != m2.m22) return false;
return true;
}
///
/// Are these matrices not equal.
///
public static bool operator !=(Matrix3x3d m1, Matrix3x3d m2)
{
if (m1.m00 != m2.m00) return true;
if (m1.m01 != m2.m01) return true;
if (m1.m02 != m2.m02) return true;
if (m1.m10 != m2.m10) return true;
if (m1.m11 != m2.m11) return true;
if (m1.m12 != m2.m12) return true;
if (m1.m20 != m2.m20) return true;
if (m1.m21 != m2.m21) return true;
if (m1.m22 != m2.m22) return true;
return false;
}
///
/// Are these matrices equal.
///
public override bool Equals(object obj)
{
if (!(obj is Matrix3x3d)) return false;
Matrix3x3d mat = (Matrix3x3d)obj;
return this == mat;
}
///
/// Are these matrices equal.
///
public bool Equals(Matrix3x3d mat)
{
return this == mat;
}
///
/// Are these matrices equal.
///
public bool EqualsWithError(Matrix3x3d m, double eps)
{
if (Math.Abs(m00 - m.m00) > eps) return false;
if (Math.Abs(m10 - m.m10) > eps) return false;
if (Math.Abs(m20 - m.m20) > eps) return false;
if (Math.Abs(m01 - m.m01) > eps) return false;
if (Math.Abs(m11 - m.m11) > eps) return false;
if (Math.Abs(m21 - m.m21) > eps) return false;
if (Math.Abs(m02 - m.m02) > eps) return false;
if (Math.Abs(m12 - m.m12) > eps) return false;
if (Math.Abs(m22 - m.m22) > eps) return false;
return true;
}
///
/// Matrices hash code.
///
public override int GetHashCode()
{
int hash = 0;
for (int i = 0; i < 9; i++)
hash ^= this[i].GetHashCode();
return hash;
}
///
/// A matrix as a string.
///
public override string ToString()
{
return this[0, 0] + "," + this[0, 1] + "," + this[0, 2] + "\n" +
this[1, 0] + "," + this[1, 1] + "," + this[1, 2] + "\n" +
this[2, 0] + "," + this[2, 1] + "," + this[2, 2];
}
///
/// The Inverse of the matrix copied into mInv.
/// Returns false if the matrix has no inverse.
/// A matrix multipled by its inverse is the idenity.
/// Invert a 3x3 using cofactors. This is about 8 times faster than
/// the Numerical Recipes code which uses Gaussian elimination.
///
public bool TryInverse(out Matrix3x3d mInv)
{
mInv.m00 = m11 * m22 - m12 * m21;
mInv.m01 = m02 * m21 - m01 * m22;
mInv.m02 = m01 * m12 - m02 * m11;
mInv.m10 = m12 * m20 - m10 * m22;
mInv.m11 = m00 * m22 - m02 * m20;
mInv.m12 = m02 * m10 - m00 * m12;
mInv.m20 = m10 * m21 - m11 * m20;
mInv.m21 = m01 * m20 - m00 * m21;
mInv.m22 = m00 * m11 - m01 * m10;
double det = m00 * mInv.m00 + m01 * mInv.m10 + m02 * mInv.m20;
if (DMath.IsZero(det))
{
mInv = Identity;
return false;
}
double invDet = 1.0 / det;
mInv.m00 *= invDet; mInv.m01 *= invDet; mInv.m02 *= invDet;
mInv.m10 *= invDet; mInv.m11 *= invDet; mInv.m12 *= invDet;
mInv.m20 *= invDet; mInv.m21 *= invDet; mInv.m22 *= invDet;
return true;
}
///
/// Get the ith column as a vector.
///
public Vector3d GetColumn(int iCol)
{
return new Vector3d(this[0, iCol], this[1, iCol], this[2, iCol]);
}
///
/// Set the ith column from avector.
///
public void SetColumn(int iCol, Vector3d v)
{
this[0, iCol] = v.x;
this[1, iCol] = v.y;
this[2, iCol] = v.z;
}
///
/// Get the ith row as a vector.
///
public Vector3d GetRow(int iRow)
{
return new Vector3d(this[iRow, 0], this[iRow, 1], this[iRow, 2]);
}
///
/// Set the ith row from avector.
///
public void SetRow(int iRow, Vector3d v)
{
this[iRow, 0] = v.x;
this[iRow, 1] = v.y;
this[iRow, 2] = v.z;
}
///
/// Convert to a double precision 4 dimension matrix.
///
public Matrix4x4d ToMatrix4x4d()
{
return new Matrix4x4d(m00, m01, m02, 0.0f,
m10, m11, m12, 0.0f,
m20, m21, m22, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f);
}
///
/// Create a translation out of a vector.
///
static public Matrix3x3d Translate(Vector2d v)
{
return new Matrix3x3d(1, 0, v.x,
0, 1, v.y,
0, 0, 1);
}
///
/// Create a scale out of a vector.
///
static public Matrix3x3d Scale(Vector2d v)
{
return new Matrix3x3d(v.x, 0, 0,
0, v.y, 0,
0, 0, 1);
}
///
/// Create a scale out of a vector.
///
static public Matrix3x3d Scale(double s)
{
return new Matrix3x3d(s, 0, 0,
0, s, 0,
0, 0, 1);
}
///
/// Create a rotation out of a angle.
///
static public Matrix3x3d RotateX(double angle)
{
double ca = Math.Cos(angle * Math.PI / 180.0);
double sa = Math.Sin(angle * Math.PI / 180.0);
return new Matrix3x3d(1, 0, 0,
0, ca, -sa,
0, sa, ca);
}
///
/// Create a rotation out of a angle.
///
static public Matrix3x3d RotateY(double angle)
{
double ca = Math.Cos(angle * Math.PI / 180.0);
double sa = Math.Sin(angle * Math.PI / 180.0);
return new Matrix3x3d(ca, 0, sa,
0, 1, 0,
-sa, 0, ca);
}
///
/// Create a rotation out of a angle.
///
static public Matrix3x3d RotateZ(double angle)
{
double ca = Math.Cos(angle * Math.PI / 180.0);
double sa = Math.Sin(angle * Math.PI / 180.0);
return new Matrix3x3d(ca, -sa, 0,
sa, ca, 0,
0, 0, 1);
}
///
/// Create a rotation out of a vector.
///
static public Matrix3x3d Rotate(Vector3d euler)
{
return Quaternion3d.FromEuler(euler).ToMatrix3x3d();
}
}
}
================================================
FILE: Assets/Common/LinearAlgebra/Matrix3x3d.cs.meta
================================================
fileFormatVersion: 2
guid: e1ff789641c35454ebfd3d438dcc6189
timeCreated: 1514536271
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Common/LinearAlgebra/Matrix3x3f.cs
================================================
using System;
using System.Collections;
using System.Runtime.InteropServices;
using Common.Core.Mathematics;
namespace Common.Core.LinearAlgebra
{
///
/// A single precision 3 dimension matrix
///
[StructLayout(LayoutKind.Sequential)]
public struct Matrix3x3f
{
///
/// The matrix
///
public float m00, m01, m02;
public float m10, m11, m12;
public float m20, m21, m22;
///
/// The Matrix Idenity.
///
static readonly public Matrix3x3f Identity = new Matrix3x3f(1, 0, 0, 0, 1, 0, 0, 0, 1);
///
/// A matrix from the following varibles.
///
public Matrix3x3f(float m00, float m01, float m02,
float m10, float m11, float m12,
float m20, float m21, float m22)
{
this.m00 = m00; this.m01 = m01; this.m02 = m02;
this.m10 = m10; this.m11 = m11; this.m12 = m12;
this.m20 = m20; this.m21 = m21; this.m22 = m22;
}
///
/// A matrix from the following varibles.
///
public Matrix3x3f(float v)
{
m00 = v; m01 = v; m02 = v;
m10 = v; m11 = v; m12 = v;
m20 = v; m21 = v; m22 = v;
}
///
/// A matrix copied from a array of varibles.
///
public Matrix3x3f(float[,] m)
{
m00 = m[0, 0]; m01 = m[0, 1]; m02 = m[0, 2];
m10 = m[1, 0]; m11 = m[1, 1]; m12 = m[1, 2];
m20 = m[2, 0]; m21 = m[2, 1]; m22 = m[2, 2];
}
///
/// A matrix copied from a array of varibles.
///
public Matrix3x3f(float[] m)
{
m00 = m[0 + 0 * 3]; m01 = m[0 + 1 * 3]; m02 = m[0 + 2 * 3];
m10 = m[1 + 0 * 3]; m11 = m[1 + 1 * 3]; m12 = m[1 + 2 * 3];
m20 = m[2 + 0 * 3]; m21 = m[2 + 1 * 3]; m22 = m[2 + 2 * 3];
}
public float Trace
{
get
{
return m00 + m11 + m22;
}
}
///
/// Access the varible at index i
///
public float this[int i]
{
get
{
switch (i)
{
case 0: return m00;
case 1: return m10;
case 2: return m20;
case 3: return m01;
case 4: return m11;
case 5: return m21;
case 6: return m02;
case 7: return m12;
case 8: return m22;
default: throw new IndexOutOfRangeException("Matrix3x3f index out of range: " + i);
}
}
set
{
switch (i)
{
case 0: m00 = value; break;
case 1: m10 = value; break;
case 2: m20 = value; break;
case 3: m01 = value; break;
case 4: m11 = value; break;
case 5: m21 = value; break;
case 6: m02 = value; break;
case 7: m12 = value; break;
case 8: m22 = value; break;
default: throw new IndexOutOfRangeException("Matrix3x3f index out of range: " + i);
}
}
}
///
/// Access the varible at index ij
///
public float this[int i, int j]
{
get
{
int k = i + j * 3;
switch (k)
{
case 0: return m00;
case 1: return m10;
case 2: return m20;
case 3: return m01;
case 4: return m11;
case 5: return m21;
case 6: return m02;
case 7: return m12;
case 8: return m22;
default: throw new IndexOutOfRangeException("Matrix3x3f index out of range: " + k);
}
}
set
{
int k = i + j * 3;
switch (k)
{
case 0: m00 = value; break;
case 1: m10 = value; break;
case 2: m20 = value; break;
case 3: m01 = value; break;
case 4: m11 = value; break;
case 5: m21 = value; break;
case 6: m02 = value; break;
case 7: m12 = value; break;
case 8: m22 = value; break;
default: throw new IndexOutOfRangeException("Matrix3x3f index out of range: " + k);
}
}
}
///
/// The transpose of the matrix. The rows and columns are flipped.
///
public Matrix3x3f Transpose
{
get
{
Matrix3x3f transpose = new Matrix3x3f();
transpose.m00 = m00;
transpose.m01 = m10;
transpose.m02 = m20;
transpose.m10 = m01;
transpose.m11 = m11;
transpose.m12 = m21;
transpose.m20 = m02;
transpose.m21 = m12;
transpose.m22 = m22;
return transpose;
}
}
///
/// The determinate of a matrix.
///
public float Determinant
{
get
{
float cofactor00 = m11 * m22 - m12 * m21;
float cofactor10 = m12 * m20 - m10 * m22;
float cofactor20 = m10 * m21 - m11 * m20;
float det = m00 * cofactor00 + m01 * cofactor10 + m02 * cofactor20;
return det;
}
}
///
/// The inverse of the matrix.
/// A matrix multipled by its inverse is the idenity.
///
public Matrix3x3f Inverse
{
get
{
Matrix3x3f inverse = Identity;
TryInverse(out inverse);
return inverse;
}
}
///
/// Add two matrices.
///
public static Matrix3x3f operator +(Matrix3x3f m1, Matrix3x3f m2)
{
Matrix3x3f kSum = new Matrix3x3f();
kSum.m00 = m1.m00 + m2.m00;
kSum.m01 = m1.m01 + m2.m01;
kSum.m02 = m1.m02 + m2.m02;
kSum.m10 = m1.m10 + m2.m10;
kSum.m11 = m1.m11 + m2.m11;
kSum.m12 = m1.m12 + m2.m12;
kSum.m20 = m1.m20 + m2.m20;
kSum.m21 = m1.m21 + m2.m21;
kSum.m22 = m1.m22 + m2.m22;
return kSum;
}
///
/// Subtract two matrices.
///
public static Matrix3x3f operator -(Matrix3x3f m1, Matrix3x3f m2)
{
Matrix3x3f kSum = new Matrix3x3f();
kSum.m00 = m1.m00 - m2.m00;
kSum.m01 = m1.m01 - m2.m01;
kSum.m02 = m1.m02 - m2.m02;
kSum.m10 = m1.m10 - m2.m10;
kSum.m11 = m1.m11 - m2.m11;
kSum.m12 = m1.m12 - m2.m12;
kSum.m20 = m1.m20 - m2.m20;
kSum.m21 = m1.m21 - m2.m21;
kSum.m22 = m1.m22 - m2.m22;
return kSum;
}
///
/// Multiply two matrices.
///
public static Matrix3x3f operator *(Matrix3x3f m1, Matrix3x3f m2)
{
Matrix3x3f kProd = new Matrix3x3f();
kProd.m00 = m1.m00 * m2.m00 + m1.m01 * m2.m10 + m1.m02 * m2.m20;
kProd.m01 = m1.m00 * m2.m01 + m1.m01 * m2.m11 + m1.m02 * m2.m21;
kProd.m02 = m1.m00 * m2.m02 + m1.m01 * m2.m12 + m1.m02 * m2.m22;
kProd.m10 = m1.m10 * m2.m00 + m1.m11 * m2.m10 + m1.m12 * m2.m20;
kProd.m11 = m1.m10 * m2.m01 + m1.m11 * m2.m11 + m1.m12 * m2.m21;
kProd.m12 = m1.m10 * m2.m02 + m1.m11 * m2.m12 + m1.m12 * m2.m22;
kProd.m20 = m1.m20 * m2.m00 + m1.m21 * m2.m10 + m1.m22 * m2.m20;
kProd.m21 = m1.m20 * m2.m01 + m1.m21 * m2.m11 + m1.m22 * m2.m21;
kProd.m22 = m1.m20 * m2.m02 + m1.m21 * m2.m12 + m1.m22 * m2.m22;
return kProd;
}
///
/// Multiply a vector by a matrix.
///
public static Vector3f operator *(Matrix3x3f m, Vector3f v)
{
Vector3f kProd = new Vector3f();
kProd.x = m.m00 * v.x + m.m01 * v.y + m.m02 * v.z;
kProd.y = m.m10 * v.x + m.m11 * v.y + m.m12 * v.z;
kProd.z = m.m20 * v.x + m.m21 * v.y + m.m22 * v.z;
return kProd;
}
///
/// Multiply a matrix by a scalar.
///
public static Matrix3x3f operator *(Matrix3x3f m1, float s)
{
Matrix3x3f kProd = new Matrix3x3f();
kProd.m00 = m1.m00 * s;
kProd.m01 = m1.m01 * s;
kProd.m02 = m1.m02 * s;
kProd.m10 = m1.m10 * s;
kProd.m11 = m1.m11 * s;
kProd.m12 = m1.m12 * s;
kProd.m20 = m1.m20 * s;
kProd.m21 = m1.m21 * s;
kProd.m22 = m1.m22 * s;
return kProd;
}
///
/// Multiply a matrix by a scalar.
///
public static Matrix3x3f operator *(float s, Matrix3x3f m1)
{
Matrix3x3f kProd = new Matrix3x3f();
kProd.m00 = m1.m00 * s;
kProd.m01 = m1.m01 * s;
kProd.m02 = m1.m02 * s;
kProd.m10 = m1.m10 * s;
kProd.m11 = m1.m11 * s;
kProd.m12 = m1.m12 * s;
kProd.m20 = m1.m20 * s;
kProd.m21 = m1.m21 * s;
kProd.m22 = m1.m22 * s;
return kProd;
}
///
/// Are these matrices equal.
///
public static bool operator ==(Matrix3x3f m1, Matrix3x3f m2)
{
if (m1.m00 != m2.m00) return false;
if (m1.m01 != m2.m01) return false;
if (m1.m02 != m2.m02) return false;
if (m1.m10 != m2.m10) return false;
if (m1.m11 != m2.m11) return false;
if (m1.m12 != m2.m12) return false;
if (m1.m20 != m2.m20) return false;
if (m1.m21 != m2.m21) return false;
if (m1.m22 != m2.m22) return false;
return true;
}
///
/// Are these matrices not equal.
///
public static bool operator !=(Matrix3x3f m1, Matrix3x3f m2)
{
if (m1.m00 != m2.m00) return true;
if (m1.m01 != m2.m01) return true;
if (m1.m02 != m2.m02) return true;
if (m1.m10 != m2.m10) return true;
if (m1.m11 != m2.m11) return true;
if (m1.m12 != m2.m12) return true;
if (m1.m20 != m2.m20) return true;
if (m1.m21 != m2.m21) return true;
if (m1.m22 != m2.m22) return true;
return false;
}
///
/// Are these matrices equal.
///
public override bool Equals (object obj)
{
if(!(obj is Matrix3x3f)) return false;
Matrix3x3f mat = (Matrix3x3f)obj;
return this == mat;
}
///
/// Are these matrices equal.
///
public bool Equals(Matrix3x3f mat)
{
return this == mat;
}
///
/// Are these matrices equal.
///
public bool EqualsWithError(Matrix3x3f m, float eps)
{
if (Math.Abs(m00 - m.m00) > eps) return false;
if (Math.Abs(m10 - m.m10) > eps) return false;
if (Math.Abs(m20 - m.m20) > eps) return false;
if (Math.Abs(m01 - m.m01) > eps) return false;
if (Math.Abs(m11 - m.m11) > eps) return false;
if (Math.Abs(m21 - m.m21) > eps) return false;
if (Math.Abs(m02 - m.m02) > eps) return false;
if (Math.Abs(m12 - m.m12) > eps) return false;
if (Math.Abs(m22 - m.m22) > eps) return false;
return true;
}
///
/// Matrices hash code.
///
public override int GetHashCode()
{
int hash = 0;
for(int i = 0; i < 9; i++)
hash ^= this[i].GetHashCode();
return hash;
}
///
/// A matrix as a string.
///
public override string ToString()
{
return this[0, 0] + "," + this[0, 1] + "," + this[0, 2] + "\n" +
this[1, 0] + "," + this[1, 1] + "," + this[1, 2] + "\n" +
this[2, 0] + "," + this[2, 1] + "," + this[2, 2];
}
///
/// The Inverse of the matrix copied into mInv.
/// Returns false if the matrix has no inverse.
/// A matrix multipled by its inverse is the idenity.
/// Invert a 3x3 using cofactors. This is about 8 times faster than
/// the Numerical Recipes code which uses Gaussian elimination.
///
public bool TryInverse(out Matrix3x3f mInv)
{
mInv.m00 = m11 * m22 - m12 * m21;
mInv.m01 = m02 * m21 - m01 * m22;
mInv.m02 = m01 * m12 - m02 * m11;
mInv.m10 = m12 * m20 - m10 * m22;
mInv.m11 = m00 * m22 - m02 * m20;
mInv.m12 = m02 * m10 - m00 * m12;
mInv.m20 = m10 * m21 - m11 * m20;
mInv.m21 = m01 * m20 - m00 * m21;
mInv.m22 = m00 * m11 - m01 * m10;
float det = m00 * mInv.m00 + m01 * mInv.m10 + m02 * mInv.m20;
if (FMath.IsZero(det))
{
mInv = Identity;
return false;
}
float invDet = 1.0f / det;
mInv.m00 *= invDet; mInv.m01 *= invDet; mInv.m02 *= invDet;
mInv.m10 *= invDet; mInv.m11 *= invDet; mInv.m12 *= invDet;
mInv.m20 *= invDet; mInv.m21 *= invDet; mInv.m22 *= invDet;
return true;
}
///
/// Get the ith column as a vector.
///
public Vector3f GetColumn(int iCol)
{
return new Vector3f(this[0, iCol], this[1, iCol], this[2, iCol]);
}
///
/// Set the ith column from avector.
///
public void SetColumn(int iCol, Vector3f v)
{
this[0, iCol] = v.x;
this[1, iCol] = v.y;
this[2, iCol] = v.z;
}
///
/// Get the ith row as a vector.
///
public Vector3f GetRow(int iRow)
{
return new Vector3f(this[iRow, 0], this[iRow, 1], this[iRow, 2]);
}
///
/// Set the ith row from avector.
///
public void SetRow(int iRow, Vector3f v)
{
this[iRow, 0] = v.x;
this[iRow, 1] = v.y;
this[iRow, 2] = v.z;
}
///
/// Convert to a single precision 4 dimension matrix.
///
public Matrix4x4f ToMatrix4x4f()
{
return new Matrix4x4f(m00, m01, m02, 0.0f,
m10, m11, m12, 0.0f,
m20, m21, m22, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f);
}
///
/// Create a translation out of a vector.
///
static public Matrix3x3f Translate(Vector2f v)
{
return new Matrix3x3f(1, 0, v.x,
0, 1, v.y,
0, 0, 1);
}
///
/// Create a scale out of a vector.
///
static public Matrix3x3f Scale(Vector2f v)
{
return new Matrix3x3f(v.x, 0, 0,
0, v.y, 0,
0, 0, 1);
}
///
/// Create a scale out of a vector.
///
static public Matrix3x3f Scale(float s)
{
return new Matrix3x3f(s, 0, 0,
0, s, 0,
0, 0, 1);
}
///
/// Create a rotation out of a angle.
///
static public Matrix3x3f RotateX(float angle)
{
float ca = (float)Math.Cos(angle * Math.PI / 180.0);
float sa = (float)Math.Sin(angle * Math.PI / 180.0);
return new Matrix3x3f(1, 0, 0,
0, ca, -sa,
0, sa, ca);
}
///
/// Create a rotation out of a angle.
///
static public Matrix3x3f RotateY(float angle)
{
float ca = (float)Math.Cos(angle * Math.PI / 180.0);
float sa = (float)Math.Sin(angle * Math.PI / 180.0);
return new Matrix3x3f(ca, 0, sa,
0, 1, 0,
-sa, 0, ca);
}
///
/// Create a rotation out of a angle.
///
static public Matrix3x3f RotateZ(float angle)
{
float ca = (float)Math.Cos(angle * Math.PI / 180.0);
float sa = (float)Math.Sin(angle * Math.PI / 180.0);
return new Matrix3x3f(ca, -sa, 0,
sa, ca, 0,
0, 0, 1);
}
///
/// Create a rotation out of a vector.
///
static public Matrix3x3f Rotate(Vector3f euler)
{
return Quaternion3f.FromEuler(euler).ToMatrix3x3f();
}
}
}
================================================
FILE: Assets/Common/LinearAlgebra/Matrix3x3f.cs.meta
================================================
fileFormatVersion: 2
guid: 0d592915ed7730b46b7e07319de6f32c
timeCreated: 1514536270
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Common/LinearAlgebra/Matrix4x4d.cs
================================================
using System;
using System.Collections;
using System.Runtime.InteropServices;
using Common.Core.Mathematics;
namespace Common.Core.LinearAlgebra
{
///
/// A single precision 3 dimension matrix
///
[StructLayout(LayoutKind.Sequential)]
public struct Matrix4x4d
{
///
/// The matrix
///
public double m00, m01, m02, m03;
public double m10, m11, m12, m13;
public double m20, m21, m22, m23;
public double m30, m31, m32, m33;
///
/// The Matrix Idenity.
///
static readonly public Matrix4x4d Identity = new Matrix4x4d(1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1);
///
/// A matrix from the following varibles.
///
public Matrix4x4d(double m00, double m01, double m02, double m03,
double m10, double m11, double m12, double m13,
double m20, double m21, double m22, double m23,
double m30, double m31, double m32, double m33)
{
this.m00 = m00; this.m01 = m01; this.m02 = m02; this.m03 = m03;
this.m10 = m10; this.m11 = m11; this.m12 = m12; this.m13 = m13;
this.m20 = m20; this.m21 = m21; this.m22 = m22; this.m23 = m23;
this.m30 = m30; this.m31 = m31; this.m32 = m32; this.m33 = m33;
}
///
/// A matrix from the following varibles.
///
public Matrix4x4d(double v)
{
m00 = v; m01 = v; m02 = v; m03 = v;
m10 = v; m11 = v; m12 = v; m13 = v;
m20 = v; m21 = v; m22 = v; m23 = v;
m30 = v; m31 = v; m32 = v; m33 = v;
}
///
/// A matrix copied from a array of varibles.
///
public Matrix4x4d(double[,] m)
{
m00 = m[0,0]; m01 = m[0,1]; m02 = m[0,2]; m03 = m[0,3];
m10 = m[1,0]; m11 = m[1,1]; m12 = m[1,2]; m13 = m[1,3];
m20 = m[2,0]; m21 = m[2,1]; m22 = m[2,2]; m23 = m[2,3];
m30 = m[3,0]; m31 = m[3,1]; m32 = m[3,2]; m33 = m[3,3];
}
///
/// A matrix copied from a array of varibles.
///
public Matrix4x4d(double[] m)
{
m00 = m[0+0* 4]; m01 = m[0+1* 4]; m02 = m[0+2* 4]; m03 = m[0+3* 4];
m10 = m[1+0* 4]; m11 = m[1+1* 4]; m12 = m[1+2* 4]; m13 = m[1+3* 4];
m20 = m[2+0* 4]; m21 = m[2+1* 4]; m22 = m[2+2* 4]; m23 = m[2+3* 4];
m30 = m[3+0* 4]; m31 = m[3+1* 4]; m32 = m[3+2* 4]; m33 = m[3+3* 4];
}
///
/// Access the varible at index i
///
public double this[int i]
{
get
{
switch (i)
{
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("Matrix4x4d index out of range: " + i);
}
}
set
{
switch (i)
{
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("Matrix4x4d index out of range: " + i);
}
}
}
///
/// Access the varible at index ij
///
public double this[int i, int j]
{
get
{
int k = i + j * 4;
switch (k)
{
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("Matrix4x4d index out of range: " + k);
}
}
set
{
int k = i + j * 4;
switch (k)
{
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("Matrix4x4d index out of range: " + k);
}
}
}
///
/// The transpose of the matrix. The rows and columns are flipped.
///
public Matrix4x4d Transpose
{
get
{
Matrix4x4d transpose = new Matrix4x4d();
transpose.m00 = m00;
transpose.m01 = m10;
transpose.m02 = m20;
transpose.m03 = m30;
transpose.m10 = m01;
transpose.m11 = m11;
transpose.m12 = m21;
transpose.m13 = m31;
transpose.m20 = m02;
transpose.m21 = m12;
transpose.m22 = m22;
transpose.m23 = m32;
transpose.m30 = m03;
transpose.m31 = m13;
transpose.m32 = m23;
transpose.m33 = m33;
return transpose;
}
}
///
/// The determinate of a matrix.
///
public double Determinant
{
get
{
return (m00 * Minor(1, 2, 3, 1, 2, 3) -
m01 * Minor(1, 2, 3, 0, 2, 3) +
m02 * Minor(1, 2, 3, 0, 1, 3) -
m03 * Minor(1, 2, 3, 0, 1, 2));
}
}
///
/// The adjoint of a matrix.
///
public Matrix4x4d Adjoint
{
get
{
return new Matrix4x4d(
Minor(1, 2, 3, 1, 2, 3),
-Minor(0, 2, 3, 1, 2, 3),
Minor(0, 1, 3, 1, 2, 3),
-Minor(0, 1, 2, 1, 2, 3),
-Minor(1, 2, 3, 0, 2, 3),
Minor(0, 2, 3, 0, 2, 3),
-Minor(0, 1, 3, 0, 2, 3),
Minor(0, 1, 2, 0, 2, 3),
Minor(1, 2, 3, 0, 1, 3),
-Minor(0, 2, 3, 0, 1, 3),
Minor(0, 1, 3, 0, 1, 3),
-Minor(0, 1, 2, 0, 1, 3),
-Minor(1, 2, 3, 0, 1, 2),
Minor(0, 2, 3, 0, 1, 2),
-Minor(0, 1, 3, 0, 1, 2),
Minor(0, 1, 2, 0, 1, 2));
}
}
///
/// The inverse of the matrix.
/// A matrix multipled by its inverse is the idenity.
///
public Matrix4x4d Inverse
{
get
{
return Adjoint * DMath.SafeInv(Determinant);
}
}
public double Trace
{
get
{
return m00 + m11 + m22 + m33;
}
}
///
/// Add two matrices.
///
public static Matrix4x4d operator +(Matrix4x4d m1, Matrix4x4d m2)
{
Matrix4x4d kSum = new Matrix4x4d();
kSum.m00 = m1.m00 + m2.m00;
kSum.m01 = m1.m01 + m2.m01;
kSum.m02 = m1.m02 + m2.m02;
kSum.m03 = m1.m03 + m2.m03;
kSum.m10 = m1.m10 + m2.m10;
kSum.m11 = m1.m11 + m2.m11;
kSum.m12 = m1.m12 + m2.m12;
kSum.m13 = m1.m13 + m2.m13;
kSum.m20 = m1.m20 + m2.m20;
kSum.m21 = m1.m21 + m2.m21;
kSum.m22 = m1.m22 + m2.m22;
kSum.m23 = m1.m23 + m2.m23;
kSum.m30 = m1.m30 + m2.m30;
kSum.m31 = m1.m31 + m2.m31;
kSum.m32 = m1.m32 + m2.m32;
kSum.m33 = m1.m33 + m2.m33;
return kSum;
}
///
/// Subtract two matrices.
///
public static Matrix4x4d operator -(Matrix4x4d m1, Matrix4x4d m2)
{
Matrix4x4d kSum = new Matrix4x4d();
kSum.m00 = m1.m00 - m2.m00;
kSum.m01 = m1.m01 - m2.m01;
kSum.m02 = m1.m02 - m2.m02;
kSum.m03 = m1.m03 - m2.m03;
kSum.m10 = m1.m10 - m2.m10;
kSum.m11 = m1.m11 - m2.m11;
kSum.m12 = m1.m12 - m2.m12;
kSum.m13 = m1.m13 - m2.m13;
kSum.m20 = m1.m20 - m2.m20;
kSum.m21 = m1.m21 - m2.m21;
kSum.m22 = m1.m22 - m2.m22;
kSum.m23 = m1.m23 - m2.m23;
kSum.m30 = m1.m30 - m2.m30;
kSum.m31 = m1.m31 - m2.m31;
kSum.m32 = m1.m32 - m2.m32;
kSum.m33 = m1.m33 - m2.m33;
return kSum;
}
///
/// Multiply two matrices.
///
public static Matrix4x4d operator *(Matrix4x4d m1, Matrix4x4d m2)
{
Matrix4x4d kProd = new Matrix4x4d();
kProd.m00 = m1.m00 * m2.m00 + m1.m01 * m2.m10 + m1.m02 * m2.m20 + m1.m03 * m2.m30;
kProd.m01 = m1.m00 * m2.m01 + m1.m01 * m2.m11 + m1.m02 * m2.m21 + m1.m03 * m2.m31;
kProd.m02 = m1.m00 * m2.m02 + m1.m01 * m2.m12 + m1.m02 * m2.m22 + m1.m03 * m2.m32;
kProd.m03 = m1.m00 * m2.m03 + m1.m01 * m2.m13 + m1.m02 * m2.m23 + m1.m03 * m2.m33;
kProd.m10 = m1.m10 * m2.m00 + m1.m11 * m2.m10 + m1.m12 * m2.m20 + m1.m13 * m2.m30;
kProd.m11 = m1.m10 * m2.m01 + m1.m11 * m2.m11 + m1.m12 * m2.m21 + m1.m13 * m2.m31;
kProd.m12 = m1.m10 * m2.m02 + m1.m11 * m2.m12 + m1.m12 * m2.m22 + m1.m13 * m2.m32;
kProd.m13 = m1.m10 * m2.m03 + m1.m11 * m2.m13 + m1.m12 * m2.m23 + m1.m13 * m2.m33;
kProd.m20 = m1.m20 * m2.m00 + m1.m21 * m2.m10 + m1.m22 * m2.m20 + m1.m23 * m2.m30;
kProd.m21 = m1.m20 * m2.m01 + m1.m21 * m2.m11 + m1.m22 * m2.m21 + m1.m23 * m2.m31;
kProd.m22 = m1.m20 * m2.m02 + m1.m21 * m2.m12 + m1.m22 * m2.m22 + m1.m23 * m2.m32;
kProd.m23 = m1.m20 * m2.m03 + m1.m21 * m2.m13 + m1.m22 * m2.m23 + m1.m23 * m2.m33;
kProd.m30 = m1.m30 * m2.m00 + m1.m31 * m2.m10 + m1.m32 * m2.m20 + m1.m33 * m2.m30;
kProd.m31 = m1.m30 * m2.m01 + m1.m31 * m2.m11 + m1.m32 * m2.m21 + m1.m33 * m2.m31;
kProd.m32 = m1.m30 * m2.m02 + m1.m31 * m2.m12 + m1.m32 * m2.m22 + m1.m33 * m2.m32;
kProd.m33 = m1.m30 * m2.m03 + m1.m31 * m2.m13 + m1.m32 * m2.m23 + m1.m33 * m2.m33;
return kProd;
}
///
/// Multiply a vector by a matrix.
///
public static Vector3d operator *(Matrix4x4d m, Vector3d v)
{
Vector3d kProd = new Vector3d();
double invW = DMath.SafeInv(m.m30 * v.x + m.m31 * v.y + m.m32 * v.z + m.m33);
kProd.x = (m.m00 * v.x + m.m01 * v.y + m.m02 * v.z + m.m03) * invW;
kProd.y = (m.m10 * v.x + m.m11 * v.y + m.m12 * v.z + m.m13) * invW;
kProd.z = (m.m20 * v.x + m.m21 * v.y + m.m22 * v.z + m.m23) * invW;
return kProd;
}
///
/// Multiply a vector by a matrix.
///
public static Vector4d operator *(Matrix4x4d m, Vector4d v)
{
Vector4d kProd = new Vector4d();
kProd.x = m.m00 * v.x + m.m01 * v.y + m.m02 * v.z + m.m03 * v.w;
kProd.y = m.m10 * v.x + m.m11 * v.y + m.m12 * v.z + m.m13 * v.w;
kProd.z = m.m20 * v.x + m.m21 * v.y + m.m22 * v.z + m.m23 * v.w;
kProd.w = m.m30 * v.x + m.m31 * v.y + m.m32 * v.z + m.m33 * v.w;
return kProd;
}
///
/// Multiply a matrix by a scalar.
///
public static Matrix4x4d operator *(Matrix4x4d m1, double s)
{
Matrix4x4d kProd = new Matrix4x4d();
kProd.m00 = m1.m00 * s;
kProd.m01 = m1.m01 * s;
kProd.m02 = m1.m02 * s;
kProd.m03 = m1.m03 * s;
kProd.m10 = m1.m10 * s;
kProd.m11 = m1.m11 * s;
kProd.m12 = m1.m12 * s;
kProd.m13 = m1.m13 * s;
kProd.m20 = m1.m20 * s;
kProd.m21 = m1.m21 * s;
kProd.m22 = m1.m22 * s;
kProd.m23 = m1.m23 * s;
kProd.m30 = m1.m30 * s;
kProd.m31 = m1.m31 * s;
kProd.m32 = m1.m32 * s;
kProd.m33 = m1.m33 * s;
return kProd;
}
///
/// Multiply a matrix by a scalar.
///
public static Matrix4x4d operator *(double s, Matrix4x4d m1)
{
Matrix4x4d kProd = new Matrix4x4d();
kProd.m00 = m1.m00 * s;
kProd.m01 = m1.m01 * s;
kProd.m02 = m1.m02 * s;
kProd.m03 = m1.m03 * s;
kProd.m10 = m1.m10 * s;
kProd.m11 = m1.m11 * s;
kProd.m12 = m1.m12 * s;
kProd.m13 = m1.m13 * s;
kProd.m20 = m1.m20 * s;
kProd.m21 = m1.m21 * s;
kProd.m22 = m1.m22 * s;
kProd.m23 = m1.m23 * s;
kProd.m30 = m1.m30 * s;
kProd.m31 = m1.m31 * s;
kProd.m32 = m1.m32 * s;
kProd.m33 = m1.m33 * s;
return kProd;
}
///
/// Are these matrices equal.
///
public static bool operator ==(Matrix4x4d m1, Matrix4x4d m2)
{
if (m1.m00 != m2.m00) return false;
if (m1.m01 != m2.m01) return false;
if (m1.m02 != m2.m02) return false;
if (m1.m03 != m2.m03) return false;
if (m1.m10 != m2.m10) return false;
if (m1.m11 != m2.m11) return false;
if (m1.m12 != m2.m12) return false;
if (m1.m13 != m2.m13) return false;
if (m1.m20 != m2.m20) return false;
if (m1.m21 != m2.m21) return false;
if (m1.m22 != m2.m22) return false;
if (m1.m23 != m2.m23) return false;
if (m1.m30 != m2.m30) return false;
if (m1.m31 != m2.m31) return false;
if (m1.m32 != m2.m32) return false;
if (m1.m33 != m2.m33) return false;
return true;
}
///
/// Are these matrices not equal.
///
public static bool operator !=(Matrix4x4d m1, Matrix4x4d m2)
{
if (m1.m00 != m2.m00) return true;
if (m1.m01 != m2.m01) return true;
if (m1.m02 != m2.m02) return true;
if (m1.m03 != m2.m03) return true;
if (m1.m10 != m2.m10) return true;
if (m1.m11 != m2.m11) return true;
if (m1.m12 != m2.m12) return true;
if (m1.m13 != m2.m13) return true;
if (m1.m20 != m2.m20) return true;
if (m1.m21 != m2.m21) return true;
if (m1.m22 != m2.m22) return true;
if (m1.m23 != m2.m23) return true;
if (m1.m30 != m2.m30) return true;
if (m1.m31 != m2.m31) return true;
if (m1.m32 != m2.m32) return true;
return false;
}
///
/// Are these matrices equal.
///
public override bool Equals (object obj)
{
if(!(obj is Matrix4x4d)) return false;
Matrix4x4d mat = (Matrix4x4d)obj;
return this == mat;
}
///
/// Are these matrices equal.
///
public bool Equals (Matrix4x4d mat)
{
return this == mat;
}
///
/// Are these matrices equal.
///
public bool EqualsWithError(Matrix4x4d m, double eps)
{
if (Math.Abs(m00 - m.m00) > eps) return false;
if (Math.Abs(m10 - m.m10) > eps) return false;
if (Math.Abs(m20 - m.m20) > eps) return false;
if (Math.Abs(m30 - m.m30) > eps) return false;
if (Math.Abs(m01 - m.m01) > eps) return false;
if (Math.Abs(m11 - m.m11) > eps) return false;
if (Math.Abs(m21 - m.m21) > eps) return false;
if (Math.Abs(m31 - m.m31) > eps) return false;
if (Math.Abs(m02 - m.m02) > eps) return false;
if (Math.Abs(m12 - m.m12) > eps) return false;
if (Math.Abs(m22 - m.m22) > eps) return false;
if (Math.Abs(m32 - m.m32) > eps) return false;
if (Math.Abs(m03 - m.m03) > eps) return false;
if (Math.Abs(m13 - m.m13) > eps) return false;
if (Math.Abs(m23 - m.m23) > eps) return false;
if (Math.Abs(m33 - m.m33) > eps) return false;
return true;
}
///
/// Matrices hash code.
///
public override int GetHashCode()
{
int hash = 0;
for(int i = 0; i < 16; i++)
hash ^= this[i].GetHashCode();
return hash;
}
///
/// A matrix as a string.
///
public override string ToString()
{
return this[0, 0] + "," + this[0, 1] + "," + this[0, 2] + "," + this[0, 3] + "\n" +
this[1, 0] + "," + this[1, 1] + "," + this[1, 2] + "," + this[1, 3] + "\n" +
this[2, 0] + "," + this[2, 1] + "," + this[2, 2] + "," + this[2, 3] + "\n" +
this[3, 0] + "," + this[3, 1] + "," + this[3, 2] + "," + this[3, 3];
}
///
/// The minor of a matrix.
///
private double Minor(int r0, int r1, int r2, int c0, int c1, int c2)
{
return this[r0, c0] * (this[r1, c1] * this[r2, c2] - this[r2, c1] * this[r1, c2]) -
this[r0, c1] * (this[r1, c0] * this[r2, c2] - this[r2, c0] * this[r1, c2]) +
this[r0, c2] * (this[r1, c0] * this[r2, c1] - this[r2, c0] * this[r1, c1]);
}
///
/// The inverse of the matrix.
/// A matrix multipled by its inverse is the idenity.
///
public bool TryInverse(out Matrix4x4d mInv)
{
double det = Determinant;
if (DMath.IsZero(det))
{
mInv = Identity;
return false;
}
mInv = Adjoint * (1.0 / det);
return true;
}
///
/// Get the ith column as a vector.
///
public Vector4d GetColumn(int iCol)
{
return new Vector4d(this[0, iCol], this[1, iCol], this[2, iCol], this[3, iCol]);
}
///
/// Set the ith column from a vector.
///
public void SetColumn(int iCol, Vector4d v)
{
this[0, iCol] = v.x;
this[1, iCol] = v.y;
this[2, iCol] = v.z;
this[3, iCol] = v.w;
}
///
/// Flip the ith column.
///
public void FlipColumn(int iCol)
{
this[0, iCol] *= -1.0;
this[1, iCol] *= -1.0;
this[2, iCol] *= -1.0;
this[3, iCol] *= -1.0;
}
///
/// Get the ith row as a vector.
///
public Vector4d GetRow(int iRow)
{
return new Vector4d(this[iRow, 0], this[iRow, 1], this[iRow, 2], this[iRow, 3]);
}
///
/// Set the ith row from a vector.
///
public void SetRow(int iRow, Vector4d v)
{
this[iRow, 0] = v.x;
this[iRow, 1] = v.y;
this[iRow, 2] = v.z;
this[iRow, 3] = v.w;
}
///
/// Flip the ith row.
///
public void FlipRow(int iRow)
{
this[iRow, 0] *= -1.0f;
this[iRow, 1] *= -1.0f;
this[iRow, 2] *= -1.0f;
this[iRow, 3] *= -1.0f;
}
///
/// Convert to a 3 dimension matrix.
///
public Matrix3x3d ToMatrix3x3d()
{
Matrix3x3d mat = new Matrix3x3d();
mat.m00 = m00; mat.m01 = m01; mat.m02 = m02;
mat.m10 = m10; mat.m11 = m11; mat.m12 = m12;
mat.m20 = m20; mat.m21 = m21; mat.m22 = m22;
return mat;
}
///
/// Create a translation, rotation and scale.
///
static public Matrix4x4d TranslateRotateScale(Vector3d t, Quaternion3d r, Vector3d s)
{
Matrix4x4d T = Translate(t);
Matrix4x4d R = r.ToMatrix4x4d();
Matrix4x4d S = Scale(s);
return T * R * S;
}
///
/// Create a translation and rotation.
///
static public Matrix4x4d TranslateRotate(Vector3d t, Quaternion3d r)
{
Matrix4x4d T = Translate(t);
Matrix4x4d R = r.ToMatrix4x4d();
return T * R;
}
///
/// Create a translation and scale.
///
static public Matrix4x4d TranslateScale(Vector3d t, Vector3d s)
{
Matrix4x4d T = Translate(t);
Matrix4x4d S = Scale(s);
return T * S;
}
///
/// Create a rotation and scale.
///
static public Matrix4x4d RotateScale(Quaternion3d r, Vector3d s)
{
Matrix4x4d R = r.ToMatrix4x4d();
Matrix4x4d S = Scale(s);
return R * S;
}
///
/// Create a translation out of a vector.
///
static public Matrix4x4d Translate(Vector3d v)
{
return new Matrix4x4d( 1, 0, 0, v.x,
0, 1, 0, v.y,
0, 0, 1, v.z,
0, 0, 0, 1);
}
///
/// Create a scale out of a vector.
///
static public Matrix4x4d Scale(Vector3d v)
{
return new Matrix4x4d( v.x, 0, 0, 0,
0, v.y, 0, 0,
0, 0, v.z, 0,
0, 0, 0, 1);
}
///
/// Create a scale out of a vector.
///
static public Matrix4x4d Scale(double s)
{
return new Matrix4x4d(s, 0, 0, 0,
0, s, 0, 0,
0, 0, s, 0,
0, 0, 0, 1);
}
///
/// Create a rotation out of a angle.
///
static public Matrix4x4d RotateX(double angle)
{
double ca = Math.Cos(angle * Math.PI / 180.0);
double sa = Math.Sin(angle * Math.PI / 180.0);
return new Matrix4x4d( 1, 0, 0, 0,
0, ca, -sa, 0,
0, sa, ca, 0,
0, 0, 0, 1);
}
///
/// Create a rotation out of a angle.
///
static public Matrix4x4d RotateY(double angle)
{
double ca = Math.Cos(angle * Math.PI / 180.0);
double sa = Math.Sin(angle * Math.PI / 180.0);
return new Matrix4x4d( ca, 0, sa, 0,
0, 1, 0, 0,
-sa, 0, ca, 0,
0, 0, 0, 1);
}
///
/// Create a rotation out of a angle.
///
static public Matrix4x4d RotateZ(double angle)
{
double ca = Math.Cos(angle * Math.PI / 180.0);
double sa = Math.Sin(angle * Math.PI / 180.0);
return new Matrix4x4d( ca, -sa, 0, 0,
sa, ca, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1);
}
///
/// Create a rotation out of a vector.
///
static public Matrix4x4d Rotate(Vector3d euler)
{
return Quaternion3d.FromEuler(euler).ToMatrix4x4d();
}
///
/// Create a perspective matrix.
///
static public Matrix4x4d Perspective(double fovy, double aspect, double zNear, double zFar)
{
double f = 1.0 / Math.Tan((fovy * Math.PI / 180.0) / 2.0);
return new Matrix4x4d( f / aspect, 0, 0, 0,
0, f, 0, 0,
0, 0, (zFar + zNear) / (zNear - zFar), (2.0f * zFar * zNear) / (zNear - zFar),
0, 0, -1, 0);
}
///
/// Create a ortho matrix.
///
static public Matrix4x4d Ortho(double xRight, double xLeft, double yTop, double yBottom, double zNear, double zFar)
{
double tx, ty, tz;
tx = -(xRight + xLeft) / (xRight - xLeft);
ty = -(yTop + yBottom) / (yTop - yBottom);
tz = -(zFar + zNear) / (zFar - zNear);
return new Matrix4x4d( 2.0 / (xRight - xLeft), 0, 0, tx,
0, 2.0 / (yTop - yBottom), 0, ty,
0, 0, -2.0 / (zFar - zNear), tz,
0, 0, 0, 1);
}
///
/// Creates the matrix need to look at target from position.
///
static public Matrix4x4d LookAt(Vector3d position, Vector3d target, Vector3d Up)
{
Vector3d zaxis = (position - target).Normalized;
Vector3d xaxis = Up.Cross(zaxis).Normalized;
Vector3d yaxis = zaxis.Cross(xaxis);
return new Matrix4x4d( xaxis.x, xaxis.y, xaxis.z, -Vector3d.Dot(xaxis, position),
yaxis.x, yaxis.y, yaxis.z, -Vector3d.Dot(yaxis, position),
zaxis.x, zaxis.y, zaxis.z, -Vector3d.Dot(zaxis, position),
0, 0, 0, 1);
}
}
}
================================================
FILE: Assets/Common/LinearAlgebra/Matrix4x4d.cs.meta
================================================
fileFormatVersion: 2
guid: deeb67b15435ece419f1249c52ba4c99
timeCreated: 1514536271
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Common/LinearAlgebra/Matrix4x4f.cs
================================================
using System;
using System.Collections;
using System.Runtime.InteropServices;
using Common.Core.Mathematics;
namespace Common.Core.LinearAlgebra
{
///
/// A single precision 3 dimension matrix
///
[StructLayout(LayoutKind.Sequential)]
public struct Matrix4x4f : IEquatable
{
///
/// The matrix
///
public float m00, m01, m02, m03;
public float m10, m11, m12, m13;
public float m20, m21, m22, m23;
public float m30, m31, m32, m33;
///
/// The Matrix Idenity.
///
static readonly public Matrix4x4f Identity = new Matrix4x4f(1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1);
///
/// A matrix from the following varibles.
///
public Matrix4x4f(float m00, float m01, float m02, float m03,
float m10, float m11, float m12, float m13,
float m20, float m21, float m22, float m23,
float m30, float m31, float m32, float m33)
{
this.m00 = m00; this.m01 = m01; this.m02 = m02; this.m03 = m03;
this.m10 = m10; this.m11 = m11; this.m12 = m12; this.m13 = m13;
this.m20 = m20; this.m21 = m21; this.m22 = m22; this.m23 = m23;
this.m30 = m30; this.m31 = m31; this.m32 = m32; this.m33 = m33;
}
///
/// A matrix from the following varibles.
///
public Matrix4x4f(float v)
{
m00 = v; m01 = v; m02 = v; m03 = v;
m10 = v; m11 = v; m12 = v; m13 = v;
m20 = v; m21 = v; m22 = v; m23 = v;
m30 = v; m31 = v; m32 = v; m33 = v;
}
///
/// A matrix copied from a array of varibles.
///
public Matrix4x4f(float[,] m)
{
m00 = m[0,0]; m01 = m[0,1]; m02 = m[0,2]; m03 = m[0,3];
m10 = m[1,0]; m11 = m[1,1]; m12 = m[1,2]; m13 = m[1,3];
m20 = m[2,0]; m21 = m[2,1]; m22 = m[2,2]; m23 = m[2,3];
m30 = m[3,0]; m31 = m[3,1]; m32 = m[3,2]; m33 = m[3,3];
}
///
/// A matrix copied from a array of varibles.
///
public Matrix4x4f(float[] m)
{
m00 = m[0+0* 4]; m01 = m[0+1* 4]; m02 = m[0+2* 4]; m03 = m[0+3* 4];
m10 = m[1+0* 4]; m11 = m[1+1* 4]; m12 = m[1+2* 4]; m13 = m[1+3* 4];
m20 = m[2+0* 4]; m21 = m[2+1* 4]; m22 = m[2+2* 4]; m23 = m[2+3* 4];
m30 = m[3+0* 4]; m31 = m[3+1* 4]; m32 = m[3+2* 4]; m33 = m[3+3* 4];
}
///
/// Access the varible at index i
///
public float this[int i]
{
get
{
switch (i)
{
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("Matrix4x4f index out of range: " + i);
}
}
set
{
switch (i)
{
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("Matrix4x4f index out of range: " + i);
}
}
}
///
/// Access the varible at index ij
///
public float this[int i, int j]
{
get
{
int k = i + j * 4;
switch (k)
{
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("Matrix4x4f index out of range: " + k);
}
}
set
{
int k = i + j * 4;
switch (k)
{
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("Matrix4x4f index out of range: " + k);
}
}
}
///
/// The transpose of the matrix. The rows and columns are flipped.
///
public Matrix4x4f Transpose
{
get
{
Matrix4x4f transpose = new Matrix4x4f();
transpose.m00 = m00;
transpose.m01 = m10;
transpose.m02 = m20;
transpose.m03 = m30;
transpose.m10 = m01;
transpose.m11 = m11;
transpose.m12 = m21;
transpose.m13 = m31;
transpose.m20 = m02;
transpose.m21 = m12;
transpose.m22 = m22;
transpose.m23 = m32;
transpose.m30 = m03;
transpose.m31 = m13;
transpose.m32 = m23;
transpose.m33 = m33;
return transpose;
}
}
///
/// The determinate of a matrix.
///
public float Determinant
{
get
{
return (m00 * Minor(1, 2, 3, 1, 2, 3) -
m01 * Minor(1, 2, 3, 0, 2, 3) +
m02 * Minor(1, 2, 3, 0, 1, 3) -
m03 * Minor(1, 2, 3, 0, 1, 2));
}
}
///
/// The adjoint of a matrix.
///
public Matrix4x4f Adjoint
{
get
{
return new Matrix4x4f(
Minor(1, 2, 3, 1, 2, 3),
-Minor(0, 2, 3, 1, 2, 3),
Minor(0, 1, 3, 1, 2, 3),
-Minor(0, 1, 2, 1, 2, 3),
-Minor(1, 2, 3, 0, 2, 3),
Minor(0, 2, 3, 0, 2, 3),
-Minor(0, 1, 3, 0, 2, 3),
Minor(0, 1, 2, 0, 2, 3),
Minor(1, 2, 3, 0, 1, 3),
-Minor(0, 2, 3, 0, 1, 3),
Minor(0, 1, 3, 0, 1, 3),
-Minor(0, 1, 2, 0, 1, 3),
-Minor(1, 2, 3, 0, 1, 2),
Minor(0, 2, 3, 0, 1, 2),
-Minor(0, 1, 3, 0, 1, 2),
Minor(0, 1, 2, 0, 1, 2));
}
}
///
/// The inverse of the matrix.
/// A matrix multipled by its inverse is the idenity.
///
public Matrix4x4f Inverse
{
get
{
return Adjoint * FMath.SafeInv(Determinant);
}
}
public float Trace
{
get
{
return m00 + m11 + m22 + m33;
}
}
///
/// Add two matrices.
///
public static Matrix4x4f operator +(Matrix4x4f m1, Matrix4x4f m2)
{
Matrix4x4f kSum = new Matrix4x4f();
kSum.m00 = m1.m00 + m2.m00;
kSum.m01 = m1.m01 + m2.m01;
kSum.m02 = m1.m02 + m2.m02;
kSum.m03 = m1.m03 + m2.m03;
kSum.m10 = m1.m10 + m2.m10;
kSum.m11 = m1.m11 + m2.m11;
kSum.m12 = m1.m12 + m2.m12;
kSum.m13 = m1.m13 + m2.m13;
kSum.m20 = m1.m20 + m2.m20;
kSum.m21 = m1.m21 + m2.m21;
kSum.m22 = m1.m22 + m2.m22;
kSum.m23 = m1.m23 + m2.m23;
kSum.m30 = m1.m30 + m2.m30;
kSum.m31 = m1.m31 + m2.m31;
kSum.m32 = m1.m32 + m2.m32;
kSum.m33 = m1.m33 + m2.m33;
return kSum;
}
///
/// Subtract two matrices.
///
public static Matrix4x4f operator -(Matrix4x4f m1, Matrix4x4f m2)
{
Matrix4x4f kSum = new Matrix4x4f();
kSum.m00 = m1.m00 - m2.m00;
kSum.m01 = m1.m01 - m2.m01;
kSum.m02 = m1.m02 - m2.m02;
kSum.m03 = m1.m03 - m2.m03;
kSum.m10 = m1.m10 - m2.m10;
kSum.m11 = m1.m11 - m2.m11;
kSum.m12 = m1.m12 - m2.m12;
kSum.m13 = m1.m13 - m2.m13;
kSum.m20 = m1.m20 - m2.m20;
kSum.m21 = m1.m21 - m2.m21;
kSum.m22 = m1.m22 - m2.m22;
kSum.m23 = m1.m23 - m2.m23;
kSum.m30 = m1.m30 - m2.m30;
kSum.m31 = m1.m31 - m2.m31;
kSum.m32 = m1.m32 - m2.m32;
kSum.m33 = m1.m33 - m2.m33;
return kSum;
}
///
/// Multiply two matrices.
///
public static Matrix4x4f operator *(Matrix4x4f m1, Matrix4x4f m2)
{
Matrix4x4f kProd = new Matrix4x4f();
kProd.m00 = m1.m00 * m2.m00 + m1.m01 * m2.m10 + m1.m02 * m2.m20 + m1.m03 * m2.m30;
kProd.m01 = m1.m00 * m2.m01 + m1.m01 * m2.m11 + m1.m02 * m2.m21 + m1.m03 * m2.m31;
kProd.m02 = m1.m00 * m2.m02 + m1.m01 * m2.m12 + m1.m02 * m2.m22 + m1.m03 * m2.m32;
kProd.m03 = m1.m00 * m2.m03 + m1.m01 * m2.m13 + m1.m02 * m2.m23 + m1.m03 * m2.m33;
kProd.m10 = m1.m10 * m2.m00 + m1.m11 * m2.m10 + m1.m12 * m2.m20 + m1.m13 * m2.m30;
kProd.m11 = m1.m10 * m2.m01 + m1.m11 * m2.m11 + m1.m12 * m2.m21 + m1.m13 * m2.m31;
kProd.m12 = m1.m10 * m2.m02 + m1.m11 * m2.m12 + m1.m12 * m2.m22 + m1.m13 * m2.m32;
kProd.m13 = m1.m10 * m2.m03 + m1.m11 * m2.m13 + m1.m12 * m2.m23 + m1.m13 * m2.m33;
kProd.m20 = m1.m20 * m2.m00 + m1.m21 * m2.m10 + m1.m22 * m2.m20 + m1.m23 * m2.m30;
kProd.m21 = m1.m20 * m2.m01 + m1.m21 * m2.m11 + m1.m22 * m2.m21 + m1.m23 * m2.m31;
kProd.m22 = m1.m20 * m2.m02 + m1.m21 * m2.m12 + m1.m22 * m2.m22 + m1.m23 * m2.m32;
kProd.m23 = m1.m20 * m2.m03 + m1.m21 * m2.m13 + m1.m22 * m2.m23 + m1.m23 * m2.m33;
kProd.m30 = m1.m30 * m2.m00 + m1.m31 * m2.m10 + m1.m32 * m2.m20 + m1.m33 * m2.m30;
kProd.m31 = m1.m30 * m2.m01 + m1.m31 * m2.m11 + m1.m32 * m2.m21 + m1.m33 * m2.m31;
kProd.m32 = m1.m30 * m2.m02 + m1.m31 * m2.m12 + m1.m32 * m2.m22 + m1.m33 * m2.m32;
kProd.m33 = m1.m30 * m2.m03 + m1.m31 * m2.m13 + m1.m32 * m2.m23 + m1.m33 * m2.m33;
return kProd;
}
///
/// Multiply a vector by a matrix.
///
public static Vector3f operator *(Matrix4x4f m, Vector3f v)
{
Vector3f kProd = new Vector3f();
float invW = FMath.SafeInv(m.m30 * v.x + m.m31 * v.y + m.m32 * v.z + m.m33);
kProd.x = (m.m00 * v.x + m.m01 * v.y + m.m02 * v.z + m.m03) * invW;
kProd.y = (m.m10 * v.x + m.m11 * v.y + m.m12 * v.z + m.m13) * invW;
kProd.z = (m.m20 * v.x + m.m21 * v.y + m.m22 * v.z + m.m23) * invW;
return kProd;
}
///
/// Multiply a vector by a matrix.
///
public static Vector4f operator *(Matrix4x4f m, Vector4f v)
{
Vector4f kProd = new Vector4f();
kProd.x = m.m00 * v.x + m.m01 * v.y + m.m02 * v.z + m.m03 * v.w;
kProd.y = m.m10 * v.x + m.m11 * v.y + m.m12 * v.z + m.m13 * v.w;
kProd.z = m.m20 * v.x + m.m21 * v.y + m.m22 * v.z + m.m23 * v.w;
kProd.w = m.m30 * v.x + m.m31 * v.y + m.m32 * v.z + m.m33 * v.w;
return kProd;
}
///
/// Multiply a matrix by a scalar.
///
public static Matrix4x4f operator *(Matrix4x4f m1, float s)
{
Matrix4x4f kProd = new Matrix4x4f();
kProd.m00 = m1.m00 * s;
kProd.m01 = m1.m01 * s;
kProd.m02 = m1.m02 * s;
kProd.m03 = m1.m03 * s;
kProd.m10 = m1.m10 * s;
kProd.m11 = m1.m11 * s;
kProd.m12 = m1.m12 * s;
kProd.m13 = m1.m13 * s;
kProd.m20 = m1.m20 * s;
kProd.m21 = m1.m21 * s;
kProd.m22 = m1.m22 * s;
kProd.m23 = m1.m23 * s;
kProd.m30 = m1.m30 * s;
kProd.m31 = m1.m31 * s;
kProd.m32 = m1.m32 * s;
kProd.m33 = m1.m33 * s;
return kProd;
}
///
/// Multiply a matrix by a scalar.
///
public static Matrix4x4f operator *(float s, Matrix4x4f m1)
{
Matrix4x4f kProd = new Matrix4x4f();
kProd.m00 = m1.m00 * s;
kProd.m01 = m1.m01 * s;
kProd.m02 = m1.m02 * s;
kProd.m03 = m1.m03 * s;
kProd.m10 = m1.m10 * s;
kProd.m11 = m1.m11 * s;
kProd.m12 = m1.m12 * s;
kProd.m13 = m1.m13 * s;
kProd.m20 = m1.m20 * s;
kProd.m21 = m1.m21 * s;
kProd.m22 = m1.m22 * s;
kProd.m23 = m1.m23 * s;
kProd.m30 = m1.m30 * s;
kProd.m31 = m1.m31 * s;
kProd.m32 = m1.m32 * s;
kProd.m33 = m1.m33 * s;
return kProd;
}
///
/// Are these matrices equal.
///
public static bool operator ==(Matrix4x4f m1, Matrix4x4f m2)
{
if (m1.m00 != m2.m00) return false;
if (m1.m01 != m2.m01) return false;
if (m1.m02 != m2.m02) return false;
if (m1.m03 != m2.m03) return false;
if (m1.m10 != m2.m10) return false;
if (m1.m11 != m2.m11) return false;
if (m1.m12 != m2.m12) return false;
if (m1.m13 != m2.m13) return false;
if (m1.m20 != m2.m20) return false;
if (m1.m21 != m2.m21) return false;
if (m1.m22 != m2.m22) return false;
if (m1.m23 != m2.m23) return false;
if (m1.m30 != m2.m30) return false;
if (m1.m31 != m2.m31) return false;
if (m1.m32 != m2.m32) return false;
if (m1.m33 != m2.m33) return false;
return true;
}
///
/// Are these matrices not equal.
///
public static bool operator !=(Matrix4x4f m1, Matrix4x4f m2)
{
if (m1.m00 != m2.m00) return true;
if (m1.m01 != m2.m01) return true;
if (m1.m02 != m2.m02) return true;
if (m1.m03 != m2.m03) return true;
if (m1.m10 != m2.m10) return true;
if (m1.m11 != m2.m11) return true;
if (m1.m12 != m2.m12) return true;
if (m1.m13 != m2.m13) return true;
if (m1.m20 != m2.m20) return true;
if (m1.m21 != m2.m21) return true;
if (m1.m22 != m2.m22) return true;
if (m1.m23 != m2.m23) return true;
if (m1.m30 != m2.m30) return true;
if (m1.m31 != m2.m31) return true;
if (m1.m32 != m2.m32) return true;
return false;
}
///
/// Are these matrices equal.
///
public override bool Equals (object obj)
{
if(!(obj is Matrix4x4f)) return false;
Matrix4x4f mat = (Matrix4x4f)obj;
return this == mat;
}
///
/// Are these matrices equal.
///
public bool Equals (Matrix4x4f mat)
{
return this == mat;
}
///
/// Are these matrices equal.
///
public bool EqualsWithError(Matrix4x4f m, float eps)
{
if (Math.Abs(m00 - m.m00) > eps) return false;
if (Math.Abs(m10 - m.m10) > eps) return false;
if (Math.Abs(m20 - m.m20) > eps) return false;
if (Math.Abs(m30 - m.m30) > eps) return false;
if (Math.Abs(m01 - m.m01) > eps) return false;
if (Math.Abs(m11 - m.m11) > eps) return false;
if (Math.Abs(m21 - m.m21) > eps) return false;
if (Math.Abs(m31 - m.m31) > eps) return false;
if (Math.Abs(m02 - m.m02) > eps) return false;
if (Math.Abs(m12 - m.m12) > eps) return false;
if (Math.Abs(m22 - m.m22) > eps) return false;
if (Math.Abs(m32 - m.m32) > eps) return false;
if (Math.Abs(m03 - m.m03) > eps) return false;
if (Math.Abs(m13 - m.m13) > eps) return false;
if (Math.Abs(m23 - m.m23) > eps) return false;
if (Math.Abs(m33 - m.m33) > eps) return false;
return true;
}
///
/// Matrices hash code.
///
public override int GetHashCode()
{
int hash = 0;
for(int i = 0; i < 16; i++)
hash ^= this[i].GetHashCode();
return hash;
}
///
/// A matrix as a string.
///
public override string ToString()
{
return this[0, 0] + "," + this[0, 1] + "," + this[0, 2] + "," + this[0, 3] + "\n" +
this[1, 0] + "," + this[1, 1] + "," + this[1, 2] + "," + this[1, 3] + "\n" +
this[2, 0] + "," + this[2, 1] + "," + this[2, 2] + "," + this[2, 3] + "\n" +
this[3, 0] + "," + this[3, 1] + "," + this[3, 2] + "," + this[3, 3];
}
///
/// The minor of a matrix.
///
private float Minor(int r0, int r1, int r2, int c0, int c1, int c2)
{
return this[r0, c0] * (this[r1, c1] * this[r2, c2] - this[r2, c1] * this[r1, c2]) -
this[r0, c1] * (this[r1, c0] * this[r2, c2] - this[r2, c0] * this[r1, c2]) +
this[r0, c2] * (this[r1, c0] * this[r2, c1] - this[r2, c0] * this[r1, c1]);
}
///
/// The inverse of the matrix.
/// A matrix multipled by its inverse is the idenity.
///
public bool TryInverse(out Matrix4x4f mInv)
{
float det = Determinant;
if (FMath.IsZero(det))
{
mInv = Identity;
return false;
}
mInv = Adjoint * (1.0f / det);
return true;
}
///
/// Get the ith column as a vector.
///
public Vector4f GetColumn(int iCol)
{
return new Vector4f(this[0, iCol], this[1, iCol], this[2, iCol], this[3, iCol]);
}
///
/// Set the ith column from a vector.
///
public void SetColumn(int iCol, Vector4f v)
{
this[0, iCol] = v.x;
this[1, iCol] = v.y;
this[2, iCol] = v.z;
this[3, iCol] = v.w;
}
///
/// Flip the ith column.
///
public void FlipColumn(int iCol)
{
this[0, iCol] *= -1.0f;
this[1, iCol] *= -1.0f;
this[2, iCol] *= -1.0f;
this[3, iCol] *= -1.0f;
}
///
/// Get the ith row as a vector.
///
public Vector4f GetRow(int iRow)
{
return new Vector4f(this[iRow, 0], this[iRow, 1], this[iRow, 2], this[iRow, 3]);
}
///
/// Set the ith row from a vector.
///
public void SetRow(int iRow, Vector4f v)
{
this[iRow, 0] = v.x;
this[iRow, 1] = v.y;
this[iRow, 2] = v.z;
this[iRow, 3] = v.w;
}
///
/// Flip the ith row.
///
public void FlipRow(int iRow)
{
this[iRow, 0] *= -1.0f;
this[iRow, 1] *= -1.0f;
this[iRow, 2] *= -1.0f;
this[iRow, 3] *= -1.0f;
}
///
/// Convert to a 3 dimension matrix.
///
public Matrix3x3f ToMatrix3x3f()
{
Matrix3x3f mat = new Matrix3x3f();
mat.m00 = m00; mat.m01 = m01; mat.m02 = m02;
mat.m10 = m10; mat.m11 = m11; mat.m12 = m12;
mat.m20 = m20; mat.m21 = m21; mat.m22 = m22;
return mat;
}
///
/// Create a translation, rotation and scale.
///
static public Matrix4x4f TranslateRotateScale(Vector3f t, Quaternion3f r, Vector3f s)
{
Matrix4x4f T = Translate(t);
Matrix4x4f R = r.ToMatrix4x4f();
Matrix4x4f S = Scale(s);
return T * R * S;
}
///
/// Create a translation and rotation.
///
static public Matrix4x4f TranslateRotate(Vector3f t, Quaternion3f r)
{
Matrix4x4f T = Translate(t);
Matrix4x4f R = r.ToMatrix4x4f();
return T * R;
}
///
/// Create a translation and scale.
///
static public Matrix4x4f TranslateScale(Vector3f t, Vector3f s)
{
Matrix4x4f T = Translate(t);
Matrix4x4f S = Scale(s);
return T * S;
}
///
/// Create a rotation and scale.
///
static public Matrix4x4f RotateScale(Quaternion3f r, Vector3f s)
{
Matrix4x4f R = r.ToMatrix4x4f();
Matrix4x4f S = Scale(s);
return R * S;
}
///
/// Create a translation out of a vector.
///
static public Matrix4x4f Translate(Vector3f v)
{
return new Matrix4x4f( 1, 0, 0, v.x,
0, 1, 0, v.y,
0, 0, 1, v.z,
0, 0, 0, 1);
}
///
/// Create a scale out of a vector.
///
static public Matrix4x4f Scale(Vector3f v)
{
return new Matrix4x4f( v.x, 0, 0, 0,
0, v.y, 0, 0,
0, 0, v.z, 0,
0, 0, 0, 1);
}
///
/// Create a scale out of a vector.
///
static public Matrix4x4f Scale(float s)
{
return new Matrix4x4f(s, 0, 0, 0,
0, s, 0, 0,
0, 0, s, 0,
0, 0, 0, 1);
}
///
/// Create a rotation out of a angle.
///
static public Matrix4x4f RotateX(float angle)
{
float ca = (float)Math.Cos(angle * Math.PI / 180.0);
float sa = (float)Math.Sin(angle * Math.PI / 180.0);
return new Matrix4x4f( 1, 0, 0, 0,
0, ca, -sa, 0,
0, sa, ca, 0,
0, 0, 0, 1);
}
///
/// Create a rotation out of a angle.
///
static public Matrix4x4f RotateY(float angle)
{
float ca = (float)Math.Cos(angle * Math.PI / 180.0);
float sa = (float)Math.Sin(angle * Math.PI / 180.0);
return new Matrix4x4f( ca, 0, sa, 0,
0, 1, 0, 0,
-sa, 0, ca, 0,
0, 0, 0, 1);
}
///
/// Create a rotation out of a angle.
///
static public Matrix4x4f RotateZ(float angle)
{
float ca = (float)Math.Cos(angle * Math.PI / 180.0);
float sa = (float)Math.Sin(angle * Math.PI / 180.0);
return new Matrix4x4f( ca, -sa, 0, 0,
sa, ca, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1);
}
///
/// Create a rotation out of a vector.
///
static public Matrix4x4f Rotate(Vector3f euler)
{
return Quaternion3f.FromEuler(euler).ToMatrix4x4f();
}
///
/// Create a perspective matrix.
///
static public Matrix4x4f Perspective(float fovy, float aspect, float zNear, float zFar)
{
float f = 1.0f / (float)Math.Tan((fovy * Math.PI / 180.0) / 2.0);
return new Matrix4x4f( f / aspect, 0, 0, 0,
0, f, 0, 0,
0, 0, (zFar + zNear) / (zNear - zFar), (2.0f * zFar * zNear) / (zNear - zFar),
0, 0, -1, 0);
}
///
/// Create a ortho matrix.
///
static public Matrix4x4f Ortho(float xRight, float xLeft, float yTop, float yBottom, float zNear, float zFar)
{
float tx, ty, tz;
tx = -(xRight + xLeft) / (xRight - xLeft);
ty = -(yTop + yBottom) / (yTop - yBottom);
tz = -(zFar + zNear) / (zFar - zNear);
return new Matrix4x4f( 2.0f / (xRight - xLeft), 0, 0, tx,
0, 2.0f / (yTop - yBottom), 0, ty,
0, 0, -2.0f / (zFar - zNear), tz,
0, 0, 0, 1);
}
///
/// Creates the matrix need to look at target from position.
///
static public Matrix4x4f LookAt(Vector3f position, Vector3f target, Vector3f Up)
{
Vector3f zaxis = (position - target).Normalized;
Vector3f xaxis = Up.Cross(zaxis).Normalized;
Vector3f yaxis = zaxis.Cross(xaxis);
return new Matrix4x4f( xaxis.x, xaxis.y, xaxis.z, -Vector3f.Dot(xaxis, position),
yaxis.x, yaxis.y, yaxis.z, -Vector3f.Dot(yaxis, position),
zaxis.x, zaxis.y, zaxis.z, -Vector3f.Dot(zaxis, position),
0, 0, 0, 1);
}
}
}
================================================
FILE: Assets/Common/LinearAlgebra/Matrix4x4f.cs.meta
================================================
fileFormatVersion: 2
guid: b23ff530d822b7145adbcab5a4583011
timeCreated: 1514536270
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Common/LinearAlgebra/MatrixMxN.cs
================================================
using System;
using System.Collections.Generic;
using Common.Core.Mathematics;
namespace Common.Core.LinearAlgebra
{
public static class MatrixMxN
{
public static double[] MultiplyVector(double[,] matrix, double[] vector)
{
int M = matrix.GetLength(0);
int N = matrix.GetLength(1);
if (vector.Length != matrix.GetLength(1))
throw new ArgumentException("Matrix must have same number of columns as vectors length.");
double[] multiplied = new double[M];
for (int i = 0; i < M; i++)
{
double sum = 0.0;
for (int j = 0; j < N; j++)
{
sum += vector[j] * matrix[i, j];
}
multiplied[i] = sum;
}
return multiplied;
}
public static double[] MultiplyMatrix(double[] matrix1, double[,] matrix2)
{
int M = matrix1.Length;
int N = matrix2.GetLength(1);
if (matrix1.Length != matrix2.GetLength(0))
throw new ArgumentException("Matrix2 must have same number of rows as matrix1 has columns.");
double[] multiplied = new double[N];
for (int j = 0; j < N; j++)
{
double sum = 0.0;
for (int i = 0; i < M; i++)
{
sum += matrix1[i] * matrix2[i, j];
}
multiplied[j] = sum;
}
return multiplied;
}
public static double[,] MultiplyMatrix(double[,] matrix1, double[,] matrix2)
{
int M = matrix1.GetLength(0);
int N = matrix2.GetLength(1);
if (matrix1.GetLength(1) != matrix2.GetLength(0))
throw new ArgumentException("Matrix2 must have same number of rows as matrix1 has columns.");
double[,] multiplied = new double[M, N];
for (int i = 0; i < M; i++)
{
for (int j = 0; j < N; j++)
{
double sum = 0.0;
for (int k = 0; k < matrix1.GetLength(1); k++)
{
sum += matrix1[i, k] * matrix2[k, j];
}
multiplied[i, j] = sum;
}
}
return multiplied;
}
public static double[,] MultiplyScalar(double[,] matrix, double v)
{
int M = matrix.GetLength(0);
int N = matrix.GetLength(1);
double[,] multiplied = new double[M, N];
for (int i = 0; i < M; i++)
{
for (int j = 0; j < N; j++)
multiplied[i, j] = matrix[i, j] * v;
}
return multiplied;
}
public static double[,] Add(double[,] matrix1, double[,] matrix2)
{
int M = matrix1.GetLength(0);
int N = matrix1.GetLength(1);
if (M != matrix2.GetLength(0) || N != matrix2.GetLength(1))
throw new ArgumentException("Two matrices should be the same dimension to add.");
double[,] sum = new double[M, N];
for (int i = 0; i < M; i++)
{
for (int j = 0; j < N; j++)
sum[i, j] = matrix1[i, j] + matrix2[i, j];
}
return sum;
}
public static double[,] Subtract(double[,] matrix1, double[,] matrix2)
{
int M = matrix1.GetLength(0);
int N = matrix1.GetLength(1);
if (M != matrix2.GetLength(0) || N != matrix2.GetLength(1))
throw new ArgumentException("Two matrices should be the same dimension.");
double[,] sum = new double[M, N];
for (int i = 0; i < M; i++)
{
for (int j = 0; j < N; j++)
sum[i, j] = matrix1[i, j] - matrix2[i, j];
}
return sum;
}
public static double[,] Transpose(double[,] matrix)
{
int M = matrix.GetLength(0);
int N = matrix.GetLength(1);
double[,] transposed = new double[N, M];
for (int i = 0; i < M; i++)
{
for (int j = 0; j < N; j++)
{
transposed[j, i] = matrix[i, j];
}
}
return transposed;
}
public static double[,] Inverse(double[,] matrix)
{
return MultiplyScalar(Transpose(Cofactor(matrix)), DMath.SafeInv(Determinant(matrix)));
}
public static double Determinant(double[,] matrix)
{
int M = matrix.GetLength(0);
int N = matrix.GetLength(1);
if (N != M)
throw new ArgumentException("Matrix need to be square to find determinant.");
if (M == 1)
return matrix[0, 0];
if (M == 2)
return matrix[0, 0] * matrix[1, 1] - matrix[0, 1] * matrix[1, 0];
double sum = 0.0;
for (int i = 0; i < N; i++)
sum += ChangeSign(i) * matrix[0, i] * Determinant(SubMatrix(matrix, 0, i));
return sum;
}
public static double[,] Cofactor(double[,] matrix)
{
int M = matrix.GetLength(0);
int N = matrix.GetLength(1);
double[,] mat = new double[M, N];
for (int i = 0; i < M; i++)
{
for (int j = 0; j < N; j++)
{
mat[i, j] = ChangeSign(i) * ChangeSign(j) * Determinant(SubMatrix(matrix, i, j));
}
}
return mat;
}
public static double[,] SubMatrix(double[,] matrix, int excluding_row, int excluding_col)
{
int M = matrix.GetLength(0);
int N = matrix.GetLength(1);
double[,] mat = new double[M - 1, N - 1];
int r = -1;
for (int i = 0; i < M; i++)
{
if (i == excluding_row)
continue;
r++;
int c = -1;
for (int j = 0; j < N; j++)
{
if (j == excluding_col)
continue;
mat[r, ++c] = matrix[i, j];
}
}
return mat;
}
private static int ChangeSign(int i)
{
if (i % 2 == 0)
return 1;
return -1;
}
}
}
================================================
FILE: Assets/Common/LinearAlgebra/MatrixMxN.cs.meta
================================================
fileFormatVersion: 2
guid: d64ab62afd178ca4f9b734695ee8f4e6
timeCreated: 1514536270
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Common/LinearAlgebra/Quaternion3d.cs
================================================
using System;
using System.Runtime.InteropServices;
using Common.Core.Mathematics;
namespace Common.Core.LinearAlgebra
{
///
/// A double precision quaternion.
///
[StructLayout(LayoutKind.Sequential)]
public struct Quaternion3d
{
public double x, y, z, w;
public readonly static Quaternion3d Identity = new Quaternion3d(0, 0, 0, 1);
public readonly static Quaternion3d Zero = new Quaternion3d(0, 0, 0, 0);
///
/// A Quaternion from varibles.
///
public Quaternion3d(double x, double y, double z, double w)
{
this.x = x;
this.y = y;
this.z = z;
this.w = w;
}
///
/// A Quaternion copied from a array.
///
public Quaternion3d(double[] v)
{
this.x = v[0];
this.y = v[1];
this.z = v[2];
this.w = v[3];
}
///
/// The inverse of the quaternion.
///
public Quaternion3d Inverse
{
get
{
return new Quaternion3d(-x, -y, -z, w);
}
}
///
/// The length of the quaternion.
///
double Length
{
get
{
double len = x * x + y * y + z * z + w * w;
return DMath.SafeSqrt(len);
}
}
///
/// The a normalized quaternion.
///
public Quaternion3d Normalized
{
get
{
double inv = DMath.SafeInv(Length);
return new Quaternion3d(x * inv, y * inv, z * inv, w * inv);
}
}
///
/// Are these Quaternions equal.
///
public static bool operator ==(Quaternion3d v1, Quaternion3d v2)
{
return (v1.x == v2.x && v1.y == v2.y && v1.z == v2.z && v1.w == v2.w);
}
///
/// Are these Quaternions not equal.
///
public static bool operator !=(Quaternion3d v1, Quaternion3d v2)
{
return (v1.x != v2.x || v1.y != v2.y || v1.z != v2.z || v1.w != v2.w);
}
///
/// Are these Quaternions equal.
///
public override bool Equals (object obj)
{
if(!(obj is Quaternion3d)) return false;
Quaternion3d v = (Quaternion3d)obj;
return this == v;
}
///
/// Quaternions hash code.
///
public override int GetHashCode()
{
double hashcode = 23;
hashcode = (hashcode * 37) + x;
hashcode = (hashcode * 37) + y;
hashcode = (hashcode * 37) + z;
hashcode = (hashcode * 37) + w;
return unchecked((int)hashcode);
}
///
/// Quaternion as a string.
///
public override string ToString()
{
return "(" + x + "," + y + "," + z + "," + w + ")";
}
///
/// A Quaternion from a vector axis and angle.
/// The axis is the up direction and the angle is the rotation.
///
public Quaternion3d(Vector3d axis, double angle)
{
Vector3d axisN = axis.Normalized;
double a = angle * 0.5;
double sina = Math.Sin(a);
double cosa = Math.Cos(a);
x = axisN.x * sina;
y = axisN.y * sina;
z = axisN.z * sina;
w = cosa;
}
///
/// A quaternion with the rotation required to
/// rotation from the from direction to the to direction.
///
public Quaternion3d(Vector3d to, Vector3d from)
{
Vector3d f = from.Normalized;
Vector3d t = to.Normalized;
double dotProdPlus1 = 1.0 + Vector3d.Dot(f, t);
if (dotProdPlus1 < DMath.EPS)
{
w = 0;
if (Math.Abs(f.x) < 0.6)
{
double norm = Math.Sqrt(1 - f.x * f.x);
x = 0;
y = f.z / norm;
z = -f.y / norm;
}
else if (Math.Abs(f.y) < 0.6)
{
double norm = Math.Sqrt(1 - f.y * f.y);
x = -f.z / norm;
y = 0;
z = f.x / norm;
}
else
{
double norm = Math.Sqrt(1 - f.z * f.z);
x = f.y / norm;
y = -f.x / norm;
z = 0;
}
}
else
{
double s = Math.Sqrt(0.5 * dotProdPlus1);
Vector3d tmp = (f.Cross(t)) / (2.0 * s);
x = tmp.x;
y = tmp.y;
z = tmp.z;
w = s;
}
}
///
/// Multiply two quaternions together.
///
public static Quaternion3d operator*( Quaternion3d q1, Quaternion3d q2 )
{
return new Quaternion3d(q2.w * q1.x + q2.x * q1.w + q2.y * q1.z - q2.z * q1.y,
q2.w * q1.y - q2.x * q1.z + q2.y * q1.w + q2.z * q1.x,
q2.w * q1.z + q2.x * q1.y - q2.y * q1.x + q2.z * q1.w,
q2.w * q1.w - q2.x * q1.x - q2.y * q1.y - q2.z * q1.z);
}
///
/// Multiply a quaternion and a vector together.
///
public static Vector3d operator*(Quaternion3d q, Vector3d v)
{
return q.ToMatrix3x3d() * v;
}
///
/// Convert to a double precision 3 dimension matrix.
///
public Matrix3x3d ToMatrix3x3d()
{
double xx = x * x,
xy = x * y,
xz = x * z,
xw = x * w,
yy = y * y,
yz = y * z,
yw = y * w,
zz = z * z,
zw = z * w;
return new Matrix3x3d
(
1.0 - 2.0 * (yy + zz), 2.0 * (xy - zw), 2.0 * (xz + yw),
2.0 * (xy + zw), 1.0 - 2.0 * (xx + zz), 2.0 * (yz - xw),
2.0 * (xz - yw), 2.0 * (yz + xw), 1.0 - 2.0 * (xx + yy)
);
}
///
/// Convert to a double precision 4 dimension matrix.
///
public Matrix4x4d ToMatrix4x4d()
{
double xx = x * x,
xy = x * y,
xz = x * z,
xw = x * w,
yy = y * y,
yz = y * z,
yw = y * w,
zz = z * z,
zw = z * w;
return new Matrix4x4d
(
1.0 - 2.0 * (yy + zz), 2.0 * (xy - zw), 2.0 * (xz + yw), 0.0,
2.0 * (xy + zw), 1.0 - 2.0 * (xx + zz), 2.0 * (yz - xw), 0.0,
2.0 * (xz - yw), 2.0 * (yz + xw), 1.0 - 2.0 * (xx + yy), 0.0,
0.0, 0.0, 0.0, 1.0
);
}
///
/// The normalize the quaternion.
///
public void Normalize()
{
double invLength = DMath.SafeInv(Length);
x *= invLength;
y *= invLength;
z *= invLength;
w *= invLength;
}
///
/// Slerp the quaternion by t.
///
public static Quaternion3d Slerp(Quaternion3d from, Quaternion3d to, double t)
{
if (t <= 0.0)
{
return from;
}
else if (t >= 1.0)
{
return to;
}
else
{
double cosom = from.x * to.x + from.y * to.y + from.z * to.z + from.w * to.w;
double absCosom = Math.Abs(cosom);
double scale0;
double scale1;
if (1.0 - absCosom > DMath.EPS)
{
double omega = DMath.SafeAcos(absCosom);
double sinom = 1.0 / Math.Sin( omega );
scale0 = Math.Sin( ( 1.0 - t ) * omega ) * sinom;
scale1 = Math.Sin( t * omega ) * sinom;
}
else
{
scale0 = 1.0 - t;
scale1 = t;
}
Quaternion3d res = new Quaternion3d(scale0 * from.x + scale1 * to.x,
scale0 * from.y + scale1 * to.y,
scale0 * from.z + scale1 * to.z,
scale0 * from.w + scale1 * to.w);
return res.Normalized;
}
}
///
/// Create a rotation out of a vector.
///
public static Quaternion3d FromEuler(Vector3d euler)
{
double degToRad = Math.PI / 180.0;
double yaw = euler.x * degToRad;
double pitch = euler.y * degToRad;
double roll = euler.z * degToRad;
double rollOver2 = roll * 0.5;
double sinRollOver2 = Math.Sin(rollOver2);
double cosRollOver2 = Math.Cos(rollOver2);
double pitchOver2 = pitch * 0.5;
double sinPitchOver2 = Math.Sin(pitchOver2);
double cosPitchOver2 = Math.Cos(pitchOver2);
double yawOver2 = yaw * 0.5;
double sinYawOver2 = Math.Sin(yawOver2);
double cosYawOver2 = Math.Cos(yawOver2);
Quaternion3d result;
result.x = cosYawOver2 * cosPitchOver2 * cosRollOver2 + sinYawOver2 * sinPitchOver2 * sinRollOver2;
result.y = cosYawOver2 * cosPitchOver2 * sinRollOver2 - sinYawOver2 * sinPitchOver2 * cosRollOver2;
result.z = cosYawOver2 * sinPitchOver2 * cosRollOver2 + sinYawOver2 * cosPitchOver2 * sinRollOver2;
result.w = sinYawOver2 * cosPitchOver2 * cosRollOver2 - cosYawOver2 * sinPitchOver2 * sinRollOver2;
return result;
}
}
}
================================================
FILE: Assets/Common/LinearAlgebra/Quaternion3d.cs.meta
================================================
fileFormatVersion: 2
guid: c2b4193eee97e4649ad3948f8e99a317
timeCreated: 1514536270
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Common/LinearAlgebra/Quaternion3f.cs
================================================
using System;
using System.Runtime.InteropServices;
using Common.Core.Mathematics;
namespace Common.Core.LinearAlgebra
{
///
/// A single precision quaternion.
///
[StructLayout(LayoutKind.Sequential)]
public struct Quaternion3f
{
public float x, y, z, w;
public readonly static Quaternion3f Identity = new Quaternion3f(0, 0, 0, 1);
public readonly static Quaternion3f Zero = new Quaternion3f(0, 0, 0, 0);
///
/// A Quaternion from varibles.
///
public Quaternion3f(float x, float y, float z, float w)
{
this.x = x;
this.y = y;
this.z = z;
this.w = w;
}
///
/// A Quaternion copied from a array.
///
public Quaternion3f(float[] v)
{
this.x = v[0];
this.y = v[1];
this.z = v[2];
this.w = v[3];
}
///
/// The inverse of the quaternion.
///
public Quaternion3f Inverse
{
get
{
return new Quaternion3f(-x, -y, -z, w);
}
}
///
/// The length of the quaternion.
///
float Length
{
get
{
float len = x * x + y * y + z * z + w * w;
return FMath.SafeSqrt(len);
}
}
///
/// The a normalized quaternion.
///
public Quaternion3f Normalized
{
get
{
float inv = FMath.SafeInv(Length);
return new Quaternion3f(x * inv, y * inv, z * inv, w * inv);
}
}
///
/// Are these Quaternions equal.
///
public static bool operator ==(Quaternion3f v1, Quaternion3f v2)
{
return (v1.x == v2.x && v1.y == v2.y && v1.z == v2.z && v1.w == v2.w);
}
///
/// Are these Quaternions not equal.
///
public static bool operator !=(Quaternion3f v1, Quaternion3f v2)
{
return (v1.x != v2.x || v1.y != v2.y || v1.z != v2.z || v1.w != v2.w);
}
///
/// Are these Quaternions equal.
///
public override bool Equals (object obj)
{
if(!(obj is Quaternion3f)) return false;
Quaternion3f v = (Quaternion3f)obj;
return this == v;
}
///
/// Quaternions hash code.
///
public override int GetHashCode()
{
float hashcode = 23;
hashcode = (hashcode * 37) + x;
hashcode = (hashcode * 37) + y;
hashcode = (hashcode * 37) + z;
hashcode = (hashcode * 37) + w;
return unchecked((int)hashcode);
}
///
/// Quaternion as a string.
///
public override string ToString()
{
return "(" + x + "," + y + "," + z + "," + w + ")";
}
///
/// A Quaternion from a vector axis and angle.
/// The axis is the up direction and the angle is the rotation.
///
public Quaternion3f(Vector3f axis, float angle)
{
Vector3f axisN = axis.Normalized;
float a = angle * 0.5f;
float sina = (float)Math.Sin(a);
float cosa = (float)Math.Cos(a);
x = axisN.x * sina;
y = axisN.y * sina;
z = axisN.z * sina;
w = cosa;
}
///
/// A quaternion with the rotation required to
/// rotation from the from direction to the to direction.
///
public Quaternion3f(Vector3f to, Vector3f from)
{
Vector3f f = from.Normalized;
Vector3f t = to.Normalized;
float dotProdPlus1 = 1.0f + Vector3f.Dot(f, t);
if (dotProdPlus1 < FMath.EPS)
{
w = 0;
if (Math.Abs(f.x) < 0.6f)
{
float norm = (float)Math.Sqrt(1 - f.x * f.x);
x = 0;
y = f.z / norm;
z = -f.y / norm;
}
else if (Math.Abs(f.y) < 0.6f)
{
float norm = (float)Math.Sqrt(1 - f.y * f.y);
x = -f.z / norm;
y = 0;
z = f.x / norm;
}
else
{
float norm = (float)Math.Sqrt(1 - f.z * f.z);
x = f.y / norm;
y = -f.x / norm;
z = 0;
}
}
else
{
float s = (float)Math.Sqrt(0.5f * dotProdPlus1);
Vector3f tmp = (f.Cross(t)) / (2.0f * s);
x = tmp.x;
y = tmp.y;
z = tmp.z;
w = s;
}
}
///
/// Multiply two quternions together.
///
public static Quaternion3f operator *(Quaternion3f q1, Quaternion3f q2)
{
return new Quaternion3f(q2.w * q1.x + q2.x * q1.w + q2.y * q1.z - q2.z * q1.y,
q2.w * q1.y - q2.x * q1.z + q2.y * q1.w + q2.z * q1.x,
q2.w * q1.z + q2.x * q1.y - q2.y * q1.x + q2.z * q1.w,
q2.w * q1.w - q2.x * q1.x - q2.y * q1.y - q2.z * q1.z);
}
///
/// Multiply a quaternion and a vector together.
///
public static Vector3f operator *(Quaternion3f q, Vector3f v)
{
return q.ToMatrix3x3f() * v;
}
///
/// Convert to a single precision 3 dimension matrix.
///
public Matrix3x3f ToMatrix3x3f()
{
float xx = x * x,
xy = x * y,
xz = x * z,
xw = x * w,
yy = y * y,
yz = y * z,
yw = y * w,
zz = z * z,
zw = z * w;
return new Matrix3x3f
(
1.0f - 2.0f * (yy + zz), 2.0f * (xy - zw), 2.0f * (xz + yw),
2.0f * (xy + zw), 1.0f - 2.0f * (xx + zz), 2.0f * (yz - xw),
2.0f * (xz - yw), 2.0f * (yz + xw), 1.0f - 2.0f * (xx + yy)
);
}
///
/// Convert to a single precision 4 dimension matrix.
///
public Matrix4x4f ToMatrix4x4f()
{
float xx = x * x,
xy = x * y,
xz = x * z,
xw = x * w,
yy = y * y,
yz = y * z,
yw = y * w,
zz = z * z,
zw = z * w;
return new Matrix4x4f
(
1.0f - 2.0f * (yy + zz), 2.0f * (xy - zw), 2.0f * (xz + yw), 0.0f,
2.0f * (xy + zw), 1.0f - 2.0f * (xx + zz), 2.0f * (yz - xw), 0.0f,
2.0f * (xz - yw), 2.0f * (yz + xw), 1.0f - 2.0f * (xx + yy), 0.0f,
0.0f, 0.0f, 0.0f, 1.0f
);
}
///
/// The normalize the quaternion.
///
public void Normalize()
{
float invLength = FMath.SafeInv(Length);
x *= invLength;
y *= invLength;
z *= invLength;
w *= invLength;
}
///
/// Slerp the quaternion from the from rotation to the to rotation by t.
///
public static Quaternion3f Slerp(Quaternion3f from, Quaternion3f to, float t)
{
if (t <= 0.0f)
{
return from;
}
else if (t >= 1.0f)
{
return to;
}
else
{
float cosom = from.x * to.x + from.y * to.y + from.z * to.z + from.w * to.w;
float absCosom = Math.Abs(cosom);
float scale0;
float scale1;
if ((1 - absCosom) > FMath.EPS)
{
float omega = FMath.SafeAcos(absCosom);
float sinom = 1.0f / (float)Math.Sin(omega);
scale0 = (float)Math.Sin((1.0f - t) * omega) * sinom;
scale1 = (float)Math.Sin(t * omega) * sinom;
}
else
{
scale0 = 1 - t;
scale1 = t;
}
Quaternion3f res = new Quaternion3f(scale0 * from.x + scale1 * to.x,
scale0 * from.y + scale1 * to.y,
scale0 * from.z + scale1 * to.z,
scale0 * from.w + scale1 * to.w);
return res.Normalized;
}
}
///
/// Create a rotation out of a vector.
///
public static Quaternion3f FromEuler(Vector3f euler)
{
float degToRad = (float)(Math.PI / 180.0);
var yaw = euler.x * degToRad;
var pitch = euler.y * degToRad;
var roll = euler.z * degToRad;
float rollOver2 = roll * 0.5f;
float sinRollOver2 = (float)Math.Sin(rollOver2);
float cosRollOver2 = (float)Math.Cos(rollOver2);
float pitchOver2 = pitch * 0.5f;
float sinPitchOver2 = (float)Math.Sin(pitchOver2);
float cosPitchOver2 = (float)Math.Cos(pitchOver2);
float yawOver2 = yaw * 0.5f;
float sinYawOver2 = (float)Math.Sin(yawOver2);
float cosYawOver2 = (float)Math.Cos(yawOver2);
Quaternion3f result;
result.x = cosYawOver2 * cosPitchOver2 * cosRollOver2 + sinYawOver2 * sinPitchOver2 * sinRollOver2;
result.y = cosYawOver2 * cosPitchOver2 * sinRollOver2 - sinYawOver2 * sinPitchOver2 * cosRollOver2;
result.z = cosYawOver2 * sinPitchOver2 * cosRollOver2 + sinYawOver2 * cosPitchOver2 * sinRollOver2;
result.w = sinYawOver2 * cosPitchOver2 * cosRollOver2 - cosYawOver2 * sinPitchOver2 * sinRollOver2;
return result;
}
}
}
================================================
FILE: Assets/Common/LinearAlgebra/Quaternion3f.cs.meta
================================================
fileFormatVersion: 2
guid: da6fc536acb153944a010e07ae652bf9
timeCreated: 1514536271
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Common/LinearAlgebra/Vector2d.cs
================================================
using System;
using System.Collections;
using System.Runtime.InteropServices;
using Common.Core.Mathematics;
namespace Common.Core.LinearAlgebra
{
///
/// A 2d double precision vector.
///
[StructLayout(LayoutKind.Sequential)]
public struct Vector2d
{
public double x, y;
///
/// The unit x vector.
///
public readonly static Vector2d UnitX = new Vector2d(1, 0);
///
/// The unit y vector.
///
public readonly static Vector2d UnitY = new Vector2d(0, 1);
///
/// A vector of zeros.
///
public readonly static Vector2d Zero = new Vector2d(0);
///
/// A vector of ones.
///
public readonly static Vector2d One = new Vector2d(1);
///
/// A vector of positive infinity.
///
public readonly static Vector2d PositiveInfinity = new Vector2d(double.PositiveInfinity);
///
/// A vector of negative infinity.
///
public readonly static Vector2d NegativeInfinity = new Vector2d(double.NegativeInfinity);
///
/// Convert to a 3 dimension vector.
///
public Vector3d x0z
{
get { return new Vector3d(x, 0, y); }
}
///
/// A vector all with the value v.
///
public Vector2d(double v)
{
this.x = v;
this.y = v;
}
///
/// A vector from the varibles.
///
public Vector2d(double x, double y)
{
this.x = x;
this.y = y;
}
public double this[int i]
{
get
{
switch (i)
{
case 0: return x;
case 1: return y;
default: throw new IndexOutOfRangeException("Vector2d index out of range: " + i);
}
}
set
{
switch (i)
{
case 0: x = value; break;
case 1: y = value; break;
default: throw new IndexOutOfRangeException("Vector2d index out of range: " + i);
}
}
}
///
/// The length of the vector.
///
public double Magnitude
{
get
{
return DMath.SafeSqrt(SqrMagnitude);
}
}
///
/// The length of the vector squared.
///
public double SqrMagnitude
{
get
{
return (x * x + y * y);
}
}
///
/// The vector normalized.
///
public Vector2d Normalized
{
get
{
double invLength = DMath.SafeInvSqrt(1.0, x * x + y * y);
return new Vector2d(x * invLength, y * invLength);
}
}
///
/// Counter clock-wise perpendicular.
///
public Vector2d PerpendicularCCW
{
get
{
return new Vector2d(-y, x);
}
}
///
/// Clock-wise perpendicular.
///
public Vector2d PerpendicularCW
{
get
{
return new Vector2d(y, -x);
}
}
///
/// The vectors absolute values.
///
public Vector2d Absolute
{
get
{
return new Vector2d(Math.Abs(x), Math.Abs(y));
}
}
///
/// Add two vectors.
///
public static Vector2d operator +(Vector2d v1, Vector2d v2)
{
return new Vector2d(v1.x + v2.x, v1.y + v2.y);
}
///
/// Add vector and scalar.
///
public static Vector2d operator +(Vector2d v1, double s)
{
return new Vector2d(v1.x + s, v1.y + s);
}
///
/// Add vector and scalar.
///
public static Vector2d operator +(double s, Vector2d v1)
{
return new Vector2d(v1.x + s, v1.y + s);
}
///
/// Subtract two vectors.
///
public static Vector2d operator -(Vector2d v1, Vector2d v2)
{
return new Vector2d(v1.x - v2.x, v1.y - v2.y);
}
///
/// Subtract vector and scalar.
///
public static Vector2d operator -(Vector2d v1, double s)
{
return new Vector2d(v1.x - s, v1.y - s);
}
///
/// Subtract vector and scalar.
///
public static Vector2d operator -(double s, Vector2d v1)
{
return new Vector2d(v1.x - s, v1.y - s);
}
///
/// Multiply two vectors.
///
public static Vector2d operator *(Vector2d v1, Vector2d v2)
{
return new Vector2d(v1.x * v2.x, v1.y * v2.y);
}
///
/// Multiply a vector and a scalar.
///
public static Vector2d operator *(Vector2d v, double s)
{
return new Vector2d(v.x * s, v.y * s);
}
///
/// Multiply a vector and a scalar.
///
public static Vector2d operator *(double s, Vector2d v)
{
return new Vector2d(v.x * s, v.y * s);
}
///
/// Divide two vectors.
///
public static Vector2d operator /(Vector2d v1, Vector2d v2)
{
return new Vector2d(v1.x / v2.x, v1.y / v2.y);
}
///
/// Divide a vector and a scalar.
///
public static Vector2d operator /(Vector2d v, double s)
{
return new Vector2d(v.x / s, v.y / s);
}
///
/// Are these vectors equal.
///
public static bool operator ==(Vector2d v1, Vector2d v2)
{
return (v1.x == v2.x && v1.y == v2.y);
}
///
/// Are these vectors not equal.
///
public static bool operator !=(Vector2d v1, Vector2d v2)
{
return (v1.x != v2.x || v1.y != v2.y);
}
///
/// Are these vectors equal.
///
public override bool Equals (object obj)
{
if(!(obj is Vector2d)) return false;
Vector2d v = (Vector2d)obj;
return this == v;
}
///
/// Are these vectors equal given the error.
///
public bool EqualsWithError(Vector2d v, double eps)
{
if(Math.Abs(x-v.x)> eps) return false;
if(Math.Abs(y-v.y)> eps) return false;
return true;
}
///
/// Are these vectors equal.
///
public bool Equals(Vector2d v)
{
return this == v;
}
///
/// Vectors hash code.
///
public override int GetHashCode()
{
double hashcode = 23;
hashcode = (hashcode * 37) + x;
hashcode = (hashcode * 37) + y;
return unchecked((int)hashcode);
}
///
/// Vector as a string.
///
public override string ToString()
{
return x + "," + y;
}
///
/// Vector from a string.
///
static public Vector2d FromString(string s)
{
Vector2d v = new Vector2d();
try
{
string[] separators = new string[] { "," };
string[] result = s.Split(separators, StringSplitOptions.None);
v.x = double.Parse(result[0]);
v.y = double.Parse(result[1]);
}
catch { }
return v;
}
///
/// The dot product of two vectors.
///
public static double Dot(Vector2d v0, Vector2d v1)
{
return (v0.x*v1.x + v0.y*v1.y);
}
///
/// Normalize the vector.
///
public void Normalize()
{
double invLength = DMath.SafeInvSqrt(1.0, x*x + y*y);
x *= invLength;
y *= invLength;
}
///
/// Cross two vectors.
///
public static double Cross(Vector2d v0, Vector2d v1)
{
return v0.x * v1.y - v0.y * v1.x;
}
///
/// Distance between two vectors.
///
public static double Distance(Vector2d v0, Vector2d v1)
{
return DMath.SafeSqrt(SqrDistance(v0, v1));
}
///
/// Square distance between two vectors.
///
public static double SqrDistance(Vector2d v0, Vector2d v1)
{
double x = v0.x - v1.x;
double y = v0.y - v1.y;
return x * x + y * y;
}
///
/// Angle between two vectors in degrees from 180 to -180.
///
public static double Angle180(Vector2d a, Vector2d b)
{
double m = a.Magnitude * b.Magnitude;
if (m == 0.0) return 0;
double angle = Dot(a, b) / m;
return DMath.SafeAcos(angle) * DMath.Rad2Deg;
}
///
/// Angle between two vectors in degrees from 0 to 360;
///
public static double AngleCCW(Vector2d a, Vector2d b)
{
double angle = Math.Atan2(a.y, a.x) - Math.Atan2(b.y, b.x);
if (angle <= 0.0)
angle = Math.PI * 2.0 + angle;
return 360.0 - angle * DMath.Rad2Deg;
}
///
/// The minimum value between s and each component in vector.
///
public void Min(double s)
{
x = Math.Min(x, s);
y = Math.Min(y, s);
}
///
/// The minimum value between each component in vectors.
///
public void Min(Vector2d v)
{
x = Math.Min(x, v.x);
y = Math.Min(y, v.y);
}
///
/// The maximum value between s and each component in vector.
///
public void Max(double s)
{
x = Math.Max(x, s);
y = Math.Max(y, s);
}
///
/// The maximum value between each component in vectors.
///
public void Max(Vector2d v)
{
x = Math.Max(x, v.x);
y = Math.Max(y, v.y);
}
///
/// The absolute vector.
///
public void Abs()
{
x = Math.Abs(x);
y = Math.Abs(y);
}
///
/// Clamp the each component to specified min and max.
///
public void Clamp(double min, double max)
{
x = Math.Max(Math.Min(x, max), min);
y = Math.Max(Math.Min(y, max), min);
}
///
/// Clamp the each component to specified min and max.
///
public void Clamp(Vector2d min, Vector2d max)
{
x = Math.Max(Math.Min(x, max.x), min.x);
y = Math.Max(Math.Min(y, max.y), min.y);
}
///
/// Lerp between two vectors.
///
public static Vector2d Lerp(Vector2d from, Vector2d to, double t)
{
if (t < 0.0) t = 0.0;
if (t > 1.0) t = 1.0;
if (t == 0.0) return from;
if (t == 1.0) return to;
double t1 = 1.0 - t;
Vector2d v = new Vector2d();
v.x = from.x * t1 + to.x * t;
v.y = from.y * t1 + to.y * t;
return v;
}
///
/// Slerp between two vectors arc.
///
public static Vector2d Slerp(Vector2d from, Vector2d to, double t)
{
if (t < 0.0) t = 0.0;
if (t > 1.0) t = 1.0;
if (t == 0.0) return from;
if (t == 1.0) return to;
if (to.x == from.x && to.y == from.y) return to;
double m = from.Magnitude * to.Magnitude;
if (DMath.IsZero(m)) return Vector2d.Zero;
double theta = Math.Acos(Dot(from, to) / m);
if (theta == 0.0) return to;
double sinTheta = Math.Sin(theta);
double st1 = Math.Sin((1.0 - t) * theta) / sinTheta;
double st = Math.Sin(t * theta) / sinTheta;
Vector2d v = new Vector2d();
v.x = from.x * st1 + to.x * st;
v.y = from.y * st1 + to.y * st;
return v;
}
}
}
================================================
FILE: Assets/Common/LinearAlgebra/Vector2d.cs.meta
================================================
fileFormatVersion: 2
guid: c1b7dd742e9f9aa49957980a1f94d794
timeCreated: 1514536270
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Common/LinearAlgebra/Vector2f.cs
================================================
using System;
using System.Collections;
using System.Runtime.InteropServices;
using Common.Core.Mathematics;
namespace Common.Core.LinearAlgebra
{
///
/// A 2d single precision vector.
///
[StructLayout(LayoutKind.Sequential)]
public struct Vector2f
{
public float x, y;
///
/// The unit x vector.
///
public readonly static Vector2f UnitX = new Vector2f(1, 0);
///
/// The unit y vector.
///
public readonly static Vector2f UnitY = new Vector2f(0, 1);
///
/// A vector of zeros.
///
public readonly static Vector2f Zero = new Vector2f(0);
///
/// A vector of ones.
///
public readonly static Vector2f One = new Vector2f(1);
///
/// A vector of positive infinity.
///
public readonly static Vector2f PositiveInfinity = new Vector2f(float.PositiveInfinity);
///
/// A vector of negative infinity.
///
public readonly static Vector2f NegativeInfinity = new Vector2f(float.NegativeInfinity);
///
/// Convert to a 3 dimension vector.
///
public Vector3f x0z
{
get { return new Vector3f(x, 0, y); }
}
///
/// A vector all with the value v.
///
public Vector2f(float v)
{
this.x = v;
this.y = v;
}
///
/// A vector from the varibles.
///
public Vector2f(float x, float y)
{
this.x = x;
this.y = y;
}
public float this[int i]
{
get
{
switch (i)
{
case 0: return x;
case 1: return y;
default: throw new IndexOutOfRangeException("Vector2f index out of range: " + i);
}
}
set
{
switch (i)
{
case 0: x = value; break;
case 1: y = value; break;
default: throw new IndexOutOfRangeException("Vector2f index out of range: " + i);
}
}
}
///
/// The length of the vector.
///
public float Magnitude
{
get
{
return FMath.SafeSqrt(SqrMagnitude);
}
}
///
/// The length of the vector squared.
///
public float SqrMagnitude
{
get
{
return (x * x + y * y);
}
}
///
/// The vector normalized.
///
public Vector2f Normalized
{
get
{
float invLength = FMath.SafeInvSqrt(1.0f, x * x + y * y);
return new Vector2f(x * invLength, y * invLength);
}
}
///
/// Counter clock-wise perpendicular.
///
public Vector2f PerpendicularCCW
{
get
{
return new Vector2f(-y, x);
}
}
///
/// Clock-wise perpendicular.
///
public Vector2f PerpendicularCW
{
get
{
return new Vector2f(y, -x);
}
}
///
/// The vectors absolute values.
///
public Vector2f Absolute
{
get
{
return new Vector2f(Math.Abs(x), Math.Abs(y));
}
}
///
/// Add two vectors.
///
public static Vector2f operator +(Vector2f v1, Vector2f v2)
{
return new Vector2f(v1.x + v2.x, v1.y + v2.y);
}
///
/// Add vector and scalar.
///
public static Vector2f operator +(Vector2f v1, float s)
{
return new Vector2f(v1.x + s, v1.y + s);
}
///
/// Add vector and scalar.
///
public static Vector2f operator +(float s, Vector2f v1)
{
return new Vector2f(v1.x + s, v1.y + s);
}
///
/// Subtract two vectors.
///
public static Vector2f operator -(Vector2f v1, Vector2f v2)
{
return new Vector2f(v1.x - v2.x, v1.y - v2.y);
}
///
/// Subtract vector and scalar.
///
public static Vector2f operator -(Vector2f v1, float s)
{
return new Vector2f(v1.x - s, v1.y - s);
}
///
/// Subtract vector and scalar.
///
public static Vector2f operator -(float s, Vector2f v1)
{
return new Vector2f(v1.x - s, v1.y - s);
}
///
/// Multiply two vectors.
///
public static Vector2f operator *(Vector2f v1, Vector2f v2)
{
return new Vector2f(v1.x * v2.x, v1.y * v2.y);
}
///
/// Multiply a vector and a scalar.
///
public static Vector2f operator *(Vector2f v, float s)
{
return new Vector2f(v.x * s, v.y * s);
}
///
/// Multiply a vector and a scalar.
///
public static Vector2f operator *(float s, Vector2f v)
{
return new Vector2f(v.x * s, v.y * s);
}
///
/// Divide two vectors.
///
public static Vector2f operator /(Vector2f v1, Vector2f v2)
{
return new Vector2f(v1.x / v2.x, v1.y / v2.y);
}
///
/// Divide a vector and a scalar.
///
public static Vector2f operator /(Vector2f v, float s)
{
return new Vector2f(v.x / s, v.y / s);
}
///
/// Are these vectors equal.
///
public static bool operator ==(Vector2f v1, Vector2f v2)
{
return (v1.x == v2.x && v1.y == v2.y);
}
///
/// Are these vectors not equal.
///
public static bool operator !=(Vector2f v1, Vector2f v2)
{
return (v1.x != v2.x || v1.y != v2.y);
}
///
/// Are these vectors equal.
///
public override bool Equals (object obj)
{
if(!(obj is Vector2f)) return false;
Vector2f v = (Vector2f)obj;
return this == v;
}
///
/// Are these vectors equal given the error.
///
public bool EqualsWithError(Vector2f v, float eps)
{
if(Math.Abs(x-v.x)> eps) return false;
if(Math.Abs(y-v.y)> eps) return false;
return true;
}
///
/// Are these vectors equal.
///
public bool Equals(Vector2f v)
{
return this == v;
}
///
/// Vectors hash code.
///
public override int GetHashCode()
{
float hashcode = 23;
hashcode = (hashcode * 37) + x;
hashcode = (hashcode * 37) + y;
return unchecked((int)hashcode);
}
///
/// Vector as a string.
///
public override string ToString()
{
return x + "," + y;
}
///
/// Vector from a string.
///
static public Vector2f FromString(string s)
{
Vector2f v = new Vector2f();
try
{
string[] separators = new string[] { "," };
string[] result = s.Split(separators, StringSplitOptions.None);
v.x = float.Parse(result[0]);
v.y = float.Parse(result[1]);
}
catch { }
return v;
}
///
/// The dot product of two vectors.
///
public static float Dot(Vector2f v0, Vector2f v1)
{
return v0.x * v1.x + v0.y * v1.y;
}
///
/// Normalize the vector.
///
public void Normalize()
{
float invLength = FMath.SafeInvSqrt(1.0f, x * x + y * y);
x *= invLength;
y *= invLength;
}
///
/// Cross two vectors.
///
public static float Cross(Vector2f v0, Vector2f v1)
{
return v0.x * v1.y - v0.y * v1.x;
}
///
/// Distance between two vectors.
///
public static float Distance(Vector2f v0, Vector2f v1)
{
return FMath.SafeSqrt(SqrDistance(v0, v1));
}
///
/// Square distance between two vectors.
///
public static float SqrDistance(Vector2f v0, Vector2f v1)
{
float x = v0.x - v1.x;
float y = v0.y - v1.y;
return x * x + y * y;
}
///
/// Angle between two vectors in degrees from 180 to -180.
///
public static float Angle180(Vector2f a, Vector2f b)
{
float m = a.Magnitude * b.Magnitude;
if (m == 0.0f) return 0;
float angle = Dot(a, b) / m;
if (angle < -1.0f) angle = -1.0f;
if (angle > 1.0f) angle = 1.0f;
return FMath.SafeAcos(angle) * FMath.Rad2Deg;
}
///
/// Angle between two vectors in degrees from 0 to 360;
///
public static float Angle360(Vector2f a, Vector2f b)
{
float angle = (float)(Math.Atan2(a.y, a.x) - Math.Atan2(b.y, b.x));
float PI = (float)Math.PI;
if (angle <= 0.0f)
angle = PI * 2.0f + angle;
return 360 - angle * FMath.Rad2Deg;
}
///
/// The minimum value between s and each component in vector.
///
public void Min(float s)
{
x = Math.Min(x, s);
y = Math.Min(y, s);
}
///
/// The minimum value between each component in vectors.
///
public void Min(Vector2f v)
{
x = Math.Min(x, v.x);
y = Math.Min(y, v.y);
}
///
/// The maximum value between s and each component in vector.
///
public void Max(float s)
{
x = Math.Max(x, s);
y = Math.Max(y, s);
}
///
/// The maximum value between each component in vectors.
///
public void Max(Vector2f v)
{
x = Math.Max(x, v.x);
y = Math.Max(y, v.y);
}
///
/// The absolute vector.
///
public void Abs()
{
x = Math.Abs(x);
y = Math.Abs(y);
}
///
/// Clamp the each component to specified min and max.
///
public void Clamp(float min, float max)
{
x = Math.Max(Math.Min(x, max), min);
y = Math.Max(Math.Min(y, max), min);
}
///
/// Clamp the each component to specified min and max.
///
public void Clamp(Vector2f min, Vector2f max)
{
x = Math.Max(Math.Min(x, max.x), min.x);
y = Math.Max(Math.Min(y, max.y), min.y);
}
///
/// Lerp between two vectors.
///
public static Vector2f Lerp(Vector2f from, Vector2f to, float t)
{
if (t < 0.0f) t = 0.0f;
if (t > 1.0f) t = 1.0f;
if (t == 0.0f) return from;
if (t == 1.0f) return to;
float t1 = 1.0f - t;
Vector2f v = new Vector2f();
v.x = from.x * t1 + to.x * t;
v.y = from.y * t1 + to.y * t;
return v;
}
///
/// Slerp between two vectors arc.
///
public static Vector2f Slerp(Vector2f from, Vector2f to, float t)
{
if (t < 0.0f) t = 0.0f;
if (t > 1.0f) t = 1.0f;
if (t == 0.0f) return from;
if (t == 1.0f) return to;
if (to.x == from.x && to.y == from.y) return to;
float m = from.Magnitude * to.Magnitude;
if (FMath.IsZero(m)) return Vector2f.Zero;
double theta = Math.Acos(Dot(from, to) / m);
if (theta == 0.0) return to;
double sinTheta = Math.Sin(theta);
float st1 = (float)(Math.Sin((1.0 - t) * theta) / sinTheta);
float st = (float)(Math.Sin(t * theta) / sinTheta);
Vector2f v = new Vector2f();
v.x = from.x * st1 + to.x * st;
v.y = from.y * st1 + to.y * st;
return v;
}
}
}
================================================
FILE: Assets/Common/LinearAlgebra/Vector2f.cs.meta
================================================
fileFormatVersion: 2
guid: f2c52c29076b7bb40a45c08b61f46fd4
timeCreated: 1514536271
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Common/LinearAlgebra/Vector2i.cs
================================================
using System;
using System.Collections;
using System.Runtime.InteropServices;
using Common.Core.Mathematics;
namespace Common.Core.LinearAlgebra
{
[StructLayout(LayoutKind.Sequential)]
public struct Vector2i
{
public int x, y;
///
/// The unit x vector.
///
public readonly static Vector2i UnitX = new Vector2i(1, 0);
///
/// The unit y vector.
///
public readonly static Vector2i UnitY = new Vector2i(0, 1);
///
/// A vector of zeros.
///
public readonly static Vector2i Zero = new Vector2i(0);
///
/// A vector of ones.
///
public readonly static Vector2i One = new Vector2i(1);
///
/// A vector of min int.
///
public readonly static Vector2i MinInt = new Vector2i(int.MinValue);
///
/// A vector of max int.
///
public readonly static Vector2i MaxInt = new Vector2i(int.MaxValue);
///
/// Convert to a 3 dimension vector.
///
public Vector3i x0z
{
get { return new Vector3i(x, 0, y); }
}
public Vector2i(int v)
{
this.x = v;
this.y = v;
}
public Vector2i(int x, int y)
{
this.x = x;
this.y = y;
}
public int this[int i]
{
get
{
switch (i)
{
case 0: return x;
case 1: return y;
default: throw new IndexOutOfRangeException("Vector2i index out of range: " + i);
}
}
set
{
switch (i)
{
case 0: x = value; break;
case 1: y = value; break;
default: throw new IndexOutOfRangeException("Vector2i index out of range: " + i);
}
}
}
///
/// The length of the vector.
///
public double Magnitude
{
get
{
return DMath.SafeSqrt(SqrMagnitude);
}
}
///
/// The length of the vector squared.
///
public double SqrMagnitude
{
get
{
return (x * x + y * y);
}
}
///
/// The vectors absolute values.
///
public Vector2i Absolute
{
get
{
return new Vector2i(Math.Abs(x), Math.Abs(y));
}
}
///
/// Add two vectors.
///
public static Vector2i operator +(Vector2i v1, Vector2i v2)
{
return new Vector2i(v1.x + v2.x, v1.y + v2.y);
}
///
/// Add vector and scalar.
///
public static Vector2i operator +(Vector2i v1, int s)
{
return new Vector2i(v1.x + s, v1.y + s);
}
///
/// Add vector and scalar.
///
public static Vector2i operator +(int s, Vector2i v1)
{
return new Vector2i(v1.x + s, v1.y + s);
}
///
/// Subtract two vectors.
///
public static Vector2i operator -(Vector2i v1, Vector2i v2)
{
return new Vector2i(v1.x - v2.x, v1.y - v2.y);
}
///
/// Subtract vector and scalar.
///
public static Vector2i operator -(Vector2i v1, int s)
{
return new Vector2i(v1.x - s, v1.y - s);
}
///
/// Subtract vector and scalar.
///
public static Vector2i operator -(int s, Vector2i v1)
{
return new Vector2i(v1.x - s, v1.y - s);
}
///
/// Multiply two vectors.
///
public static Vector2i operator *(Vector2i v1, Vector2i v2)
{
return new Vector2i(v1.x * v2.x, v1.y * v2.y);
}
///
/// Multiply a vector and a scalar.
///
public static Vector2i operator *(Vector2i v, int s)
{
return new Vector2i(v.x * s, v.y * s);
}
///
/// Multiply a vector and a scalar.
///
public static Vector2i operator *(int s, Vector2i v)
{
return new Vector2i(v.x * s, v.y * s);
}
///
/// Divide two vectors.
///
public static Vector2i operator /(Vector2i v1, Vector2i v2)
{
return new Vector2i(v1.x / v2.x, v1.y / v2.y);
}
///
/// Divide a vector and a scalar.
///
public static Vector2i operator /(Vector2i v, int s)
{
return new Vector2i(v.x / s, v.y / s);
}
///
/// Are these vectors equal.
///
public static bool operator ==(Vector2i v1, Vector2i v2)
{
return (v1.x == v2.x && v1.y == v2.y);
}
///
/// Are these vectors not equal.
///
public static bool operator !=(Vector2i v1, Vector2i v2)
{
return (v1.x != v2.x || v1.y != v2.y);
}
///
/// Are these vectors equal.
///
public override bool Equals (object obj)
{
if(!(obj is Vector2i)) return false;
Vector2i v = (Vector2i)obj;
return this == v;
}
///
/// Are these vectors equal.
///
public bool Equals(Vector2i v)
{
return this == v;
}
///
/// Vectors hash code.
///
public override int GetHashCode()
{
int hashcode = 23;
unchecked
{
hashcode = (hashcode * 37) + x;
hashcode = (hashcode * 37) + y;
}
return hashcode;
}
///
/// Vector as a string.
///
public override string ToString()
{
return x + "," + y;
}
///
/// Vector from a string.
///
static public Vector2i FromString(string s)
{
Vector2i v = new Vector2i();
try
{
string[] separators = new string[] { "," };
string[] result = s.Split(separators, StringSplitOptions.None);
v.x = int.Parse(result[0]);
v.y = int.Parse(result[1]);
}
catch { }
return v;
}
///
/// The dot product of two vectors.
///
public static int Dot(Vector2i v0, Vector2i v1)
{
return (v0.x * v1.x + v0.y * v1.y);
}
///
/// Cross two vectors.
///
public static int Cross(Vector2i v0, Vector2i v1)
{
return v0.x * v1.y - v0.y * v1.x;
}
///
/// Distance between two vectors.
///
public static double Distance(Vector2i v0, Vector2i v1)
{
return DMath.SafeSqrt(SqrDistance(v0, v1));
}
///
/// Square distance between two vectors.
///
public static double SqrDistance(Vector2i v0, Vector2i v1)
{
double x = v0.x - v1.x;
double y = v0.y - v1.y;
return x * x + y * y;
}
///
/// The minimum value between s and each component in vector.
///
public void Min(int s)
{
x = Math.Min(x, s);
y = Math.Min(y, s);
}
///
/// The minimum value between each component in vectors.
///
public void Min(Vector2i v)
{
x = Math.Min(x, v.x);
y = Math.Min(y, v.y);
}
///
/// The maximum value between s and each component in vector.
///
public void Max(int s)
{
x = Math.Max(x, s);
y = Math.Max(y, s);
}
///
/// The maximum value between each component in vectors.
///
public void Max(Vector2i v)
{
x = Math.Max(x, v.x);
y = Math.Max(y, v.y);
}
///
/// The absolute vector.
///
public void Abs()
{
x = Math.Abs(x);
y = Math.Abs(y);
}
///
/// Clamp the each component to specified min and max.
///
public void Clamp(int min, int max)
{
x = Math.Max(Math.Min(x, max), min);
y = Math.Max(Math.Min(y, max), min);
}
///
/// Clamp the each component to specified min and max.
///
public void Clamp(Vector2i min, Vector2i max)
{
x = Math.Max(Math.Min(x, max.x), min.x);
y = Math.Max(Math.Min(y, max.y), min.y);
}
}
}
================================================
FILE: Assets/Common/LinearAlgebra/Vector2i.cs.meta
================================================
fileFormatVersion: 2
guid: fcce9ee7e2939b748bb7812d444e1375
timeCreated: 1514536271
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Common/LinearAlgebra/Vector3d.cs
================================================
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Common.Core.Mathematics;
namespace Common.Core.LinearAlgebra
{
///
/// A 3d double precision vector.
///
[StructLayout(LayoutKind.Sequential)]
public struct Vector3d
{
public double x, y, z;
///
/// The unit x vector.
///
public readonly static Vector3d UnitX = new Vector3d(1, 0, 0);
///
/// The unit y vector.
///
public readonly static Vector3d UnitY = new Vector3d(0, 1, 0);
///
/// The unit z vector.
///
public readonly static Vector3d UnitZ = new Vector3d(0, 0, 1);
///
/// A vector of zeros.
///
public readonly static Vector3d Zero = new Vector3d(0);
///
/// A vector of ones.
///
public readonly static Vector3d One = new Vector3d(1);
///
/// A vector of positive infinity.
///
public readonly static Vector3d PositiveInfinity = new Vector3d(double.PositiveInfinity);
///
/// A vector of negative infinity.
///
public readonly static Vector3d NegativeInfinity = new Vector3d(double.NegativeInfinity);
///
/// Convert to a 2 dimension vector.
///
public Vector2d xy
{
get { return new Vector2d(x, y); }
}
///
/// Convert to a 2 dimension vector.
///
public Vector2d xz
{
get { return new Vector2d(x, z); }
}
///
/// Convert to a 4 dimension vector.
///
public Vector4d xyz0
{
get { return new Vector4d(x, y, z, 0); }
}
///
/// Convert to a 4 dimension vector.
///
public Vector4d xyz1
{
get { return new Vector4d(x, y, z, 1); }
}
///
/// A vector all with the value v.
///
public Vector3d(double v)
{
this.x = v;
this.y = v;
this.z = v;
}
///
/// A vector from the varibles.
///
public Vector3d(double x, double y, double z)
{
this.x = x;
this.y = y;
this.z = z;
}
///
/// A vector from a 2d vector and the z varible.
///
public Vector3d(Vector2d v, double z)
{
x = v.x;
y = v.y;
this.z = z;
}
public double this[int i]
{
get
{
switch (i)
{
case 0: return x;
case 1: return y;
case 2: return z;
default: throw new IndexOutOfRangeException("Vector3d index out of range: " + i);
}
}
set
{
switch (i)
{
case 0: x = value; break;
case 1: y = value; break;
case 2: z = value; break;
default: throw new IndexOutOfRangeException("Vector3d index out of range: " + i);
}
}
}
///
/// The length of the vector.
///
public double Magnitude
{
get
{
return DMath.SafeSqrt(SqrMagnitude);
}
}
///
/// The length of the vector squared.
///
public double SqrMagnitude
{
get
{
return (x * x + y * y + z * z);
}
}
///
/// The vector normalized.
///
public Vector3d Normalized
{
get
{
double invLength = DMath.SafeInvSqrt(1.0, x * x + y * y + z * z);
return new Vector3d(x * invLength, y * invLength, z * invLength);
}
}
///
/// The vectors absolute values.
///
public Vector3d Absolute
{
get
{
return new Vector3d(Math.Abs(x), Math.Abs(y), Math.Abs(z));
}
}
///
/// Add two vectors.
///
public static Vector3d operator +(Vector3d v1, Vector3d v2)
{
return new Vector3d(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
}
///
/// Add vector and scalar.
///
public static Vector3d operator +(Vector3d v1, double s)
{
return new Vector3d(v1.x + s, v1.y + s, v1.z + s);
}
///
/// Add vector and scalar.
///
public static Vector3d operator +(double s, Vector3d v1)
{
return new Vector3d(v1.x + s, v1.y + s, v1.z + s);
}
///
/// Subtract two vectors.
///
public static Vector3d operator -(Vector3d v1, Vector3d v2)
{
return new Vector3d(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
}
///
/// Subtract vector and scalar.
///
public static Vector3d operator -(Vector3d v1, double s)
{
return new Vector3d(v1.x - s, v1.y - s, v1.z - s);
}
///
/// Subtract vector and scalar.
///
public static Vector3d operator -(double s, Vector3d v1)
{
return new Vector3d(v1.x - s, v1.y - s, v1.z - s);
}
///
/// Multiply two vectors.
///
public static Vector3d operator *(Vector3d v1, Vector3d v2)
{
return new Vector3d(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z);
}
///
/// Multiply a vector and a scalar.
///
public static Vector3d operator *(Vector3d v, double s)
{
return new Vector3d(v.x * s, v.y * s, v.z * s);
}
///
/// Multiply a vector and a scalar.
///
public static Vector3d operator *(double s, Vector3d v)
{
return new Vector3d(v.x * s, v.y * s, v.z * s);
}
///
/// Divide two vectors.
///
public static Vector3d operator /(Vector3d v1, Vector3d v2)
{
return new Vector3d(v1.x / v2.x, v1.y / v2.y, v1.z / v2.z);
}
///
/// Divide a vector and a scalar.
///
public static Vector3d operator /(Vector3d v, double s)
{
return new Vector3d(v.x / s, v.y / s, v.z / s);
}
///
/// Are these vectors equal.
///
public static bool operator ==(Vector3d v1, Vector3d v2)
{
return (v1.x == v2.x && v1.y == v2.y && v1.z == v2.z);
}
///
/// Are these vectors not equal.
///
public static bool operator !=(Vector3d v1, Vector3d v2)
{
return (v1.x != v2.x || v1.y != v2.y || v1.z != v2.z);
}
///
/// Are these vectors equal.
///
public override bool Equals (object obj)
{
if(!(obj is Vector3d)) return false;
Vector3d v = (Vector3d)obj;
return this == v;
}
///
/// Are these vectors equal given the error.
///
public bool EqualsWithError(Vector3d v, double eps)
{
if(Math.Abs(x-v.x)> eps) return false;
if(Math.Abs(y-v.y)> eps) return false;
if(Math.Abs(z-v.z)> eps) return false;
return true;
}
///
/// Are these vectors equal.
///
public bool Equals(Vector3d v)
{
return this == v;
}
///
/// Vectors hash code.
///
public override int GetHashCode()
{
double hashcode = 23;
hashcode = (hashcode * 37) + x;
hashcode = (hashcode * 37) + y;
hashcode = (hashcode * 37) + z;
return unchecked((int)hashcode);
}
///
/// Vector as a string.
///
public override string ToString()
{
return x + "," + y + "," + z;
}
///
/// Vector from a string.
///
static public Vector3d FromString(string s)
{
Vector3d v = new Vector3d();
try
{
string[] separators = new string[] { "," };
string[] result = s.Split(separators, StringSplitOptions.None);
v.x = double.Parse(result[0]);
v.y = double.Parse(result[1]);
v.z = double.Parse(result[2]);
}
catch { }
return v;
}
///
/// The dot product of two vectors.
///
public static double Dot(Vector3d v0, Vector3d v1)
{
return (v0.x*v1.x + v0.y*v1.y + v0.z*v1.z);
}
///
/// Normalize the vector.
///
public void Normalize()
{
double invLength = DMath.SafeInvSqrt(1.0, x * x + y * y + z * z);
x *= invLength;
y *= invLength;
z *= invLength;
}
///
/// Cross two vectors.
///
public Vector3d Cross(Vector3d v)
{
return new Vector3d(y*v.z - z*v.y, z*v.x - x*v.z, x*v.y - y*v.x);
}
///
/// Cross two vectors.
///
public static Vector3d Cross(Vector3d v0, Vector3d v1)
{
return new Vector3d(v0.y*v1.z - v0.z*v1.y, v0.z*v1.x - v0.x*v1.z, v0.x*v1.y - v0.y*v1.x);
}
///
/// Distance between two vectors.
///
public static double Distance(Vector3d v0, Vector3d v1)
{
return DMath.SafeSqrt(SqrDistance(v0, v1));
}
///
/// Square distance between two vectors.
///
public static double SqrDistance(Vector3d v0, Vector3d v1)
{
double x = v0.x - v1.x;
double y = v0.y - v1.y;
double z = v0.z - v1.z;
return x * x + y * y + z * z;
}
///
/// The minimum value between s and each component in vector.
///
public void Min(double s)
{
x = Math.Min(x, s);
y = Math.Min(y, s);
z = Math.Min(z, s);
}
///
/// The minimum value between each component in vectors.
///
public void Min(Vector3d v)
{
x = Math.Min(x, v.x);
y = Math.Min(y, v.y);
z = Math.Min(z, v.z);
}
///
/// The maximum value between s and each component in vector.
///
public void Max(double s)
{
x = Math.Max(x, s);
y = Math.Max(y, s);
z = Math.Max(z, s);
}
///
/// The maximum value between each component in vectors.
///
public void Max(Vector3d v)
{
x = Math.Max(x, v.x);
y = Math.Max(y, v.y);
z = Math.Max(z, v.z);
}
///
/// The absolute vector.
///
public void Abs()
{
x = Math.Abs(x);
y = Math.Abs(y);
z = Math.Abs(z);
}
///
/// Clamp the each component to specified min and max.
///
public void Clamp(double min, double max)
{
x = Math.Max(Math.Min(x, max), min);
y = Math.Max(Math.Min(y, max), min);
z = Math.Max(Math.Min(z, max), min);
}
///
/// Clamp the each component to specified min and max.
///
public void Clamp(Vector3d min, Vector3d max)
{
x = Math.Max(Math.Min(x, max.x), min.x);
y = Math.Max(Math.Min(y, max.y), min.y);
z = Math.Max(Math.Min(z, max.z), min.z);
}
///
/// Lerp between two vectors.
///
public static Vector3d Lerp(Vector3d from, Vector3d to, double t)
{
if (t < 0.0) t = 0.0;
if (t > 1.0) t = 1.0;
if (t == 0.0) return from;
if (t == 1.0) return to;
double t1 = 1.0 - t;
Vector3d v = new Vector3d();
v.x = from.x * t1 + to.x * t;
v.y = from.y * t1 + to.y * t;
v.z = from.z * t1 + to.z * t;
return v;
}
///
/// Slerp between two vectors arc.
///
public static Vector3d Slerp(Vector3d from, Vector3d to, double t)
{
if (t < 0.0f) t = 0.0f;
if (t > 1.0f) t = 1.0f;
if (t == 0.0f) return from;
if (t == 1.0f) return to;
if (to.x == from.x && to.y == from.y && to.z == from.z) return to;
double m = from.Magnitude * to.Magnitude;
if (DMath.IsZero(m)) return Vector3d.Zero;
double theta = Math.Acos(Dot(from, to) / m);
if (theta == 0.0) return to;
double sinTheta = Math.Sin(theta);
double st1 = Math.Sin((1.0 - t) * theta) / sinTheta;
double st = Math.Sin(t * theta) / sinTheta;
Vector3d v = new Vector3d();
v.x = from.x * st1 + to.x * st;
v.y = from.y * st1 + to.y * st;
v.z = from.z * st1 + to.z * st;
return v;
}
}
}
================================================
FILE: Assets/Common/LinearAlgebra/Vector3d.cs.meta
================================================
fileFormatVersion: 2
guid: b9c045103d2bd44499952cd87cbdca3d
timeCreated: 1514536270
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Common/LinearAlgebra/Vector3f.cs
================================================
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Common.Core.Mathematics;
namespace Common.Core.LinearAlgebra
{
///
/// A 3d single precision vector.
///
[StructLayout(LayoutKind.Sequential)]
public struct Vector3f
{
public float x, y, z;
///
/// The unit x vector.
///
public readonly static Vector3f UnitX = new Vector3f(1, 0, 0);
///
/// The unit y vector.
///
public readonly static Vector3f UnitY = new Vector3f(0, 1, 0);
///
/// The unit z vector.
///
public readonly static Vector3f UnitZ = new Vector3f(0, 0, 1);
///
/// A vector of zeros.
///
public readonly static Vector3f Zero = new Vector3f(0);
///
/// A vector of ones.
///
public readonly static Vector3f One = new Vector3f(1);
///
/// A vector of positive infinity.
///
public readonly static Vector3f PositiveInfinity = new Vector3f(float.PositiveInfinity);
///
/// A vector of negative infinity.
///
public readonly static Vector3f NegativeInfinity = new Vector3f(float.NegativeInfinity);
///
/// Convert to a 2 dimension vector.
///
public Vector2f xy
{
get { return new Vector2f(x, y); }
}
///
/// Convert to a 2 dimension vector.
///
public Vector2f xz
{
get { return new Vector2f(x, z); }
}
///
/// Convert to a 4 dimension vector.
///
public Vector4f xyz0
{
get { return new Vector4f(x, y, z, 0); }
}
///
/// Convert to a 4 dimension vector.
///
public Vector4f xyz1
{
get { return new Vector4f(x, y, z, 1); }
}
///
/// A vector all with the value v.
///
public Vector3f(float v)
{
this.x = v;
this.y = v;
this.z = v;
}
///
/// A vector from the varibles.
///
public Vector3f(float x, float y, float z)
{
this.x = x;
this.y = y;
this.z = z;
}
///
/// A vector from a 2d vector and the z varible.
///
public Vector3f(Vector2f v, float z)
{
x = v.x;
y = v.y;
this.z = z;
}
public float this[int i]
{
get
{
switch (i)
{
case 0: return x;
case 1: return y;
case 2: return z;
default: throw new IndexOutOfRangeException("Vector3f index out of range: " + i);
}
}
set
{
switch (i)
{
case 0: x = value; break;
case 1: y = value; break;
case 2: z = value; break;
default: throw new IndexOutOfRangeException("Vector3f index out of range: " + i);
}
}
}
///
/// The length of the vector.
///
public float Magnitude
{
get
{
return FMath.SafeSqrt(SqrMagnitude);
}
}
///
/// The length of the vector squared.
///
public float SqrMagnitude
{
get
{
return (x * x + y * y + z * z);
}
}
///
/// The vector normalized.
///
public Vector3f Normalized
{
get
{
float invLength = FMath.SafeInvSqrt(1.0f, x * x + y * y + z * z);
return new Vector3f(x * invLength, y * invLength, z * invLength);
}
}
///
/// The vectors absolute values.
///
public Vector3f Absolute
{
get
{
return new Vector3f(Math.Abs(x), Math.Abs(y), Math.Abs(z));
}
}
///
/// Add two vectors.
///
public static Vector3f operator +(Vector3f v1, Vector3f v2)
{
return new Vector3f(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
}
///
/// Add vector and scalar.
///
public static Vector3f operator +(Vector3f v1, float s)
{
return new Vector3f(v1.x + s, v1.y + s, v1.z + s);
}
///
/// Add vector and scalar.
///
public static Vector3f operator +(float s, Vector3f v1)
{
return new Vector3f(v1.x + s, v1.y + s, v1.z + s);
}
///
/// Subtract two vectors.
///
public static Vector3f operator -(Vector3f v1, Vector3f v2)
{
return new Vector3f(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
}
///
/// Subtract vector and scalar.
///
public static Vector3f operator -(Vector3f v1, float s)
{
return new Vector3f(v1.x - s, v1.y - s, v1.z - s);
}
///
/// Subtract vector and scalar.
///
public static Vector3f operator -(float s, Vector3f v1)
{
return new Vector3f(v1.x - s, v1.y - s, v1.z - s);
}
///
/// Multiply two vectors.
///
public static Vector3f operator *(Vector3f v1, Vector3f v2)
{
return new Vector3f(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z);
}
///
/// Multiply a vector and a scalar.
///
public static Vector3f operator *(Vector3f v, float s)
{
return new Vector3f(v.x * s, v.y * s, v.z * s);
}
///
/// Multiply a vector and a scalar.
///
public static Vector3f operator *(float s, Vector3f v)
{
return new Vector3f(v.x * s, v.y * s, v.z * s);
}
///
/// Divide two vectors.
///
public static Vector3f operator /(Vector3f v1, Vector3f v2)
{
return new Vector3f(v1.x / v2.x, v1.y / v2.y, v1.z / v2.z);
}
///
/// Divide a vector and a scalar.
///
public static Vector3f operator /(Vector3f v, float s)
{
return new Vector3f(v.x / s, v.y / s, v.z / s);
}
///
/// Are these vectors equal.
///
public static bool operator ==(Vector3f v1, Vector3f v2)
{
return (v1.x == v2.x && v1.y == v2.y && v1.z == v2.z);
}
///
/// Are these vectors not equal.
///
public static bool operator !=(Vector3f v1, Vector3f v2)
{
return (v1.x != v2.x || v1.y != v2.y || v1.z != v2.z);
}
///
/// Are these vectors equal.
///
public override bool Equals (object obj)
{
if(!(obj is Vector3f)) return false;
Vector3f v = (Vector3f)obj;
return this == v;
}
///
/// Are these vectors equal given the error.
///
public bool EqualsWithError(Vector3f v, float eps)
{
if(Math.Abs(x-v.x)> eps) return false;
if(Math.Abs(y-v.y)> eps) return false;
if(Math.Abs(z-v.z)> eps) return false;
return true;
}
///
/// Are these vectors equal.
///
public bool Equals(Vector3f v)
{
return this == v;
}
///
/// Vectors hash code.
///
public override int GetHashCode()
{
float hashcode = 23;
hashcode = (hashcode * 37) + x;
hashcode = (hashcode * 37) + y;
hashcode = (hashcode * 37) + z;
return unchecked((int)hashcode);
}
///
/// Vector as a string.
///
public override string ToString()
{
return x + "," + y + "," + z;
}
///
/// Vector from a string.
///
static public Vector3f FromString(string s)
{
Vector3f v = new Vector3f();
try
{
string[] separators = new string[] { "," };
string[] result = s.Split(separators, StringSplitOptions.None);
v.x = float.Parse(result[0]);
v.y = float.Parse(result[1]);
v.z = float.Parse(result[2]);
}
catch { }
return v;
}
///
/// The dot product of two vectors.
///
public static float Dot(Vector3f v0, Vector3f v1)
{
return (v0.x * v1.x + v0.y * v1.y + v0.z * v1.z);
}
///
/// Normalize the vector.
///
public void Normalize()
{
float invLength = FMath.SafeInvSqrt(1.0f, x * x + y * y + z * z);
x *= invLength;
y *= invLength;
z *= invLength;
}
///
/// Cross two vectors.
///
public Vector3f Cross(Vector3f v)
{
return new Vector3f(y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x);
}
///
/// Cross two vectors.
///
public static Vector3f Cross(Vector3f v0, Vector3f v1)
{
return new Vector3f(v0.y * v1.z - v0.z * v1.y, v0.z * v1.x - v0.x * v1.z, v0.x * v1.y - v0.y * v1.x);
}
///
/// Distance between two vectors.
///
public static float Distance(Vector3f v0, Vector3f v1)
{
return FMath.SafeSqrt(SqrDistance(v0, v1));
}
///
/// Square distance between two vectors.
///
public static float SqrDistance(Vector3f v0, Vector3f v1)
{
float x = v0.x - v1.x;
float y = v0.y - v1.y;
float z = v0.z - v1.z;
return x * x + y * y + z * z;
}
///
/// The minimum value between s and each component in vector.
///
public void Min(float s)
{
x = Math.Min(x, s);
y = Math.Min(y, s);
z = Math.Min(z, s);
}
///
/// The minimum value between each component in vectors.
///
public void Min(Vector3f v)
{
x = Math.Min(x, v.x);
y = Math.Min(y, v.y);
z = Math.Min(z, v.z);
}
///
/// The maximum value between s and each component in vector.
///
public void Max(float s)
{
x = Math.Max(x, s);
y = Math.Max(y, s);
z = Math.Max(z, s);
}
///
/// The maximum value between each component in vectors.
///
public void Max(Vector3f v)
{
x = Math.Max(x, v.x);
y = Math.Max(y, v.y);
z = Math.Max(z, v.z);
}
///
/// The absolute vector.
///
public void Abs()
{
x = Math.Abs(x);
y = Math.Abs(y);
z = Math.Abs(z);
}
///
/// Clamp the each component to specified min and max.
///
public void Clamp(float min, float max)
{
x = Math.Max(Math.Min(x, max), min);
y = Math.Max(Math.Min(y, max), min);
z = Math.Max(Math.Min(z, max), min);
}
///
/// Clamp the each component to specified min and max.
///
public void Clamp(Vector3f min, Vector3f max)
{
x = Math.Max(Math.Min(x, max.x), min.x);
y = Math.Max(Math.Min(y, max.y), min.y);
z = Math.Max(Math.Min(z, max.z), min.z);
}
///
/// Lerp between two vectors.
///
public static Vector3f Lerp(Vector3f from, Vector3f to, float t)
{
if (t < 0.0f) t = 0.0f;
if (t > 1.0f) t = 1.0f;
if (t == 0.0f) return from;
if (t == 1.0f) return to;
float t1 = 1.0f - t;
Vector3f v = new Vector3f();
v.x = from.x * t1 + to.x * t;
v.y = from.y * t1 + to.y * t;
v.z = from.z * t1 + to.z * t;
return v;
}
///
/// Slerp between two vectors arc.
///
public static Vector3f Slerp(Vector3f from, Vector3f to, float t)
{
if (t < 0.0f) t = 0.0f;
if (t > 1.0f) t = 1.0f;
if (t == 0.0f) return from;
if (t == 1.0f) return to;
if (to.x == from.x && to.y == from.y && to.z == from.z) return to;
float m = from.Magnitude * to.Magnitude;
if (FMath.IsZero(m)) return Vector3f.Zero;
double theta = Math.Acos(Dot(from, to) / m);
if (theta == 0.0) return to;
double sinTheta = Math.Sin(theta);
float st1 = (float)(Math.Sin((1.0 - t) * theta) / sinTheta);
float st = (float)(Math.Sin(t * theta) / sinTheta);
Vector3f v = new Vector3f();
v.x = from.x * st1 + to.x * st;
v.y = from.y * st1 + to.y * st;
v.z = from.z * st1 + to.z * st;
return v;
}
}
}
================================================
FILE: Assets/Common/LinearAlgebra/Vector3f.cs.meta
================================================
fileFormatVersion: 2
guid: 094df8240bc2a7c4db01c45a93d719d3
timeCreated: 1514536270
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Common/LinearAlgebra/Vector3i.cs
================================================
using System;
using System.Collections;
using System.Runtime.InteropServices;
using Common.Core.Mathematics;
namespace Common.Core.LinearAlgebra
{
[StructLayout(LayoutKind.Sequential)]
public struct Vector3i
{
public int x, y, z;
///
/// The unit x vector.
///
public readonly static Vector3i UnitX = new Vector3i(1, 0, 0);
///
/// The unit y vector.
///
public readonly static Vector3i UnitY = new Vector3i(0, 1, 0);
///
/// The unit z vector.
///
public readonly static Vector3i UnitZ = new Vector3i(0, 0, 1);
///
/// A vector of zeros.
///
public readonly static Vector3i Zero = new Vector3i(0);
///
/// A vector of ones.
///
public readonly static Vector3i One = new Vector3i(1);
///
/// A vector of min int.
///
public readonly static Vector3i MinInt = new Vector3i(int.MinValue);
///
/// A vector of max int.
///
public readonly static Vector3i MaxInt = new Vector3i(int.MaxValue);
public Vector3i(int v)
{
this.x = v;
this.y = v;
this.z = v;
}
public Vector3i(int x, int y, int z)
{
this.x = x;
this.y = y;
this.z = z;
}
public int this[int i]
{
get
{
switch (i)
{
case 0: return x;
case 1: return y;
case 2: return z;
default: throw new IndexOutOfRangeException("Vector3i index out of range: " + i);
}
}
set
{
switch (i)
{
case 0: x = value; break;
case 1: y = value; break;
case 2: z = value; break;
default: throw new IndexOutOfRangeException("Vector3i index out of range: " + i);
}
}
}
///
/// The length of the vector.
///
public double Magnitude
{
get
{
return DMath.SafeSqrt(SqrMagnitude);
}
}
///
/// The length of the vector squared.
///
public int SqrMagnitude
{
get
{
return (x * x + y * y + z * z);
}
}
///
/// The vectors absolute values.
///
public Vector3i Absolute
{
get
{
return new Vector3i(Math.Abs(x), Math.Abs(y), Math.Abs(z));
}
}
///
/// Add two vectors.
///
public static Vector3i operator +(Vector3i v1, Vector3i v2)
{
return new Vector3i(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z);
}
///
/// Add vector and scalar.
///
public static Vector3i operator +(Vector3i v1, int s)
{
return new Vector3i(v1.x + s, v1.y + s, v1.z + s);
}
///
/// Add vector and scalar.
///
public static Vector3i operator +(int s, Vector3i v1)
{
return new Vector3i(v1.x + s, v1.y + s, v1.z + s);
}
///
/// Subtract two vectors.
///
public static Vector3i operator -(Vector3i v1, Vector3i v2)
{
return new Vector3i(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
}
///
/// Subtract vector and scalar.
///
public static Vector3i operator -(Vector3i v1, int s)
{
return new Vector3i(v1.x - s, v1.y - s, v1.z - s);
}
///
/// Subtract vector and scalar.
///
public static Vector3i operator -(int s, Vector3i v1)
{
return new Vector3i(v1.x - s, v1.y - s, v1.z - s);
}
///
/// Multiply two vectors.
///
public static Vector3i operator *(Vector3i v1, Vector3i v2)
{
return new Vector3i(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z);
}
///
/// Multiply a vector and a scalar.
///
public static Vector3i operator *(Vector3i v, int s)
{
return new Vector3i(v.x * s, v.y * s, v.z * s);
}
///
/// Multiply a vector and a scalar.
///
public static Vector3i operator *(int s, Vector3i v)
{
return new Vector3i(v.x * s, v.y * s, v.z * s);
}
///
/// Divide two vectors.
///
public static Vector3i operator /(Vector3i v1, Vector3i v2)
{
return new Vector3i(v1.x / v2.x, v1.y / v2.y, v1.z / v2.z);
}
///
/// Divide a vector and a scalar.
///
public static Vector3i operator /(Vector3i v, int s)
{
return new Vector3i(v.x / s, v.y / s, v.z / s);
}
///
/// Are these vectors equal.
///
public static bool operator ==(Vector3i v1, Vector3i v2)
{
return (v1.x == v2.x && v1.y == v2.y && v1.z == v2.z);
}
///
/// Are these vectors not equal.
///
public static bool operator !=(Vector3i v1, Vector3i v2)
{
return (v1.x != v2.x || v1.y != v2.y || v1.z != v2.z);
}
///
/// Are these vectors equal.
///
public override bool Equals (object obj)
{
if(!(obj is Vector3i)) return false;
Vector3i v = (Vector3i)obj;
return this == v;
}
///
/// Are these vectors equal.
///
public bool Equals(Vector3i v)
{
return this == v;
}
///
/// Vectors hash code.
///
public override int GetHashCode()
{
int hashcode = 23;
unchecked
{
hashcode = (hashcode * 37) + x;
hashcode = (hashcode * 37) + y;
hashcode = (hashcode * 37) + z;
}
return hashcode;
}
///
/// Vector as a string.
///
public override string ToString()
{
return x + "," + y + "," + z;
}
///
/// Vector from a string.
///
static public Vector3i FromString(string s)
{
Vector3i v = new Vector3i();
try
{
string[] separators = new string[] { "," };
string[] result = s.Split(separators, StringSplitOptions.None);
v.x = int.Parse(result[0]);
v.y = int.Parse(result[1]);
v.z = int.Parse(result[2]);
}
catch { }
return v;
}
///
/// The dot product of two vectors.
///
public static int Dot(Vector3i v0, Vector3i v1)
{
return (v0.x * v1.x + v0.y * v1.y + v0.z * v1.z);
}
///
/// Cross two vectors.
///
public static Vector3i Cross(Vector3i v0, Vector3i v1)
{
return new Vector3i(v0.y * v1.z - v0.z * v1.y, v0.z * v1.x - v0.x * v1.z, v0.x * v1.y - v0.y * v1.x);
}
///
/// Distance between two vectors.
///
public static double Distance(Vector3i v0, Vector3i v1)
{
return DMath.SafeSqrt(SqrDistance(v0, v1));
}
///
/// Square distance between two vectors.
///
public static double SqrDistance(Vector3i v0, Vector3i v1)
{
double x = v0.x - v1.x;
double y = v0.y - v1.y;
double z = v0.z - v1.z;
return x * x + y * y + z * z;
}
///
/// The minimum value between s and each component in vector.
///
public void Min(int s)
{
x = Math.Min(x, s);
y = Math.Min(y, s);
z = Math.Min(z, s);
}
///
/// The minimum value between each component in vectors.
///
public void Min(Vector3i v)
{
x = Math.Min(x, v.x);
y = Math.Min(y, v.y);
z = Math.Min(z, v.z);
}
///
/// The maximum value between s and each component in vector.
///
public void Max(int s)
{
x = Math.Max(x, s);
y = Math.Max(y, s);
z = Math.Max(z, s);
}
///
/// The maximum value between each component in vectors.
///
public void Max(Vector3i v)
{
x = Math.Max(x, v.x);
y = Math.Max(y, v.y);
z = Math.Max(z, v.z);
}
///
/// The absolute vector.
///
public void Abs()
{
x = Math.Abs(x);
y = Math.Abs(y);
z = Math.Abs(z);
}
///
/// Clamp the each component to specified min and max.
///
public void Clamp(int min, int max)
{
x = Math.Max(Math.Min(x, max), min);
y = Math.Max(Math.Min(y, max), min);
z = Math.Max(Math.Min(z, max), min);
}
///
/// Clamp the each component to specified min and max.
///
public void Clamp(Vector3i min, Vector3i max)
{
x = Math.Max(Math.Min(x, max.x), min.x);
y = Math.Max(Math.Min(y, max.y), min.y);
z = Math.Max(Math.Min(z, max.z), min.z);
}
}
}
================================================
FILE: Assets/Common/LinearAlgebra/Vector3i.cs.meta
================================================
fileFormatVersion: 2
guid: c429b2b651bebc94387a8eadd602aaea
timeCreated: 1514536270
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Common/LinearAlgebra/Vector4d.cs
================================================
using System;
using System.Collections;
using System.Runtime.InteropServices;
using Common.Core.Mathematics;
namespace Common.Core.LinearAlgebra
{
///
/// A 4d double precision vector.
///
[StructLayout(LayoutKind.Sequential)]
public struct Vector4d
{
public double x, y, z, w;
///
/// The unit x vector.
///
public readonly static Vector4d UnitX = new Vector4d(1, 0, 0, 0);
///
/// The unit y vector.
///
public readonly static Vector4d UnitY = new Vector4d(0, 1, 0, 0);
///
/// The unit z vector.
///
public readonly static Vector4d UnitZ = new Vector4d(0, 0, 1, 0);
///
/// The unit w vector.
///
public readonly static Vector4d UnitW = new Vector4d(0, 0, 0, 1);
///
/// A vector of zeros.
///
public readonly static Vector4d Zero = new Vector4d(0);
///
/// A vector of ones.
///
public readonly static Vector4d One = new Vector4d(1);
///
/// A vector of positive infinity.
///
public readonly static Vector4d PositiveInfinity = new Vector4d(double.PositiveInfinity);
///
/// A vector of negative infinity.
///
public readonly static Vector4d NegativeInfinity = new Vector4d(double.NegativeInfinity);
///
/// Convert to a 2 dimension vector.
///
public Vector2d xy
{
get { return new Vector2d(x, y); }
}
///
/// Convert to a 3 dimension vector.
///
public Vector3d xyz
{
get { return new Vector3d(x, y, z); }
}
///
/// A copy of the vector with w as 0.
///
public Vector4d xyz0
{
get { return new Vector4d(x, y, z, 0); }
}
///
/// A vector all with the value v.
///
public Vector4d(double v)
{
this.x = v;
this.y = v;
this.z = v;
this.w = v;
}
///
/// A vector from the varibles.
///
public Vector4d(double x, double y, double z, double w)
{
this.x = x;
this.y = y;
this.z = z;
this.w = w;
}
///
/// A vector from a 2d vector and the z and w varibles.
///
public Vector4d(Vector2d v, double z, double w)
{
x = v.x;
y = v.y;
this.z = z;
this.w = w;
}
///
/// A vector from a 3d vector and the w varible.
///
public Vector4d(Vector3d v, double w)
{
x = v.x;
y = v.y;
z = v.z;
this.w = w;
}
public double this[int i]
{
get
{
switch (i)
{
case 0: return x;
case 1: return y;
case 2: return z;
case 3: return w;
default: throw new IndexOutOfRangeException("Vector4d index out of range: " + i);
}
}
set
{
switch (i)
{
case 0: x = value; break;
case 1: y = value; break;
case 2: z = value; break;
case 3: w = value; break;
default: throw new IndexOutOfRangeException("Vector4d index out of range: " + i);
}
}
}
///
/// The length of the vector.
///
public double Magnitude
{
get
{
return DMath.SafeSqrt(SqrMagnitude);
}
}
///
/// The length of the vector squared.
///
public double SqrMagnitude
{
get
{
return (x * x + y * y + z * z + w * w);
}
}
///
/// The vector normalized.
///
public Vector4d Normalized
{
get
{
double invLength = DMath.SafeInvSqrt(1.0, x * x + y * y + z * z + w * w);
return new Vector4d(x * invLength, y * invLength, z * invLength, w * invLength);
}
}
///
/// The vectors absolute values.
///
public Vector4d Absolute
{
get
{
return new Vector4d(Math.Abs(x), Math.Abs(y), Math.Abs(z), Math.Abs(w));
}
}
///
/// Add two vectors.
///
public static Vector4d operator +(Vector4d v1, Vector4d v2)
{
return new Vector4d(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z, v1.w + v2.w);
}
///
/// Add vector and scalar.
///
public static Vector4d operator +(Vector4d v1, double s)
{
return new Vector4d(v1.x + s, v1.y + s, v1.z + s, v1.w + s);
}
///
/// Add vector and scalar.
///
public static Vector4d operator +(double s, Vector4d v1)
{
return new Vector4d(v1.x + s, v1.y + s, v1.z + s, v1.w + s);
}
///
/// Subtract two vectors.
///
public static Vector4d operator -(Vector4d v1, Vector4d v2)
{
return new Vector4d(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z, v1.w - v2.w);
}
///
/// Subtract vector and scalar.
///
public static Vector4d operator -(Vector4d v1, double s)
{
return new Vector4d(v1.x - s, v1.y - s, v1.z - s, v1.w - s);
}
///
/// Subtract vector and scalar.
///
public static Vector4d operator -(double s, Vector4d v1)
{
return new Vector4d(v1.x - s, v1.y - s, v1.z - s, v1.w - s);
}
///
/// Multiply two vectors.
///
public static Vector4d operator *(Vector4d v1, Vector4d v2)
{
return new Vector4d(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z, v1.w * v2.w);
}
///
/// Multiply a vector and a scalar.
///
public static Vector4d operator *(Vector4d v, double s)
{
return new Vector4d(v.x * s, v.y * s, v.z * s, v.w * s);
}
///
/// Multiply a vector and a scalar.
///
public static Vector4d operator *(double s, Vector4d v)
{
return new Vector4d(v.x * s, v.y * s, v.z * s, v.w * s);
}
///
/// Divide two vectors.
///
public static Vector4d operator /(Vector4d v1, Vector4d v2)
{
return new Vector4d(v1.x / v2.x, v1.y / v2.y, v1.z / v2.z, v1.w / v2.w);
}
///
/// Divide a vector and a scalar.
///
public static Vector4d operator /(Vector4d v, double s)
{
return new Vector4d(v.x / s, v.y / s, v.z / s, v.w / s);
}
///
/// Are these vectors equal.
///
public static bool operator ==(Vector4d v1, Vector4d v2)
{
return (v1.x == v2.x && v1.y == v2.y && v1.z == v2.z && v1.w == v2.w);
}
///
/// Are these vectors not equal.
///
public static bool operator !=(Vector4d v1, Vector4d v2)
{
return (v1.x != v2.x || v1.y != v2.y || v1.z != v2.z || v1.w != v2.w);
}
///
/// Are these vectors equal.
///
public override bool Equals (object obj)
{
if(!(obj is Vector4d)) return false;
Vector4d v = (Vector4d)obj;
return this == v;
}
///
/// Are these vectors equal given the error.
///
public bool EqualsWithError(Vector4d v, double eps)
{
if(Math.Abs(x-v.x)> eps) return false;
if(Math.Abs(y-v.y)> eps) return false;
if(Math.Abs(z-v.z)> eps) return false;
if(Math.Abs(w-v.w)> eps) return false;
return true;
}
///
/// Are these vectors equal.
///
public bool Equals(Vector4d v)
{
return this == v;
}
///
/// Vectors hash code.
///
public override int GetHashCode()
{
double hashcode = 23;
hashcode = (hashcode * 37) + x;
hashcode = (hashcode * 37) + y;
hashcode = (hashcode * 37) + z;
hashcode = (hashcode * 37) + w;
return unchecked((int)hashcode);
}
///
/// Vector as a string.
///
public override string ToString() {
return x + "," + y + "," + z + "," + w;
}
///
/// Vector from a string.
///
static public Vector4d FromString(string s)
{
Vector4d v = new Vector4d();
try
{
string[] separators = new string[] { "," };
string[] result = s.Split(separators, StringSplitOptions.None);
v.x = double.Parse(result[0]);
v.y = double.Parse(result[1]);
v.z = double.Parse(result[2]);
v.w = double.Parse(result[3]);
}
catch { }
return v;
}
///
/// The dot product of two vectors.
///
public static double Dot(Vector4d v0, Vector4d v1)
{
return (v0.x*v1.x + v0.y*v1.y + v0.z*v1.z + v0.w*v1.w);
}
///
/// Distance between two vectors.
///
public static double Distance(Vector4d v0, Vector4d v1)
{
return DMath.SafeSqrt(SqrDistance(v0, v1));
}
///
/// Square distance between two vectors.
///
public static double SqrDistance(Vector4d v0, Vector4d v1)
{
double x = v0.x - v1.x;
double y = v0.y - v1.y;
double z = v0.z - v1.z;
double w = v0.w - v1.w;
return x * x + y * y + z * z + w * w;
}
///
/// Normalize the vector.
///
public void Normalize()
{
double invLength = DMath.SafeInvSqrt(1.0, x * x + y * y + z * z + w * w);
x *= invLength;
y *= invLength;
z *= invLength;
w *= invLength;
}
///
/// The minimum value between s and each component in vector.
///
public void Min(double s)
{
x = Math.Min(x, s);
y = Math.Min(y, s);
z = Math.Min(z, s);
w = Math.Min(w, s);
}
///
/// The minimum value between each component in vectors.
///
public void Min(Vector4d v)
{
x = Math.Min(x, v.x);
y = Math.Min(y, v.y);
z = Math.Min(z, v.z);
w = Math.Min(w, v.w);
}
///
/// The maximum value between s and each component in vector.
///
public void Max(double s)
{
x = Math.Max(x, s);
y = Math.Max(y, s);
z = Math.Max(z, s);
w = Math.Max(w, s);
}
///
/// The maximum value between each component in vectors.
///
public void Max(Vector4d v)
{
x = Math.Max(x, v.x);
y = Math.Max(y, v.y);
z = Math.Max(z, v.z);
w = Math.Max(w, v.w);
}
///
/// The absolute vector.
///
public void Abs()
{
x = Math.Abs(x);
y = Math.Abs(y);
z = Math.Abs(z);
w = Math.Abs(w);
}
///
/// Clamp the each component to specified min and max.
///
public void Clamp(double min, double max)
{
x = Math.Max(Math.Min(x, max), min);
y = Math.Max(Math.Min(y, max), min);
z = Math.Max(Math.Min(z, max), min);
w = Math.Max(Math.Min(w, max), min);
}
///
/// Clamp the each component to specified min and max.
///
public void Clamp(Vector4d min, Vector4d max)
{
x = Math.Max(Math.Min(x, max.x), min.x);
y = Math.Max(Math.Min(y, max.y), min.y);
z = Math.Max(Math.Min(z, max.z), min.z);
w = Math.Max(Math.Min(w, max.w), min.w);
}
///
/// Lerp between two vectors.
///
public static Vector4d Lerp(Vector4d from, Vector4d to, double t)
{
if (t < 0.0) t = 0.0;
if (t > 1.0) t = 1.0;
if (t == 0.0) return from;
if (t == 1.0) return to;
double t1 = 1.0 - t;
Vector4d v = new Vector4d();
v.x = from.x * t1 + to.x * t;
v.y = from.y * t1 + to.y * t;
v.z = from.z * t1 + to.z * t;
v.w = from.w * t1 + to.w * t;
return v;
}
}
}
================================================
FILE: Assets/Common/LinearAlgebra/Vector4d.cs.meta
================================================
fileFormatVersion: 2
guid: 2766e509106656041a199c994b986a25
timeCreated: 1514536270
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Common/LinearAlgebra/Vector4f.cs
================================================
using System;
using System.Collections;
using System.Runtime.InteropServices;
using Common.Core.Mathematics;
namespace Common.Core.LinearAlgebra
{
///
/// A 4d float precision vector.
///
[StructLayout(LayoutKind.Sequential)]
public struct Vector4f
{
public float x, y, z, w;
///
/// The unit x vector.
///
public readonly static Vector4f UnitX = new Vector4f(1, 0, 0, 0);
///
/// The unit y vector.
///
public readonly static Vector4f UnitY = new Vector4f(0, 1, 0, 0);
///
/// The unit z vector.
///
public readonly static Vector4f UnitZ = new Vector4f(0, 0, 1, 0);
///
/// The unit w vector.
///
public readonly static Vector4f UnitW = new Vector4f(0, 0, 0, 1);
///
/// A vector of zeros.
///
public readonly static Vector4f Zero = new Vector4f(0);
///
/// A vector of ones.
///
public readonly static Vector4f One = new Vector4f(1);
///
/// A vector of positive infinity.
///
public readonly static Vector4f PositiveInfinity = new Vector4f(float.PositiveInfinity);
///
/// A vector of negative infinity.
///
public readonly static Vector4f NegativeInfinity = new Vector4f(float.NegativeInfinity);
///
/// Convert to a 2 dimension vector.
///
public Vector2f xy
{
get { return new Vector2f(x, y); }
}
///
/// Convert to a 3 dimension vector.
///
public Vector3f xyz
{
get { return new Vector3f(x, y, z); }
}
///
/// A copy of the vector with w as 0.
///
public Vector4f xyz0
{
get { return new Vector4f(x, y, z, 0); }
}
///
/// A vector all with the value v.
///
public Vector4f(float v)
{
this.x = v;
this.y = v;
this.z = v;
this.w = v;
}
///
/// A vector from the varibles.
///
public Vector4f(float x, float y, float z, float w)
{
this.x = x;
this.y = y;
this.z = z;
this.w = w;
}
///
/// A vector from a 2d vector and the z and w varibles.
///
public Vector4f(Vector2f v, float z, float w)
{
x = v.x;
y = v.y;
this.z = z;
this.w = w;
}
///
/// A vector from a 3d vector and the w varible.
///
public Vector4f(Vector3f v, float w)
{
x = v.x;
y = v.y;
z = v.z;
this.w = w;
}
public float this[int i]
{
get
{
switch (i)
{
case 0: return x;
case 1: return y;
case 2: return z;
case 3: return w;
default: throw new IndexOutOfRangeException("Vector4f index out of range: " + i);
}
}
set
{
switch (i)
{
case 0: x = value; break;
case 1: y = value; break;
case 2: z = value; break;
case 3: w = value; break;
default: throw new IndexOutOfRangeException("Vector4f index out of range: " + i);
}
}
}
///
/// The length of the vector.
///
public float Magnitude
{
get
{
return FMath.SafeSqrt(SqrMagnitude);
}
}
///
/// The length of the vector squared.
///
public float SqrMagnitude
{
get
{
return (x * x + y * y + z * z + w * w);
}
}
///
/// The vector normalized.
///
public Vector4f Normalized
{
get
{
float invLength = FMath.SafeInvSqrt(1.0f, x * x + y * y + z * z + w * w);
return new Vector4f(x * invLength, y * invLength, z * invLength, w * invLength);
}
}
///
/// The vectors absolute values.
///
public Vector4f Absolute
{
get
{
return new Vector4f(Math.Abs(x), Math.Abs(y), Math.Abs(z), Math.Abs(w));
}
}
///
/// Add two vectors.
///
public static Vector4f operator +(Vector4f v1, Vector4f v2)
{
return new Vector4f(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z, v1.w + v2.w);
}
///
/// Add vector and scalar.
///
public static Vector4f operator +(Vector4f v1, float s)
{
return new Vector4f(v1.x + s, v1.y + s, v1.z + s, v1.w + s);
}
///
/// Add vector and scalar.
///
public static Vector4f operator +(float s, Vector4f v1)
{
return new Vector4f(v1.x + s, v1.y + s, v1.z + s, v1.w + s);
}
///
/// Subtract two vectors.
///
public static Vector4f operator -(Vector4f v1, Vector4f v2)
{
return new Vector4f(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z, v1.w - v2.w);
}
///
/// Subtract vector and scalar.
///
public static Vector4f operator -(Vector4f v1, float s)
{
return new Vector4f(v1.x - s, v1.y - s, v1.z - s, v1.w - s);
}
///
/// Subtract vector and scalar.
///
public static Vector4f operator -(float s, Vector4f v1)
{
return new Vector4f(v1.x - s, v1.y - s, v1.z - s, v1.w - s);
}
///
/// Multiply two vectors.
///
public static Vector4f operator *(Vector4f v1, Vector4f v2)
{
return new Vector4f(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z, v1.w * v2.w);
}
///
/// Multiply a vector and a scalar.
///
public static Vector4f operator *(Vector4f v, float s)
{
return new Vector4f(v.x * s, v.y * s, v.z * s, v.w * s);
}
///
/// Multiply a vector and a scalar.
///
public static Vector4f operator *(float s, Vector4f v)
{
return new Vector4f(v.x * s, v.y * s, v.z * s, v.w * s);
}
///
/// Divide two vectors.
///
public static Vector4f operator /(Vector4f v1, Vector4f v2)
{
return new Vector4f(v1.x / v2.x, v1.y / v2.y, v1.z / v2.z, v1.w / v2.w);
}
///
/// Divide a vector and a scalar.
///
public static Vector4f operator /(Vector4f v, float s)
{
return new Vector4f(v.x / s, v.y / s, v.z / s, v.w / s);
}
///
/// Are these vectors equal.
///
public static bool operator ==(Vector4f v1, Vector4f v2)
{
return (v1.x == v2.x && v1.y == v2.y && v1.z == v2.z && v1.w == v2.w);
}
///
/// Are these vectors not equal.
///
public static bool operator !=(Vector4f v1, Vector4f v2)
{
return (v1.x != v2.x || v1.y != v2.y || v1.z != v2.z || v1.w != v2.w);
}
///
/// Are these vectors equal.
///
public override bool Equals (object obj)
{
if(!(obj is Vector4f)) return false;
Vector4f v = (Vector4f)obj;
return this == v;
}
///
/// Are these vectors equal given the error.
///
public bool EqualsWithError(Vector4f v, float eps)
{
if(Math.Abs(x-v.x)> eps) return false;
if(Math.Abs(y-v.y)> eps) return false;
if(Math.Abs(z-v.z)> eps) return false;
if(Math.Abs(w-v.w)> eps) return false;
return true;
}
///
/// Are these vectors equal.
///
public bool Equals(Vector4f v)
{
return this == v;
}
///
/// Vectors hash code.
///
public override int GetHashCode()
{
float hashcode = 23;
hashcode = (hashcode * 37) + x;
hashcode = (hashcode * 37) + y;
hashcode = (hashcode * 37) + z;
hashcode = (hashcode * 37) + w;
return unchecked((int)hashcode);
}
///
/// Vector as a string.
///
public override string ToString()
{
return x + "," + y + "," + z + "," + w;
}
///
/// Vector from a string.
///
static public Vector4f FromString(string s)
{
Vector4f v = new Vector4f();
try
{
string[] separators = new string[] { "," };
string[] result = s.Split(separators, StringSplitOptions.None);
v.x = float.Parse(result[0]);
v.y = float.Parse(result[1]);
v.z = float.Parse(result[2]);
v.w = float.Parse(result[3]);
}
catch { }
return v;
}
///
/// The dot product of two vectors.
///
public static float Dot(Vector4f v0, Vector4f v1)
{
return (v0.x * v1.x + v0.y * v1.y + v0.z * v1.z + v0.w * v1.w);
}
///
/// Distance between two vectors.
///
public static float Distance(Vector4f v0, Vector4f v1)
{
return FMath.SafeSqrt(SqrDistance(v0, v1));
}
///
/// Square distance between two vectors.
///
public static float SqrDistance(Vector4f v0, Vector4f v1)
{
float x = v0.x - v1.x;
float y = v0.y - v1.y;
float z = v0.z - v1.z;
float w = v0.w - v1.w;
return x * x + y * y + z * z + w*w;
}
///
/// Normalize the vector.
///
public void Normalize()
{
float invLength = FMath.SafeInvSqrt(1.0f, x * x + y * y + z * z + w * w);
x *= invLength;
y *= invLength;
z *= invLength;
w *= invLength;
}
///
/// The minimum value between s and each component in vector.
///
public void Min(float s)
{
x = Math.Min(x, s);
y = Math.Min(y, s);
z = Math.Min(z, s);
w = Math.Min(w, s);
}
///
/// The minimum value between each component in vectors.
///
public void Min(Vector4f v)
{
x = Math.Min(x, v.x);
y = Math.Min(y, v.y);
z = Math.Min(z, v.z);
w = Math.Min(w, v.w);
}
///
/// The maximum value between s and each component in vector.
///
public void Max(float s)
{
x = Math.Max(x, s);
y = Math.Max(y, s);
z = Math.Max(z, s);
w = Math.Max(w, s);
}
///
/// The maximum value between each component in vectors.
///
public void Max(Vector4f v)
{
x = Math.Max(x, v.x);
y = Math.Max(y, v.y);
z = Math.Max(z, v.z);
w = Math.Max(w, v.w);
}
///
/// The absolute vector.
///
public void Abs()
{
x = Math.Abs(x);
y = Math.Abs(y);
z = Math.Abs(z);
w = Math.Abs(w);
}
///
/// Clamp the each component to specified min and max.
///
public void Clamp(float min, float max)
{
x = Math.Max(Math.Min(x, max), min);
y = Math.Max(Math.Min(y, max), min);
z = Math.Max(Math.Min(z, max), min);
w = Math.Max(Math.Min(w, max), min);
}
///
/// Clamp the each component to specified min and max.
///
public void Clamp(Vector4f min, Vector4f max)
{
x = Math.Max(Math.Min(x, max.x), min.x);
y = Math.Max(Math.Min(y, max.y), min.y);
z = Math.Max(Math.Min(z, max.z), min.z);
w = Math.Max(Math.Min(w, max.w), min.w);
}
///
/// Lerp between two vectors.
///
public static Vector4f Lerp(Vector4f from, Vector4f to, float t)
{
if (t < 0.0f) t = 0.0f;
if (t > 1.0f) t = 1.0f;
if (t == 0.0f) return from;
if (t == 1.0f) return to;
float t1 = 1.0f - t;
Vector4f v = new Vector4f();
v.x = from.x * t1 + to.x * t;
v.y = from.y * t1 + to.y * t;
v.z = from.z * t1 + to.z * t;
v.w = from.w * t1 + to.w * t;
return v;
}
}
}
================================================
FILE: Assets/Common/LinearAlgebra/Vector4f.cs.meta
================================================
fileFormatVersion: 2
guid: 8ea49a7834165304c8ca5b1bc42aaf48
timeCreated: 1514536270
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Common/LinearAlgebra/Vector4i.cs
================================================
using System;
using System.Collections;
using System.Runtime.InteropServices;
using Common.Core.Mathematics;
namespace Common.Core.LinearAlgebra
{
[StructLayout(LayoutKind.Sequential)]
public struct Vector4i
{
public int x, y, z, w;
///
/// The unit x vector.
///
public readonly static Vector4i UnitX = new Vector4i(1, 0, 0, 0);
///
/// The unit y vector.
///
public readonly static Vector4i UnitY = new Vector4i(0, 1, 0, 0);
///
/// The unit z vector.
///
public readonly static Vector4i UnitZ = new Vector4i(0, 0, 1, 0);
///
/// The unit w vector.
///
public readonly static Vector4i UnitW = new Vector4i(0, 0, 0, 1);
///
/// A vector of zeros.
///
public readonly static Vector4i Zero = new Vector4i(0);
///
/// A vector of ones.
///
public readonly static Vector4i One = new Vector4i(1);
///
/// A vector of min int.
///
public readonly static Vector4i MinInt = new Vector4i(int.MinValue);
///
/// A vector of max int.
///
public readonly static Vector4i MaxInt = new Vector4i(int.MaxValue);
public Vector4i(int v)
{
this.x = v;
this.y = v;
this.z = v;
this.w = v;
}
public Vector4i(int x, int y, int z, int w)
{
this.x = x;
this.y = y;
this.z = z;
this.w = w;
}
public int this[int i]
{
get
{
switch (i)
{
case 0: return x;
case 1: return y;
case 2: return z;
case 3: return w;
default: throw new IndexOutOfRangeException("Vector4i index out of range: " + i);
}
}
set
{
switch (i)
{
case 0: x = value; break;
case 1: y = value; break;
case 2: z = value; break;
case 3: w = value; break;
default: throw new IndexOutOfRangeException("Vector4i index out of range: " + i);
}
}
}
///
/// The length of the vector.
///
public double Magnitude
{
get
{
return DMath.SafeSqrt(SqrMagnitude);
}
}
///
/// The length of the vector squared.
///
public int SqrMagnitude
{
get
{
return (x * x + y * y + z * z + w * w);
}
}
///
/// The vectors absolute values.
///
public Vector4i Absolute
{
get
{
return new Vector4i(Math.Abs(x), Math.Abs(y), Math.Abs(z), Math.Abs(w));
}
}
///
/// Add two vectors.
///
public static Vector4i operator +(Vector4i v1, Vector4i v2)
{
return new Vector4i(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z, v1.w + v2.w);
}
///
/// Add vector and scalar.
///
public static Vector4i operator +(Vector4i v1, int s)
{
return new Vector4i(v1.x + s, v1.y + s, v1.z + s, v1.w + s);
}
///
/// Add vector and scalar.
///
public static Vector4i operator +(int s, Vector4i v1)
{
return new Vector4i(v1.x + s, v1.y + s, v1.z + s, v1.w + s);
}
///
/// Subtract two vectors.
///
public static Vector4i operator -(Vector4i v1, Vector4i v2)
{
return new Vector4i(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z, v1.w - v2.w);
}
///
/// Subtract vector and scalar.
///
public static Vector4i operator -(Vector4i v1, int s)
{
return new Vector4i(v1.x - s, v1.y - s, v1.z - s, v1.w - s);
}
///
/// Subtract vector and scalar.
///
public static Vector4i operator -(int s, Vector4i v1)
{
return new Vector4i(v1.x - s, v1.y - s, v1.z - s, v1.w - s);
}
///
/// Multiply two vectors.
///
public static Vector4i operator *(Vector4i v1, Vector4i v2)
{
return new Vector4i(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z, v1.w * v2.w);
}
///
/// Multiply a vector and a scalar.
///
public static Vector4i operator *(Vector4i v, int s)
{
return new Vector4i(v.x * s, v.y * s, v.z * s, v.w * s);
}
///
/// Multiply a vector and a scalar.
///
public static Vector4i operator *(int s, Vector4i v)
{
return new Vector4i(v.x * s, v.y * s, v.z * s, v.w * s);
}
///
/// Divide two vectors.
///
public static Vector4i operator /(Vector4i v1, Vector4i v2)
{
return new Vector4i(v1.x / v2.x, v1.y / v2.y, v1.z / v2.z, v1.w / v2.w);
}
///
/// Divide a vector and a scalar.
///
public static Vector4i operator /(Vector4i v, int s)
{
return new Vector4i(v.x / s, v.y / s, v.z / s, v.w / s);
}
///
/// Are these vectors equal.
///
public static bool operator ==(Vector4i v1, Vector4i v2)
{
return (v1.x == v2.x && v1.y == v2.y && v1.z == v2.z && v1.w == v2.w);
}
///
/// Are these vectors not equal.
///
public static bool operator !=(Vector4i v1, Vector4i v2)
{
return (v1.x != v2.x || v1.y != v2.y || v1.z != v2.z || v1.w != v2.w);
}
///
/// Are these vectors equal.
///
public override bool Equals (object obj)
{
if(!(obj is Vector4i)) return false;
Vector4i v = (Vector4i)obj;
return this == v;
}
///
/// Are these vectors equal.
///
public bool Equals(Vector4i v)
{
return this == v;
}
///
/// Vectors hash code.
///
public override int GetHashCode()
{
int hashcode = 23;
unchecked
{
hashcode = (hashcode * 37) + x;
hashcode = (hashcode * 37) + y;
hashcode = (hashcode * 37) + z;
hashcode = (hashcode * 37) + w;
}
return hashcode;
}
///
/// Vector as a string.
///
public override string ToString()
{
return x + "," + y + "," + z + "," + w;
}
///
/// Vector from a string.
///
static public Vector4i FromString(string s)
{
Vector4i v = new Vector4i();
try
{
string[] separators = new string[] { "," };
string[] result = s.Split(separators, StringSplitOptions.None);
v.x = int.Parse(result[0]);
v.y = int.Parse(result[1]);
v.z = int.Parse(result[2]);
v.w = int.Parse(result[3]);
}
catch { }
return v;
}
///
/// The dot product of two vectors.
///
public static int Dot(Vector4i v0, Vector4i v1)
{
return (v0.x * v1.x + v0.y * v1.y + v0.z * v1.z + v0.w * v1.w);
}
///
/// Distance between two vectors.
///
public static double Distance(Vector4i v0, Vector4i v1)
{
return DMath.SafeSqrt(SqrDistance(v0, v1));
}
///
/// Square distance between two vectors.
///
public static double SqrDistance(Vector4i v0, Vector4i v1)
{
double x = v0.x - v1.x;
double y = v0.y - v1.y;
double z = v0.z - v1.z;
double w = v0.w - v1.w;
return x * x + y * y + z * z + w * w;
}
///
/// The minimum value between s and each component in vector.
///
public void Min(int s)
{
x = Math.Min(x, s);
y = Math.Min(y, s);
z = Math.Min(z, s);
w = Math.Min(w, s);
}
///
/// The minimum value between each component in vectors.
///
public void Min(Vector4i v)
{
x = Math.Min(x, v.x);
y = Math.Min(y, v.y);
z = Math.Min(z, v.z);
w = Math.Min(w, v.w);
}
///
/// The maximum value between s and each component in vector.
///
public void Max(int s)
{
x = Math.Max(x, s);
y = Math.Max(y, s);
z = Math.Max(z, s);
w = Math.Max(w, s);
}
///
/// The maximum value between each component in vectors.
///
public void Max(Vector4i v)
{
x = Math.Max(x, v.x);
y = Math.Max(y, v.y);
z = Math.Max(z, v.z);
w = Math.Max(w, v.w);
}
///
/// The absolute vector.
///
public void Abs()
{
x = Math.Abs(x);
y = Math.Abs(y);
z = Math.Abs(z);
w = Math.Abs(w);
}
///
/// Clamp the each component to specified min and max.
///
public void Clamp(int min, int max)
{
x = Math.Max(Math.Min(x, max), min);
y = Math.Max(Math.Min(y, max), min);
z = Math.Max(Math.Min(z, max), min);
w = Math.Max(Math.Min(w, max), min);
}
///
/// Clamp the each component to specified min and max.
///
public void Clamp(Vector4i min, Vector4i max)
{
x = Math.Max(Math.Min(x, max.x), min.x);
y = Math.Max(Math.Min(y, max.y), min.y);
z = Math.Max(Math.Min(z, max.z), min.z);
w = Math.Max(Math.Min(w, max.w), min.w);
}
}
}
================================================
FILE: Assets/Common/LinearAlgebra/Vector4i.cs.meta
================================================
fileFormatVersion: 2
guid: 76636d8a8f9545a43a7ca5a30de4b00e
timeCreated: 1514536270
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Common/LinearAlgebra.meta
================================================
fileFormatVersion: 2
guid: dbcf441fe7fb93143a9acab04c44f587
folderAsset: yes
timeCreated: 1514536270
licenseType: Free
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Common/Mathematics/DMath.cs
================================================
using System;
namespace Common.Core.Mathematics
{
public class DMath
{
public static readonly double EPS = 1e-18;
public static readonly double PI = Math.PI;
public static readonly double Rad2Deg = 180.0 / PI;
public static readonly double Deg2Rad = PI / 180.0;
public static double SafeAcos(double r)
{
return Math.Acos(Math.Min(1.0, Math.Max(-1.0, r)));
}
public static double SafeAsin(double r)
{
return Math.Asin(Math.Min(1.0, Math.Max(-1.0, r)));
}
public static double SafeSqrt(double v)
{
if (v <= 0.0) return 0.0;
return Math.Sqrt(v);
}
public static double SafeInvSqrt(double n, double d)
{
if (d <= 0.0) return 0.0;
d = Math.Sqrt(d);
if (d < EPS) return 0.0;
return n / d;
}
public static double SafeInv(double v)
{
if (Math.Abs(v) < EPS) return 0.0;
return 1.0 / v;
}
public static double SafeDiv(double n, double d)
{
if (Math.Abs(d) < EPS) return 0.0;
return n / d;
}
public static bool IsZero(double v)
{
return Math.Abs(v) < EPS;
}
public static bool IsFinite(double f)
{
return !(double.IsInfinity(f) || double.IsNaN(f));
}
public static double Clamp(double v, double min, double max)
{
if (v < min) v = min;
if (v > max) v = max;
return v;
}
public static double Clamp01(double v)
{
if (v < 0.0) v = 0.0;
if (v > 1.0) v = 1.0;
return v;
}
public static double SmoothStep(double edge0, double edge1, double x)
{
double t = Clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);
return t * t * (3.0 - 2.0 * t);
}
public static double Frac(double x)
{
return x - Math.Floor(x);
}
public static double Lerp(double v0, double v1, double a)
{
return v0 * (1.0 - a) + v1 * a;
}
}
}
================================================
FILE: Assets/Common/Mathematics/DMath.cs.meta
================================================
fileFormatVersion: 2
guid: e9811506d7286624cbaaa86bf5ea2ac2
timeCreated: 1514536310
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Common/Mathematics/FMath.cs
================================================
using System;
namespace Common.Core.Mathematics
{
public class FMath
{
public static readonly float EPS = 1e-9f;
public static readonly float PI = (float)Math.PI;
public static readonly float Rad2Deg = 180.0f / PI;
public static readonly float Deg2Rad = PI / 180.0f;
public static float SafeAcos(float r)
{
return (float)Math.Acos(Math.Min(1.0f, Math.Max(-1.0f, r)));
}
public static float SafeAsin(float r)
{
return (float)Math.Asin(Math.Min(1.0f, Math.Max(-1.0f, r)));
}
public static float SafeSqrt(float v)
{
if (v <= 0.0f) return 0.0f;
return (float)Math.Sqrt(v);
}
public static float SafeInvSqrt(float n, float d)
{
if (d <= 0.0f) return 0.0f;
d = (float)Math.Sqrt(d);
if (d < EPS) return 0.0f;
return n / d;
}
public static float SafeInv(float v)
{
if (Math.Abs(v) < EPS) return 0.0f;
return 1.0f / v;
}
public static float SafeDiv(float n, float d)
{
if (Math.Abs(d) < EPS) return 0.0f;
return n / d;
}
public static bool IsZero(float v)
{
return Math.Abs(v) < EPS;
}
public static bool IsFinite(float f)
{
return !(float.IsInfinity(f) || float.IsNaN(f));
}
public static float Clamp(float v, float min, float max)
{
if (v < min) v = min;
if (v > max) v = max;
return v;
}
public static float Clamp01(float v)
{
if (v < 0.0f) v = 0.0f;
if (v > 1.0f) v = 1.0f;
return v;
}
public static float SmoothStep(float edge0, float edge1, float x)
{
float t = Clamp((x - edge0) / (edge1 - edge0), 0.0f, 1.0f);
return t * t * (3.0f - 2.0f * t);
}
public static float Frac(float x)
{
return x - (float)Math.Floor(x);
}
public static float Lerp(float v0, float v1, float a)
{
return v0 * (1.0f - a) + v1 * a;
}
}
}
================================================
FILE: Assets/Common/Mathematics/FMath.cs.meta
================================================
fileFormatVersion: 2
guid: 20b1889a7c1251b4b8ff543a0ebcb6d0
timeCreated: 1514536310
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Common/Mathematics/IMath.cs
================================================
using System;
namespace Common.Core.Mathematics
{
public class IMath
{
public static int Clamp(int v, int min, int max)
{
if (v < min) v = min;
if (v > max) v = max;
return v;
}
public static bool IsPow2(int num)
{
int power = (int)(Math.Log(num) / Math.Log(2.0));
double result = Math.Pow(2.0, power);
return (result == num);
}
public static int NearestPow2(int num)
{
int n = num > 0 ? num - 1 : 0;
n |= n >> 1;
n |= n >> 2;
n |= n >> 4;
n |= n >> 8;
n |= n >> 16;
n++;
return n;
}
public static int LowerPow2(int num)
{
int n = num > 0 ? num - 1 : 0;
n |= n >> 1;
n |= n >> 2;
n |= n >> 4;
n |= n >> 8;
n |= n >> 16;
n++;
return n - (n >> 1);
}
}
}
================================================
FILE: Assets/Common/Mathematics/IMath.cs.meta
================================================
fileFormatVersion: 2
guid: fd9b410d6fb0aeb4695a51db5bb1eaea
timeCreated: 1514536310
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Common/Mathematics.meta
================================================
fileFormatVersion: 2
guid: bc2beaf82238a5249a353d02afb0edca
folderAsset: yes
timeCreated: 1514536310
licenseType: Free
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Common.meta
================================================
fileFormatVersion: 2
guid: 0ad1543cd6efc234284c34aeefa1430a
folderAsset: yes
timeCreated: 1514536270
licenseType: Free
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/FEM2D/Demo.unity
================================================
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!29 &1
OcclusionCullingSettings:
m_ObjectHideFlags: 0
serializedVersion: 2
m_OcclusionBakeSettings:
smallestOccluder: 5
smallestHole: 0.25
backfaceThreshold: 100
m_SceneGUID: 00000000000000000000000000000000
m_OcclusionCullingData: {fileID: 0}
--- !u!104 &2
RenderSettings:
m_ObjectHideFlags: 0
serializedVersion: 9
m_Fog: 0
m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1}
m_FogMode: 3
m_FogDensity: 0.01
m_LinearFogStart: 0
m_LinearFogEnd: 300
m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1}
m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1}
m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1}
m_AmbientIntensity: 1
m_AmbientMode: 0
m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1}
m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0}
m_HaloStrength: 0.5
m_FlareStrength: 1
m_FlareFadeSpeed: 3
m_HaloTexture: {fileID: 0}
m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0}
m_DefaultReflectionMode: 0
m_DefaultReflectionResolution: 128
m_ReflectionBounces: 1
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0.44657898, g: 0.4964133, b: 0.5748178, a: 1}
m_UseRadianceAmbientProbe: 0
--- !u!157 &3
LightmapSettings:
m_ObjectHideFlags: 0
serializedVersion: 12
m_GIWorkflowMode: 0
m_GISettings:
serializedVersion: 2
m_BounceScale: 1
m_IndirectOutputScale: 1
m_AlbedoBoost: 1
m_EnvironmentLightingMode: 0
m_EnableBakedLightmaps: 1
m_EnableRealtimeLightmaps: 1
m_LightmapEditorSettings:
serializedVersion: 12
m_Resolution: 2
m_BakeResolution: 40
m_AtlasSize: 1024
m_AO: 0
m_AOMaxDistance: 1
m_CompAOExponent: 1
m_CompAOExponentDirect: 0
m_ExtractAmbientOcclusion: 0
m_Padding: 2
m_LightmapParameters: {fileID: 0}
m_LightmapsBakeMode: 1
m_TextureCompression: 1
m_FinalGather: 0
m_FinalGatherFiltering: 1
m_FinalGatherRayCount: 256
m_ReflectionCompression: 2
m_MixedBakeMode: 1
m_BakeBackend: 0
m_PVRSampling: 1
m_PVRDirectSampleCount: 32
m_PVRSampleCount: 500
m_PVRBounces: 2
m_PVREnvironmentSampleCount: 500
m_PVREnvironmentReferencePointCount: 2048
m_PVRFilteringMode: 0
m_PVRDenoiserTypeDirect: 0
m_PVRDenoiserTypeIndirect: 0
m_PVRDenoiserTypeAO: 0
m_PVRFilterTypeDirect: 0
m_PVRFilterTypeIndirect: 0
m_PVRFilterTypeAO: 0
m_PVREnvironmentMIS: 0
m_PVRCulling: 1
m_PVRFilteringGaussRadiusDirect: 1
m_PVRFilteringGaussRadiusIndirect: 5
m_PVRFilteringGaussRadiusAO: 2
m_PVRFilteringAtrousPositionSigmaDirect: 0.5
m_PVRFilteringAtrousPositionSigmaIndirect: 2
m_PVRFilteringAtrousPositionSigmaAO: 1
m_ExportTrainingData: 0
m_TrainingDataDestination: TrainingData
m_LightProbeSampleCountMultiplier: 4
m_LightingDataAsset: {fileID: 0}
m_LightingSettings: {fileID: 53020077}
--- !u!196 &4
NavMeshSettings:
serializedVersion: 2
m_ObjectHideFlags: 0
m_BuildSettings:
serializedVersion: 2
agentTypeID: 0
agentRadius: 0.5
agentHeight: 2
agentSlope: 45
agentClimb: 0.4
ledgeDropHeight: 0
maxJumpAcrossDistance: 0
minRegionArea: 2
manualCellSize: 0
cellSize: 0.16666667
manualTileSize: 0
tileSize: 256
accuratePlacement: 0
maxJobWorkers: 0
preserveTilesOutsideBounds: 0
debug:
m_Flags: 0
m_NavMeshData: {fileID: 0}
--- !u!850595691 &53020077
LightingSettings:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: Settings.lighting
serializedVersion: 2
m_GIWorkflowMode: 0
m_EnableBakedLightmaps: 1
m_EnableRealtimeLightmaps: 1
m_RealtimeEnvironmentLighting: 1
m_BounceScale: 1
m_AlbedoBoost: 1
m_IndirectOutputScale: 1
m_UsingShadowmask: 0
m_BakeBackend: 0
m_LightmapMaxSize: 1024
m_BakeResolution: 40
m_Padding: 2
m_TextureCompression: 1
m_AO: 0
m_AOMaxDistance: 1
m_CompAOExponent: 1
m_CompAOExponentDirect: 0
m_ExtractAO: 0
m_MixedBakeMode: 1
m_LightmapsBakeMode: 1
m_FilterMode: 1
m_LightmapParameters: {fileID: 0}
m_ExportTrainingData: 0
m_TrainingDataDestination: TrainingData
m_RealtimeResolution: 2
m_ForceWhiteAlbedo: 0
m_ForceUpdates: 0
m_FinalGather: 0
m_FinalGatherRayCount: 256
m_FinalGatherFiltering: 1
m_PVRCulling: 1
m_PVRSampling: 1
m_PVRDirectSampleCount: 32
m_PVRSampleCount: 500
m_PVREnvironmentSampleCount: 500
m_PVREnvironmentReferencePointCount: 2048
m_LightProbeSampleCountMultiplier: 4
m_PVRBounces: 2
m_PVRRussianRouletteStartBounce: 2
m_PVREnvironmentMIS: 0
m_PVRFilteringMode: 0
m_PVRDenoiserTypeDirect: 0
m_PVRDenoiserTypeIndirect: 0
m_PVRDenoiserTypeAO: 0
m_PVRFilterTypeDirect: 0
m_PVRFilterTypeIndirect: 0
m_PVRFilterTypeAO: 0
m_PVRFilteringGaussRadiusDirect: 1
m_PVRFilteringGaussRadiusIndirect: 5
m_PVRFilteringGaussRadiusAO: 2
m_PVRFilteringAtrousPositionSigmaDirect: 0.5
m_PVRFilteringAtrousPositionSigmaIndirect: 2
m_PVRFilteringAtrousPositionSigmaAO: 1
--- !u!1 &617497645
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 617497648}
- component: {fileID: 617497647}
- component: {fileID: 617497646}
m_Layer: 0
m_Name: Main Camera
m_TagString: MainCamera
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &617497646
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 617497645}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 21b56fa4ac510b34d865a6cae689b006, type: 3}
m_Name:
m_EditorClassIdentifier:
option: 3
drawWireframe: 1
armadillo: {fileID: 2800000, guid: 8d4354cace070ef41a318c34670ff88a, type: 3}
bunny: {fileID: 2800000, guid: 689440ccb80c6a348afee121dd2fa9e3, type: 3}
donut: {fileID: 2800000, guid: 4df4a7e175870f94ca81a95b3d9c28f4, type: 3}
textureMaterial: {fileID: 2100000, guid: 716d33869f0597743928b3f83bbdbd52, type: 2}
--- !u!20 &617497647
Camera:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 617497645}
m_Enabled: 1
serializedVersion: 2
m_ClearFlags: 2
m_BackGroundColor: {r: 0, g: 0, b: 0, a: 0}
m_projectionMatrixMode: 1
m_GateFitMode: 2
m_FOVAxisMode: 0
m_SensorSize: {x: 36, y: 24}
m_LensShift: {x: 0, y: 0}
m_FocalLength: 50
m_NormalizedViewPortRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
near clip plane: 0.3
far clip plane: 1000
field of view: 60
orthographic: 1
orthographic size: 2
m_Depth: -1
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingPath: -1
m_TargetTexture: {fileID: 0}
m_TargetDisplay: 0
m_TargetEye: 3
m_HDR: 0
m_AllowMSAA: 1
m_AllowDynamicResolution: 0
m_ForceIntoRT: 0
m_OcclusionCulling: 1
m_StereoConvergence: 10
m_StereoSeparation: 0.022
--- !u!4 &617497648
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 617497645}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: -1}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 0
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &958705224
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 958705226}
- component: {fileID: 958705225}
m_Layer: 0
m_Name: Directional Light
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!108 &958705225
Light:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 958705224}
m_Enabled: 1
serializedVersion: 10
m_Type: 1
m_Shape: 0
m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1}
m_Intensity: 1
m_Range: 10
m_SpotAngle: 30
m_InnerSpotAngle: 21.80208
m_CookieSize: 10
m_Shadows:
m_Type: 2
m_Resolution: -1
m_CustomResolution: -1
m_Strength: 1
m_Bias: 0.05
m_NormalBias: 0.4
m_NearPlane: 0.2
m_CullingMatrixOverride:
e00: 1
e01: 0
e02: 0
e03: 0
e10: 0
e11: 1
e12: 0
e13: 0
e20: 0
e21: 0
e22: 1
e23: 0
e30: 0
e31: 0
e32: 0
e33: 1
m_UseCullingMatrixOverride: 0
m_Cookie: {fileID: 0}
m_DrawHalo: 0
m_Flare: {fileID: 0}
m_RenderMode: 0
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingLayerMask: 1
m_Lightmapping: 4
m_LightShadowCasterMode: 0
m_AreaSize: {x: 1, y: 1}
m_BounceIntensity: 1
m_ColorTemperature: 6570
m_UseColorTemperature: 0
m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0}
m_UseBoundingSphereOverride: 0
m_ShadowRadius: 0
m_ShadowAngle: 0
--- !u!4 &958705226
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 958705224}
m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261}
m_LocalPosition: {x: 0, y: 3, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 0}
m_RootOrder: 1
m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0}
================================================
FILE: Assets/FEM2D/Demo.unity.meta
================================================
fileFormatVersion: 2
guid: 0ab61520f30dba1468adadce55fe25dd
timeCreated: 1488699394
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/FEM2D/Materials/TextureMaterial.mat
================================================
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!21 &2100000
Material:
serializedVersion: 6
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_Name: TextureMaterial
m_Shader: {fileID: 4800000, guid: e66837fa03fca10469cf24b483791e6d, type: 3}
m_ShaderKeywords:
m_LightmapFlags: 4
m_EnableInstancingVariants: 0
m_DoubleSidedGI: 0
m_CustomRenderQueue: -1
stringTagMap: {}
disabledShaderPasses: []
m_SavedProperties:
serializedVersion: 3
m_TexEnvs:
- _BumpMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailAlbedoMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailMask:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _DetailNormalMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _EmissionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MainTex:
m_Texture: {fileID: 2800000, guid: 4df4a7e175870f94ca81a95b3d9c28f4, type: 3}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _MetallicGlossMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _OcclusionMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
- _ParallaxMap:
m_Texture: {fileID: 0}
m_Scale: {x: 1, y: 1}
m_Offset: {x: 0, y: 0}
m_Floats:
- _BumpScale: 1
- _Cutoff: 0.5
- _DetailNormalMapScale: 1
- _DstBlend: 0
- _GlossMapScale: 1
- _Glossiness: 0.5
- _GlossyReflections: 1
- _Metallic: 0
- _Mode: 0
- _OcclusionStrength: 1
- _Parallax: 0.02
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _UVSec: 0
- _ZWrite: 1
m_Colors:
- _Color: {r: 1, g: 1, b: 1, a: 1}
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
m_BuildTextureStacks: []
================================================
FILE: Assets/FEM2D/Materials/TextureMaterial.mat.meta
================================================
fileFormatVersion: 2
guid: 716d33869f0597743928b3f83bbdbd52
timeCreated: 1514631150
licenseType: Free
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 2100000
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/FEM2D/Materials/TextureShader.shader
================================================
Shader "Unlit/TextureShader"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv);
// apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
ENDCG
}
}
}
================================================
FILE: Assets/FEM2D/Materials/TextureShader.shader.meta
================================================
fileFormatVersion: 2
guid: e66837fa03fca10469cf24b483791e6d
timeCreated: 1514631092
licenseType: Free
ShaderImporter:
externalObjects: {}
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/FEM2D/Materials.meta
================================================
fileFormatVersion: 2
guid: 6ccc40a7591015c4f914ee5ef5e031b1
folderAsset: yes
timeCreated: 1514632914
licenseType: Free
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/FEM2D/Scripts/CreateCantileverBeam.cs
================================================
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Common.Core.LinearAlgebra;
namespace FEM2D
{
public static class CreateCantileverBeam
{
public static FEMScene Create(Vector2f origin, float scale, int numPoints, bool weld)
{
FEMScene Scene = new FEMScene();
Scene.Substeps = 40;
Scene.Drag = 1.0f;
Scene.LameLambda = 4000.0f;
Scene.LameMu = 4000.0f;
Scene.Damping = 200.0f;
Scene.Friction = 0.5f;
Scene.Toughness = 8000.0f;
float u = scale / (numPoints-1.0f);
for (int i = 0; i < numPoints; ++i)
{
Scene.Particles.Add(new FEMParticle(origin + new Vector2f(i * u, 0.0f), 1.0f));
Scene.Particles.Add(new FEMParticle(origin + new Vector2f(i * u, u), 1.0f));
if (i != 0)
{
// add quad
int start = (i - 1) * 2;
Scene.Triangles.Add(new Triangle(start + 0, start + 2, start + 1));
Scene.Triangles.Add(new Triangle(start + 1, start + 2, start + 3));
}
}
if (weld)
{
Scene.Particles[0].invMass = 0.0f;
Scene.Particles[1].invMass = 0.0f;
}
// assign index to particles
for (int i = 0; i < Scene.Particles.Count; ++i)
Scene.Particles[i].index = i;
Scene.CreateElements();
return Scene;
}
}
}
================================================
FILE: Assets/FEM2D/Scripts/CreateCantileverBeam.cs.meta
================================================
fileFormatVersion: 2
guid: 28cacb6d1b62dc240b8580f8e3b751c3
timeCreated: 1514597507
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/FEM2D/Scripts/CreateFromImage.cs
================================================
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Common.Core.LinearAlgebra;
namespace FEM2D
{
public static class CreateFromImage
{
private static float resolution = 0.08f;
private static float scale = 2.0f;
private static float density = 140f;
private static float aspect;
private static Vector2f ToWorldPos(Vector2f p)
{
float x = (p.x - 0.5f) * scale;
float y = (p.y - 0.5f) * scale * aspect;
return new Vector2f(x, y);
}
public static FEMScene Create(Texture2D img)
{
FEMScene Scene = new FEMScene();
if (img == null) return Scene;
Scene.Substeps = 80;
Scene.Drag = 0.1f;
Scene.LameLambda = 42000.0f;
Scene.LameMu = 42000.0f;
Scene.Damping = 250.0f;
Scene.Friction = 0.8f;
Scene.Toughness = 40000.0f;
List points = new List();
List bpoints = new List();
// controls how finely the object is sampled
aspect = (float)img.height / img.width;
float fw = img.width;
float fh = img.height;
int inc = Mathf.FloorToInt(img.width * resolution);
int margin = Mathf.Max((inc - 1) / 2, 1);
// distribute points interior to the object or near it's boundary
for (int y = 0; y < img.height; y += inc)
{
for (int x = 0; x < img.width; x += inc)
{
// if value non-zero then add a point
int n = Neighbours(img, x, y, margin);
if (n > 0)
{
Vector2f uv = new Vector2f(x / fw, y / fh);
points.Add(uv);
}
}
}
// distribute points on the boundary
for (int y = 0; y < img.height; y++)
{
for (int x = 0; x < img.width; x++)
{
if (EdgeDetect(img, x, y))
{
Vector2f uv = new Vector2f(x / fw, y / fh);
bpoints.Add(uv);
}
}
}
// triangulate
int iterations = 7;
List verts;
List tris;
Mesher.TriangulateVariational(points, bpoints, iterations, out verts, out tris);
//no longer used
points = null;
bpoints = null;
// discard triangles whose centroid is not inside the shape
for (int i = 0; i < tris.Count;)
{
Vector2f p = verts[tris[i + 0]];
Vector2f q = verts[tris[i + 1]];
Vector2f r = verts[tris[i + 2]];
Vector2f c = (p + q + r) / 3.0f;
//int x = Mathf.FloorToInt(c.x * fw);
//int y = Mathf.FloorToInt(c.y * fh);
//Color col = img.GetPixel(x, y);
Color col = img.GetPixelBilinear(c.x, c.y);
if (col.grayscale == 0.0f)
tris.RemoveRange(i, 3);
else
i += 3;
}
// generate particles
for (int i = 0; i < verts.Count; ++i)
{
Vector2f uv = verts[i];
Scene.Particles.Add(new FEMParticle(ToWorldPos(uv), uv, 0.0f));
}
// generate elements and assign mass based on connected area
for (int t = 0; t < tris.Count; t += 3)
{
int i = tris[t];
int j = tris[t + 1];
int k = tris[t + 2];
// calculate tri area
Vector2f a = Scene.Particles[i].p;
Vector2f b = Scene.Particles[j].p;
Vector2f c = Scene.Particles[k].p;
float area = 0.5f * Vector2f.Cross(b - a, c - a);
float mass = density * area / 3.0f;
Scene.Particles[i].invMass += mass;
Scene.Particles[j].invMass += mass;
Scene.Particles[k].invMass += mass;
Scene.Triangles.Add(new Triangle(i, j, k));
}
// convert mass to invmass
for (int i = 0; i < Scene.Particles.Count; ++i)
{
if (Scene.Particles[i].invMass > 0.0f)
Scene.Particles[i].invMass = 1.0f / Scene.Particles[i].invMass;
}
// assign index to particles
for (int i = 0; i < Scene.Particles.Count; ++i)
Scene.Particles[i].index = i;
Scene.CreateElements();
return Scene;
}
///
/// return true if any pixels in box are non-zero
///
private static int Neighbours(Texture2D img, int cx, int cy, int margin)
{
int xmin = Mathf.Max(0, cx - margin);
int xmax = Mathf.Min(cx + margin, img.width - 1);
int ymin = Mathf.Max(0, cy - margin);
int ymax = Mathf.Min(cy + margin, img.height - 1);
int count = 0;
for (int y = ymin; y <= ymax; ++y)
{
for (int x = xmin; x <= xmax; ++x)
{
Color col = img.GetPixel(x, y);
if (col.grayscale > 0.0f)
{
++count;
}
}
}
return count;
}
private static bool EdgeDetect(Texture2D img, int x, int y)
{
Color colp0 = img.GetPixel(x + 1, y);
Color coln0 = img.GetPixel(x - 1, y);
if ((colp0.grayscale > 0.0f) != (coln0.grayscale > 0.0f))
return true;
Color col0p = img.GetPixel(x, y + 1);
Color col0n = img.GetPixel(x, y - 1);
if ((col0p.grayscale > 0.0f) != (col0n.grayscale > 0.0f))
return true;
return false;
}
}
}
================================================
FILE: Assets/FEM2D/Scripts/CreateFromImage.cs.meta
================================================
fileFormatVersion: 2
guid: 9b53bb4644f88484687638a032f37ea1
timeCreated: 1514625832
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/FEM2D/Scripts/CreateRandomConvex.cs
================================================
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Common.Core.LinearAlgebra;
namespace FEM2D
{
public static class CreateRandomConvex
{
public static FEMScene Create(Vector2f origin, float scale, int numPoints)
{
FEMScene Scene = new FEMScene();
Scene.Substeps = 40;
Scene.Drag = 1.0f;
Scene.LameLambda = 10000.0f;
Scene.LameMu = 10000.0f;
Scene.Damping = 80.0f;
Scene.Friction = 0.95f;
Scene.Toughness = 20000.0f;
List points = new List();
//Random.InitState(0);
for (int i = 0; i < numPoints; ++i)
{
float rx = Random.Range(-scale, scale) * 0.5f;
float ry = Random.Range(-scale, scale) * 0.5f;
points.Add(origin + new Vector2f(rx, ry));
}
List verts;
List tris;
Mesher.TriangulateDelaunay(points, out verts, out tris);
// generate elements
for (int i = 0; i < verts.Count; ++i)
Scene.Particles.Add(new FEMParticle(verts[i], 1.0f));
for (int i = 0; i < tris.Count / 3; ++i)
Scene.Triangles.Add(new Triangle(tris[i * 3], tris[i * 3 + 1], tris[i * 3 + 2]));
// assign index to particles
for (int i = 0; i < Scene.Particles.Count; ++i)
Scene.Particles[i].index = i;
Scene.CreateElements();
return Scene;
}
}
}
================================================
FILE: Assets/FEM2D/Scripts/CreateRandomConvex.cs.meta
================================================
fileFormatVersion: 2
guid: c42a9d7090e6ce74ea170a267ecd28b4
timeCreated: 1514601543
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/FEM2D/Scripts/CreateTorus.cs
================================================
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Common.Core.LinearAlgebra;
namespace FEM2D
{
public static class CreateTorus
{
public static FEMScene Create(Vector2f origin, float inner, float outer, int segments)
{
FEMScene Scene = new FEMScene();
Scene.Substeps = 40;
Scene.Drag = 1.0f;
Scene.LameLambda = 10000.0f;
Scene.LameMu = 10000.0f;
Scene.Damping = 80.0f;
Scene.Friction = 0.95f;
Scene.Toughness = 20000.0f;
List verts = new List();
List tris = new List();
Mesher.CreateTorus(verts, tris, inner, outer, segments);
// generate elements
for (int i = 0; i < verts.Count; ++i)
Scene.Particles.Add(new FEMParticle(origin + verts[i], 1.0f));
for (int i = 0; i < tris.Count / 3; ++i)
Scene.Triangles.Add(new Triangle(tris[i * 3], tris[i * 3 + 1], tris[i * 3 + 2]));
// assign index to particles
for (int i = 0; i < Scene.Particles.Count; ++i)
Scene.Particles[i].index = i;
Scene.CreateElements();
return Scene;
}
}
}
================================================
FILE: Assets/FEM2D/Scripts/CreateTorus.cs.meta
================================================
fileFormatVersion: 2
guid: a1f44a96f585d494c9f236e5ed6e9d11
timeCreated: 1514615740
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/FEM2D/Scripts/DelaunayTriangulation.cs
================================================
using System;
using System.Collections.Generic;
using UnityEngine;
using Common.Core.LinearAlgebra;
namespace FEM2D
{
public class DelaunayTriangle
{
public int i0, i1, i2;
public Vector2f CircumCenter;
public float CircumRadius;
public DelaunayTriangle(int i, int j, int k)
{
i0 = i;
i1 = j;
i2 = k;
}
public void CalculateCircumcircle(IList vertices)
{
Vector2f p = vertices[i0];
Vector2f q = vertices[i1];
Vector2f r = vertices[i2];
// calculate the intersection of two perpendicular bisectors
Vector2f pq = q - p;
Vector2f qr = r - q;
// check winding
if(Vector2f.Cross(pq, qr) < 0.0f)
throw new InvalidOperationException("Triangle winding order incorrect");
// mid-points of edges
Vector2f a = 0.5f * (p + q);
Vector2f b = 0.5f * (q + r);
Vector2f u = pq.PerpendicularCCW;
float d = Vector2f.Dot(u, qr);
float t = Vector2f.Dot(b - a, qr) / d;
CircumCenter = a + t* u;
CircumRadius = (CircumCenter-p).Magnitude;
}
public void MakeCCW(IList vertices)
{
if(TriArea(vertices) < 0.0f)
{
int tmp = i0;
i0 = i2;
i2 = tmp;
}
}
public float TriArea(IList vertices)
{
Vector2f a = vertices[i0];
Vector2f b = vertices[i1];
Vector2f c = vertices[i2];
return 0.5f * (Vector2f.Cross(b - a, c - a));
}
public int this[int i]
{
get
{
switch (i)
{
case 0: return i0;
case 1: return i1;
case 2: return i2;
default: throw new IndexOutOfRangeException("Index out of range: " + i);
}
}
set
{
switch (i)
{
case 0: i0 = value; break;
case 1: i1 = value; break;
case 2: i2 = value; break;
default: throw new IndexOutOfRangeException("Index out of range: " + i);
}
}
}
}
public class Edge
{
public int i0, i1;
public Edge(int i, int j)
{
i0 = i;
i1 = j;
}
};
public class DelaunayTriangulation
{
public List Vertices;
public List Triangles;
public DelaunayTriangulation()
{
Vertices = new List();
Triangles = new List();
}
public void Triangulate(IList points)
{
Vertices.Clear();
Triangles.Clear();
AddBoundingTriangle(points);
int numPoints = points.Count;
if (numPoints < 3) return;
for (int i = 0; i < numPoints; ++i)
Insert(points[i]);
//Remove bounding triangle;
Vertices.RemoveRange(0, 3);
for (int i = 0; i < Triangles.Count;)
{
var t =Triangles[i];
// throw away tris connected to the initial bounding box
if (t.i0 < 3 || t.i1 < 3 || t.i2 < 3)
{
Triangles.Remove(t);
}
else
{
t.i0 -= 3;
t.i1 -= 3;
t.i2 -= 3;
i++;
}
}
}
private void AddBoundingTriangle(IList points)
{
Vector2f lower = Vector2f.PositiveInfinity;
Vector2f upper = Vector2f.NegativeInfinity;
int numPoints = points.Count;
// find bounding box
for (int i = 0; i < numPoints; ++i)
{
if (points[i].x < lower.x) lower.x = points[i].x;
if (points[i].y < lower.y) lower.y = points[i].y;
if (points[i].x > upper.x) upper.x = points[i].x;
if (points[i].y > upper.y) upper.y = points[i].y;
}
Vector2f margin = upper - lower;
lower -= margin;
upper += margin;
Vector2f extents = upper - lower;
// initialize triangulation with a bounding triangle
Vertices.Add(lower);
Vertices.Add(lower + 2.0f * new Vector2f(extents.x, 0.0f));
Vertices.Add(lower + 2.0f * new Vector2f(0.0f, extents.y));
var tri = new DelaunayTriangle(0, 1, 2);
tri.MakeCCW(Vertices);
tri.CalculateCircumcircle(Vertices);
Triangles.Add(tri);
}
private int ContainsEdge(List edges, Edge e)
{
for(int i = 0; i < edges.Count; i++)
{
if (edges[i].i0 == e.i0 && edges[i].i1 == e.i1) return i;
if (edges[i].i0 == e.i1 && edges[i].i1 == e.i0) return i;
}
return -1;
}
private void Insert(Vector2f p)
{
List edges = new List();
int i = Vertices.Count;
Vertices.Add(p);
// find all triangles for which inserting this point would
// violate the Delaunay condition, that is, which triangles
// circumcircles does this point lie inside
for (int j = 0; j < Triangles.Count;)
{
var t = Triangles[j];
Vector2f a = Vertices[t.i0];
Vector2f b = Vertices[t.i1];
Vector2f c = Vertices[t.i2];
if ((t.CircumCenter - p).Magnitude < t.CircumRadius)
{
for (int e = 0; e < 3; ++e)
{
Edge edge = new Edge(t[e], t[(e + 1) % 3]);
// if edge doesn't already exist add it
int index = ContainsEdge(edges, edge);
if (index == -1)
edges.Add(edge);
else
edges.RemoveAt(index);
}
// remove triangle
Triangles.RemoveAt(j);
}
else
{
// next triangle
++j;
}
}
// re-triangulate point to the enclosing set of edges
for (int e = 0; e < edges.Count; ++e)
{
var t = new DelaunayTriangle(edges[e].i0, edges[e].i1, i);
t.MakeCCW(Vertices);
t.CalculateCircumcircle(Vertices);
Triangles.Add(t);
}
}
}
}
================================================
FILE: Assets/FEM2D/Scripts/DelaunayTriangulation.cs.meta
================================================
fileFormatVersion: 2
guid: 20ef28c4aeb64764d857a7de84df261f
timeCreated: 1514598499
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/FEM2D/Scripts/FEMDemo.cs
================================================
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Common.Core.LinearAlgebra;
namespace FEM2D
{
public enum FEM_SCENE { BEAM, RANDOM_CONVEX, TORUS, ARMADILLO, BUNNY, DONUT };
public class FEMDemo : MonoBehaviour
{
public FEM_SCENE option = FEM_SCENE.ARMADILLO;
public bool drawWireframe = false;
[HideInInspector]
public Texture2D armadillo, bunny, donut;
[HideInInspector]
public Material textureMaterial;
private Texture2D texture;
private FEMScene Scene;
private Vector2f MousePos;
private int MouseIndex;
private bool drawTexture;
private float mouseStrength = 1000;
private Material m_colorMaterial;
private Material ColorMaterial
{
get
{
if (m_colorMaterial == null)
m_colorMaterial = new Material(Shader.Find("Hidden/Internal-Colored"));
return m_colorMaterial;
}
}
void Start()
{
switch(option)
{
case FEM_SCENE.BEAM:
drawWireframe = true;
drawTexture = false;
mouseStrength = 200;
Scene = CreateCantileverBeam.Create(new Vector2f(-0.5f, 0.5f), 1.0f, 6, true);
break;
case FEM_SCENE.RANDOM_CONVEX:
drawWireframe = true;
drawTexture = false;
mouseStrength = 200;
Scene = CreateRandomConvex.Create(new Vector2f(0.0f, 0.5f), 1.0f, 10);
break;
case FEM_SCENE.TORUS:
drawWireframe = true;
drawTexture = false;
mouseStrength = 200;
Scene = CreateTorus.Create(new Vector2f(0.0f, 0.5f), 0.2f, 0.5f, 12);
break;
case FEM_SCENE.ARMADILLO:
drawTexture = true;
texture = armadillo;
mouseStrength = 2000;
Scene = CreateFromImage.Create(texture);
break;
case FEM_SCENE.BUNNY:
drawTexture = true;
texture = bunny;
mouseStrength = 2000;
Scene = CreateFromImage.Create(texture);
break;
case FEM_SCENE.DONUT:
drawTexture = true;
texture = donut;
mouseStrength = 2000;
Scene = CreateFromImage.Create(texture);
break;
}
Scene.Planes.Add(new Vector3f(0.0f, 1.0f, 1.8f));
Scene.Planes.Add(new Vector3f(1.0f, 0.0f, 2.8f));
Scene.Planes.Add(new Vector3f(-1.0f, 0.0f, 2.8f));
if (textureMaterial != null)
textureMaterial.SetTexture("_MainTex", texture);
}
void FixedUpdate()
{
if (Scene == null) return;
float dt = Time.fixedDeltaTime;
int steps = Scene.Substeps;
dt /= steps;
Vector3 p = Input.mousePosition;
p = Camera.main.ScreenToWorldPoint(p);
MousePos = new Vector2f(p.x, p.y);
MouseIndex = -1;
if (Input.GetMouseButton(0))
MouseIndex = FindClosestParticle();
for (int i = 0; i < steps; ++i)
{
MoveByMouseDrag(dt);
Scene.Update(dt);
}
}
int FindClosestParticle()
{
float minDistSq = float.PositiveInfinity;
int minIndex = -1;
for (int i = 0; i < Scene.Particles.Count; ++i)
{
float d = (MousePos - Scene.Particles[i].p).Magnitude;
if (d < minDistSq)
{
minDistSq = d;
minIndex = i;
}
}
return minIndex;
}
void MoveByMouseDrag(float dt)
{
float dampStrength = 10;
if (MouseIndex != -1)
{
Vector2f pq = MousePos - Scene.Particles[MouseIndex].p;
Vector2f damp = -dampStrength * Vector2f.Dot(pq.Normalized, Scene.Particles[MouseIndex].v) * pq.Normalized;
Vector2f stretch = mouseStrength * pq;
Scene.Particles[MouseIndex].f += stretch + damp;
}
}
private void OnPostRender()
{
Camera camera = Camera.current;
if (camera == null) return;
if (Scene == null) return;
GL.PushMatrix();
GL.LoadIdentity();
GL.MultMatrix(camera.worldToCameraMatrix);
GL.LoadProjectionMatrix(camera.projectionMatrix);
DrawTexturedTriangles();
DrawLineTriangles();
DrawMouseLine();
DrawScenePlanes();
//DrawFracturePlanes();
DrawMouseVert();
DrawModelVerts();
GL.PopMatrix();
}
private void DrawPoint(Vector2f p, float s)
{
GL.Vertex3(p.x + s, p.y + s, 0.0f);
GL.Vertex3(p.x + s, p.y - s, 0.0f);
GL.Vertex3(p.x - s, p.y - s, 0.0f);
GL.Vertex3(p.x - s, p.y + s, 0.0f);
}
private void DrawPoint(Vector2 p, float s)
{
GL.Vertex3(p.x + s, p.y + s, 0.0f);
GL.Vertex3(p.x + s, p.y - s, 0.0f);
GL.Vertex3(p.x - s, p.y - s, 0.0f);
GL.Vertex3(p.x - s, p.y + s, 0.0f);
}
private void DrawMouseLine()
{
ColorMaterial.SetPass(0);
GL.Begin(GL.LINES);
GL.Color(Color.red);
if (MouseIndex != -1)
{
Vector2f v0 = Scene.Particles[MouseIndex].p;
Vector2f v1 = MousePos;
GL.Vertex3(v0.x, v0.y, 0.0f);
GL.Vertex3(v1.x, v1.y, 0.0f);
}
GL.End();
}
private void DrawScenePlanes()
{
ColorMaterial.SetPass(0);
GL.Begin(GL.LINES);
GL.Color(Color.red);
for (int i = 0; i < Scene.Planes.Count; ++i)
{
Vector3f plane = Scene.Planes[i];
Vector2f n = plane.xy;
Vector2f c = -plane.z * n;
Vector2f v0 = c + n.PerpendicularCCW * 100.0f;
Vector2f v1 = c - n.PerpendicularCCW * 100.0f;
GL.Vertex3(v0.x, v0.y, 0.0f);
GL.Vertex3(v1.x, v1.y, 0.0f);
}
GL.End();
}
private void DrawFracturePlanes()
{
ColorMaterial.SetPass(0);
GL.Begin(GL.LINES);
GL.Color(Color.green);
for (int i = 0; i < Scene.Fractures.Count; ++i)
{
Vector3f plane = Scene.Fractures[i].Plane;
Vector2f n = plane.xy;
Vector2f c = -plane.z * n;
Vector2f v0 = c + n.PerpendicularCCW * 100.0f;
Vector2f v1 = c - n.PerpendicularCCW * 100.0f;
GL.Vertex3(v0.x, v0.y, 0.0f);
GL.Vertex3(v1.x, v1.y, 0.0f);
}
GL.End();
}
private void DrawTexturedTriangles()
{
if (!drawTexture) return;
if (textureMaterial == null) return;
if (texture == null) return;
textureMaterial.SetPass(0);
textureMaterial.SetTexture("_MainTex", texture);
GL.Begin(GL.TRIANGLES);
for (int i = 0; i < Scene.Triangles.Count; i++)
{
int i0 = Scene.Triangles[i].i;
int i1 = Scene.Triangles[i].j;
int i2 = Scene.Triangles[i].k;
Vector2f v0 = Scene.Particles[i0].p;
Vector2f v1 = Scene.Particles[i1].p;
Vector2f v2 = Scene.Particles[i2].p;
Vector2f uv0 = Scene.Particles[i0].uv;
Vector2f uv1 = Scene.Particles[i1].uv;
Vector2f uv2 = Scene.Particles[i2].uv;
//triangles are ccw but should be cw for drawing so flip them
GL.TexCoord2(uv2.x, uv2.y);
GL.Vertex3(v2.x, v2.y, 0.0f);
GL.TexCoord2(uv1.x, uv1.y);
GL.Vertex3(v1.x, v1.y, 0.0f);
GL.TexCoord2(uv0.x, uv0.y);
GL.Vertex3(v0.x, v0.y, 0.0f);
}
GL.End();
}
private void DrawLineTriangles()
{
if (!drawWireframe) return;
ColorMaterial.SetPass(0);
GL.Begin(GL.LINES);
GL.Color(Color.blue);
for (int i = 0; i < Scene.Triangles.Count; i++)
{
int i0 = Scene.Triangles[i].i;
int i1 = Scene.Triangles[i].j;
int i2 = Scene.Triangles[i].k;
Vector2f v0 = Scene.Particles[i0].p;
Vector2f v1 = Scene.Particles[i1].p;
Vector2f v2 = Scene.Particles[i2].p;
GL.Vertex3(v0.x, v0.y, 0.0f);
GL.Vertex3(v1.x, v1.y, 0.0f);
GL.Vertex3(v0.x, v0.y, 0.0f);
GL.Vertex3(v2.x, v2.y, 0.0f);
GL.Vertex3(v2.x, v2.y, 0.0f);
GL.Vertex3(v1.x, v1.y, 0.0f);
}
GL.End();
}
private void DrawMouseVert()
{
ColorMaterial.SetPass(0);
GL.Begin(GL.QUADS);
GL.Color(Color.yellow);
if (MouseIndex != -1)
{
DrawPoint(MousePos, 0.005f);
}
GL.End();
}
private void DrawModelVerts()
{
if (!drawWireframe) return;
ColorMaterial.SetPass(0);
GL.Begin(GL.QUADS);
GL.Color(Color.yellow);
for (int i = 0; i < Scene.Particles.Count; i++)
{
DrawPoint(Scene.Particles[i].p, 0.005f);
}
GL.End();
}
}
}
================================================
FILE: Assets/FEM2D/Scripts/FEMDemo.cs.meta
================================================
fileFormatVersion: 2
guid: 21b56fa4ac510b34d865a6cae689b006
timeCreated: 1514697612
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences:
- armadillo: {fileID: 2800000, guid: 8d4354cace070ef41a318c34670ff88a, type: 3}
- bunny: {fileID: 2800000, guid: 689440ccb80c6a348afee121dd2fa9e3, type: 3}
- donut: {fileID: 2800000, guid: 4df4a7e175870f94ca81a95b3d9c28f4, type: 3}
- textureMaterial: {fileID: 2100000, guid: 716d33869f0597743928b3f83bbdbd52, type: 2}
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/FEM2D/Scripts/FEMElement.cs
================================================
using System;
using System.Collections.Generic;
using UnityEngine;
using Common.Core.LinearAlgebra;
namespace FEM2D
{
public class FEMElement
{
public FEMElement(Vector2f[] x)
{
Vector2f e1 = x[1] - x[0];
Vector2f e2 = x[2] - x[0];
Vector2f e3 = x[2] - x[1];
Matrix2x2f m = new Matrix2x2f();
m.SetColumn(0, e1);
m.SetColumn(1, e2);
mInvDm = m.Inverse;
mB = new Vector2f[3];
mB[0] = e3.PerpendicularCCW;
mB[1] = e2.PerpendicularCW;
mB[2] = e1.PerpendicularCCW;
}
public Matrix2x2f mInvDm; // inverse rest configuration
public Matrix2x2f mEp; // plastic strain
public Vector2f[] mB; // area weighted normals in material space
}
}
================================================
FILE: Assets/FEM2D/Scripts/FEMElement.cs.meta
================================================
fileFormatVersion: 2
guid: 29457e410e915114ebb5a9f738e34e06
timeCreated: 1514543113
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/FEM2D/Scripts/FEMFractureEvent.cs
================================================
using System;
using System.Collections.Generic;
using UnityEngine;
using Common.Core.LinearAlgebra;
namespace FEM2D
{
public struct FEMFractureEvent
{
public int Tri;
public int Node;
public Vector3f Plane;
}
}
================================================
FILE: Assets/FEM2D/Scripts/FEMFractureEvent.cs.meta
================================================
fileFormatVersion: 2
guid: 44af2fa5db0b53846894b4e1292f6fe9
timeCreated: 1514543146
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/FEM2D/Scripts/FEMParticle.cs
================================================
using System;
using System.Collections.Generic;
using UnityEngine;
using Common.Core.LinearAlgebra;
namespace FEM2D
{
public class FEMParticle
{
public Vector2f p;
public Vector2f v;
public Vector2f f;
public Vector2f c;
public Vector2f uv;
public float invMass;
public int index;
public float max;
public FEMParticle(Vector2f pos, float im)
{
p = pos;
invMass = im;
index = 0;
}
public FEMParticle(Vector2f pos, Vector2f uv, float im)
{
p = pos;
this.uv = uv;
invMass = im;
index = 0;
}
public FEMParticle Copy()
{
FEMParticle particle = new FEMParticle(p, invMass);
particle.v = v;
particle.f = f;
particle.c = c;
particle.index = index;
particle.max = max;
return particle;
}
}
}
================================================
FILE: Assets/FEM2D/Scripts/FEMParticle.cs.meta
================================================
fileFormatVersion: 2
guid: 6944fa5b6e65d92449bcb768b46dba06
timeCreated: 1514543104
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/FEM2D/Scripts/FEMScene.cs
================================================
using System;
using System.Collections.Generic;
using UnityEngine;
using Common.Core.LinearAlgebra;
using Common.Mathematics.Decomposition;
namespace FEM2D
{
public class FEMScene
{
public Vector2f Gravity = new Vector2f(0, -9.8f);
public float LameLambda = 1000.0f;
public float LameMu = 1000.0f;
public float Yield = 0.5f;
public float Creep = 25.0f;
public float Damping = 10.0f;
public float Drag = 0.0f;
public float Friction = 0.5f;
public float Toughness = 500.0f;
public int Substeps = 1;
public List Particles;
public List Triangles;
public List Elements;
public List Planes;
public List Fractures;
private System.Random Rnd;
public FEMScene()
{
Rnd = new System.Random(0);
Particles = new List();
Triangles = new List();
Planes = new List();
Fractures = new List();
Elements = new List();
}
public void CreateElements()
{
// calculate inverse of the initial configuration
for (int i = 0; i < Triangles.Count; ++i)
{
Triangle t = Triangles[i];
// read particles into a local array
Vector2f[] x = new Vector2f[]
{
Particles[t.i].p,
Particles[t.j].p,
Particles[t.k].p
};
Elements.Add(new FEMElement(x));
}
}
public void Update(float dt)
{
Fractures.Clear();
bool performFracture = true;
UpdateForces(dt, performFracture);
CollidePlanes();
IntegrateForces(dt);
if (performFracture)
{
//Not implemented
}
}
private void UpdateForces(float dt, bool performFracture)
{
for (int i = 0; i < Particles.Count; ++i)
{
Particles[i].max = 0;
if (Particles[i].invMass > 0.0f)
Particles[i].f += Gravity / Particles[i].invMass;
else
Particles[i].f += Vector2f.Zero - Drag * Particles[i].v;
}
Vector2f[] x = new Vector2f[3];
Vector2f[] v = new Vector2f[3];
for (int i = 0; i < Triangles.Count; ++i)
{
Triangle tri = Triangles[i];
FEMElement elem = Elements[i];
x[0] = Particles[tri.i].p;
x[1] = Particles[tri.j].p;
x[2] = Particles[tri.k].p;
v[0] = Particles[tri.i].v;
v[1] = Particles[tri.j].v;
v[2] = Particles[tri.k].v;
if (performFracture)
{
Matrix2x2f f = CalcDeformation(x, elem.mInvDm);
Matrix2x2f q = Decomposition2x2f.QRDecomposition(f);
// strain
Matrix2x2f e = CalcCauchyStrainTensor(q.Transpose * f);
// update plastic strain
float ef = FrobeniusNorm(e);
if (ef > Yield)
elem.mEp += e * dt * Creep;
const float epmax = 0.6f;
if (ef > epmax)
elem.mEp *= epmax / ef;
// adjust strain
e -= elem.mEp;
Matrix2x2f s = CalcStressTensor(e, LameLambda, LameMu);
// damping forces
Matrix2x2f dfdt = CalcDeformation(v, elem.mInvDm);
Matrix2x2f dedt = CalcCauchyStrainTensorDt(q.Transpose * dfdt);
Matrix2x2f dsdt = CalcStressTensor(dedt, Damping, Damping);
Matrix2x2f p = s + dsdt;
float e1, e2;
Decomposition2x2f.EigenDecomposition(p, out e1, out e2);
float me = Mathf.Max(e1, e2);
if (me > Toughness)
{
// calculate Eigenvector corresponding to max Eigenvalue
Vector2f ev = q * (new Vector2f(p.m01, me - p.m00)).Normalized;
// pick a random vertex to split on
int splitNode = Rnd.Next(0, 2);
// don't fracture immovable nodes
if (Particles[GetVertex(tri, splitNode)].invMass == 0.0f)
break;
// fracture plane perpendicular to ev
Vector3f plane = new Vector3f(ev.x, ev.y, -Vector2f.Dot(ev, Particles[GetVertex(tri, splitNode)].p));
FEMFractureEvent fracture = new FEMFractureEvent();
fracture.Tri = i;
fracture.Node = splitNode;
fracture.Plane = plane;
//Fracture not implemented so these fracture planes are not used.
Fractures.Add(fracture);
}
// calculate force on each edge due to stress and distribute to the nodes
Vector2f f1 = q * p * elem.mB[0];
Vector2f f2 = q * p * elem.mB[1];
Vector2f f3 = q * p * elem.mB[2];
Particles[tri.i].f -= f1/3.0f;
Particles[tri.j].f -= f2/3.0f;
Particles[tri.k].f -= f3/3.0f;
}
else
{
//This was the code used when fracturing was disabled
//in the original. It seems very unstable for me. maybe
//a bug or precision issue. Not used atm.
Matrix2x2f f = CalcDeformation(x, elem.mInvDm);
// elastic forces
Matrix2x2f e = CalcGreenStrainTensor(f);
Matrix2x2f s = CalcStressTensor(e, LameLambda, LameMu);
// damping forces
Matrix2x2f dfdt = CalcDeformation(v, elem.mInvDm);
Matrix2x2f dedt = CalcGreenStrainTensorDt(f, dfdt);
Matrix2x2f dsdt = CalcStressTensor(dedt, Damping, Damping);
Matrix2x2f p = s + dsdt;
float e1, e2;
Decomposition2x2f.EigenDecomposition(p, out e1, out e2);
float me = Mathf.Max(e1, e2);
Matrix2x2f finv = f.Transpose.Inverse;
Vector2f f1 = p * (finv * elem.mB[0]);
Vector2f f2 = p * (finv * elem.mB[1]);
Vector2f f3 = p * (finv * elem.mB[2]);
Particles[tri.i].f -= f1 / 3.0f;
Particles[tri.j].f -= f2 / 3.0f;
Particles[tri.k].f -= f3 / 3.0f;
Particles[tri.i].max += me / 3.0f;
Particles[tri.j].max += me / 3.0f;
Particles[tri.k].max += me / 3.0f;
}
}
}
private void IntegrateForces(float dt)
{
// integrate particles forward in time, symplectic Euler step
for (int i = 0; i < Particles.Count; ++i)
{
Particles[i].v += Particles[i].f * Particles[i].invMass * dt;
Particles[i].p += Particles[i].v * dt;
Particles[i].f = Vector2f.Zero;
}
}
private void CollidePlanes()
{
for (int i = 0; i < Particles.Count; ++i)
{
for (int p = 0; p < Planes.Count; ++p)
{
Vector2f n = Planes[p].xy;
float d = Vector2f.Dot(Particles[i].p, n) + Planes[p].z;
if (d < 0.0f)
{
// push out of halfspace
Particles[i].p -= d * n;
// make relative velocity separating
float rv = Vector2f.Dot(Particles[i].v, n);
if (rv< 0.0f)
{
// zero normal velocity, material simulation will take care of restitution
Vector2f nv = -rv * n;
// friction
Vector2f tv = (Particles[i].v + nv) * Friction;
// update velocity
Particles[i].v = tv;
}
}
}
}
}
private int GetVertex(Triangle tri, int i)
{
if (i == 0)
return tri.i;
else if (i == 1)
return tri.j;
else if (i == 2)
return tri.k;
else
throw new IndexOutOfRangeException("Triangle index out of range");
}
float FrobeniusNorm(Matrix2x2f m)
{
float f = 0.0f;
for (int i = 0; i < 2; ++i)
for (int j = 0; j < 2; ++j)
f += m[i, j] * m[i, j];
return (float)Math.Sqrt(f);
}
///
/// deformation gradient
///
private Matrix2x2f CalcDeformation(Vector2f[] x, Matrix2x2f invM)
{
Vector2f e1 = x[1] - x[0];
Vector2f e2 = x[2] - x[0];
Matrix2x2f m = new Matrix2x2f();
m.SetColumn(0, e1);
m.SetColumn(1, e2);
// mapping from material coordinates to world coordinates
Matrix2x2f f = m * invM;
return f;
}
///
/// calculate Green's non-linear strain tensor
///
private Matrix2x2f CalcGreenStrainTensor(Matrix2x2f f)
{
Matrix2x2f e = (f.Transpose * f - Matrix2x2f.Identity) * 0.5f;
return e;
}
///
/// calculate time derivative of Green's strain
///
private Matrix2x2f CalcGreenStrainTensorDt(Matrix2x2f f, Matrix2x2f dfdt)
{
Matrix2x2f e = (f * dfdt.Transpose + dfdt * f.Transpose) * 0.5f;
return e;
}
///
/// calculate Cauchy's linear strain tensor
///
private Matrix2x2f CalcCauchyStrainTensor(Matrix2x2f f)
{
Matrix2x2f e = (f + f.Transpose) * 0.5f - Matrix2x2f.Identity;
return e;
}
///
/// calculate time derivative of Cauchy's strain tensor
///
private Matrix2x2f CalcCauchyStrainTensorDt(Matrix2x2f dfdt)
{
Matrix2x2f e = (dfdt + dfdt.Transpose) * 0.5f;
return e;
}
///
/// calculate isotropic Hookean stress tensor, lambda and mu are the Lame parameters
///
private Matrix2x2f CalcStressTensor(Matrix2x2f e, float lambda, float mu)
{
Matrix2x2f s = Matrix2x2f.Identity * e.Trace * lambda + e * mu * 2.0f;
return s;
}
}
}
================================================
FILE: Assets/FEM2D/Scripts/FEMScene.cs.meta
================================================
fileFormatVersion: 2
guid: da2457346ca976a47ba80cc04748d813
timeCreated: 1488701314
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/FEM2D/Scripts/Mesher.cs
================================================
using System;
using System.Collections.Generic;
using UnityEngine;
using Common.Core.LinearAlgebra;
namespace FEM2D
{
public class Mesher
{
///
/// incremental insert Delaunay triangulation based on Bowyer/Watson's algorithm
///
public static void TriangulateDelaunay(List points, out List outPoints, out List outTris)
{
var mesh = new DelaunayTriangulation();
mesh.Triangulate(points);
int vertCount = mesh.Vertices.Count;
int triCount = mesh.Triangles.Count;
outPoints = new List(vertCount);
outTris = new List(triCount * 3);
int offset = 0;
for (int i = offset; i < vertCount; ++i)
{
outPoints.Add(mesh.Vertices[i]);
}
for (int i = 0; i < triCount; ++i)
{
var t = mesh.Triangles[i];
// throw away tris connected to the initial bounding box
if (t.i0 < offset || t.i1 < offset || t.i2 < offset)
continue;
outTris.Add(t.i0 - offset);
outTris.Add(t.i1 - offset);
outTris.Add(t.i2 - offset);
}
}
public static void CreateTorus(List points, List indices, float inner, float outer, int segments)
{
int b;
for (int i = 0; i < segments; ++i)
{
float theta = (float)i / segments * Mathf.PI * 2.0f;
float x = Mathf.Sin(theta);
float y = Mathf.Cos(theta);
points.Add(new Vector2f(x, y) * outer);
points.Add(new Vector2f(x, y) * inner);
if (i > 0)
{
b = (i - 1) * 2;
indices.Add(b + 0);
indices.Add(b + 1);
indices.Add(b + 2);
indices.Add(b + 2);
indices.Add(b + 1);
indices.Add(b + 3);
}
}
b = points.Count - 2;
indices.Add(b + 0);
indices.Add(b + 1);
indices.Add(0);
indices.Add(0);
indices.Add(b + 1);
indices.Add(1);
}
///
/// iterative optimisation algoirthm based on Variational Tetrahedral Meshing
///
public static void TriangulateVariational(List inPoints, List bPoints, int iterations, out List outPoints, out List outTris)
{
Vector2f[] points = new Vector2f[inPoints.Count];
float[] weights = new float[inPoints.Count];
for (int i = 0; i < points.Length; ++i)
points[i] = inPoints[i];
var mesh = new DelaunayTriangulation();
for (int k = 0; k < iterations; ++k)
{
mesh.Triangulate(points);
Array.Clear(points, 0, points.Length);
Array.Clear(weights, 0, weights.Length);
// optimize boundary points
for (int i = 0; i < bPoints.Count; ++i)
{
int closest = 0;
float closestDistSq = float.PositiveInfinity;
Vector2f b = bPoints[i];
// find closest point (todo: use spatial hash)
for (int j = 0; j < mesh.Vertices.Count; ++j)
{
float dSq = (mesh.Vertices[j] - b).SqrMagnitude;
if (dSq < closestDistSq)
{
closest = j;
closestDistSq = dSq;
}
}
points[closest] -= b;
weights[closest] -= 1.0f;
}
// optimize interior points by moving them to the centroid of their 1-ring
for (int i = 0; i < mesh.Triangles.Count; ++i)
{
var t = mesh.Triangles[i];
float w = t.TriArea(mesh.Vertices);
for (int v = 0; v < 3; ++v)
{
int s = t[v];
if (weights[s] >= 0.0f)
{
points[s] += w * t.CircumCenter;
weights[s] += w;
}
}
}
for (int i = 0; i < points.Length; ++i)
{
points[i] /= weights[i];
}
}
mesh.Triangulate(points);
/*
points.resize(0);
points.assign(mesh.vertices.begin()+3, mesh.vertices.end());
// remove any sliver tris on the boundary
for (uint32_t i = 0; i 3.0f)
mesh.triangles.erase(mesh.triangles.begin() + i);
else
++i;
}
*/
outPoints = new List(mesh.Vertices);
outTris = new List(mesh.Triangles.Count * 3);
for (int i = 0; i< mesh.Triangles.Count; ++i)
{
var t = mesh.Triangles[i];
outTris.Add(t.i0);
outTris.Add(t.i1);
outTris.Add(t.i2);
}
}
}
}
================================================
FILE: Assets/FEM2D/Scripts/Mesher.cs.meta
================================================
fileFormatVersion: 2
guid: 0aec6e65a8759ea44b63d58e7680ddad
timeCreated: 1514598008
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/FEM2D/Scripts/Triangle.cs
================================================
using System;
using System.Collections.Generic;
using UnityEngine;
using Common.Core.LinearAlgebra;
namespace FEM2D
{
public class Triangle
{
public int i, j, k;
public Triangle(int i, int j, int k)
{
this.i = i;
this.j = j;
this.k = k;
}
}
}
================================================
FILE: Assets/FEM2D/Scripts/Triangle.cs.meta
================================================
fileFormatVersion: 2
guid: 35ec53c1f7d74e54fbf9b83612e93df7
timeCreated: 1514543471
licenseType: Free
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/FEM2D/Scripts.meta
================================================
fileFormatVersion: 2
guid: 6a97a42ecbc1e4149bb3100fd18cc420
folderAsset: yes
timeCreated: 1514543123
licenseType: Free
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/FEM2D/Textures/armadillo.png.meta
================================================
fileFormatVersion: 2
guid: 8d4354cace070ef41a318c34670ff88a
timeCreated: 1514625724
licenseType: Free
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 4
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 1
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -1
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 100
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
- buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/FEM2D/Textures/bunny.png.meta
================================================
fileFormatVersion: 2
guid: 689440ccb80c6a348afee121dd2fa9e3
timeCreated: 1514625724
licenseType: Free
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 4
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 1
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -1
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 100
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
- buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/FEM2D/Textures/donut1.png.meta
================================================
fileFormatVersion: 2
guid: 4df4a7e175870f94ca81a95b3d9c28f4
timeCreated: 1514625724
licenseType: Free
TextureImporter:
fileIDToRecycleName: {}
externalObjects: {}
serializedVersion: 4
mipmaps:
mipMapMode: 0
enableMipMap: 1
sRGBTexture: 1
linearTexture: 0
fadeOut: 0
borderMipMap: 0
mipMapsPreserveCoverage: 0
alphaTestReferenceValue: 0.5
mipMapFadeDistanceStart: 1
mipMapFadeDistanceEnd: 3
bumpmap:
convertToNormalMap: 0
externalNormalMap: 0
heightScale: 0.25
normalMapFilter: 0
isReadable: 1
grayScaleToAlpha: 0
generateCubemap: 6
cubemapConvolution: 0
seamlessCubemap: 0
textureFormat: 1
maxTextureSize: 2048
textureSettings:
serializedVersion: 2
filterMode: -1
aniso: -1
mipBias: -1
wrapU: 1
wrapV: 1
wrapW: 1
nPOTScale: 0
lightmap: 0
compressionQuality: 50
spriteMode: 0
spriteExtrude: 1
spriteMeshType: 1
alignment: 0
spritePivot: {x: 0.5, y: 0.5}
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
spritePixelsToUnits: 100
alphaUsage: 1
alphaIsTransparency: 0
spriteTessellationDetail: -1
textureType: 0
textureShape: 1
maxTextureSizeSet: 0
compressionQualitySet: 0
textureFormatSet: 0
platformSettings:
- buildTarget: DefaultTexturePlatform
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
- buildTarget: Standalone
maxTextureSize: 2048
resizeAlgorithm: 0
textureFormat: -1
textureCompression: 0
compressionQuality: 50
crunchedCompression: 0
allowsAlphaSplitting: 0
overridden: 0
spriteSheet:
serializedVersion: 2
sprites: []
outline: []
physicsShape: []
spritePackingTag:
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/FEM2D/Textures.meta
================================================
fileFormatVersion: 2
guid: 7a3c443360e76cc4a856e4c16eaccd25
folderAsset: yes
timeCreated: 1514625721
licenseType: Free
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/FEM2D.meta
================================================
fileFormatVersion: 2
guid: 7abf378388cbc1e42a90855390a552b4
folderAsset: yes
timeCreated: 1514536684
licenseType: Free
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2017 Justin
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
The MIT License (MIT)
Copyright (c) 2016 Miles Macklin
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: Packages/manifest.json
================================================
{
"dependencies": {
"com.unity.collab-proxy": "1.3.9",
"com.unity.ide.rider": "1.2.1",
"com.unity.ide.visualstudio": "2.0.2",
"com.unity.ide.vscode": "1.2.1",
"com.unity.test-framework": "1.1.16",
"com.unity.textmeshpro": "3.0.1",
"com.unity.timeline": "1.3.5",
"com.unity.ugui": "1.0.0",
"com.unity.modules.ai": "1.0.0",
"com.unity.modules.androidjni": "1.0.0",
"com.unity.modules.animation": "1.0.0",
"com.unity.modules.assetbundle": "1.0.0",
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.cloth": "1.0.0",
"com.unity.modules.director": "1.0.0",
"com.unity.modules.imageconversion": "1.0.0",
"com.unity.modules.imgui": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0",
"com.unity.modules.particlesystem": "1.0.0",
"com.unity.modules.physics": "1.0.0",
"com.unity.modules.physics2d": "1.0.0",
"com.unity.modules.screencapture": "1.0.0",
"com.unity.modules.terrain": "1.0.0",
"com.unity.modules.terrainphysics": "1.0.0",
"com.unity.modules.tilemap": "1.0.0",
"com.unity.modules.ui": "1.0.0",
"com.unity.modules.uielements": "1.0.0",
"com.unity.modules.umbra": "1.0.0",
"com.unity.modules.unityanalytics": "1.0.0",
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.unitywebrequestassetbundle": "1.0.0",
"com.unity.modules.unitywebrequestaudio": "1.0.0",
"com.unity.modules.unitywebrequesttexture": "1.0.0",
"com.unity.modules.unitywebrequestwww": "1.0.0",
"com.unity.modules.vehicles": "1.0.0",
"com.unity.modules.video": "1.0.0",
"com.unity.modules.vr": "1.0.0",
"com.unity.modules.wind": "1.0.0",
"com.unity.modules.xr": "1.0.0"
}
}
================================================
FILE: Packages/packages-lock.json
================================================
{
"dependencies": {
"com.unity.collab-proxy": {
"version": "1.3.9",
"depth": 0,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.ext.nunit": {
"version": "1.0.0",
"depth": 1,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.ide.rider": {
"version": "1.2.1",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.test-framework": "1.1.1"
},
"url": "https://packages.unity.com"
},
"com.unity.ide.visualstudio": {
"version": "2.0.2",
"depth": 0,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.ide.vscode": {
"version": "1.2.1",
"depth": 0,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.test-framework": {
"version": "1.1.16",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.ext.nunit": "1.0.0",
"com.unity.modules.imgui": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.textmeshpro": {
"version": "3.0.1",
"depth": 0,
"source": "registry",
"dependencies": {
"com.unity.ugui": "1.0.0"
},
"url": "https://packages.unity.com"
},
"com.unity.timeline": {
"version": "1.3.5",
"depth": 0,
"source": "registry",
"dependencies": {},
"url": "https://packages.unity.com"
},
"com.unity.ugui": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.ui": "1.0.0",
"com.unity.modules.imgui": "1.0.0"
}
},
"com.unity.modules.ai": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.androidjni": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.animation": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.assetbundle": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.audio": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.cloth": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.physics": "1.0.0"
}
},
"com.unity.modules.director": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.animation": "1.0.0"
}
},
"com.unity.modules.imageconversion": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.imgui": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.jsonserialize": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.particlesystem": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.physics": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.physics2d": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.screencapture": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.imageconversion": "1.0.0"
}
},
"com.unity.modules.subsystems": {
"version": "1.0.0",
"depth": 1,
"source": "builtin",
"dependencies": {
"com.unity.modules.jsonserialize": "1.0.0"
}
},
"com.unity.modules.terrain": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.terrainphysics": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.physics": "1.0.0",
"com.unity.modules.terrain": "1.0.0"
}
},
"com.unity.modules.tilemap": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.physics2d": "1.0.0"
}
},
"com.unity.modules.ui": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.uielements": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.ui": "1.0.0",
"com.unity.modules.imgui": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0",
"com.unity.modules.uielementsnative": "1.0.0"
}
},
"com.unity.modules.uielementsnative": {
"version": "1.0.0",
"depth": 1,
"source": "builtin",
"dependencies": {
"com.unity.modules.ui": "1.0.0",
"com.unity.modules.imgui": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0"
}
},
"com.unity.modules.umbra": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.unityanalytics": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0"
}
},
"com.unity.modules.unitywebrequest": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.unitywebrequestassetbundle": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.assetbundle": "1.0.0",
"com.unity.modules.unitywebrequest": "1.0.0"
}
},
"com.unity.modules.unitywebrequestaudio": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.audio": "1.0.0"
}
},
"com.unity.modules.unitywebrequesttexture": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.imageconversion": "1.0.0"
}
},
"com.unity.modules.unitywebrequestwww": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.unitywebrequest": "1.0.0",
"com.unity.modules.unitywebrequestassetbundle": "1.0.0",
"com.unity.modules.unitywebrequestaudio": "1.0.0",
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.assetbundle": "1.0.0",
"com.unity.modules.imageconversion": "1.0.0"
}
},
"com.unity.modules.vehicles": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.physics": "1.0.0"
}
},
"com.unity.modules.video": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.audio": "1.0.0",
"com.unity.modules.ui": "1.0.0",
"com.unity.modules.unitywebrequest": "1.0.0"
}
},
"com.unity.modules.vr": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.jsonserialize": "1.0.0",
"com.unity.modules.physics": "1.0.0",
"com.unity.modules.xr": "1.0.0"
}
},
"com.unity.modules.wind": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {}
},
"com.unity.modules.xr": {
"version": "1.0.0",
"depth": 0,
"source": "builtin",
"dependencies": {
"com.unity.modules.physics": "1.0.0",
"com.unity.modules.jsonserialize": "1.0.0",
"com.unity.modules.subsystems": "1.0.0"
}
}
}
}
================================================
FILE: ProjectSettings/AudioManager.asset
================================================
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!11 &1
AudioManager:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Volume: 1
Rolloff Scale: 1
Doppler Factor: 1
Default Speaker Mode: 2
m_SampleRate: 0
m_DSPBufferSize: 1024
m_VirtualVoiceCount: 512
m_RealVoiceCount: 32
m_SpatializerPlugin:
m_AmbisonicDecoderPlugin:
m_DisableAudio: 0
m_VirtualizeEffects: 1
m_RequestedDSPBufferSize: 0
================================================
FILE: ProjectSettings/ClusterInputManager.asset
================================================
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!236 &1
ClusterInputManager:
m_ObjectHideFlags: 0
m_Inputs: []
================================================
FILE: ProjectSettings/DynamicsManager.asset
================================================
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!55 &1
PhysicsManager:
m_ObjectHideFlags: 0
serializedVersion: 13
m_Gravity: {x: 0, y: -9.81, z: 0}
m_DefaultMaterial: {fileID: 0}
m_BounceThreshold: 2
m_DefaultMaxDepenetrationVelocity: 10
m_SleepThreshold: 0.005
m_DefaultContactOffset: 0.01
m_DefaultSolverIterations: 6
m_DefaultSolverVelocityIterations: 1
m_QueriesHitBackfaces: 0
m_QueriesHitTriggers: 1
m_EnableAdaptiveForce: 0
m_ClothInterCollisionDistance: 0.1
m_ClothInterCollisionStiffness: 0.2
m_ContactsGeneration: 1
m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
m_AutoSimulation: 1
m_AutoSyncTransforms: 0
m_ReuseCollisionCallbacks: 0
m_ClothInterCollisionSettingsToggle: 0
m_ClothGravity: {x: 0, y: -9.81, z: 0}
m_ContactPairsMode: 0
m_BroadphaseType: 0
m_WorldBounds:
m_Center: {x: 0, y: 0, z: 0}
m_Extent: {x: 250, y: 250, z: 250}
m_WorldSubdivisions: 8
m_FrictionType: 0
m_EnableEnhancedDeterminism: 0
m_EnableUnifiedHeightmaps: 1
m_SolverType: 0
m_DefaultMaxAngularSpeed: 50
================================================
FILE: ProjectSettings/EditorBuildSettings.asset
================================================
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1045 &1
EditorBuildSettings:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Scenes: []
m_configObjects: {}
================================================
FILE: ProjectSettings/EditorSettings.asset
================================================
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!159 &1
EditorSettings:
m_ObjectHideFlags: 0
serializedVersion: 11
m_SerializationMode: 2
m_LineEndingsForNewScripts: 2
m_DefaultBehaviorMode: 0
m_PrefabRegularEnvironment: {fileID: 0}
m_PrefabUIEnvironment: {fileID: 0}
m_SpritePackerMode: 0
m_SpritePackerPaddingPower: 1
m_EtcTextureCompressorBehavior: 1
m_EtcTextureFastCompressor: 1
m_EtcTextureNormalCompressor: 2
m_EtcTextureBestCompressor: 4
m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd;asmdef;asmref;rsp
m_ProjectGenerationRootNamespace:
m_EnableTextureStreamingInEditMode: 1
m_EnableTextureStreamingInPlayMode: 1
m_AsyncShaderCompilation: 1
m_CachingShaderPreprocessor: 0
m_EnterPlayModeOptionsEnabled: 0
m_EnterPlayModeOptions: 3
m_GameObjectNamingDigits: 1
m_GameObjectNamingScheme: 0
m_AssetNamingUsesSpace: 1
m_UseLegacyProbeSampleCount: 0
m_SerializeInlineMappingsOnOneLine: 1
m_DisableCookiesInLightmapper: 0
m_AssetPipelineMode: 1
m_CacheServerMode: 0
m_CacheServerEndpoint:
m_CacheServerNamespacePrefix: default
m_CacheServerEnableDownload: 1
m_CacheServerEnableUpload: 1
m_CacheServerEnableAuth: 0
m_CacheServerEnableTls: 0
================================================
FILE: ProjectSettings/GraphicsSettings.asset
================================================
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!30 &1
GraphicsSettings:
m_ObjectHideFlags: 0
serializedVersion: 13
m_Deferred:
m_Mode: 1
m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0}
m_DeferredReflections:
m_Mode: 1
m_Shader: {fileID: 74, guid: 0000000000000000f000000000000000, type: 0}
m_ScreenSpaceShadows:
m_Mode: 1
m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0}
m_LegacyDeferred:
m_Mode: 1
m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0}
m_DepthNormals:
m_Mode: 1
m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0}
m_MotionVectors:
m_Mode: 1
m_Shader: {fileID: 75, guid: 0000000000000000f000000000000000, type: 0}
m_LightHalo:
m_Mode: 1
m_Shader: {fileID: 105, guid: 0000000000000000f000000000000000, type: 0}
m_LensFlare:
m_Mode: 1
m_Shader: {fileID: 102, guid: 0000000000000000f000000000000000, type: 0}
m_VideoShadersIncludeMode: 2
m_AlwaysIncludedShaders:
- {fileID: 7, guid: 0000000000000000f000000000000000, type: 0}
- {fileID: 15104, guid: 0000000000000000f000000000000000, type: 0}
- {fileID: 15105, guid: 0000000000000000f000000000000000, type: 0}
- {fileID: 15106, guid: 0000000000000000f000000000000000, type: 0}
- {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0}
- {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0}
- {fileID: 10783, guid: 0000000000000000f000000000000000, type: 0}
m_PreloadedShaders: []
m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0}
m_CustomRenderPipeline: {fileID: 0}
m_TransparencySortMode: 0
m_TransparencySortAxis: {x: 0, y: 0, z: 1}
m_DefaultRenderingPath: 1
m_DefaultMobileRenderingPath: 1
m_TierSettings: []
m_LightmapStripping: 0
m_FogStripping: 0
m_InstancingStripping: 0
m_LightmapKeepPlain: 1
m_LightmapKeepDirCombined: 1
m_LightmapKeepDynamicPlain: 1
m_LightmapKeepDynamicDirCombined: 1
m_LightmapKeepShadowMask: 1
m_LightmapKeepSubtractive: 1
m_FogKeepLinear: 1
m_FogKeepExp: 1
m_FogKeepExp2: 1
m_AlbedoSwatchInfos: []
m_LightsUseLinearIntensity: 0
m_LightsUseColorTemperature: 0
m_LogWhenShaderIsCompiled: 0
================================================
FILE: ProjectSettings/InputManager.asset
================================================
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!13 &1
InputManager:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Axes:
- serializedVersion: 3
m_Name: Horizontal
descriptiveName:
descriptiveNegativeName:
negativeButton: left
positiveButton: right
altNegativeButton: a
altPositiveButton: d
gravity: 3
dead: 0.001
sensitivity: 3
snap: 1
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Vertical
descriptiveName:
descriptiveNegativeName:
negativeButton: down
positiveButton: up
altNegativeButton: s
altPositiveButton: w
gravity: 3
dead: 0.001
sensitivity: 3
snap: 1
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Fire1
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: left ctrl
altNegativeButton:
altPositiveButton: mouse 0
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Fire2
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: left alt
altNegativeButton:
altPositiveButton: mouse 1
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Fire3
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: left shift
altNegativeButton:
altPositiveButton: mouse 2
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Jump
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: space
altNegativeButton:
altPositiveButton:
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Mouse X
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton:
altNegativeButton:
altPositiveButton:
gravity: 0
dead: 0
sensitivity: 0.1
snap: 0
invert: 0
type: 1
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Mouse Y
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton:
altNegativeButton:
altPositiveButton:
gravity: 0
dead: 0
sensitivity: 0.1
snap: 0
invert: 0
type: 1
axis: 1
joyNum: 0
- serializedVersion: 3
m_Name: Mouse ScrollWheel
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton:
altNegativeButton:
altPositiveButton:
gravity: 0
dead: 0
sensitivity: 0.1
snap: 0
invert: 0
type: 1
axis: 2
joyNum: 0
- serializedVersion: 3
m_Name: Horizontal
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton:
altNegativeButton:
altPositiveButton:
gravity: 0
dead: 0.19
sensitivity: 1
snap: 0
invert: 0
type: 2
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Vertical
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton:
altNegativeButton:
altPositiveButton:
gravity: 0
dead: 0.19
sensitivity: 1
snap: 0
invert: 1
type: 2
axis: 1
joyNum: 0
- serializedVersion: 3
m_Name: Fire1
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: joystick button 0
altNegativeButton:
altPositiveButton:
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Fire2
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: joystick button 1
altNegativeButton:
altPositiveButton:
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Fire3
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: joystick button 2
altNegativeButton:
altPositiveButton:
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Jump
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: joystick button 3
altNegativeButton:
altPositiveButton:
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Submit
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: return
altNegativeButton:
altPositiveButton: joystick button 0
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Submit
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: enter
altNegativeButton:
altPositiveButton: space
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
- serializedVersion: 3
m_Name: Cancel
descriptiveName:
descriptiveNegativeName:
negativeButton:
positiveButton: escape
altNegativeButton:
altPositiveButton: joystick button 1
gravity: 1000
dead: 0.001
sensitivity: 1000
snap: 0
invert: 0
type: 0
axis: 0
joyNum: 0
================================================
FILE: ProjectSettings/NavMeshAreas.asset
================================================
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!126 &1
NavMeshProjectSettings:
m_ObjectHideFlags: 0
serializedVersion: 2
areas:
- name: Walkable
cost: 1
- name: Not Walkable
cost: 1
- name: Jump
cost: 2
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
- name:
cost: 1
m_LastAgentTypeID: -887442657
m_Settings:
- serializedVersion: 2
agentTypeID: 0
agentRadius: 0.5
agentHeight: 2
agentSlope: 45
agentClimb: 0.75
ledgeDropHeight: 0
maxJumpAcrossDistance: 0
minRegionArea: 2
manualCellSize: 0
cellSize: 0.16666667
manualTileSize: 0
tileSize: 256
accuratePlacement: 0
maxJobWorkers: 0
preserveTilesOutsideBounds: 0
debug:
m_Flags: 0
m_SettingNames:
- Humanoid
================================================
FILE: ProjectSettings/PackageManagerSettings.asset
================================================
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &1
MonoBehaviour:
m_ObjectHideFlags: 61
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 13964, guid: 0000000000000000e000000000000000, type: 0}
m_Name:
m_EditorClassIdentifier:
m_EnablePreviewPackages: 0
m_EnablePackageDependencies: 0
m_AdvancedSettingsExpanded: 1
m_ScopedRegistriesSettingsExpanded: 1
oneTimeWarningShown: 0
m_Registries:
- m_Id: main
m_Name:
m_Url: https://packages.unity.com
m_Scopes: []
m_IsDefault: 1
m_Capabilities: 7
m_UserSelectedRegistryName:
m_UserAddingNewScopedRegistry: 0
m_RegistryInfoDraft:
m_ErrorMessage:
m_Original:
m_Id:
m_Name:
m_Url:
m_Scopes: []
m_IsDefault: 0
m_Capabilities: 0
m_Modified: 0
m_Name:
m_Url:
m_Scopes:
-
m_SelectedScopeIndex: 0
================================================
FILE: ProjectSettings/Physics2DSettings.asset
================================================
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!19 &1
Physics2DSettings:
m_ObjectHideFlags: 0
serializedVersion: 5
m_Gravity: {x: 0, y: -9.81}
m_DefaultMaterial: {fileID: 0}
m_VelocityIterations: 8
m_PositionIterations: 3
m_VelocityThreshold: 1
m_MaxLinearCorrection: 0.2
m_MaxAngularCorrection: 8
m_MaxTranslationSpeed: 100
m_MaxRotationSpeed: 360
m_BaumgarteScale: 0.2
m_BaumgarteTimeOfImpactScale: 0.75
m_TimeToSleep: 0.5
m_LinearSleepTolerance: 0.01
m_AngularSleepTolerance: 2
m_DefaultContactOffset: 0.01
m_JobOptions:
serializedVersion: 2
useMultithreading: 0
useConsistencySorting: 0
m_InterpolationPosesPerJob: 100
m_NewContactsPerJob: 30
m_CollideContactsPerJob: 100
m_ClearFlagsPerJob: 200
m_ClearBodyForcesPerJob: 200
m_SyncDiscreteFixturesPerJob: 50
m_SyncContinuousFixturesPerJob: 50
m_FindNearestContactsPerJob: 100
m_UpdateTriggerContactsPerJob: 100
m_IslandSolverCostThreshold: 100
m_IslandSolverBodyCostScale: 1
m_IslandSolverContactCostScale: 10
m_IslandSolverJointCostScale: 10
m_IslandSolverBodiesPerJob: 50
m_IslandSolverContactsPerJob: 50
m_SimulationMode: 0
m_QueriesHitTriggers: 1
m_QueriesStartInColliders: 1
m_CallbacksOnDisable: 1
m_ReuseCollisionCallbacks: 0
m_AutoSyncTransforms: 0
m_AlwaysShowColliders: 0
m_ShowColliderSleep: 1
m_ShowColliderContacts: 0
m_ShowColliderAABB: 0
m_ContactArrowScale: 0.2
m_ColliderAwakeColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.7529412}
m_ColliderAsleepColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.36078432}
m_ColliderContactColor: {r: 1, g: 0, b: 1, a: 0.6862745}
m_ColliderAABBColor: {r: 1, g: 1, b: 0, a: 0.2509804}
m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
================================================
FILE: ProjectSettings/PresetManager.asset
================================================
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1386491679 &1
PresetManager:
m_ObjectHideFlags: 0
serializedVersion: 2
m_DefaultPresets: {}
================================================
FILE: ProjectSettings/ProjectSettings.asset
================================================
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!129 &1
PlayerSettings:
m_ObjectHideFlags: 0
serializedVersion: 20
productGUID: 3b3617942226a3b43be6a56804ede4ff
AndroidProfiler: 0
AndroidFilterTouchesWhenObscured: 0
AndroidEnableSustainedPerformanceMode: 0
defaultScreenOrientation: 4
targetDevice: 2
useOnDemandResources: 0
accelerometerFrequency: 60
companyName: DefaultCompany
productName: 2D-Deformable-body-in-Unity
defaultCursor: {fileID: 0}
cursorHotspot: {x: 0, y: 0}
m_SplashScreenBackgroundColor: {r: 0.13725491, g: 0.12156863, b: 0.1254902, a: 1}
m_ShowUnitySplashScreen: 1
m_ShowUnitySplashLogo: 1
m_SplashScreenOverlayOpacity: 1
m_SplashScreenAnimation: 1
m_SplashScreenLogoStyle: 1
m_SplashScreenDrawMode: 0
m_SplashScreenBackgroundAnimationZoom: 1
m_SplashScreenLogoAnimationZoom: 1
m_SplashScreenBackgroundLandscapeAspect: 1
m_SplashScreenBackgroundPortraitAspect: 1
m_SplashScreenBackgroundLandscapeUvs:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
m_SplashScreenBackgroundPortraitUvs:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
m_SplashScreenLogos: []
m_VirtualRealitySplashScreen: {fileID: 0}
m_HolographicTrackingLossScreen: {fileID: 0}
defaultScreenWidth: 1024
defaultScreenHeight: 768
defaultScreenWidthWeb: 960
defaultScreenHeightWeb: 600
m_StereoRenderingPath: 0
m_ActiveColorSpace: 0
m_MTRendering: 1
mipStripping: 0
numberOfMipsStripped: 0
m_StackTraceTypes: 010000000100000001000000010000000100000001000000
iosShowActivityIndicatorOnLoading: -1
androidShowActivityIndicatorOnLoading: -1
iosUseCustomAppBackgroundBehavior: 0
iosAllowHTTPDownload: 1
allowedAutorotateToPortrait: 1
allowedAutorotateToPortraitUpsideDown: 1
allowedAutorotateToLandscapeRight: 1
allowedAutorotateToLandscapeLeft: 1
useOSAutorotation: 1
use32BitDisplayBuffer: 1
preserveFramebufferAlpha: 0
disableDepthAndStencilBuffers: 0
androidStartInFullscreen: 1
androidRenderOutsideSafeArea: 1
androidUseSwappy: 1
androidBlitType: 0
defaultIsNativeResolution: 1
macRetinaSupport: 1
runInBackground: 0
captureSingleScreen: 0
muteOtherAudioSources: 0
Prepare IOS For Recording: 0
Force IOS Speakers When Recording: 0
deferSystemGesturesMode: 0
hideHomeButton: 0
submitAnalytics: 1
usePlayerLog: 1
bakeCollisionMeshes: 0
forceSingleInstance: 0
useFlipModelSwapchain: 1
resizableWindow: 0
useMacAppStoreValidation: 0
macAppStoreCategory: public.app-category.games
gpuSkinning: 0
xboxPIXTextureCapture: 0
xboxEnableAvatar: 0
xboxEnableKinect: 0
xboxEnableKinectAutoTracking: 0
xboxEnableFitness: 0
visibleInBackground: 1
allowFullscreenSwitch: 1
fullscreenMode: 1
xboxSpeechDB: 0
xboxEnableHeadOrientation: 0
xboxEnableGuest: 0
xboxEnablePIXSampling: 0
metalFramebufferOnly: 0
xboxOneResolution: 0
xboxOneSResolution: 0
xboxOneXResolution: 3
xboxOneMonoLoggingLevel: 0
xboxOneLoggingLevel: 1
xboxOneDisableEsram: 0
xboxOneEnableTypeOptimization: 0
xboxOnePresentImmediateThreshold: 0
switchQueueCommandMemory: 1048576
switchQueueControlMemory: 16384
switchQueueComputeMemory: 262144
switchNVNShaderPoolsGranularity: 33554432
switchNVNDefaultPoolsGranularity: 16777216
switchNVNOtherPoolsGranularity: 16777216
switchNVNMaxPublicTextureIDCount: 0
switchNVNMaxPublicSamplerIDCount: 0
stadiaPresentMode: 0
stadiaTargetFramerate: 0
vulkanNumSwapchainBuffers: 3
vulkanEnableSetSRGBWrite: 0
m_SupportedAspectRatios:
4:3: 1
5:4: 1
16:10: 1
16:9: 1
Others: 1
bundleVersion: 1.0
preloadedAssets: []
metroInputSource: 0
wsaTransparentSwapchain: 0
m_HolographicPauseOnTrackingLoss: 1
xboxOneDisableKinectGpuReservation: 1
xboxOneEnable7thCore: 1
vrSettings:
cardboard:
depthFormat: 0
enableTransitionView: 0
daydream:
depthFormat: 0
useSustainedPerformanceMode: 0
enableVideoLayer: 0
useProtectedVideoMemory: 0
minimumSupportedHeadTracking: 0
maximumSupportedHeadTracking: 1
hololens:
depthFormat: 1
depthBufferSharingEnabled: 1
lumin:
depthFormat: 0
frameTiming: 2
enableGLCache: 0
glCacheMaxBlobSize: 524288
glCacheMaxFileSize: 8388608
oculus:
sharedDepthBuffer: 1
dashSupport: 1
lowOverheadMode: 0
protectedContext: 0
v2Signing: 1
enable360StereoCapture: 0
isWsaHolographicRemotingEnabled: 0
enableFrameTimingStats: 0
useHDRDisplay: 0
D3DHDRBitDepth: 0
m_ColorGamuts: 00000000
targetPixelDensity: 0
resolutionScalingMode: 0
androidSupportedAspectRatio: 1
androidMaxAspectRatio: 2.1
applicationIdentifier: {}
buildNumber: {}
AndroidBundleVersionCode: 1
AndroidMinSdkVersion: 19
AndroidTargetSdkVersion: 0
AndroidPreferredInstallLocation: 1
aotOptions:
stripEngineCode: 1
iPhoneStrippingLevel: 0
iPhoneScriptCallOptimization: 0
ForceInternetPermission: 0
ForceSDCardPermission: 0
CreateWallpaper: 0
APKExpansionFiles: 0
keepLoadedShadersAlive: 0
StripUnusedMeshComponents: 0
VertexChannelCompressionMask: 4054
iPhoneSdkVersion: 988
iOSTargetOSVersionString:
tvOSSdkVersion: 0
tvOSRequireExtendedGameController: 0
tvOSTargetOSVersionString:
uIPrerenderedIcon: 0
uIRequiresPersistentWiFi: 0
uIRequiresFullScreen: 1
uIStatusBarHidden: 1
uIExitOnSuspend: 0
uIStatusBarStyle: 0
appleTVSplashScreen: {fileID: 0}
appleTVSplashScreen2x: {fileID: 0}
tvOSSmallIconLayers: []
tvOSSmallIconLayers2x: []
tvOSLargeIconLayers: []
tvOSLargeIconLayers2x: []
tvOSTopShelfImageLayers: []
tvOSTopShelfImageLayers2x: []
tvOSTopShelfImageWideLayers: []
tvOSTopShelfImageWideLayers2x: []
iOSLaunchScreenType: 0
iOSLaunchScreenPortrait: {fileID: 0}
iOSLaunchScreenLandscape: {fileID: 0}
iOSLaunchScreenBackgroundColor:
serializedVersion: 2
rgba: 0
iOSLaunchScreenFillPct: 100
iOSLaunchScreenSize: 100
iOSLaunchScreenCustomXibPath:
iOSLaunchScreeniPadType: 0
iOSLaunchScreeniPadImage: {fileID: 0}
iOSLaunchScreeniPadBackgroundColor:
serializedVersion: 2
rgba: 0
iOSLaunchScreeniPadFillPct: 100
iOSLaunchScreeniPadSize: 100
iOSLaunchScreeniPadCustomXibPath:
iOSUseLaunchScreenStoryboard: 0
iOSLaunchScreenCustomStoryboardPath:
iOSDeviceRequirements: []
iOSURLSchemes: []
iOSBackgroundModes: 0
iOSMetalForceHardShadows: 0
metalEditorSupport: 1
metalAPIValidation: 1
iOSRenderExtraFrameOnPause: 0
appleDeveloperTeamID:
iOSManualSigningProvisioningProfileID:
tvOSManualSigningProvisioningProfileID:
iOSManualSigningProvisioningProfileType: 0
tvOSManualSigningProvisioningProfileType: 0
appleEnableAutomaticSigning: 0
iOSRequireARKit: 0
iOSAutomaticallyDetectAndAddCapabilities: 1
appleEnableProMotion: 0
clonedFromGUID: 00000000000000000000000000000000
templatePackageId:
templateDefaultScene:
AndroidTargetArchitectures: 1
AndroidSplashScreenScale: 0
androidSplashScreen: {fileID: 0}
AndroidKeystoreName:
AndroidKeyaliasName:
AndroidBuildApkPerCpuArchitecture: 0
AndroidTVCompatibility: 0
AndroidIsGame: 1
AndroidEnableTango: 0
androidEnableBanner: 1
androidUseLowAccuracyLocation: 0
androidUseCustomKeystore: 0
m_AndroidBanners:
- width: 320
height: 180
banner: {fileID: 0}
androidGamepadSupportLevel: 0
AndroidMinifyWithR8: 0
AndroidMinifyRelease: 0
AndroidMinifyDebug: 0
AndroidValidateAppBundleSize: 1
AndroidAppBundleSizeToValidate: 150
m_BuildTargetIcons: []
m_BuildTargetPlatformIcons: []
m_BuildTargetBatching: []
m_BuildTargetGraphicsJobs: []
m_BuildTargetGraphicsJobMode: []
m_BuildTargetGraphicsAPIs: []
m_BuildTargetVRSettings: []
openGLRequireES31: 0
openGLRequireES31AEP: 0
openGLRequireES32: 0
m_TemplateCustomTags: {}
mobileMTRendering:
Android: 1
iPhone: 1
tvOS: 1
m_BuildTargetGroupLightmapEncodingQuality: []
m_BuildTargetGroupLightmapSettings: []
playModeTestRunnerEnabled: 0
runPlayModeTestAsEditModeTest: 0
actionOnDotNetUnhandledException: 1
enableInternalProfiler: 0
logObjCUncaughtExceptions: 1
enableCrashReportAPI: 0
cameraUsageDescription:
locationUsageDescription:
microphoneUsageDescription:
switchNMETAOverride:
switchNetLibKey:
switchSocketMemoryPoolSize: 6144
switchSocketAllocatorPoolSize: 128
switchSocketConcurrencyLimit: 14
switchScreenResolutionBehavior: 2
switchUseCPUProfiler: 0
switchUseGOLDLinker: 0
switchApplicationID: 0x01004b9000490000
switchNSODependencies:
switchTitleNames_0:
switchTitleNames_1:
switchTitleNames_2:
switchTitleNames_3:
switchTitleNames_4:
switchTitleNames_5:
switchTitleNames_6:
switchTitleNames_7:
switchTitleNames_8:
switchTitleNames_9:
switchTitleNames_10:
switchTitleNames_11:
switchTitleNames_12:
switchTitleNames_13:
switchTitleNames_14:
switchPublisherNames_0:
switchPublisherNames_1:
switchPublisherNames_2:
switchPublisherNames_3:
switchPublisherNames_4:
switchPublisherNames_5:
switchPublisherNames_6:
switchPublisherNames_7:
switchPublisherNames_8:
switchPublisherNames_9:
switchPublisherNames_10:
switchPublisherNames_11:
switchPublisherNames_12:
switchPublisherNames_13:
switchPublisherNames_14:
switchIcons_0: {fileID: 0}
switchIcons_1: {fileID: 0}
switchIcons_2: {fileID: 0}
switchIcons_3: {fileID: 0}
switchIcons_4: {fileID: 0}
switchIcons_5: {fileID: 0}
switchIcons_6: {fileID: 0}
switchIcons_7: {fileID: 0}
switchIcons_8: {fileID: 0}
switchIcons_9: {fileID: 0}
switchIcons_10: {fileID: 0}
switchIcons_11: {fileID: 0}
switchIcons_12: {fileID: 0}
switchIcons_13: {fileID: 0}
switchIcons_14: {fileID: 0}
switchSmallIcons_0: {fileID: 0}
switchSmallIcons_1: {fileID: 0}
switchSmallIcons_2: {fileID: 0}
switchSmallIcons_3: {fileID: 0}
switchSmallIcons_4: {fileID: 0}
switchSmallIcons_5: {fileID: 0}
switchSmallIcons_6: {fileID: 0}
switchSmallIcons_7: {fileID: 0}
switchSmallIcons_8: {fileID: 0}
switchSmallIcons_9: {fileID: 0}
switchSmallIcons_10: {fileID: 0}
switchSmallIcons_11: {fileID: 0}
switchSmallIcons_12: {fileID: 0}
switchSmallIcons_13: {fileID: 0}
switchSmallIcons_14: {fileID: 0}
switchManualHTML:
switchAccessibleURLs:
switchLegalInformation:
switchMainThreadStackSize: 1048576
switchPresenceGroupId:
switchLogoHandling: 0
switchReleaseVersion: 0
switchDisplayVersion: 1.0.0
switchStartupUserAccount: 0
switchTouchScreenUsage: 0
switchSupportedLanguagesMask: 0
switchLogoType: 0
switchApplicationErrorCodeCategory:
switchUserAccountSaveDataSize: 0
switchUserAccountSaveDataJournalSize: 0
switchApplicationAttribute: 0
switchCardSpecSize: -1
switchCardSpecClock: -1
switchRatingsMask: 0
switchRatingsInt_0: 0
switchRatingsInt_1: 0
switchRatingsInt_2: 0
switchRatingsInt_3: 0
switchRatingsInt_4: 0
switchRatingsInt_5: 0
switchRatingsInt_6: 0
switchRatingsInt_7: 0
switchRatingsInt_8: 0
switchRatingsInt_9: 0
switchRatingsInt_10: 0
switchRatingsInt_11: 0
switchRatingsInt_12: 0
switchLocalCommunicationIds_0:
switchLocalCommunicationIds_1:
switchLocalCommunicationIds_2:
switchLocalCommunicationIds_3:
switchLocalCommunicationIds_4:
switchLocalCommunicationIds_5:
switchLocalCommunicationIds_6:
switchLocalCommunicationIds_7:
switchParentalControl: 0
switchAllowsScreenshot: 1
switchAllowsVideoCapturing: 1
switchAllowsRuntimeAddOnContentInstall: 0
switchDataLossConfirmation: 0
switchUserAccountLockEnabled: 0
switchSystemResourceMemory: 16777216
switchSupportedNpadStyles: 22
switchNativeFsCacheSize: 32
switchIsHoldTypeHorizontal: 0
switchSupportedNpadCount: 8
switchSocketConfigEnabled: 0
switchTcpInitialSendBufferSize: 32
switchTcpInitialReceiveBufferSize: 64
switchTcpAutoSendBufferSizeMax: 256
switchTcpAutoReceiveBufferSizeMax: 256
switchUdpSendBufferSize: 9
switchUdpReceiveBufferSize: 42
switchSocketBufferEfficiency: 4
switchSocketInitializeEnabled: 1
switchNetworkInterfaceManagerInitializeEnabled: 1
switchPlayerConnectionEnabled: 1
ps4NPAgeRating: 12
ps4NPTitleSecret:
ps4NPTrophyPackPath:
ps4ParentalLevel: 11
ps4ContentID: ED1633-NPXX51362_00-0000000000000000
ps4Category: 0
ps4MasterVersion: 01.00
ps4AppVersion: 01.00
ps4AppType: 0
ps4ParamSfxPath:
ps4VideoOutPixelFormat: 0
ps4VideoOutInitialWidth: 1920
ps4VideoOutBaseModeInitialWidth: 1920
ps4VideoOutReprojectionRate: 60
ps4PronunciationXMLPath:
ps4PronunciationSIGPath:
ps4BackgroundImagePath:
ps4StartupImagePath:
ps4StartupImagesFolder:
ps4IconImagesFolder:
ps4SaveDataImagePath:
ps4SdkOverride:
ps4BGMPath:
ps4ShareFilePath:
ps4ShareOverlayImagePath:
ps4PrivacyGuardImagePath:
ps4ExtraSceSysFile:
ps4NPtitleDatPath:
ps4RemotePlayKeyAssignment: -1
ps4RemotePlayKeyMappingDir:
ps4PlayTogetherPlayerCount: 0
ps4EnterButtonAssignment: 2
ps4ApplicationParam1: 0
ps4ApplicationParam2: 0
ps4ApplicationParam3: 0
ps4ApplicationParam4: 0
ps4DownloadDataSize: 0
ps4GarlicHeapSize: 2048
ps4ProGarlicHeapSize: 2560
playerPrefsMaxSize: 32768
ps4Passcode: frAQBc8Wsa1xVPfvJcrgRYwTiizs2trQ
ps4pnSessions: 1
ps4pnPresence: 1
ps4pnFriends: 1
ps4pnGameCustomData: 1
playerPrefsSupport: 0
enableApplicationExit: 0
resetTempFolder: 1
restrictedAudioUsageRights: 0
ps4UseResolutionFallback: 0
ps4ReprojectionSupport: 0
ps4UseAudio3dBackend: 0
ps4UseLowGarlicFragmentationMode: 1
ps4SocialScreenEnabled: 0
ps4ScriptOptimizationLevel: 2
ps4Audio3dVirtualSpeakerCount: 14
ps4attribCpuUsage: 0
ps4PatchPkgPath:
ps4PatchLatestPkgPath:
ps4PatchChangeinfoPath:
ps4PatchDayOne: 0
ps4attribUserManagement: 0
ps4attribMoveSupport: 0
ps4attrib3DSupport: 0
ps4attribShareSupport: 0
ps4attribExclusiveVR: 0
ps4disableAutoHideSplash: 0
ps4videoRecordingFeaturesUsed: 0
ps4contentSearchFeaturesUsed: 0
ps4CompatibilityPS5: 0
ps4GPU800MHz: 1
ps4attribEyeToEyeDistanceSettingVR: 0
ps4IncludedModules: []
ps4attribVROutputEnabled: 0
monoEnv:
splashScreenBackgroundSourceLandscape: {fileID: 0}
splashScreenBackgroundSourcePortrait: {fileID: 0}
blurSplashScreenBackground: 1
spritePackerPolicy:
webGLMemorySize: 32
webGLExceptionSupport: 1
webGLNameFilesAsHashes: 0
webGLDataCaching: 1
webGLDebugSymbols: 0
webGLEmscriptenArgs:
webGLModulesDirectory:
webGLTemplate: APPLICATION:Default
webGLAnalyzeBuildSize: 0
webGLUseEmbeddedResources: 0
webGLCompressionFormat: 0
webGLWasmArithmeticExceptions: 0
webGLLinkerTarget: 1
webGLThreadsSupport: 0
webGLDecompressionFallback: 0
scriptingDefineSymbols: {}
platformArchitecture: {}
scriptingBackend: {}
il2cppCompilerConfiguration: {}
managedStrippingLevel: {}
incrementalIl2cppBuild: {}
allowUnsafeCode: 0
useDeterministicCompilation: 1
additionalIl2CppArgs:
scriptingRuntimeVersion: 1
gcIncremental: 1
gcWBarrierValidation: 0
apiCompatibilityLevelPerPlatform: {}
m_RenderingPath: 1
m_MobileRenderingPath: 1
metroPackageName: 2D-Deformable-body-in-Unity
metroPackageVersion:
metroCertificatePath:
metroCertificatePassword:
metroCertificateSubject:
metroCertificateIssuer:
metroCertificateNotAfter: 0000000000000000
metroApplicationDescription: 2D-Deformable-body-in-Unity
wsaImages: {}
metroTileShortName:
metroTileShowName: 0
metroMediumTileShowName: 0
metroLargeTileShowName: 0
metroWideTileShowName: 0
metroSupportStreamingInstall: 0
metroLastRequiredScene: 0
metroDefaultTileSize: 1
metroTileForegroundText: 2
metroTileBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21568628, a: 0}
metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628, a: 1}
metroSplashScreenUseBackgroundColor: 0
platformCapabilities: {}
metroTargetDeviceFamilies: {}
metroFTAName:
metroFTAFileTypes: []
metroProtocolName:
XboxOneProductId:
XboxOneUpdateKey:
XboxOneSandboxId:
XboxOneContentId:
XboxOneTitleId:
XboxOneSCId:
XboxOneGameOsOverridePath:
XboxOnePackagingOverridePath:
XboxOneAppManifestOverridePath:
XboxOneVersion: 1.0.0.0
XboxOnePackageEncryption: 0
XboxOnePackageUpdateGranularity: 2
XboxOneDescription:
XboxOneLanguage:
- enus
XboxOneCapability: []
XboxOneGameRating: {}
XboxOneIsContentPackage: 0
XboxOneEnableGPUVariability: 1
XboxOneSockets: {}
XboxOneSplashScreen: {fileID: 0}
XboxOneAllowedProductIds: []
XboxOnePersistentLocalStorageSize: 0
XboxOneXTitleMemory: 8
XboxOneOverrideIdentityName:
XboxOneOverrideIdentityPublisher:
vrEditorSettings:
daydream:
daydreamIconForeground: {fileID: 0}
daydreamIconBackground: {fileID: 0}
cloudServicesEnabled: {}
luminIcon:
m_Name:
m_ModelFolderPath:
m_PortalFolderPath:
luminCert:
m_CertPath:
m_SignPackage: 1
luminIsChannelApp: 0
luminVersion:
m_VersionCode: 1
m_VersionName:
apiCompatibilityLevel: 6
cloudProjectId:
framebufferDepthMemorylessMode: 0
projectName:
organizationId:
cloudEnabled: 0
enableNativePlatformBackendsForNewInputSystem: 0
disableOldInputManagerSupport: 0
legacyClampBlendShapeWeights: 0
virtualTexturingSupportEnabled: 0
================================================
FILE: ProjectSettings/ProjectVersion.txt
================================================
m_EditorVersion: 2020.1.6f1
m_EditorVersionWithRevision: 2020.1.6f1 (fc477ca6df10)
================================================
FILE: ProjectSettings/QualitySettings.asset
================================================
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!47 &1
QualitySettings:
m_ObjectHideFlags: 0
serializedVersion: 5
m_CurrentQuality: 5
m_QualitySettings:
- serializedVersion: 2
name: Very Low
pixelLightCount: 0
shadows: 0
shadowResolution: 0
shadowProjection: 1
shadowCascades: 1
shadowDistance: 15
shadowNearPlaneOffset: 3
shadowCascade2Split: 0.33333334
shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
shadowmaskMode: 0
skinWeights: 1
textureQuality: 1
anisotropicTextures: 0
antiAliasing: 0
softParticles: 0
softVegetation: 0
realtimeReflectionProbes: 0
billboardsFaceCameraPosition: 0
vSyncCount: 0
lodBias: 0.3
maximumLODLevel: 0
streamingMipmapsActive: 0
streamingMipmapsAddAllCameras: 1
streamingMipmapsMemoryBudget: 512
streamingMipmapsRenderersPerFrame: 512
streamingMipmapsMaxLevelReduction: 2
streamingMipmapsMaxFileIORequests: 1024
particleRaycastBudget: 4
asyncUploadTimeSlice: 2
asyncUploadBufferSize: 16
asyncUploadPersistentBuffer: 1
resolutionScalingFixedDPIFactor: 1
customRenderPipeline: {fileID: 0}
excludedTargetPlatforms: []
- serializedVersion: 2
name: Low
pixelLightCount: 0
shadows: 0
shadowResolution: 0
shadowProjection: 1
shadowCascades: 1
shadowDistance: 20
shadowNearPlaneOffset: 3
shadowCascade2Split: 0.33333334
shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
shadowmaskMode: 0
skinWeights: 2
textureQuality: 0
anisotropicTextures: 0
antiAliasing: 0
softParticles: 0
softVegetation: 0
realtimeReflectionProbes: 0
billboardsFaceCameraPosition: 0
vSyncCount: 0
lodBias: 0.4
maximumLODLevel: 0
streamingMipmapsActive: 0
streamingMipmapsAddAllCameras: 1
streamingMipmapsMemoryBudget: 512
streamingMipmapsRenderersPerFrame: 512
streamingMipmapsMaxLevelReduction: 2
streamingMipmapsMaxFileIORequests: 1024
particleRaycastBudget: 16
asyncUploadTimeSlice: 2
asyncUploadBufferSize: 16
asyncUploadPersistentBuffer: 1
resolutionScalingFixedDPIFactor: 1
customRenderPipeline: {fileID: 0}
excludedTargetPlatforms: []
- serializedVersion: 2
name: Medium
pixelLightCount: 1
shadows: 1
shadowResolution: 0
shadowProjection: 1
shadowCascades: 1
shadowDistance: 20
shadowNearPlaneOffset: 3
shadowCascade2Split: 0.33333334
shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
shadowmaskMode: 0
skinWeights: 2
textureQuality: 0
anisotropicTextures: 1
antiAliasing: 0
softParticles: 0
softVegetation: 0
realtimeReflectionProbes: 0
billboardsFaceCameraPosition: 0
vSyncCount: 1
lodBias: 0.7
maximumLODLevel: 0
streamingMipmapsActive: 0
streamingMipmapsAddAllCameras: 1
streamingMipmapsMemoryBudget: 512
streamingMipmapsRenderersPerFrame: 512
streamingMipmapsMaxLevelReduction: 2
streamingMipmapsMaxFileIORequests: 1024
particleRaycastBudget: 64
asyncUploadTimeSlice: 2
asyncUploadBufferSize: 16
asyncUploadPersistentBuffer: 1
resolutionScalingFixedDPIFactor: 1
customRenderPipeline: {fileID: 0}
excludedTargetPlatforms: []
- serializedVersion: 2
name: High
pixelLightCount: 2
shadows: 2
shadowResolution: 1
shadowProjection: 1
shadowCascades: 2
shadowDistance: 40
shadowNearPlaneOffset: 3
shadowCascade2Split: 0.33333334
shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
shadowmaskMode: 1
skinWeights: 2
textureQuality: 0
anisotropicTextures: 1
antiAliasing: 0
softParticles: 0
softVegetation: 1
realtimeReflectionProbes: 1
billboardsFaceCameraPosition: 1
vSyncCount: 1
lodBias: 1
maximumLODLevel: 0
streamingMipmapsActive: 0
streamingMipmapsAddAllCameras: 1
streamingMipmapsMemoryBudget: 512
streamingMipmapsRenderersPerFrame: 512
streamingMipmapsMaxLevelReduction: 2
streamingMipmapsMaxFileIORequests: 1024
particleRaycastBudget: 256
asyncUploadTimeSlice: 2
asyncUploadBufferSize: 16
asyncUploadPersistentBuffer: 1
resolutionScalingFixedDPIFactor: 1
customRenderPipeline: {fileID: 0}
excludedTargetPlatforms: []
- serializedVersion: 2
name: Very High
pixelLightCount: 3
shadows: 2
shadowResolution: 2
shadowProjection: 1
shadowCascades: 2
shadowDistance: 70
shadowNearPlaneOffset: 3
shadowCascade2Split: 0.33333334
shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
shadowmaskMode: 1
skinWeights: 4
textureQuality: 0
anisotropicTextures: 2
antiAliasing: 2
softParticles: 1
softVegetation: 1
realtimeReflectionProbes: 1
billboardsFaceCameraPosition: 1
vSyncCount: 1
lodBias: 1.5
maximumLODLevel: 0
streamingMipmapsActive: 0
streamingMipmapsAddAllCameras: 1
streamingMipmapsMemoryBudget: 512
streamingMipmapsRenderersPerFrame: 512
streamingMipmapsMaxLevelReduction: 2
streamingMipmapsMaxFileIORequests: 1024
particleRaycastBudget: 1024
asyncUploadTimeSlice: 2
asyncUploadBufferSize: 16
asyncUploadPersistentBuffer: 1
resolutionScalingFixedDPIFactor: 1
customRenderPipeline: {fileID: 0}
excludedTargetPlatforms: []
- serializedVersion: 2
name: Ultra
pixelLightCount: 4
shadows: 2
shadowResolution: 2
shadowProjection: 1
shadowCascades: 4
shadowDistance: 150
shadowNearPlaneOffset: 3
shadowCascade2Split: 0.33333334
shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667}
shadowmaskMode: 1
skinWeights: 255
textureQuality: 0
anisotropicTextures: 2
antiAliasing: 2
softParticles: 1
softVegetation: 1
realtimeReflectionProbes: 1
billboardsFaceCameraPosition: 1
vSyncCount: 1
lodBias: 2
maximumLODLevel: 0
streamingMipmapsActive: 0
streamingMipmapsAddAllCameras: 1
streamingMipmapsMemoryBudget: 512
streamingMipmapsRenderersPerFrame: 512
streamingMipmapsMaxLevelReduction: 2
streamingMipmapsMaxFileIORequests: 1024
particleRaycastBudget: 4096
asyncUploadTimeSlice: 2
asyncUploadBufferSize: 16
asyncUploadPersistentBuffer: 1
resolutionScalingFixedDPIFactor: 1
customRenderPipeline: {fileID: 0}
excludedTargetPlatforms: []
m_PerPlatformDefaultQuality:
Android: 2
CloudRendering: 5
Lumin: 5
Nintendo Switch: 5
PS4: 5
Stadia: 5
Standalone: 5
WebGL: 3
Windows Store Apps: 5
XboxOne: 5
iPhone: 2
tvOS: 2
================================================
FILE: ProjectSettings/TagManager.asset
================================================
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!78 &1
TagManager:
serializedVersion: 2
tags: []
layers:
- Default
- TransparentFX
- Ignore Raycast
-
- Water
- UI
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
m_SortingLayers:
- name: Default
uniqueID: 0
locked: 0
================================================
FILE: ProjectSettings/TimeManager.asset
================================================
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!5 &1
TimeManager:
m_ObjectHideFlags: 0
Fixed Timestep: 0.02
Maximum Allowed Timestep: 0.33333334
m_TimeScale: 1
Maximum Particle Timestep: 0.03
================================================
FILE: ProjectSettings/UnityConnectSettings.asset
================================================
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!310 &1
UnityConnectSettings:
m_ObjectHideFlags: 0
serializedVersion: 1
m_Enabled: 0
m_TestMode: 0
m_EventOldUrl: https://api.uca.cloud.unity3d.com/v1/events
m_EventUrl: https://cdp.cloud.unity3d.com/v1/events
m_ConfigUrl: https://config.uca.cloud.unity3d.com
m_TestInitMode: 0
CrashReportingSettings:
m_EventUrl: https://perf-events.cloud.unity3d.com
m_Enabled: 0
m_LogBufferSize: 10
m_CaptureEditorExceptions: 1
UnityPurchasingSettings:
m_Enabled: 0
m_TestMode: 0
UnityAnalyticsSettings:
m_Enabled: 0
m_TestMode: 0
m_InitializeOnStartup: 1
UnityAdsSettings:
m_Enabled: 0
m_InitializeOnStartup: 1
m_TestMode: 0
m_IosGameId:
m_AndroidGameId:
m_GameIds: {}
m_GameId:
PerformanceReportingSettings:
m_Enabled: 0
================================================
FILE: ProjectSettings/VFXManager.asset
================================================
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!937362698 &1
VFXManager:
m_ObjectHideFlags: 0
m_IndirectShader: {fileID: 0}
m_CopyBufferShader: {fileID: 0}
m_SortShader: {fileID: 0}
m_StripUpdateShader: {fileID: 0}
m_RenderPipeSettingsPath:
m_FixedTimeStep: 0.016666668
m_MaxDeltaTime: 0.05
m_CompiledVersion: 0
m_RuntimeVersion: 0
================================================
FILE: ProjectSettings/VersionControlSettings.asset
================================================
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!890905787 &1
VersionControlSettings:
m_ObjectHideFlags: 0
m_Mode: Visible Meta Files
m_CollabEditorSettings:
inProgressEnabled: 1
================================================
FILE: ProjectSettings/XRSettings.asset
================================================
{
"m_SettingKeys": [
"VR Device Disabled",
"VR Device User Alert"
],
"m_SettingValues": [
"False",
"False"
]
}
================================================
FILE: README.md
================================================
# 2D-Deformable-body-in-Unity
A 2D Deformable body simulation in Unity using FEM
This a port of the 2D FEM project by [Miles Macklin](http://blog.mmacklin.com/) found [here](https://github.com/mmacklin/sandbox) from C++/OpenGL to C# Unity. The code is not that stable and the physics can break if pushed too far but its a nice introduction to deformable bodies using the Finite Element Method.
The original did also implement fracturing of the mesh but I have not fully ported that and probably wont. The project provides a few options to load the scene with various meshes and has some neat code that creates a mesh from a image.
There's a armadillo, bunny and a donut.


There's also a few basic shapes created from code like a beam, torus and a random convex as shown below.

And here's a GIF of the armadillo being thrown around.

List of physics projects
[Position-Based-Dynamics](https://github.com/Scrawk/Position-Based-Dynamics)\
[PBD-Fluid-in-Unity](https://github.com/Scrawk/PBD-Fluid-in-Unity)\
[GPU-GEMS-NBody-Simulation](https://github.com/Scrawk/GPU-GEMS-NBody-Simulation)\
[GPU-GEMS-2D-Fluid-Simulation](https://github.com/Scrawk/GPU-GEMS-2D-Fluid-Simulation)\
[GPU-GEMS-3D-Fluid-Simulation](https://github.com/Scrawk/GPU-GEMS-3D-Fluid-Simulation)\
[CyclonePhysicsEngine](https://github.com/Scrawk/CyclonePhysicsEngine)\
[2D-Deformable-body-in-Unity](https://github.com/Scrawk/2D-Deformable-body-in-Unity)