diff --git a/src/main.c b/src/main.c index 3118a4f..977dab7 100755 --- a/src/main.c +++ b/src/main.c @@ -23,69 +23,94 @@ unsigned char palette[] = 0x7A,0x1C,0xAC,0xff, }; -void calc_normal(float* p1, float* p2, float* p3,float* normal, unsigned char n) -{ - float alpha; - vec4 v1, v2, v3; - vec4 u1, u2, u3; - - switch (n) - { - case 3: +void calc_normal(float* p1, float* p2, float* p3, float* normal, unsigned char n) { + float alpha; + vec4 v1, v2, v3; + vec4 u1, u2, u3; - glm_vec3_sub(p2, p1, v1); - glm_vec3_sub(p3, p1, v2); + switch (n) { + case 3: + glm_vec3_sub(p2, p1, v1); + glm_vec3_sub(p3, p1, v2); - glm_vec3_cross(v1, v2, normal); - glm_vec3_normalize(normal); - return; + glm_vec3_cross(v1, v2, normal); + glm_vec3_normalize(normal); + return; - case 4: - - /* - In Grant-Shmidth we need 3 linearly independian vector that forms a basis, - so we can have a ortonormal version of that basis, since, we must have - v1 = p3 - p1 - v2 = p2 - p1 - Then v3 = p1, will most certantly be linerly independiant to v1 and v2. - */ - glm_vec4_sub(p2, p1, v1); - glm_vec4_sub(p3, p1, v2); - glm_vec4_copy(p1, v3); + case 4: + glm_vec4_sub(p2, p1, v1); + glm_vec4_sub(p3, p1, v2); + glm_vec4_copy(p1, v3); + glm_vec4_copy(v1, u1); + { + vec4 proj; + alpha = glm_vec4_dot(v2, u1) / glm_vec4_dot(u1, u1); + glm_vec4_scale(u1, alpha, proj); + glm_vec4_sub(v2, proj, u2); + } - /* Setup U1 */ - { - glm_vec4_copy(v1, u1); - } + { + vec4 proj1, proj2; + alpha = glm_vec4_dot(v3, u1) / glm_vec4_dot(u1, u1); + glm_vec4_scale(u1, alpha, proj1); - /* Setup U2 */ - { - vec4 proj; + alpha = glm_vec4_dot(v3, u2) / glm_vec4_dot(u2, u2); + glm_vec4_scale(u2, alpha, proj2); - alpha = glm_vec4_dot(v2, u1) / glm_vec4_dot(u1, u1); - glm_vec4_scale(u1, alpha, proj); + glm_vec4_sub(v3, proj1, u3); + glm_vec4_sub(u3, proj2, u3); + } - glm_vec4_sub(v2, proj, u2); - } + glm_vec4_copy(u3, normal); + glm_vec4_normalize(normal); + return; - /* Setup U3 */ - { - vec4 proj1, proj2; + default: + float** u = malloc((n - 1) * sizeof(float*)); + for (unsigned char i = 0; i < n - 1; i++) { + u[i] = malloc(n * sizeof(float)); + } - alpha = glm_vec4_dot(v3, u1) / glm_vec4_dot(u1, u1); - glm_vec4_scale(u1, alpha, proj1); - - alpha = glm_vec4_dot(v3, u2) / glm_vec4_dot(u2, u2); - glm_vec4_scale(u2, alpha, proj2); - - glm_vec4_sub(v3, proj1, u3); - glm_vec4_sub(u3, proj2, u3); - } - - glm_vec4_copy(u3, normal); - glm_vec4_normalize(normal); - return; - } + for (unsigned char i = 0; i < n - 1; i++) { + float* vi = malloc(n * sizeof(float)); + for (unsigned char j = 0; j < n; j++) { + vi[j] = p2[j] - p1[j]; + } + + for (unsigned char j = 0; j < i; j++) { + float dot_vu = 0.0f, dot_uu = 0.0f; + + for (unsigned char k = 0; k < n; k++) { + dot_vu += vi[k] * u[j][k]; + dot_uu += u[j][k] * u[j][k]; + } + + for (unsigned char k = 0; k < n; k++) { + vi[k] -= (dot_vu / dot_uu) * u[j][k]; + } + } + + memcpy(u[i], vi, n * sizeof(float)); + free(vi); + } + + memcpy(normal, u[n - 2], n * sizeof(float)); + + float norm = 0.0f; + for (unsigned char i = 0; i < n; i++) { + norm += normal[i] * normal[i]; + } + norm = sqrtf(norm); + for (unsigned char i = 0; i < n; i++) { + normal[i] /= norm; + } + + for (unsigned char i = 0; i < n - 1; i++) { + free(u[i]); + } + free(u); + return; + } } float * fill_normal( float * d, unsigned char m )