|
@@ -2473,6 +2473,74 @@ void MeshBinormals(Mesh *mesh)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// Smooth (average) vertex normals
|
|
|
|
+void MeshNormalsSmooth(Mesh *mesh)
|
|
|
|
+{
|
|
|
|
+ #define EPSILON 0.000001 // A small number
|
|
|
|
+
|
|
|
|
+ int uvCounter = 0;
|
|
|
|
+ Vector3 *uniqueVertices = (Vector3 *)RL_CALLOC(mesh->vertexCount, sizeof(Vector3));
|
|
|
|
+ Vector3 *summedNormals = (Vector3 *)RL_CALLOC(mesh->vertexCount, sizeof(Vector3));
|
|
|
|
+
|
|
|
|
+ int uiCounter = 0;
|
|
|
|
+ int *uniqueIndices = (int *)RL_CALLOC(mesh->vertexCount, sizeof(int));
|
|
|
|
+
|
|
|
|
+ // Sum normals grouped by vertex
|
|
|
|
+ for (int i = 0; i < mesh->vertexCount; i++)
|
|
|
|
+ {
|
|
|
|
+ Vector3 v = { mesh->vertices[(i + 0)*3 + 0], mesh->vertices[(i + 0)*3 + 1], mesh->vertices[(i + 0)*3 + 2] };
|
|
|
|
+ Vector3 n = { mesh->normals[(i + 0)*3 + 0], mesh->normals[(i + 0)*3 + 1], mesh->normals[(i + 0)*3 + 2] };
|
|
|
|
+
|
|
|
|
+ bool matched = false;
|
|
|
|
+
|
|
|
|
+ // TODO: Matching vertices is brute force O(N^2). Do it more efficiently?
|
|
|
|
+ for (int j = 0; j < uvCounter; j++)
|
|
|
|
+ {
|
|
|
|
+ Vector3 uv = uniqueVertices[j];
|
|
|
|
+
|
|
|
|
+ bool match = true;
|
|
|
|
+ match = match && fabs(uv.x - v.x) < EPSILON;
|
|
|
|
+ match = match && fabs(uv.y - v.y) < EPSILON;
|
|
|
|
+ match = match && fabs(uv.z - v.z) < EPSILON;
|
|
|
|
+
|
|
|
|
+ if (match)
|
|
|
|
+ {
|
|
|
|
+ matched = true;
|
|
|
|
+ summedNormals[j] = Vector3Add(summedNormals[j], n);
|
|
|
|
+ uniqueIndices[i] = j;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (!matched)
|
|
|
|
+ {
|
|
|
|
+ int j = uvCounter++;
|
|
|
|
+ uniqueVertices[j] = v;
|
|
|
|
+ summedNormals[j] = n;
|
|
|
|
+ uniqueIndices[i] = j;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Average and update normals
|
|
|
|
+ for (int i = 0; i < mesh->vertexCount; i++)
|
|
|
|
+ {
|
|
|
|
+ int j = uniqueIndices[i];
|
|
|
|
+ Vector3 n = Vector3Normalize(summedNormals[j]);
|
|
|
|
+ mesh->normals[(i + 0)*3 + 0] = n.x;
|
|
|
|
+ mesh->normals[(i + 0)*3 + 1] = n.y;
|
|
|
|
+ mesh->normals[(i + 0)*3 + 2] = n.z;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 2=normals, see rlUpdateMeshAt()
|
|
|
|
+ rlUpdateMesh(*mesh, 2, mesh->vertexCount);
|
|
|
|
+
|
|
|
|
+ RL_FREE(uniqueVertices);
|
|
|
|
+ RL_FREE(summedNormals);
|
|
|
|
+ RL_FREE(uniqueIndices);
|
|
|
|
+
|
|
|
|
+ TRACELOG(LOG_INFO, "MESH: Normals smoothed (%d vertices, %d unique)", mesh->vertexCount, uvCounter);
|
|
|
|
+}
|
|
|
|
+
|
|
// Draw a model (with texture if set)
|
|
// Draw a model (with texture if set)
|
|
void DrawModel(Model model, Vector3 position, float scale, Color tint)
|
|
void DrawModel(Model model, Vector3 position, float scale, Color tint)
|
|
{
|
|
{
|