@@ -579,7 +579,7 @@ module Mesh3DModule
579
579
println (" point at" )
580
580
# Calculate direction to cube
581
581
cubePos = this. parent. transform. position
582
- cameraPos = vec3d (camera. position. x, camera. position. y, camera. zPosition )
582
+ cameraPos = vec3d (camera. position. x, camera. position. y, camera. position . z )
583
583
direction = MatrixOps. vector_sub (vec3d (cubePos. x, cubePos. y, cubePos. z), cameraPos)
584
584
direction = MatrixOps. vector_normalize (direction)
585
585
@@ -613,7 +613,7 @@ module Mesh3DModule
613
613
this. matWorld = MatrixOps. matrix_multiply_matrix (this. matWorld, matTrans)
614
614
615
615
# Get camera position and create view matrix
616
- cameraPos = vec3d (main. scene. camera. position. x, main. scene. camera. position. y, main. scene. camera. zPosition )
616
+ cameraPos = vec3d (main. scene. camera. position. x, main. scene. camera. position. y, main. scene. camera. position . z )
617
617
vUp = vec3d (0 , 1 , 0 )
618
618
vTarget = vec3d (0 , 0 , 1 )
619
619
@@ -632,67 +632,52 @@ module Mesh3DModule
632
632
# Process each triangle
633
633
for tri in this. mesh. tris
634
634
triProjected:: triangle = triangle ()
635
- triTransformed:: triangle = triangle ()
636
- triViewed:: Ref{triangle} = Ref (triangle ())
635
+ triTransformed:: triangle = triangle ()
636
+ triViewed:: Ref{triangle} = Ref (triangle ())
637
637
638
638
# Transform triangle vertices
639
639
triTransformed. p[1 ] = MatrixOps. matrix_multiply_vector (this. matWorld, tri. p[1 ])
640
640
triTransformed. p[2 ] = MatrixOps. matrix_multiply_vector (this. matWorld, tri. p[2 ])
641
641
triTransformed. p[3 ] = MatrixOps. matrix_multiply_vector (this. matWorld, tri. p[3 ])
642
642
643
- # Debug check for NaNs after world transform
644
- if any (isnan .(triTransformed. p[1 ]. x) .|| isnan .(triTransformed. p[1 ]. y) .|| isnan .(triTransformed. p[1 ]. z))
645
- println (" NaN detected after world transform" )
646
- println (" Position: " , pos)
647
- println (" Scale: " , scale)
648
- println (" Rotation: " , rot)
649
- end
650
-
643
+ # Calculate normal
651
644
normal:: vec3d = vec3d (0 , 0 , 0 )
652
- line1:: vec3d = vec3d (0 , 0 , 0 )
653
- line2:: vec3d = vec3d (0 , 0 , 0 )
645
+ line1:: vec3d = vec3d (0 , 0 , 0 )
646
+ line2:: vec3d = vec3d (0 , 0 , 0 )
654
647
655
648
# Get lines either side of the triangle
656
649
line1 = MatrixOps. vector_sub (triTransformed. p[2 ], triTransformed. p[1 ])
657
650
line2 = MatrixOps. vector_sub (triTransformed. p[3 ], triTransformed. p[1 ])
658
651
659
652
# Take cross product of lines to get normal to triangle surface
660
653
normal = MatrixOps. vector_cross_product (line1, line2)
661
-
662
- # you normally need to normalize a normal!
663
654
normal = MatrixOps. vector_normalize (normal)
664
-
655
+
656
+ # Calculate distance from camera to triangle center
657
+ triCenter = MatrixOps. vector_div (
658
+ MatrixOps. vector_add (
659
+ MatrixOps. vector_add (triTransformed. p[1 ], triTransformed. p[2 ]),
660
+ triTransformed. p[3 ]
661
+ ),
662
+ 3.0
663
+ )
664
+ distanceToCamera = MatrixOps. vector_length (
665
+ MatrixOps. vector_sub (cameraPos, triCenter)
666
+ )
667
+
668
+ # Skip triangles that are too far away
669
+ if distanceToCamera > this. fFar
670
+ continue
671
+ end
672
+
665
673
# Get Ray from triangle to camera
666
674
vCameraRay:: vec3d = MatrixOps. vector_sub (cameraPos, triTransformed. p[1 ])
667
675
if MatrixOps. vector_dot_product (normal, vCameraRay) > 0.0
668
- # Combine camera-based lighting with fixed light direction
669
- camera_light = MatrixOps. vector_normalize (vCameraRay)
670
- fixed_light = MatrixOps. vector_normalize (vec3d (- 0.707 , - 0.707 , - 1.0 ))
671
-
672
- # Calculate dot products for both light sources
673
- dp_camera = MatrixOps. vector_dot_product (normal, camera_light)
674
- dp_fixed = MatrixOps. vector_dot_product (normal, fixed_light)
675
-
676
- # Combine the lighting (weighted average)
677
- dp = 0.3 * dp_camera + 0.7 * dp_fixed
678
-
679
- # Add some ambient light to prevent completely dark faces
680
- ambient = 0.2
681
- dp = max (ambient, dp)
682
-
683
676
# Convert to view space
684
677
triViewed[]. p[1 ] = MatrixOps. matrix_multiply_vector (matView, triTransformed. p[1 ])
685
678
triViewed[]. p[2 ] = MatrixOps. matrix_multiply_vector (matView, triTransformed. p[2 ])
686
679
triViewed[]. p[3 ] = MatrixOps. matrix_multiply_vector (matView, triTransformed. p[3 ])
687
680
688
- # Debug check for NaNs after view transform
689
- if any (isnan .(triViewed[]. p[1 ]. x) .|| isnan .(triViewed[]. p[1 ]. y) .|| isnan .(triViewed[]. p[1 ]. z))
690
- println (" NaN detected after view transform" )
691
- println (" Camera position: " , cameraPos)
692
- println (" Camera yaw: " , main. scene. camera. yaw)
693
- println (" Camera pitch: " , main. scene. camera. pitch)
694
- end
695
-
696
681
# Clip against near plane
697
682
clipped = Ref ([triangle ([vec3d (0.0 , 0.0 , 0.0 ), vec3d (0.0 , 0.0 , 0.0 ), vec3d (0.0 , 0.0 , 0.0 )]), triangle ([vec3d (0.0 , 0.0 , 0.0 ), vec3d (0.0 , 0.0 , 0.0 ), vec3d (0.0 , 0.0 , 0.0 )])])
698
683
nClippedTriangles = triangle_clip_against_plane (vec3d (0.0 , 0.0 , this. fNear), vec3d (0.0 , 0.0 , 1.0 ), triViewed, clipped)
@@ -704,19 +689,16 @@ module Mesh3DModule
704
689
triProjected. p[2 ] = MatrixOps. matrix_multiply_vector (this. matProj, clipped[][i]. p[2 ])
705
690
triProjected. p[3 ] = MatrixOps. matrix_multiply_vector (this. matProj, clipped[][i]. p[3 ])
706
691
707
- # Debug check for NaNs after projection
708
- if any (isnan .(triProjected. p[1 ]. x) .|| isnan .(triProjected. p[1 ]. y) .|| isnan .(triProjected. p[1 ]. z))
709
- println (" NaN detected after projection" )
710
- println (" Near plane: " , this. fNear)
711
- println (" Far plane: " , this. fFar)
712
- println (" FOV: " , this. fFov)
713
- end
714
-
715
692
# Scale into view
716
693
triProjected. p[1 ] = MatrixOps. vector_div (triProjected. p[1 ], triProjected. p[1 ]. w)
717
694
triProjected. p[2 ] = MatrixOps. vector_div (triProjected. p[2 ], triProjected. p[2 ]. w)
718
695
triProjected. p[3 ] = MatrixOps. vector_div (triProjected. p[3 ], triProjected. p[3 ]. w)
719
696
697
+ # Store the original z values for depth testing
698
+ triProjected. p[1 ]. z = triViewed[]. p[1 ]. z
699
+ triProjected. p[2 ]. z = triViewed[]. p[2 ]. z
700
+ triProjected. p[3 ]. z = triViewed[]. p[3 ]. z
701
+
720
702
# Scale to screen
721
703
windowSize = main. windowManager. windowSize
722
704
vOffsetView = vec3d (1 , 1 , 0 )
@@ -731,10 +713,15 @@ module Mesh3DModule
731
713
triProjected. p[3 ]. x *= 0.5 * windowSize. x
732
714
triProjected. p[3 ]. y *= 0.5 * windowSize. y
733
715
716
+ # Calculate lighting
717
+ light_direction = vec3d (0.0 , 0.0 , - 1.0 )
718
+ dp = MatrixOps. vector_dot_product (normal, light_direction)
719
+ dp = max (0.1 , dp) # Add some ambient light
720
+
734
721
# Set color based on lighting
735
- r = round (Int, 255 * max ( 0.0 , dp) )
736
- g = round (Int, 255 * max ( 0.0 , dp) )
737
- b = round (Int, 255 * max ( 0.0 , dp) )
722
+ r = round (Int, 255 * dp )
723
+ g = round (Int, 255 * dp )
724
+ b = round (Int, 255 * dp )
738
725
triProjected. color = SDL_Color (r, g, b, 255 )
739
726
740
727
push! (this. vecTrianglesToRaster, triProjected)
@@ -743,7 +730,7 @@ module Mesh3DModule
743
730
end
744
731
end
745
732
746
- # Sort triangles by Z depth
733
+ # Sort triangles by average z depth (back to front)
747
734
sort! (this. vecTrianglesToRaster, by = avg_z, rev = true )
748
735
749
736
# Render triangles
0 commit comments