Just post your code in code tags in the future, most of us lazy here:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Jobs;
using Unity.Burst;
using Unity.Mathematics;
using Unity.Jobs;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
public class SimpJob : MonoBehaviour
{
public float targ = 0.7f;
public float agg = 7;
public bool runTest;
public GameObject o;
public void Update()
{
if (runTest)
{
runTest = false;
Mesh m = o.GetComponent<MeshFilter>().mesh;
Test(m, targ);
}
}
public unsafe void Test(Mesh input, float t)
{
NativeArray<int> triangles = new NativeArray<int>((int)input.GetIndexCount(0), Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
NativeArray<float3> vertices = new NativeArray<float3>(input.vertexCount, Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
NativeArray<float3> normals = new NativeArray<float3>(input.vertexCount, Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
NativeArray<int> results = new NativeArray<int>(3, Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
int totalTris = (int)input.GetIndexCount(0) / 3;
var simpJob = new SimplifyJob
{
target_count = (int)(totalTris * t),
triangles = triangles,
vertices = vertices,
normals = normals,
results = results,
meshVerts = UnsafeUtility.AddressOf(ref input.vertices[0]),
meshTris = UnsafeUtility.AddressOf(ref input.triangles[0]),
meshNorms = UnsafeUtility.AddressOf(ref input.normals[0]),
agressiveness = agg
}.Schedule();
simpJob.Complete();
int triCount = results[0];
int vertCount = results[1];
int normCount = vertCount;
input.Clear();
input.SetVertices(vertices, 0, vertCount);
input.SetIndices(triangles, 0, triCount * 3, MeshTopology.Triangles, 0, true);
input.SetNormals(normals, 0, normCount);
triangles.Dispose();
vertices.Dispose();
normals.Dispose();
results.Dispose();
}
public struct Ref
{
public int tid, tvertex;
public void Set(int tid, int tvertex)
{
this.tid = tid;
this.tvertex = tvertex;
}
}
[BurstCompile]
public unsafe struct SimplifyJob : IJob
{
public NativeArray<int> results;
public NativeArray<int> triangles;
public NativeArray<float3> vertices;
public NativeArray<float3> normals;
[ReadOnly, NativeDisableUnsafePtrRestriction] public void* meshVerts;
[ReadOnly, NativeDisableUnsafePtrRestriction] public void* meshTris;
[ReadOnly, NativeDisableUnsafePtrRestriction] public void* meshNorms;
int triCount;
int vertCount;
public int target_count;
public float agressiveness;
//
// Main simplification function
//
// target_count : target nr. of triangles
// agressiveness : sharpness to increase the threshold.
// 5..8 are good numbers
// more iterations yield higher quality
//
public void Execute()
{
int indiceCount = triangles.Length;
triCount = indiceCount / 3;
vertCount = vertices.Length;
int triangle_count = triCount;
NativeArray<float> triErr = new NativeArray<float>(triCount * 4, Allocator.Temp, NativeArrayOptions.UninitializedMemory);
NativeArray<bool> vborder = new NativeArray<bool>(vertCount, Allocator.Temp);
NativeArray<bool> deletedTri = new NativeArray<bool>(triCount, Allocator.Temp);
NativeArray<float3> triNorm = new NativeArray<float3>(triCount, Allocator.Temp, NativeArrayOptions.UninitializedMemory);
NativeArray<float> syMatrix = new NativeArray<float>(vertCount * 10, Allocator.Temp);
NativeArray<float> tempMatrix = new NativeArray<float>(10, Allocator.Temp);
NativeList<Ref> refs = new NativeList<Ref>(Allocator.Temp);
NativeArray<bool> deleted0 = new NativeArray<bool>(50, Allocator.Temp);
NativeArray<bool> deleted1 = new NativeArray<bool>(50, Allocator.Temp);
NativeArray<bool> dirtyTris = new NativeArray<bool>(triCount, Allocator.Temp, NativeArrayOptions.UninitializedMemory);
NativeArray<int> tcounts = new NativeArray<int>(vertCount, Allocator.Temp, NativeArrayOptions.UninitializedMemory);
NativeArray<int> tstarts = new NativeArray<int>(vertCount, Allocator.Temp, NativeArrayOptions.UninitializedMemory);
NativeArray<int> vqs = new NativeArray<int>(vertCount, Allocator.Temp, NativeArrayOptions.UninitializedMemory);
if (agressiveness < 1)
agressiveness = 7;
for (int i = 0; i < indiceCount; i++)
{
refs.Add(new Ref());
triangles[i] = UnsafeUtility.ReadArrayElement<int>(meshTris, i);
if (i < vertCount)
{
vertices[i] = UnsafeUtility.ReadArrayElement<float3>(meshVerts, i);
normals[i] = UnsafeUtility.ReadArrayElement<float3>(meshNorms, i);
}
}
// add one extra
refs.Add(new Ref());
// main iteration loop
int deleted_triangles = 0;
for (int iteration = 0; iteration < 100; iteration++)
{
if (triangle_count - deleted_triangles <= target_count) break;
// clear dirty flag
for (int i = 0; i < triCount; i++)
{
dirtyTris[i] = false;
}
if (iteration % 5 == 0) update_mesh(iteration, deletedTri, triErr, triNorm, vborder, refs, syMatrix, tempMatrix, tstarts, tcounts, vqs);
// All triangles with edges below the threshold will be removed
//
// The following numbers works well for most models.
// If it does not, try to adjust the 3 parameters
double threshold = 0.000000001 * math.pow((iteration + 3), agressiveness);
// remove vertices & mark deleted triangles
for (int i = 0; i < triCount; i++)
{
int tvi = i * 3; // tri vertex index
int tei = i * 4; // tri error index
if (triErr[tei + 3] > threshold)
{
continue;
}
if (deletedTri[i])
{
continue;
}
if (dirtyTris[i])
{
continue;
}
for (int j = 0; j < 3; j++)
{
if (triErr[tei + j] < threshold)
{
int i0 = triangles[tvi + j];
int i1 = triangles[tvi + ((j + 1) % 3)];
// Border check
if (vborder[i0] || vborder[i1]) continue;
// Compute vertex to collapse to
float3 p;
calculate_error(i0, i1, out p, vborder, syMatrix, tempMatrix, vqs);
// don't remove if flipped
if (flipped(p, i0, i1, i0, deleted0, deletedTri, triNorm, refs, tstarts, tcounts)) continue;
if (flipped(p, i1, i0, i1, deleted1, deletedTri, triNorm, refs, tstarts, tcounts)) continue;
// calculate barycentric coords
int i2 = triangles[tvi + ((j + 2) % 3)];
float3 barycentricCoord = CalculateBarycentricCoords(p, vertices[i0], vertices[i1], vertices[i2]);
// not flipped, so remove edge
vertices[i0] = p;
AddMatrixReplace(vqs[i0], vqs[i1], syMatrix);
// record and interpolate normal
int ia0 = i0;// t.v[j];
int ia1 = i1;// t.v[(j + 1) % 3];
int ia2 = i2;// t.v[(j + 2) % 3];
InterpolateVertexAttributes(ia0, ia0, ia1, ia2, barycentricCoord);
int tstart = refs.Length;
deleted_triangles += update_triangles(i0, i0, deleted0, deletedTri, triErr, vborder, refs, syMatrix, tempMatrix, tstarts, tcounts, dirtyTris, vqs);
deleted_triangles += update_triangles(i0, i1, deleted1, deletedTri, triErr, vborder, refs, syMatrix, tempMatrix, tstarts, tcounts, dirtyTris, vqs);
int tcount = refs.Length - tstart;
if (tcount <= tcounts[i0])
{
// save ram
if (tcount > 0)
{
NativeArray<Ref>.Copy(refs, tstart, refs, tstarts[i0], tcount);
}
}
else
// append
tstarts[i0] = tstart;
tcounts[i0] = tcount;
break;
}
}
// done?
if (triangle_count - deleted_triangles <= target_count) break;
}
//results[2] = iteration;
// Debug.Log("iteration count " + iteration + " deleted "+ deleted_triangles);
}
// clean up mesh
compact_mesh(deletedTri, triErr, triNorm, tstarts, tcounts);
// dispose temp arrays
refs.Dispose();
syMatrix.Dispose();
tempMatrix.Dispose();
deleted0.Dispose();
deleted1.Dispose();
dirtyTris.Dispose();
tstarts.Dispose();
tcounts.Dispose();
vqs.Dispose();
triErr.Dispose();
vborder.Dispose();
deletedTri.Dispose();
triNorm.Dispose();
}
[BurstCompile]
void compact_mesh(NativeArray<bool> deletedTri, NativeArray<float> triErr, NativeArray<float3> triNorm, NativeArray<int> tstarts, NativeArray<int> tcounts)
{
int dst = 0;
for (int i = 0; i < vertCount; i++)
{
tcounts[i] = 0;
}
for (int i = 0; i < triCount; i++)
{
if (!deletedTri[i])
{
int ti1 = i * 3;
int ti2 = dst * 3;
// verts
triangles[ti2] = triangles[ti1];
triangles[ti2 + 1] = triangles[ti1 + 1];
triangles[ti2 + 2] = triangles[ti1 + 2];
ti1 = i * 4;
ti2 = dst * 4;
// errs
triErr[ti2] = triErr[ti1];
triErr[ti2 + 1] = triErr[ti1 + 1];
triErr[ti2 + 2] = triErr[ti1 + 2];
triErr[ti2 + 3] = triErr[ti1 + 3];
triNorm[dst] = triNorm[i];
deletedTri[dst] = false;
ti1 = i * 3;
for (int j = 0; j < 3; j++)
{
tcounts[triangles[ti1 + j]] = 1;
}
dst++;
}
}
triCount = dst;
dst = 0;
for (int i = 0; i < vertCount; i++)
{
if (tcounts[i] > 0)
{
tstarts[i] = dst;
vertices[dst] = vertices[i];
if (dst != i)
{
normals[dst] = normals[i];
}
dst++;
}
}
for (int i = 0; i < triCount; i++)
{
int ti = i * 3;
for (int j = 0; j < 3; j++)
{
triangles[ti + j] = tstarts[triangles[ti + j]];
}
}
vertCount = dst;
results[0] = triCount;
results[1] = vertCount;
}
[BurstCompile]
void update_mesh(int iteration, NativeArray<bool> deletedTri, NativeArray<float> triErr, NativeArray<float3> triNorm, NativeArray<bool> vborder, NativeList<Ref> refs, NativeArray<float> syMatrix, NativeArray<float> tempMatrix, NativeArray<int> tstarts, NativeArray<int> tcounts, NativeArray<int> vqs)
{
if (iteration > 0) // compact triangles
{
int dst = 0;
for (int i = 0; i < triCount; i++)
{
if (!deletedTri[i])
{
int ti1 = i * 3;
int ti2 = dst * 3;
// verts
triangles[ti2] = triangles[ti1];
triangles[ti2 + 1] = triangles[ti1 + 1];
triangles[ti2 + 2] = triangles[ti1 + 2];
ti1 = i * 4;
ti2 = dst * 4;
// errs
triErr[ti2] = triErr[ti1];
triErr[ti2 + 1] = triErr[ti1 + 1];
triErr[ti2 + 2] = triErr[ti1 + 2];
triErr[ti2 + 3] = triErr[ti1 + 3];
triNorm[dst] = triNorm[i];
deletedTri[dst] = false;
dst++;
}
}
triCount = dst;
}
// Init Quadrics by Plane & Edge Errors
//
// required at the beginning ( iteration == 0 )
// recomputing during the simplification is not required,
// but mostly improves the result for closed meshes
//
if (iteration == 0)
{
for (int i = 0; i < vertCount; i++)
{
vqs[i] = NewSymmetricMatrix(i);
}
NativeArray<float3> p = new NativeArray<float3>(3, Allocator.Temp);
for (int i = 0; i < triCount; i++)
{
int ti = i * 3;
float3 n;
for (int j = 0; j < 3; j++)
{
p[j] = vertices[triangles[ti + j]];
}
n = math.cross(p[1] - p[0], p[2] - p[0]);
n = math.normalize(n);
triNorm[i] = n;
for (int j = 0; j < 3; j++)
{
AssignTempMatrix(n.x, n.y, n.z, -math.dot(n, p[0]), tempMatrix);
AddMatrixReplace(vqs[triangles[ti + j]], syMatrix, tempMatrix);
}
}
p.Dispose();
for (int i = 0; i < triCount; i++)
{
// Calc Edge Error
int ti = i * 3;
int te = i * 4;
float3 p1;
for (int j = 0; j < 3; j++)
{
triErr[te + j] = calculate_error(triangles[ti + j], triangles[ti + ((j + 1) % 3)], out p1, vborder, syMatrix, tempMatrix, vqs);
}
triErr[te + 3] = math.min(triErr[te], math.min(triErr[te + 1], triErr[te + 2]));
}
}
// Init Reference ID list
for (int i = 0; i < vertCount; i++)
{
tstarts[i] = 0;
tcounts[i] = 0;
}
for (int i = 0; i < triCount; i++)
{
int ti = i * 3;
for (int j = 0; j < 3; j++)
{
tcounts[triangles[ti + j]]++;
}
}
int tstart = 0;
for (int i = 0; i < vertCount; i++)
{
tstarts[i] = tstart;
tstart += tcounts[i];
tcounts[i] = 0;
}
// Write References
for (int i = 0; i < triCount; i++)
{
int ti = i * 3;
for (int j = 0; j < 3; j++)
{
int vi = triangles[ti + j];
Ref r = new Ref();
r.tid = i;
r.tvertex = j;
refs[tstarts[vi] + tcounts[vi]] = r;
tcounts[vi]++;
}
}
// Identify boundary : vertices[].border=0,1
if (iteration == 0)
{
NativeList<int> vcount = new NativeList<int>(Allocator.Temp);
NativeList<int> vids = new NativeList<int>(Allocator.Temp);
for (int i = 0; i < vertCount; i++)
{
vcount.Clear();
vids.Clear();
for (int j = 0; j < tcounts[i]; j++)
{
int k1 = refs[tstarts[i] + j].tid;
int ti = k1 * 3;
for (int k = 0; k < 3; k++)
{
int ofs = 0, id = triangles[ti + k];
while (ofs < vcount.Length)
{
if (vids[ofs] == id) break;
ofs++;
}
if (ofs == vcount.Length)
{
vcount.Add(1);
vids.Add(id);
}
else
vcount[ofs]++;
}
}
for (int j = 0; j < vcount.Length; j++)
{
if (vcount[j] == 1)
{
vborder[vids[j]] = true;
}
}
}
vcount.Dispose();
vids.Dispose();
}
}
// this has changed from result to not being out result
[BurstCompile]
float calculate_error(int id_v1, int id_v2, out float3 result, NativeArray<bool> vborder, NativeArray<float> syMatrix, NativeArray<float> tempMatrix, NativeArray<int> vqs)
{
// compute interpolated vertex
AssignTempMatrixByAdd(vqs[id_v1], vqs[id_v2], syMatrix, tempMatrix);
bool borderEdge = vborder[id_v1] & vborder[id_v2];
float error = 0.0f;
float det = Determinant1(tempMatrix);
if (det != 0.0 && !borderEdge)
{
// q_delta is invertible
result = new float3(
(-1.0f / det * Determinant2(tempMatrix)), // vx = A41/det(q_delta)
(1.0f / det * Determinant3(tempMatrix)), // vy = A42/det(q_delta)
(-1.0f / det * Determinant4(tempMatrix))); // vz = A43/det(q_delta)
error = VertexError(result.x, result.y, result.z, tempMatrix);
}
else
{
// det = 0 -> try to find best result
float3 p1 = vertices[id_v1];
float3 p2 = vertices[id_v2];
float3 p3 = (p1 + p2) * 0.5f;
float error1 = VertexError(p1.x, p1.y, p1.z, tempMatrix);
float error2 = VertexError(p2.x, p2.y, p2.z, tempMatrix);
float error3 = VertexError(p3.x, p3.y, p3.z, tempMatrix);
error = Min(error1, error2, error3);
if (error == error3)
{
result = p3;
}
else if (error == error2)
{
result = p2;
}
else if (error == error1)
{
result = p1;
}
else
{
result = p3;
}
}
return error;
}
// Update triangle connections and edge error after a edge is collapsed
[BurstCompile]
int update_triangles(int i0, int v, NativeArray<bool> deleted, NativeArray<bool> deletedTri, NativeArray<float> triErr, NativeArray<bool> vborder, NativeList<Ref> refs, NativeArray<float> syMatrix, NativeArray<float> tempMatrix, NativeArray<int> tstarts, NativeArray<int> tcounts, NativeArray<bool> dirtyTris, NativeArray<int> vqs)
{
int deletedCount = 0;
float3 p;
for (int k = 0; k < tcounts[v]; k++)
{
Ref r = refs[tstarts[v] + k];
if (deletedTri[r.tid]) continue;
if (deleted[k])
{
deletedTri[r.tid] = true;
deletedCount++;
continue;
}
int tvi = r.tid * 3;
int tei = r.tid * 4;
triangles[tvi + r.tvertex] = i0;
dirtyTris[r.tid] = true;
triErr[tei] = calculate_error(triangles[tvi], triangles[tvi + 1], out p, vborder, syMatrix, tempMatrix, vqs);
triErr[tei + 1] = calculate_error(triangles[tvi + 1], triangles[tvi + 2], out p, vborder, syMatrix, tempMatrix, vqs);
triErr[tei + 2] = calculate_error(triangles[tvi + 2], triangles[tvi], out p, vborder, syMatrix, tempMatrix, vqs);
triErr[tei + 3] = math.min(triErr[tei], math.min(triErr[tei + 1], triErr[tei + 2]));
refs.Add(r);
}
return deletedCount;
}
// Check if a triangle flips when this edge is removed
[BurstCompile]
bool flipped(float3 p, int i0, int i1, int v0, NativeArray<bool> deleted, NativeArray<bool> deletedTri, NativeArray<float3> triNorm, NativeList<Ref> refs, NativeArray<int> tstarts, NativeArray<int> tcounts)
{
for (int k = 0; k < tcounts[v0]; k++)
{
int ti = refs[tstarts[v0] + k].tid * 3;
if (deletedTri[refs[tstarts[v0] + k].tid]) continue;
int s = refs[tstarts[v0] + k].tvertex;
int id1 = triangles[ti + ((s + 1) % 3)];
int id2 = triangles[ti + ((s + 2) % 3)];
if (id1 == i1 || id2 == i1) // delete ?
{
deleted[k] = true;
continue;
}
float3 d1 = vertices[id1] - p;
d1 = math.normalize(d1);
float3 d2 = vertices[id2] - p;
d2 = math.normalize(d2);
float dot = math.dot(d1, d2);
if (math.abs(dot) > 0.999) return true;
float3 n = math.cross(d1, d2);
n = math.normalize(n);
deleted[k] = false;
if (math.dot(n, triNorm[refs[tstarts[v0] + k].tid]) < 0.2f) return true;
}
return false;
}
[BurstCompile]
private float VertexError(float x, float y, float z, NativeArray<float> tempMatrix)
{
return tempMatrix[0] * x * x + 2 * tempMatrix[1] * x * y + 2 * tempMatrix[2] * x * z + 2 * tempMatrix[3] * x + tempMatrix[4] * y * y
+ 2 * tempMatrix[5] * y * z + 2 * tempMatrix[6] * y + tempMatrix[7] * z * z + 2 * tempMatrix[8] * z + tempMatrix[9];
}
[BurstCompile]
public float Min(float val1, float val2, float val3)
{
return (val1 < val2 ? (val1 < val3 ? val1 : val3) : (val2 < val3 ? val2 : val3));
}
[BurstCompile]
private void InterpolateVertexAttributes(int dst, int i0, int i1, int i2, float3 barycentricCoord)
{
normals[dst] = math.normalize((normals[i0] * barycentricCoord.x) + (normals[i1] * barycentricCoord.y) + (normals[i2] * barycentricCoord.z));
}
[BurstCompile]
private float3 CalculateBarycentricCoords(float3 point, float3 a, float3 b, float3 c)
{
float3 v0 = (b - a), v1 = (c - a), v2 = (point - a);
float d00 = math.dot(v0, v0);
float d01 = math.dot(v0, v1);
float d11 = math.dot(v1, v1);
float d20 = math.dot(v2, v0);
float d21 = math.dot(v2, v1);
float denom = d00 * d11 - d01 * d01;
float v = (d11 * d20 - d01 * d21) / denom;
float w = (d00 * d21 - d01 * d20) / denom;
float u = 1f - v - w;
return new float3(u, v, w);
}
[BurstCompile]
public void AddMatrixReplace(int r, int b, NativeArray<float> syMatrix)
{
syMatrix[r] = syMatrix[r] + syMatrix[b];
syMatrix[r + 1] = syMatrix[r + 1] + syMatrix[b + 1];
syMatrix[r + 2] = syMatrix[r + 2] + syMatrix[b + 2];
syMatrix[r + 3] = syMatrix[r + 3] + syMatrix[b + 3];
syMatrix[r + 4] = syMatrix[r + 4] + syMatrix[b + 4];
syMatrix[r + 5] = syMatrix[r + 5] + syMatrix[b + 5];
syMatrix[r + 6] = syMatrix[r + 6] + syMatrix[b + 6];
syMatrix[r + 7] = syMatrix[r + 7] + syMatrix[b + 7];
syMatrix[r + 8] = syMatrix[r + 8] + syMatrix[b + 8];
syMatrix[r + 9] = syMatrix[r + 9] + syMatrix[b + 9];
}
[BurstCompile]
public void AddMatrixReplace(int r, NativeArray<float> syMatrix, NativeArray<float> tempMatrix)
{
syMatrix[r] = syMatrix[r] + tempMatrix[0];
syMatrix[r + 1] = syMatrix[r + 1] + tempMatrix[1];
syMatrix[r + 2] = syMatrix[r + 2] + tempMatrix[2];
syMatrix[r + 3] = syMatrix[r + 3] + tempMatrix[3];
syMatrix[r + 4] = syMatrix[r + 4] + tempMatrix[4];
syMatrix[r + 5] = syMatrix[r + 5] + tempMatrix[5];
syMatrix[r + 6] = syMatrix[r + 6] + tempMatrix[6];
syMatrix[r + 7] = syMatrix[r + 7] + tempMatrix[7];
syMatrix[r + 8] = syMatrix[r + 8] + tempMatrix[8];
syMatrix[r + 9] = syMatrix[r + 9] + tempMatrix[9];
}
[BurstCompile]
public void AssignTempMatrix(float a, float b, float c, float d, NativeArray<float> tempMatrix)
{
tempMatrix[0] = a * a;
tempMatrix[1] = a * b;
tempMatrix[2] = a * c;
tempMatrix[3] = a * d;
tempMatrix[4] = b * b;
tempMatrix[5] = b * c;
tempMatrix[6] = b * d;
tempMatrix[7] = c * c;
tempMatrix[8] = c * d;
tempMatrix[9] = d * d;
}
[BurstCompile]
public void AssignTempMatrixByAdd(int a, int b, NativeArray<float> syMatrix, NativeArray<float> tempMatrix)
{
tempMatrix[0] = syMatrix[a] + syMatrix[b];
tempMatrix[1] = syMatrix[a + 1] + syMatrix[b + 1];
tempMatrix[2] = syMatrix[a + 2] + syMatrix[b + 2];
tempMatrix[3] = syMatrix[a + 3] + syMatrix[b + 3];
tempMatrix[4] = syMatrix[a + 4] + syMatrix[b + 4];
tempMatrix[5] = syMatrix[a + 5] + syMatrix[b + 5];
tempMatrix[6] = syMatrix[a + 6] + syMatrix[b + 6];
tempMatrix[7] = syMatrix[a + 7] + syMatrix[b + 7];
tempMatrix[8] = syMatrix[a + 8] + syMatrix[b + 8];
tempMatrix[9] = syMatrix[a + 9] + syMatrix[b + 9];
}
public float syGetFromVert(int vindex, int i, NativeArray<float> syMatrix)
{
return syMatrix[vindex * 10 + i];
}
public int NewSymmetricMatrix(int vindex)
{
int s = vindex * 10;
return s;
}
[BurstCompile]
public int NewSymmetricMatrix(int vindex, float a, float b, float c, float d, NativeArray<float> syMatrix)
{
int s = vindex * 10;
syMatrix[s] = a * a;
syMatrix[s + 1] = a * b;
syMatrix[s + 2] = a * c;
syMatrix[s + 3] = a * d;
syMatrix[s + 4] = b * b;
syMatrix[s + 5] = b * c;
syMatrix[s + 6] = b * d;
syMatrix[s + 7] = c * c;
syMatrix[s + 8] = c * d;
syMatrix[s + 9] = d * d;
return s;
}
[BurstCompile]
public float Determinant1(NativeArray<float> tempMatrix)
{
float det =
tempMatrix[0] * tempMatrix[4] * tempMatrix[7] +
tempMatrix[2] * tempMatrix[1] * tempMatrix[5] +
tempMatrix[1] * tempMatrix[5] * tempMatrix[2] -
tempMatrix[2] * tempMatrix[4] * tempMatrix[2] -
tempMatrix[0] * tempMatrix[5] * tempMatrix[5] -
tempMatrix[1] * tempMatrix[1] * tempMatrix[7];
return det;
}
[BurstCompile]
public float Determinant2(NativeArray<float> tempMatrix)
{
float det =
tempMatrix[1] * tempMatrix[5] * tempMatrix[8] +
tempMatrix[3] * tempMatrix[4] * tempMatrix[7] +
tempMatrix[2] * tempMatrix[6] * tempMatrix[5] -
tempMatrix[3] * tempMatrix[5] * tempMatrix[5] -
tempMatrix[1] * tempMatrix[6] * tempMatrix[7] -
tempMatrix[2] * tempMatrix[4] * tempMatrix[8];
return det;
}
[BurstCompile]
public float Determinant3(NativeArray<float> tempMatrix)
{
float det =
tempMatrix[0] * tempMatrix[5] * tempMatrix[8] +
tempMatrix[3] * tempMatrix[1] * tempMatrix[7] +
tempMatrix[2] * tempMatrix[6] * tempMatrix[2] -
tempMatrix[3] * tempMatrix[5] * tempMatrix[2] -
tempMatrix[0] * tempMatrix[6] * tempMatrix[7] -
tempMatrix[2] * tempMatrix[1] * tempMatrix[8];
return det;
}
[BurstCompile]
public float Determinant4(NativeArray<float> tempMatrix)
{
float det =
tempMatrix[0] * tempMatrix[4] * tempMatrix[8] +
tempMatrix[3] * tempMatrix[1] * tempMatrix[5] +
tempMatrix[1] * tempMatrix[6] * tempMatrix[2] -
tempMatrix[3] * tempMatrix[4] * tempMatrix[2] -
tempMatrix[0] * tempMatrix[6] * tempMatrix[5] -
tempMatrix[1] * tempMatrix[1] * tempMatrix[8];
return det;
}
}
}