mirror of
https://github.com/Relintai/voxelman.git
synced 2025-04-25 21:25:00 +02:00
More work on porting.
This commit is contained in:
parent
7a35337367
commit
83806f4bc1
@ -404,9 +404,9 @@ void VoxelMesher::UpdateMesh(int iteration) {
|
|||||||
for (int i = 0; i < _mu_triangles.size(); ++i) {
|
for (int i = 0; i < _mu_triangles.size(); ++i) {
|
||||||
// Calc Edge Error
|
// Calc Edge Error
|
||||||
MUTriangle triangle = _mu_triangles[i];
|
MUTriangle triangle = _mu_triangles[i];
|
||||||
_mu_triangles[i].err0 = CalculateError(_mu_vertices[triangle.v0], _mu_vertices[triangle.v1], out dummy);
|
_mu_triangles[i].err0 = CalculateError(_mu_vertices[triangle.v0], _mu_vertices[triangle.v1], &dummy);
|
||||||
_mu_triangles[i].err1 = CalculateError(_mu_vertices[triangle.v1], _mu_vertices[triangle.v2], out dummy);
|
_mu_triangles[i].err1 = CalculateError(_mu_vertices[triangle.v1], _mu_vertices[triangle.v2], &dummy);
|
||||||
_mu_triangles[i].err2 = CalculateError(_mu_vertices[triangle.v2], _mu_vertices[triangle.v0], out dummy);
|
_mu_triangles[i].err2 = CalculateError(_mu_vertices[triangle.v2], _mu_vertices[triangle.v0], &dummy);
|
||||||
_mu_triangles[i].err3 = VoxelMesher::Min3(_mu_triangles[i].err0, _mu_triangles[i].err1, _mu_triangles[i].err2);
|
_mu_triangles[i].err3 = VoxelMesher::Min3(_mu_triangles[i].err0, _mu_triangles[i].err1, _mu_triangles[i].err2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -470,6 +470,7 @@ void VoxelMesher::CompactMesh() {
|
|||||||
|
|
||||||
for (int i = 0; i < _mu_triangles.size(); i++) {
|
for (int i = 0; i < _mu_triangles.size(); i++) {
|
||||||
MUTriangle triangle = _mu_triangles[i];
|
MUTriangle triangle = _mu_triangles[i];
|
||||||
|
|
||||||
if (!triangle.deleted) {
|
if (!triangle.deleted) {
|
||||||
if (triangle.va0 != triangle.v0) {
|
if (triangle.va0 != triangle.v0) {
|
||||||
int iDest = triangle.va0;
|
int iDest = triangle.va0;
|
||||||
@ -508,22 +509,22 @@ void VoxelMesher::CompactMesh() {
|
|||||||
_mu_vertices[triangle.v1].tcount = 1;
|
_mu_vertices[triangle.v1].tcount = 1;
|
||||||
_mu_vertices[triangle.v2].tcount = 1;
|
_mu_vertices[triangle.v2].tcount = 1;
|
||||||
|
|
||||||
if (triangle.subMeshIndex > lastSubMeshIndex) {
|
//if (triangle.subMeshIndex > lastSubMeshIndex) {
|
||||||
for (int j = lastSubMeshIndex + 1; j < triangle.subMeshIndex; j++) {
|
// for (int j = lastSubMeshIndex + 1; j < triangle.subMeshIndex; j++) {
|
||||||
subMeshOffsets[j] = newTriangleIndex;
|
// subMeshOffsets[j] = newTriangleIndex;
|
||||||
}
|
// }
|
||||||
subMeshOffsets[triangle.subMeshIndex] = newTriangleIndex;
|
// subMeshOffsets[triangle.subMeshIndex] = newTriangleIndex;
|
||||||
lastSubMeshIndex = triangle.subMeshIndex;
|
// lastSubMeshIndex = triangle.subMeshIndex;
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
triangleCount = dst;
|
//triangleCount = dst;
|
||||||
for (int i = lastSubMeshIndex + 1; i < subMeshCount; i++) {
|
//for (int i = lastSubMeshIndex + 1; i < subMeshCount; i++) {
|
||||||
subMeshOffsets[i] = triangleCount;
|
// subMeshOffsets[i] = triangleCount;
|
||||||
}
|
//}
|
||||||
|
|
||||||
this.triangles.Resize(triangleCount);
|
_mu_triangles.resize(dst);
|
||||||
|
|
||||||
dst = 0;
|
dst = 0;
|
||||||
for (int i = 0; i < vertexCount; i++) {
|
for (int i = 0; i < vertexCount; i++) {
|
||||||
@ -573,16 +574,16 @@ void VoxelMesher::CompactMesh() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < triangleCount; i++) {
|
for (int i = 0; i < _mu_triangles.size(); i++) {
|
||||||
var triangle = triangles[i];
|
MUTriangle triangle = _mu_triangles[i];
|
||||||
triangle.v0 = vertices[triangle.v0].tstart;
|
triangle.v0 = _mu_vertices[triangle.v0].tstart;
|
||||||
triangle.v1 = vertices[triangle.v1].tstart;
|
triangle.v1 = _mu_vertices[triangle.v1].tstart;
|
||||||
triangle.v2 = vertices[triangle.v2].tstart;
|
triangle.v2 = _mu_vertices[triangle.v2].tstart;
|
||||||
triangles[i] = triangle;
|
_mu_triangles[i] = triangle;
|
||||||
}
|
}
|
||||||
|
|
||||||
vertexCount = dst;
|
//vertexCount = dst;
|
||||||
this.vertices.Resize(vertexCount);
|
this.vertices.Resize(dst);
|
||||||
if (vertNormals != null) this.vertNormals.Resize(vertexCount, true);
|
if (vertNormals != null) this.vertNormals.Resize(vertexCount, true);
|
||||||
if (vertTangents != null) this.vertTangents.Resize(vertexCount, true);
|
if (vertTangents != null) this.vertTangents.Resize(vertexCount, true);
|
||||||
if (vertUV2D != null) this.vertUV2D.Resize(vertexCount, true);
|
if (vertUV2D != null) this.vertUV2D.Resize(vertexCount, true);
|
||||||
@ -649,20 +650,20 @@ int VoxelMesher::RemoveVertexPass(int startTrisCount, int targetTrisCount, doubl
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Compute vertex to collapse to
|
// Compute vertex to collapse to
|
||||||
CalculateError(_mu_vertices[i0], ref _mu_vertices[i1], out p);
|
CalculateError(_mu_vertices[i0], _mu_vertices[i1], &p);
|
||||||
deleted0.Resize(_mu_vertices[i0].tcount); // normals temporarily
|
deleted0.resize(_mu_vertices[i0].tcount); // normals temporarily
|
||||||
deleted1.Resize(_mu_vertices[i1].tcount); // normals temporarily
|
deleted1.resize(_mu_vertices[i1].tcount); // normals temporarily
|
||||||
|
|
||||||
// Don't remove if flipped
|
// Don't remove if flipped
|
||||||
if (Flipped(ref p, i0, i1, ref _mu_vertices[i0], deleted0.Data))
|
if (Flipped(&p, i0, i1, &(_mu_vertices[i0]), deleted0))
|
||||||
continue;
|
continue;
|
||||||
if (Flipped(ref p, i1, i0, ref _mu_vertices[i1], deleted1.Data))
|
if (Flipped(&p, i1, i0, &(_mu_vertices[i1]), deleted1))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Calculate the barycentric coordinates within the triangle
|
// Calculate the barycentric coordinates within the triangle
|
||||||
int nextNextEdgeIndex = ((edgeIndex + 2) % 3);
|
int nextNextEdgeIndex = ((edgeIndex + 2) % 3);
|
||||||
int i2 = _mu_triangles[tid].get(nextNextEdgeIndex);
|
int i2 = _mu_triangles[tid].get(nextNextEdgeIndex);
|
||||||
CalculateBarycentricCoords(ref p, ref _mu_vertices[i0].p, ref _mu_vertices[i1].p, ref _mu_vertices[i2].p, out barycentricCoord);
|
barycentricCoord = CalculateBarycentricCoords(p, _mu_vertices[i0].p, _mu_vertices[i1].p, _mu_vertices[i2].p);
|
||||||
|
|
||||||
// Not flipped, so remove edge
|
// Not flipped, so remove edge
|
||||||
_mu_vertices[i0].p = p;
|
_mu_vertices[i0].p = p;
|
||||||
@ -672,17 +673,17 @@ int VoxelMesher::RemoveVertexPass(int startTrisCount, int targetTrisCount, doubl
|
|||||||
int ia0 = attrib_indices[edgeIndex];
|
int ia0 = attrib_indices[edgeIndex];
|
||||||
int ia1 = attrib_indices[nextEdgeIndex];
|
int ia1 = attrib_indices[nextEdgeIndex];
|
||||||
int ia2 = attrib_indices[nextNextEdgeIndex];
|
int ia2 = attrib_indices[nextNextEdgeIndex];
|
||||||
InterpolateVertexAttributes(ia0, ia0, ia1, ia2, ref barycentricCoord);
|
InterpolateVertexAttributes(ia0, ia0, ia1, ia2, barycentricCoord);
|
||||||
|
|
||||||
if (_mu_vertices[i0].uvSeamEdge) {
|
if (_mu_vertices[i0].uvSeamEdge) {
|
||||||
ia0 = -1;
|
ia0 = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int tstart = refs.Length;
|
int tstart = _mu_refs.size();
|
||||||
deletedTris = UpdateTriangles(i0, ia0, _mu_vertices[i0], deleted0, deletedTris);
|
deletedTris = UpdateTriangles(i0, ia0, &(_mu_vertices[i0]), deleted0, deletedTris);
|
||||||
deletedTris = UpdateTriangles(i0, ia0, _mu_vertices[i1], deleted1, deletedTris);
|
deletedTris = UpdateTriangles(i0, ia0, &(_mu_vertices[i1]), deleted1, deletedTris);
|
||||||
|
|
||||||
int tcount = refs.Length - tstart;
|
int tcount = _mu_refs.size() - tstart;
|
||||||
if (tcount <= _mu_vertices[i0].tcount) {
|
if (tcount <= _mu_vertices[i0].tcount) {
|
||||||
// save ram
|
// save ram
|
||||||
if (tcount > 0) {
|
if (tcount > 0) {
|
||||||
@ -734,20 +735,29 @@ double VoxelMesher::CalculateError(MUVertex vert0, MUVertex vert1, Vector3 *resu
|
|||||||
|
|
||||||
error = VoxelMesher::Min3(error1, error2, error3);
|
error = VoxelMesher::Min3(error1, error2, error3);
|
||||||
if (error == error3) {
|
if (error == error3) {
|
||||||
result = p3;
|
result->x = p3.x;
|
||||||
|
result->y = p3.y;
|
||||||
|
result->z = p3.z;
|
||||||
} else if (error == error2) {
|
} else if (error == error2) {
|
||||||
result = p2;
|
result->x = p2.x;
|
||||||
|
result->y = p2.y;
|
||||||
|
result->z = p2.z;
|
||||||
} else if (error == error1) {
|
} else if (error == error1) {
|
||||||
result = p1;
|
result->x = p1.x;
|
||||||
|
result->y = p1.y;
|
||||||
|
result->z = p1.z;
|
||||||
} else {
|
} else {
|
||||||
result = p3;
|
result->x = p3.x;
|
||||||
|
result->y = p3.y;
|
||||||
|
result->z = p3.z;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelMesher::UpdateTriangles(int i0, int ia0, MUVertex *v, PoolVector<bool> deleted, int *deletedTriangles) {
|
int VoxelMesher::UpdateTriangles(int i0, int ia0, MUVertex *v, PoolVector<bool> deleted, int p_deletedTriangles) {
|
||||||
Vector3 p;
|
Vector3 p;
|
||||||
|
int deletedTriangles = p_deletedTriangles;
|
||||||
int tcount = v->tcount;
|
int tcount = v->tcount;
|
||||||
|
|
||||||
for (int k = 0; k < tcount; k++) {
|
for (int k = 0; k < tcount; k++) {
|
||||||
@ -769,14 +779,97 @@ void VoxelMesher::UpdateTriangles(int i0, int ia0, MUVertex *v, PoolVector<bool>
|
|||||||
}
|
}
|
||||||
|
|
||||||
t.dirty = true;
|
t.dirty = true;
|
||||||
t.err0 = CalculateError(_mu_vertices[t.v0], _mu_vertices[t.v1], p);
|
t.err0 = CalculateError(_mu_vertices[t.v0], _mu_vertices[t.v1], &p);
|
||||||
t.err1 = CalculateError(_mu_vertices[t.v1], _mu_vertices[t.v2], p);
|
t.err1 = CalculateError(_mu_vertices[t.v1], _mu_vertices[t.v2], &p);
|
||||||
t.err2 = CalculateError(_mu_vertices[t.v2], _mu_vertices[t.v0], p);
|
t.err2 = CalculateError(_mu_vertices[t.v2], _mu_vertices[t.v0], &p);
|
||||||
t.err3 = VoxelMesher::Min3(t.err0, t.err1, t.err2);
|
t.err3 = VoxelMesher::Min3(t.err0, t.err1, t.err2);
|
||||||
|
|
||||||
_mu_triangles[tid] = t;
|
_mu_triangles[tid] = t;
|
||||||
_mu_refs.push_back(r);
|
_mu_refs.push_back(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return deletedTriangles;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VoxelMesher::Flipped(Vector3 *p, int i0, int i1, MUVertex *v0, PoolVector<bool> &deleted) {
|
||||||
|
int tcount = v0->tcount;
|
||||||
|
|
||||||
|
for (int k = 0; k < tcount; k++) {
|
||||||
|
MURef r = _mu_refs[v0->tstart + k];
|
||||||
|
if (_mu_triangles[r.tid].deleted)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int s = r.tvertex;
|
||||||
|
int id1 = _mu_triangles[r.tid].get((s + 1) % 3);
|
||||||
|
int id2 = _mu_triangles[r.tid].get((s + 2) % 3);
|
||||||
|
if (id1 == i1 || id2 == i1) {
|
||||||
|
deleted.set(k, true);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 d1 = _mu_vertices[id1].p - (*p);
|
||||||
|
d1.normalize();
|
||||||
|
Vector3 d2 = _mu_vertices[id2].p - (*p);
|
||||||
|
d2.normalize();
|
||||||
|
double dot = d1.dot(d2);
|
||||||
|
if (Math::abs(dot) > 0.999)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
Vector3 n = d1.cross(d2);
|
||||||
|
n.normalize();
|
||||||
|
deleted.set(k, false);
|
||||||
|
dot = n.dot(_mu_triangles[r.tid].n);
|
||||||
|
if (dot < 0.2)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 VoxelMesher::CalculateBarycentricCoords(Vector3 const &point, Vector3 const &a, Vector3 const &b, Vector3 const &c) {
|
||||||
|
Vector3 v0 = (Vector3)(b - a), v1 = (Vector3)(c - a), v2 = (Vector3)(point - a);
|
||||||
|
float d00 = v0.dot(v0);
|
||||||
|
float d01 = v0.dot(v1);
|
||||||
|
float d11 = v1.dot(v1);
|
||||||
|
float d20 = v2.dot(v0);
|
||||||
|
float d21 = v2.dot(v1);
|
||||||
|
float denom = d00 * d11 - d01 * d01;
|
||||||
|
float v = (d11 * d20 - d01 * d21) / denom;
|
||||||
|
float w = (d00 * d21 - d01 * d20) / denom;
|
||||||
|
float u = 1.0 - v - w;
|
||||||
|
|
||||||
|
return Vector3(u, v, w);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VoxelMesher::InterpolateVertexAttributes(int dst, int i0, int i1, int i2, Vector3 &barycentricCoord) {
|
||||||
|
if (vertNormals != null) {
|
||||||
|
vertNormals[dst] = Vector3.Normalize((vertNormals[i0] * barycentricCoord.x) + (vertNormals[i1] * barycentricCoord.y) + (vertNormals[i2] * barycentricCoord.z));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vertTangents != null) {
|
||||||
|
vertTangents[dst] = NormalizeTangent((vertTangents[i0] * barycentricCoord.x) + (vertTangents[i1] * barycentricCoord.y) + (vertTangents[i2] * barycentricCoord.z));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vertUV2D != null) {
|
||||||
|
for (int i = 0; i < UVChannelCount; i++) {
|
||||||
|
var vertUV = vertUV2D[i];
|
||||||
|
if (vertUV != null) {
|
||||||
|
vertUV[dst] = (vertUV[i0] * barycentricCoord.x) + (vertUV[i1] * barycentricCoord.y) + (vertUV[i2] * barycentricCoord.z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vertColors != null) {
|
||||||
|
vertColors[dst] = (vertColors[i0] * barycentricCoord.x) + (vertColors[i1] * barycentricCoord.y) + (vertColors[i2] * barycentricCoord.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blendShapes != null) {
|
||||||
|
for (int i = 0; i < blendShapes.Length; i++) {
|
||||||
|
blendShapes[i].InterpolateVertexAttributes(dst, i0, i1, i2, barycentricCoord);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: How do we interpolate the bone weights? Do we have to?
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelMesher::reset() {
|
void VoxelMesher::reset() {
|
||||||
|
@ -88,7 +88,10 @@ public:
|
|||||||
bool AreUVsTheSame(int channel, int indexA, int indexB);
|
bool AreUVsTheSame(int channel, int indexA, int indexB);
|
||||||
double VertexError(SymmetricMatrix q, double x, double y, double z);
|
double VertexError(SymmetricMatrix q, double x, double y, double z);
|
||||||
double CalculateError(MUVertex vert0, MUVertex vert1, Vector3 *result);
|
double CalculateError(MUVertex vert0, MUVertex vert1, Vector3 *result);
|
||||||
void UpdateTriangles(int i0, int ia0, MUVertex *v, PoolVector<bool> deleted, int *deletedTriangles);
|
int UpdateTriangles(int i0, int ia0, MUVertex *v, PoolVector<bool> deleted, int deletedTriangles);
|
||||||
|
bool Flipped(Vector3 *p, int i0, int i1, MUVertex *v0, PoolVector<bool> &deleted);
|
||||||
|
static Vector3 CalculateBarycentricCoords(Vector3 const &point, Vector3 const &a, Vector3 const &b, Vector3 const &c);
|
||||||
|
void InterpolateVertexAttributes(int dst, int i0, int i1, int i2, Vector3 &barycentricCoord);
|
||||||
|
|
||||||
static double Min3(double val1, double val2, double val3) {
|
static double Min3(double val1, double val2, double val3) {
|
||||||
return (val1 < val2 ? (val1 < val3 ? val1 : val3) : (val2 < val3 ? val2 : val3));
|
return (val1 < val2 ? (val1 < val3 ? val1 : val3) : (val2 < val3 ? val2 : val3));
|
||||||
|
Loading…
Reference in New Issue
Block a user