Browse Source

Fix distortion of the Cup 3D demo

rexim 2 years ago
parent
commit
dfc1de88e2
4 changed files with 16 additions and 11 deletions
  1. 6 3
      demos/cup3d.c
  2. 1 2
      index.html
  3. 9 6
      tools/obj2c.c
  4. BIN
      wasm/cup3d.wasm

+ 6 - 3
demos/cup3d.c

@@ -53,9 +53,9 @@ static Vector2 project_2d_scr(Vector2 v2)
 
 static Vector3 rotate_y(Vector3 p, float delta_angle)
 {
-    float angle = atan2f(p.z - 1.5, p.x) + delta_angle;
-    float mag = sqrtf(p.x*p.x + (p.z - 1.5)*(p.z - 1.5));
-    return make_vector3(cosf(angle)*mag, p.y, sinf(angle)*mag + 1.5);
+    float angle = atan2f(p.z, p.x) + delta_angle;
+    float mag = sqrtf(p.x*p.x + p.z*p.z);
+    return make_vector3(cosf(angle)*mag, p.y, sinf(angle)*mag);
 }
 
 Olivec_Canvas vc_render(float dt)
@@ -73,6 +73,8 @@ Olivec_Canvas vc_render(float dt)
         Vector3 v1 = rotate_y(make_vector3(vertices[a][0], vertices[a][1], vertices[a][2]), angle);
         Vector3 v2 = rotate_y(make_vector3(vertices[b][0], vertices[b][1], vertices[b][2]), angle);
         Vector3 v3 = rotate_y(make_vector3(vertices[c][0], vertices[c][1], vertices[c][2]), angle);
+        v1.z += 1.5; v2.z += 1.5; v3.z += 1.5;
+        v1.y -= 0.25; v2.y -= 0.25; v3.y -= 0.25;
         Vector2 p1 = project_2d_scr(project_3d_2d(v1));
         Vector2 p2 = project_2d_scr(project_3d_2d(v2));
         Vector2 p3 = project_2d_scr(project_3d_2d(v3));
@@ -92,6 +94,7 @@ Olivec_Canvas vc_render(float dt)
                     int u3 = det - u1 - u2;
                     if ((OLIVEC_SIGN(int, u1) == OLIVEC_SIGN(int, det) || u1 == 0) && (OLIVEC_SIGN(int, u2) == OLIVEC_SIGN(int, det) || u2 == 0) && (OLIVEC_SIGN(int, u3) == OLIVEC_SIGN(int, det) || u3 == 0)) {
                         float z = 1/v1.z*u1/det + 1/v2.z*u2/det + 1/v3.z*u3/det;
+                        // TODO: implement near/far clipping planes
                         if (z > zbuffer[y*WIDTH + x]) {
                             zbuffer[y*WIDTH + x] = z;
                             OLIVEC_PIXEL(oc, x, y) = mix_colors3(0xFF1818FF, 0xFF18FF18, 0xFFFF1818, u1, u2, det);

+ 1 - 2
index.html

@@ -46,10 +46,9 @@
       <canvas id="app-triangle3dTex"></canvas>
     </div>
 
-    <!-- TODO: fix distortion and performance of Cup 3D example on the Web -->
     <div id="sec-cup3d">
       <h2 id="demo-cup3d"><a href="#demo-cup3d">Cup 3D</a></h2>
-      Design by <a href="https://github.com/tsoding/rexim">rexim</a>. 3D model by <a href="https://github.com/kolumb">kolumb</a>. Distorted by a bug. Source:&nbsp;<a href="https://github.com/tsoding/olive.c/blob/master/demos/cup3d.c">demos/cup3d.c</a></p>
+      Design by <a href="https://github.com/rexim">rexim</a>. 3D model by <a href="https://github.com/kolumb">kolumb</a>. Source:&nbsp;<a href="https://github.com/tsoding/olive.c/blob/master/demos/cup3d.c">demos/cup3d.c</a></p>
       <canvas id="app-cup3d"></canvas>
     </div>
 

+ 9 - 6
tools/obj2c.c

@@ -149,12 +149,15 @@ void generate_code(FILE *out, Vertices vertices, Faces faces)
 // TODO: do not remap any coordinates.
 // The Cup 3D demo should just properly scale and place the object in the scene instead.
 // Otherwise we end up with distorted model.
-Vector3 remap_teapot(Vector3 v, float lx, float hx, float ly, float hy, float lz, float hz)
+Vector3 remap_object(Vector3 v, float lx, float hx, float ly, float hy, float lz, float hz)
 {
-    float scale = 1.0;
-    v.z = ((v.z - lz)/(hz - lz)*scale + 1);
-    v.x = ((v.x - lx)/(hx - lx)*2 - 1)*scale;
-    v.y = ((v.y - ly)/(hy - ly)*2 - 1)*scale;
+    float cx = lx + (hx - lx)/2;
+    float cy = ly + (hy - ly)/2;
+    float cz = lz + (hz - lz)/2;
+    float scale = 0.75;
+    v.z = (v.z - cz)*scale;
+    v.x = (v.x - cx)*scale;
+    v.y = (v.y - cy)*scale;
     return v;
 }
 
@@ -245,7 +248,7 @@ int main(int argc, char **argv)
     printf("Faces:    %zu (index: %d..%d)\n", faces.count, lf, hf);
 
     for (size_t i = 0; i < vertices.count; ++i) {
-        vertices.items[i] = remap_teapot(vertices.items[i], lx, hx, ly, hy, lz, hz);
+        vertices.items[i] = remap_object(vertices.items[i], lx, hx, ly, hy, lz, hz);
     }
 
     for (size_t i = 0; i < faces.count; ++i) {

BIN
wasm/cup3d.wasm