Skip to content

Commit f5af1e8

Browse files
committed
trying to fix parsing
1 parent a62198f commit f5af1e8

File tree

2 files changed

+211
-62
lines changed

2 files changed

+211
-62
lines changed

src/engine/3D/FastObj.jl

Lines changed: 130 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -87,39 +87,20 @@ module FastObj
8787
end
8888
elseif c == UInt8('f')
8989
# Face
90-
face = Int[]
91-
face_tex = Int[]
92-
face_norm = Int[]
90+
faces, face_texcoords, face_normals = parse_face(parser)
91+
println("Parsed face data:")
92+
println("Faces: $faces")
93+
println("Face texcoords: $face_texcoords")
94+
println("Face normals: $face_normals")
9395

94-
# Parse face indices
95-
while parser.pos <= length(parser.data) && !isspace(Char(parser.data[parser.pos]))
96-
# Vertex index
97-
v_idx = parse_int(parser)
98-
push!(face, v_idx)
99-
100-
# Check for texture coordinate and normal
101-
if parser.pos <= length(parser.data) && parser.data[parser.pos] == UInt8('/')
102-
parser.pos += 1
103-
if parser.pos <= length(parser.data) && parser.data[parser.pos] != UInt8('/')
104-
t_idx = parse_int(parser)
105-
push!(face_tex, t_idx)
106-
end
107-
108-
if parser.pos <= length(parser.data) && parser.data[parser.pos] == UInt8('/')
109-
parser.pos += 1
110-
n_idx = parse_int(parser)
111-
push!(face_norm, n_idx)
112-
end
113-
end
114-
end
115-
116-
if !isempty(face)
117-
push!(parser.faces, face)
118-
if !isempty(face_tex)
119-
push!(parser.face_texcoords, face_tex)
96+
# Add all faces to the parser
97+
for i in 1:length(faces)
98+
push!(parser.faces, faces[i])
99+
if i <= length(face_texcoords)
100+
push!(parser.face_texcoords, face_texcoords[i])
120101
end
121-
if !isempty(face_norm)
122-
push!(parser.face_normals, face_norm)
102+
if i <= length(face_normals)
103+
push!(parser.face_normals, face_normals[i])
123104
end
124105
end
125106
elseif c == UInt8('m')
@@ -174,6 +155,14 @@ module FastObj
174155
parser.pos += 1
175156
end
176157

158+
println("Final parser results:")
159+
println("Vertices: $(length(parser.vertices))")
160+
println("Normals: $(length(parser.normals))")
161+
println("Texcoords: $(length(parser.texcoords))")
162+
println("Faces: $(length(parser.faces))")
163+
println("Face texcoords: $(length(parser.face_texcoords))")
164+
println("Face normals: $(length(parser.face_normals))")
165+
177166
return parser.vertices, parser.normals, parser.texcoords, parser.faces,
178167
parser.face_texcoords, parser.face_normals, parser.materials
179168
end
@@ -196,18 +185,26 @@ module FastObj
196185
return parse(Float64, num_str)
197186
end
198187

199-
function parse_int(parser::FastObjParser)::Int
188+
function parse_int(parser::FastObjParser)::Union{Int, Nothing}
200189
# Skip whitespace
201190
while parser.pos <= length(parser.data) && isspace(Char(parser.data[parser.pos]))
202191
parser.pos += 1
203192
end
204193

194+
if parser.pos > length(parser.data)
195+
return nothing
196+
end
197+
205198
# Find the end of the number
206199
end_pos = parser.pos
207200
while end_pos <= length(parser.data) && !isspace(Char(parser.data[end_pos])) && parser.data[end_pos] != UInt8('/')
208201
end_pos += 1
209202
end
210203

204+
if end_pos == parser.pos
205+
return nothing
206+
end
207+
211208
# Parse the number
212209
num_str = String(parser.data[parser.pos:end_pos-1])
213210
parser.pos = end_pos
@@ -292,4 +289,105 @@ module FastObj
292289

293290
close(f)
294291
end
292+
293+
function parse_face(parser::FastObjParser)::Tuple{Vector{Vector{Int}}, Vector{Vector{Int}}, Vector{Vector{Int}}}
294+
faces = Vector{Vector{Int}}()
295+
face_texcoords = Vector{Vector{Int}}()
296+
face_normals = Vector{Vector{Int}}()
297+
298+
# Skip whitespace before face definition
299+
while parser.pos <= length(parser.data) && isspace(Char(parser.data[parser.pos]))
300+
parser.pos += 1
301+
end
302+
303+
if parser.pos > length(parser.data)
304+
return faces, face_texcoords, face_normals
305+
end
306+
307+
# Parse all vertices for this face
308+
vertices = Int[]
309+
texcoords = Int[]
310+
normals = Int[]
311+
312+
while parser.pos <= length(parser.data) && !isspace(Char(parser.data[parser.pos]))
313+
# Parse vertex index
314+
v_idx = parse_int(parser)
315+
if v_idx === nothing
316+
break
317+
end
318+
319+
# Handle negative indices (relative to current position)
320+
if v_idx < 0
321+
v_idx = length(parser.vertices) + v_idx + 1
322+
end
323+
324+
# Add vertex index
325+
push!(vertices, v_idx)
326+
327+
# Check for texture coordinate and normal indices
328+
if parser.pos <= length(parser.data) && parser.data[parser.pos] == UInt8('/')
329+
parser.pos += 1
330+
331+
# Parse texture coordinate index if present
332+
if parser.pos <= length(parser.data) && !isspace(Char(parser.data[parser.pos])) && parser.data[parser.pos] != UInt8('/')
333+
vt_idx = parse_int(parser)
334+
if vt_idx !== nothing
335+
if vt_idx < 0
336+
vt_idx = length(parser.texcoords) + vt_idx + 1
337+
end
338+
push!(texcoords, vt_idx)
339+
end
340+
end
341+
342+
# Parse normal index if present
343+
if parser.pos <= length(parser.data) && parser.data[parser.pos] == UInt8('/')
344+
parser.pos += 1
345+
if parser.pos <= length(parser.data) && !isspace(Char(parser.data[parser.pos]))
346+
vn_idx = parse_int(parser)
347+
if vn_idx !== nothing
348+
if vn_idx < 0
349+
vn_idx = length(parser.normals) + vn_idx + 1
350+
end
351+
push!(normals, vn_idx)
352+
end
353+
end
354+
end
355+
end
356+
end
357+
358+
println("Parsed face with $(length(vertices)) vertices")
359+
println("Vertex indices: $vertices")
360+
println("Texture coordinate indices: $texcoords")
361+
println("Normal indices: $normals")
362+
363+
# Triangulate the face using triangle fan approach
364+
if length(vertices) >= 3
365+
# For each vertex after the first two, create a triangle with the first vertex
366+
for i in 2:(length(vertices)-1)
367+
# Create triangle using first vertex and current edge
368+
triangle = [vertices[1], vertices[i], vertices[i+1]]
369+
push!(faces, triangle)
370+
println("Created triangle: $triangle")
371+
372+
# Add corresponding texture coordinates if available
373+
if !isempty(texcoords)
374+
tex_triangle = [texcoords[1], texcoords[i], texcoords[i+1]]
375+
push!(face_texcoords, tex_triangle)
376+
println("Added texture coordinates: $tex_triangle")
377+
end
378+
379+
# Add corresponding normals if available
380+
if !isempty(normals)
381+
normal_triangle = [normals[1], normals[i], normals[i+1]]
382+
push!(face_normals, normal_triangle)
383+
println("Added normal indices: $normal_triangle")
384+
end
385+
end
386+
else
387+
@warn "Face has less than 3 vertices, skipping"
388+
end
389+
390+
println("Created $(length(faces)) triangles from face")
391+
return faces, face_texcoords, face_normals
392+
end
295393
end

src/engine/Component/Mesh3D.jl

Lines changed: 81 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ module Mesh3DModule
317317
this.parent = C_NULL
318318
this.layer = 0
319319
this.isWorldEntity = true
320-
this.mesh = mesh(triangle[])
320+
this.mesh = mesh(nothing)
321321
this.fNear = fNear
322322
this.fFar = fFar
323323
this.fFov = fFov
@@ -362,37 +362,87 @@ module Mesh3DModule
362362

363363
# Create triangles from the parsed data
364364
for (i, face) in enumerate(faces)
365+
println("Processing face $i with $(length(face)) vertices")
366+
println("Face vertices: $face")
367+
365368
if length(face) >= 3
366-
# Create a triangle from the first three vertices
367-
tri = triangle([
368-
vertices[face[1]],
369-
vertices[face[2]],
370-
vertices[face[3]]
371-
])
372-
373-
# Add texture coordinates if available
374-
if i <= length(face_texcoords) && !isempty(face_texcoords[i])
375-
tri.texCoords = [
376-
texcoords[face_texcoords[i][1]],
377-
texcoords[face_texcoords[i][2]],
378-
texcoords[face_texcoords[i][3]]
379-
]
380-
end
381-
382-
# Add normals if available
383-
if i <= length(face_normals) && !isempty(face_normals[i])
384-
# Store normals in the triangle structure if needed
385-
# You might need to add a normals field to the triangle struct
369+
# For quads, create two triangles
370+
if length(face) == 4
371+
println("Creating two triangles from quad face")
372+
# First triangle
373+
tri1 = triangle([
374+
vertices[face[1]],
375+
vertices[face[2]],
376+
vertices[face[3]]
377+
])
378+
379+
# Add texture coordinates if available
380+
if i <= length(face_texcoords) && !isempty(face_texcoords[i])
381+
println("Adding texture coordinates to first triangle")
382+
tri1.texCoords = [
383+
texcoords[face_texcoords[i][1]],
384+
texcoords[face_texcoords[i][2]],
385+
texcoords[face_texcoords[i][3]]
386+
]
387+
end
388+
389+
# Set the material for this triangle
390+
tri1.material = this.mesh.currentMaterial
391+
push!(this.mesh.tris, tri1)
392+
println("Added first triangle to mesh")
393+
394+
# Second triangle
395+
tri2 = triangle([
396+
vertices[face[1]],
397+
vertices[face[3]],
398+
vertices[face[4]]
399+
])
400+
401+
# Add texture coordinates if available
402+
if i <= length(face_texcoords) && !isempty(face_texcoords[i])
403+
println("Adding texture coordinates to second triangle")
404+
tri2.texCoords = [
405+
texcoords[face_texcoords[i][1]],
406+
texcoords[face_texcoords[i][3]],
407+
texcoords[face_texcoords[i][4]]
408+
]
409+
end
410+
411+
# Set the material for this triangle
412+
tri2.material = this.mesh.currentMaterial
413+
push!(this.mesh.tris, tri2)
414+
println("Added second triangle to mesh")
415+
else
416+
println("Creating single triangle from face")
417+
# For triangles, create a single triangle
418+
tri = triangle([
419+
vertices[face[1]],
420+
vertices[face[2]],
421+
vertices[face[3]]
422+
])
423+
424+
# Add texture coordinates if available
425+
if i <= length(face_texcoords) && !isempty(face_texcoords[i])
426+
println("Adding texture coordinates to triangle")
427+
tri.texCoords = [
428+
texcoords[face_texcoords[i][1]],
429+
texcoords[face_texcoords[i][2]],
430+
texcoords[face_texcoords[i][3]]
431+
]
432+
end
433+
434+
# Set the material for this triangle
435+
tri.material = this.mesh.currentMaterial
436+
push!(this.mesh.tris, tri)
437+
println("Added triangle to mesh")
386438
end
387-
388-
# Set the material for this triangle
389-
tri.material = this.mesh.currentMaterial
390-
391-
push!(this.mesh.tris, tri)
439+
else
440+
println("Skipping face with less than 3 vertices")
392441
end
393442
end
394443

395444
println("Created $(length(this.mesh.tris)) triangles")
445+
println("Current material: $(this.mesh.currentMaterial)")
396446
return true
397447
catch e
398448
@error "Failed to load OBJ file: $file_path" exception=(e, catch_backtrace())
@@ -473,7 +523,8 @@ module Mesh3DModule
473523
this.fAspectRatio = windowSize.y / windowSize.x
474524
this.matProj = MatrixOps.matrix_make_projection(this.fFov, this.fAspectRatio, this.fNear, this.fFar)
475525

476-
if this.mesh.tris === nothing
526+
if length(this.mesh.tris) == 0
527+
println("creating cube")
477528
this.mesh = create_cube()
478529
end
479530

@@ -754,7 +805,7 @@ module Mesh3DModule
754805

755806
if texture !== nothing
756807
tex_coords = [apply_texture_mode(coord, texture) for coord in tex_coords]
757-
println("Texture coordinates applied: ", tex_coords)
808+
#println("Texture coordinates applied: ", tex_coords)
758809
end
759810

760811
sdl_verts = [
@@ -766,9 +817,9 @@ module Mesh3DModule
766817
# Use material texture if available, otherwise use color
767818
texture_ptr = texture !== nothing ? texture.texture : C_NULL
768819
if texture_ptr != C_NULL
769-
println("Rendering with texture")
820+
#println("Rendering with texture")
770821
else
771-
println("Rendering without texture")
822+
#println("Rendering without texture")
772823
end
773824

774825
# Set the blend mode for proper texture rendering

0 commit comments

Comments
 (0)