@@ -100,6 +100,16 @@ fun mat4_mul_vec(i, m) {
100100 return o;
101101}
102102
103+ // Transform a 3D vector (like a normal) using a 4x4 transformation matrix,
104+ // ignoring translation and perspective components.
105+ fun mat4_mul_vec_no_translation(i, m) {
106+ let o = Vec3(0, 0, 0);
107+ o.x = i.x * m[0][0] + i.y * m[0][1] + i.z * m[0][2];
108+ o.y = i.x * m[1][0] + i.y * m[1][1] + i.z * m[1][2];
109+ o.z = i.x * m[2][0] + i.y * m[2][1] + i.z * m[2][2];
110+ return o.normalize(); // Re-normalize after transformation
111+ }
112+
103113// Multiplies two 4x4 matrices
104114fun mat4_mul(a, b) {
105115 let result = [];
@@ -416,15 +426,27 @@ class RenderData {
416426 }
417427
418428 transform(self, mat) {
429+ let new_render_data = RenderData();
430+ new_render_data.indices = self.indices;
431+ new_render_data.colors = self.colors;
432+
419433 for (let var i = 0; i < self.vertices.len; ++i) {
420434 let v = mat4_mul_vec(self.vertices[i], mat);
421435
422436 // We need to invert Y to match screen coordinates
423437 v.x = (v.x + 1) * 0.5 * FRAME_WIDTH;
424438 v.y = (1 - v.y) * 0.5 * FRAME_HEIGHT;
425439
426- self.vertices[i] = v;
440+ new_render_data.vertices.push(v);
441+ }
442+
443+ // Transform normals as well, but without translation or perspective division
444+ for (let var i = 0; i < self.normals.len; ++i) {
445+ let n = mat4_mul_vec_no_translation(self.normals[i], mat);
446+ new_render_data.normals.push(n);
427447 }
448+
449+ return new_render_data;
428450 }
429451
430452 // Sort the triangles by depth using a bucket sort
@@ -594,16 +616,10 @@ let image = Image(FRAME_WIDTH, FRAME_HEIGHT);
594616let scene_data = RenderData();
595617generate_amiga_ball(scene_data, 1.5, 16, 32);
596618
597- // Keep a copy of the untransformed vertices
598- let orig_vertices = [];
599- for (let var i = 0; i < scene_data.vertices.len; ++i) {
600- orig_vertices.push(scene_data.vertices[i].clone());
601- }
602-
603619// Camera setup
604620let aspect = FRAME_WIDTH.to_f() / FRAME_HEIGHT.to_f();
605621let camera = Camera(
606- Vec3(0.0, 0.0, 8 .0),
622+ Vec3(0.0, 1.5, 4 .0),
607623 Vec3(0, 0, 0),
608624 70.0, // fov
609625 1.0, // near
@@ -643,11 +659,7 @@ loop {
643659
644660 // --- Render Ball ---
645661 let transform_start = $time_current_ms();
646- scene_data.vertices = [];
647- for (let var i = 0; i < orig_vertices.len; ++i) {
648- scene_data.vertices.push(orig_vertices[i].clone());
649- }
650- scene_data.transform(mat_mvp);
662+ let scene_data = scene_data.transform(mat_mvp);
651663 let transform_time = $time_current_ms() - transform_start;
652664
653665 let sort_start = $time_current_ms();
0 commit comments