Skip to content

Commit 42bb839

Browse files
committed
camera
1 parent e8998fe commit 42bb839

File tree

3 files changed

+56
-67
lines changed

3 files changed

+56
-67
lines changed

src/engine/Camera/Camera.jl

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@ module CameraModule
66
mutable struct Camera
77
backgroundColor::NTuple{4, Int}
88
offset::Vector2f
9-
position::Vector2f
9+
position::Vector3f
1010
size::Vector2
11-
zPosition::Float64
1211
yaw::Float64
1312
pitch::Float64
1413
target::Union{
@@ -17,7 +16,7 @@ module CameraModule
1716
}
1817
windowPos::Vector2
1918

20-
function Camera(size::Vector2, initialPosition::Vector2f, offset::Vector2f, target)
19+
function Camera(size::Vector2, initialPosition::Vector3f, offset::Vector2f, target)
2120
this = new()
2221

2322
this.backgroundColor = (0,0,0, 255)
@@ -26,33 +25,36 @@ module CameraModule
2625
this.offset = Vector2f(offset.x, offset.y)
2726
this.target = target
2827
this.windowPos = Vector2(0,0)
29-
this.zPosition = -5.0
3028
this.yaw = 0.0
3129
this.pitch = 0.0
3230

3331
return this
3432
end
3533
end
3634

37-
function update(this::Camera, newPosition = nothing)
35+
function update(this::Camera, newPosition::Union{Nothing, Vector3f} = nothing)
3836
SDL2.SDL_SetRenderDrawBlendMode(JulGame.Renderer::Ptr{SDL2.SDL_Renderer}, SDL2.SDL_BLENDMODE_BLEND)
3937
rgba = (r = Ref(UInt8(0)), g = Ref(UInt8(0)), b = Ref(UInt8(0)), a = Ref(UInt8(255)))
4038
SDL2.SDL_GetRenderDrawColor(JulGame.Renderer::Ptr{SDL2.SDL_Renderer}, rgba.r, rgba.g, rgba.b, rgba.a)
4139
SDL2.SDL_SetRenderDrawColor(Renderer, this.backgroundColor[1], this.backgroundColor[2], this.backgroundColor[3], this.backgroundColor[4]);
4240
SDL2.SDL_RenderFillRectF(Renderer, Ref(SDL2.SDL_FRect(this.windowPos.x, this.windowPos.y, this.size.x, this.size.y)))
4341
SDL2.SDL_SetRenderDrawColor(JulGame.Renderer::Ptr{SDL2.SDL_Renderer}, rgba.r[], rgba.g[], rgba.b[], rgba.a[]);
4442

45-
center = Vector2f(this.size.x/SCALE_UNITS/2, this.size.y/SCALE_UNITS/2)
46-
if this.target !== nothing && newPosition === nothing && this.target !== C_NULL && newPosition !== C_NULL
47-
targetPos = this.target.position
48-
targetScale = this.target.scale
49-
this.position = targetPos - center + 0.5 * targetScale + this.offset
43+
center_pixels = Vector2f(this.size.x / 2, this.size.y / 2)
44+
center_world = center_pixels / SCALE_UNITS
45+
46+
if this.target !== nothing && this.target !== C_NULL && newPosition === nothing
47+
targetPos::Vector3f = this.target.position
48+
targetScale::Vector2f = this.target.scale
49+
this.position = Vector3f(targetPos.x - center_world.x + 0.5 * targetScale.x + this.offset.x,
50+
targetPos.y - center_world.y + 0.5 * targetScale.y + this.offset.y,
51+
targetPos.z)
5052
return
5153
end
52-
if newPosition === nothing || newPosition == C_NULL
53-
return
54+
55+
if newPosition !== nothing
56+
this.position = newPosition
5457
end
55-
this.position = newPosition
5658
end
5759

5860
# making set property observable

src/engine/Component/Mesh3D.jl

Lines changed: 39 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,7 @@ module Mesh3DModule
579579
println("point at")
580580
# Calculate direction to cube
581581
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)
583583
direction = MatrixOps.vector_sub(vec3d(cubePos.x, cubePos.y, cubePos.z), cameraPos)
584584
direction = MatrixOps.vector_normalize(direction)
585585

@@ -613,7 +613,7 @@ module Mesh3DModule
613613
this.matWorld = MatrixOps.matrix_multiply_matrix(this.matWorld, matTrans)
614614

615615
# 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)
617617
vUp = vec3d(0, 1, 0)
618618
vTarget = vec3d(0, 0, 1)
619619

@@ -632,67 +632,52 @@ module Mesh3DModule
632632
# Process each triangle
633633
for tri in this.mesh.tris
634634
triProjected::triangle = triangle()
635-
triTransformed::triangle = triangle()
636-
triViewed::Ref{triangle} = Ref(triangle())
635+
triTransformed::triangle = triangle()
636+
triViewed::Ref{triangle} = Ref(triangle())
637637

638638
# Transform triangle vertices
639639
triTransformed.p[1] = MatrixOps.matrix_multiply_vector(this.matWorld, tri.p[1])
640640
triTransformed.p[2] = MatrixOps.matrix_multiply_vector(this.matWorld, tri.p[2])
641641
triTransformed.p[3] = MatrixOps.matrix_multiply_vector(this.matWorld, tri.p[3])
642642

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
651644
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)
654647

655648
# Get lines either side of the triangle
656649
line1 = MatrixOps.vector_sub(triTransformed.p[2], triTransformed.p[1])
657650
line2 = MatrixOps.vector_sub(triTransformed.p[3], triTransformed.p[1])
658651

659652
# Take cross product of lines to get normal to triangle surface
660653
normal = MatrixOps.vector_cross_product(line1, line2)
661-
662-
# you normally need to normalize a normal!
663654
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+
665673
# Get Ray from triangle to camera
666674
vCameraRay::vec3d = MatrixOps.vector_sub(cameraPos, triTransformed.p[1])
667675
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-
683676
# Convert to view space
684677
triViewed[].p[1] = MatrixOps.matrix_multiply_vector(matView, triTransformed.p[1])
685678
triViewed[].p[2] = MatrixOps.matrix_multiply_vector(matView, triTransformed.p[2])
686679
triViewed[].p[3] = MatrixOps.matrix_multiply_vector(matView, triTransformed.p[3])
687680

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-
696681
# Clip against near plane
697682
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)])])
698683
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
704689
triProjected.p[2] = MatrixOps.matrix_multiply_vector(this.matProj, clipped[][i].p[2])
705690
triProjected.p[3] = MatrixOps.matrix_multiply_vector(this.matProj, clipped[][i].p[3])
706691

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-
715692
# Scale into view
716693
triProjected.p[1] = MatrixOps.vector_div(triProjected.p[1], triProjected.p[1].w)
717694
triProjected.p[2] = MatrixOps.vector_div(triProjected.p[2], triProjected.p[2].w)
718695
triProjected.p[3] = MatrixOps.vector_div(triProjected.p[3], triProjected.p[3].w)
719696

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+
720702
# Scale to screen
721703
windowSize = main.windowManager.windowSize
722704
vOffsetView = vec3d(1, 1, 0)
@@ -731,10 +713,15 @@ module Mesh3DModule
731713
triProjected.p[3].x *= 0.5 * windowSize.x
732714
triProjected.p[3].y *= 0.5 * windowSize.y
733715

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+
734721
# 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)
738725
triProjected.color = SDL_Color(r, g, b, 255)
739726

740727
push!(this.vecTrianglesToRaster, triProjected)
@@ -743,7 +730,7 @@ module Mesh3DModule
743730
end
744731
end
745732

746-
# Sort triangles by Z depth
733+
# Sort triangles by average z depth (back to front)
747734
sort!(this.vecTrianglesToRaster, by = avg_z, rev = true)
748735

749736
# Render triangles

src/engine/SceneManagement/SceneReader.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,9 @@ module SceneReaderModule
9696
end
9797
end
9898
uiElements = deserialize_ui_elements(json.UIElements)
99-
camera = Camera(Vector2(500,500), Vector2f(),Vector2f(), C_NULL)
99+
camera = Camera(Vector2(500,500), Vector3f(),Vector2f(), C_NULL)
100100
if haskey(json, "Camera")
101-
camera = Camera(Vector2(json.Camera.size.x, json.Camera.size.y), Vector2f(json.Camera.position.x, json.Camera.position.y), Vector2f(json.Camera.offset.x, json.Camera.offset.y), C_NULL)
101+
camera = Camera(Vector2(json.Camera.size.x, json.Camera.size.y), Vector3f(json.Camera.position.x, json.Camera.position.y, 0.0), Vector2f(json.Camera.offset.x, json.Camera.offset.y), C_NULL)
102102
camera.backgroundColor = (json.Camera.backgroundColor.r, json.Camera.backgroundColor.g, json.Camera.backgroundColor.b, json.Camera.backgroundColor.a)
103103
end
104104

0 commit comments

Comments
 (0)