Skip to content

v2.2.0 - Parser Robustness, Code Hardening & Libft Integration#6

Merged
gdtknight merged 151 commits intomainfrom
develop
Feb 10, 2026
Merged

v2.2.0 - Parser Robustness, Code Hardening & Libft Integration#6
gdtknight merged 151 commits intomainfrom
develop

Conversation

@gdtknight
Copy link
Copy Markdown
Owner

@gdtknight gdtknight commented Jan 29, 2026

Description

develop 브랜치의 v2.1.0 이후 누적된 주요 변경사항을 main에 통합하는 릴리스 PR입니다.
파서 강건성 강화, 코드 하드닝, 금지 함수 제거(libft 통합), 데드 코드 정리, 성능 최적화 등 코드 품질 전반을 개선했습니다.

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Code refactoring
  • Performance improvement
  • Build/CI improvement

Changes

020-eval-compliance: 평가 규격 준수

  • t_object 구조체/유니온으로 오브젝트 표현 통합
  • Scene lifecycle 및 MLX context 분리 리팩토링
  • .rt 파일 확장자 검증 추가
  • 오브젝트 리사이즈(J/K/N/M), 회전(U/O/Y/P/LEFT/RIGHT) 키 바인딩 추가
  • BVH lazy rebuild 및 expose 핸들러 추가

021-fix-hud-keys-expose: HUD/키가이드/Expose 수정

  • 키가이드에 Resize/Rotation 섹션 추가
  • HUD 배경 블렌딩 제거, dirty render on toggle 적용
  • Expose 이벤트 시 HUD/키가이드 오버레이 복원

022-replace-forbidden-func: 금지 함수 → libft 대체

  • libft 서브모듈 통합 및 빌드 시스템 연동
  • snprintf, strlen, memset 등 금지 함수를 libft 함수로 전면 교체
  • format_helpers 유틸리티 추가

023-parsing-robustness: 파서 강건성 강화

  • parse result enum 및 에러 컨텍스트 구조체 도입
  • 버퍼 기반 line reader 구현
  • 엄격한 숫자/벡터/컬러 검증 추가
  • 토큰 유틸리티 및 element dispatching 분리

024-code-hardening: 코드 안전성 강화

  • AABB slab test 0 나눗셈 방지
  • BVH leaf traversal hit distance 초기화
  • 카메라 수직축 짐벌락 방지
  • parse_int_digits 정수 오버플로우 감지
  • object_list_grow 용량 오버플로우 가드
  • MLX 이미지 픽셀 좌표 바운드 체크
  • UI 초기화 실패 시 MLX 리소스 해제

025-dead-code-removal: 데드 코드 제거

  • 미사용 render_state 모듈, 유틸리티 파일, 헤더 선언 제거
  • 레거시 파서 및 print_error 마이그레이션
  • cleanup_all 래퍼 직접 호출로 대체

026-resource-cleanup: 리소스 정리

  • MLX context 초기화 실패 시 리소스 해제
  • HUD/키가이드 미사용 배경 이미지 버퍼 제거

fix/linux-mlx-pixel-format: Linux MLX 픽셀 수정

  • bpp/endian 기반 MLX/HUD 픽셀 바이트 핸들링 통합
  • BVH child hit distance 초기화

027-baseline-benchmark: 베이스라인 벤치마크

  • 미사용 메트릭스 카운터를 hot path에 연결
  • metrics_print_summary 베이스라인 벤치마킹 추가
  • shadow intersect 카운터를 primary에서 분리
  • BVH skip 카운터 복원
  • pixel timing 프레임 시작 시 리셋
  • benchmark-baseline 템플릿 A/B 비교 구조화

028-bvh-fallback-removal: BVH fallback 제거

  • trace_ray에서 BVH miss 시 linear fallback 제거 (P0)

029-math-optimizations: 수학 연산 최적화

  • 안전한 수학 최적화 적용 (Phase A)

030-shadow-offset-lut: 소프트 섀도우 LUT

  • soft shadow용 shadow offset LUT 사전 계산 추가 (P4)

031-perf-bottleneck-optimization: 성능 병목 최적화

  • BVH에서 plane 분리하여 별도 교차 검사 (t_plane_refs)
  • primary ray/shadow 각각 별도 plane intersection 경로
  • BVH pruning 복원 (t_max 갱신)
  • 카메라 basis 프레임 캐싱 (P2)
  • ray inverse direction 사전 계산으로 AABB 테스트 가속 (P5)
  • shadow BVH 오브젝트 개수 threshold 추가
  • shadow BVH threshold 20 → 5로 하향
  • 런타임 측정 오버헤드 제어 플래그 추가
  • 파서 벡터 범위 검증 추가
  • 카메라 캐시 씬 로드 시 초기화

032-fix-review-issues: 리뷰 이슈 수정

  • shadow offset LUT 샘플 수 변경 시 재생성
  • FOV 범위를 exclusive (0, 180)으로 제한
  • BVH plane_refs malloc 가드 및 메모리 누수 수정
  • 파서 line buffer strlcpy 전 null-terminate
  • parse 실패 시 미처리 line 메모리 해제

CI 개선

  • private libft 서브모듈 SSH deploy key 설정
  • PR Validation: develop 브랜치 naming convention 허용

Testing

Test Environment

  • OS: Ubuntu (CI), macOS (CI)
  • Compiler: gcc (Linux), clang (macOS)

Test Results

  • All existing tests pass
  • Manual testing completed
  • Norminette check passed
  • No memory leaks (valgrind/leaks)
  • CI build 및 test 전체 통과

Performance Impact

  • Performance improved
    • BVH fallback 제거로 불필요한 linear scan 차단
    • plane 분리로 BVH 트리 효율 향상
    • ray inverse direction 사전 계산, 카메라 basis 캐싱
    • shadow offset LUT 사전 계산

Statistics

  • Feature branches merged: 14 (020 ~ 032 + fix/linux-mlx-pixel-format)
  • Commit breakdown: refactor(27), fix(21), docs(21), feat(15), perf(5), merge(14), build(3), test(2), chore(2)

gdtknight and others added 30 commits January 28, 2026 11:09
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Replace separate sphere/plane/cylinder intersection functions with
unified intersect_object_new(). Add intersect_cyl_new.c for cylinder
body/cap intersection. Remove legacy intersect_cylinder.c and
intersections.c.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add scene_create/scene_destroy with flag-based element tracking
- Extract t_mlx_context from scattered void pointers
- Add error.h with typed error codes and error_print/error_exit
- Add overlay.h for HUD/keyguide rendering interface
- Remove timer_basic.c (consolidated into timer.c)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Replace individual dirty/is_rendering/low_quality booleans with
  bit-flag state_flags in t_render
- Add render_has_flag/render_set_flag/render_clear_flag helpers
- Simplify object selection into single window_selection.c
- Remove window_select_cycle.c and window_select_helpers.c
- Update spatial/render modules for unified object refs

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Adapt HUD rendering to t_object union and t_object_list
- Update parse_elements/parse_objects for scene flag helpers
- Add parse_cylinder.c for cylinder-specific parsing
- Update shadow_test and keyguide for new field paths

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Reject files without .rt extension before attempting to parse.
Outputs 'Error\n' followed by descriptive message per eval spec.

Implements: FR-001, FR-002

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- J/K: increase/decrease sphere diameter or cylinder diameter
- N/M: increase/decrease cylinder height
- Minimum threshold 0.1 prevents zero-size objects
- Plane resize ignored silently (FR-011)
- Sets RENDER_BVH_DIRTY flag for lazy BVH rebuild

Implements: FR-003, FR-004, FR-010, FR-011

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- U/O: X-axis rotation, Y/P: Y-axis, LEFT/RIGHT: Z-axis
- Rodrigues rotation formula with 5-degree step
- Axis degeneration guard: skip rotation if normalized length < EPSILON
- Sphere rotation ignored (FR-006)
- Sets RENDER_BVH_DIRTY flag for lazy BVH rebuild

Implements: FR-005, FR-006, FR-012

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add KEY_J/K/N/M/U/O/Y/P/LEFT/RIGHT constants (macOS + Linux)
- Dispatch resize/rotation keys from handle_transform_keys()
- Register expose hook (event 12) for window restore content persistence
- Add BVH dirty rebuild before render pass in render_loop()
- Set RENDER_BVH_DIRTY on object move for accurate BVH after translation

Implements: FR-007, FR-009

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add scene/, mlx_context, render_flags_set, intersect_object,
  intersect_cyl_new, parse_cylinder, window_resize, window_rotate
- Remove intersect_cylinder, intersections, timer_basic,
  window_select_cycle, window_select_helpers

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- resize_test.rt: sphere + cylinder for resize key verification
- rotation_test.rt: cylinder + plane for rotation key verification
- inside_test.rt: camera inside cylinder for interior rendering test

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- spec.md: 13 functional requirements, 6 success criteria
- plan.md: 8-phase implementation plan with 6 design decisions
- research.md: key mapping, BVH rebuild, expose, normal flip, threshold
- data-model.md: RENDER_BVH_DIRTY flag, key constants, state flows
- quickstart.md: test scenes and verification checklists
- tasks.md: 27 tasks across 9 phases (all completed)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Add missing features for mandatory evaluation:
- .rt file extension validation
- Object resize (J/K/N/M keys)
- Object rotation (U/O/Y/P/LEFT/RIGHT keys)
- Window expose handler for content persistence
- Cylinder inside normal correction
- BVH lazy rebuild on object transform
- Unified object representation refactoring
…facts

Add feature spec, plan, research, data-model, quickstart, tasks,
and requirements checklist for HUD key guide update and expose
restore fix.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Add keyguide_render_extra.c with Resize (J/K - Diameter, N/M - Height)
and Rotation (U/O - Rot X, Y/P - Rot Y, <-/-> - Rot Z) sections.
Increase KEYGUIDE_HEIGHT from 400 to 500 to accommodate new labels.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Remove hud_render_background() call to eliminate pixel-by-pixel
blending overhead. Set RENDER_DIRTY on HUD toggle to ensure clean
scene buffer after overlay text is removed.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Call hud_render() and keyguide_render() in handle_expose() when
HUD is visible, so overlays persist after window uncover/restore.
Remove unused is_movement_key static function.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
…store

- Add Resize/Rotation key sections to keyguide
- Restore HUD/keyguide overlay on expose event
- Remove HUD/keyguide background blending
- Remove unused is_movement_key function
…m compliance

Extract debounce_handle_active() and debounce_handle_preview() from
debounce_update() to stay within 25-line limit. Move debounce_cancel()
to render_debounce_timer.c to stay within 5-function limit.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Remove unused metrics_log_render(). Move metrics_reset_bvh() from
metrics_counters.c to metrics_calc.c to stay within 5-function limit.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Fix extra tab indentation in bounds_for_plane(). Move
get_object_center() to bvh_init.c to stay within 5-function limit.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Remove forward declaration from intersect_object.c to fix Norm
tab indentation error. Add prototype to ray.h instead.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Rename anonymous union to union u_object_data to satisfy Norm v4.1
union naming convention (u_ prefix required).

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Move g_error_messages from file-scope global to function-local static
const in error_get_message(). Rename to error_messages to follow local
variable naming convention.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Add libft as git submodule in lib/libft
- Update Makefile to build and link libft
- Add libft include path to CFLAGS
- Remove minilibx-linux submodule (use system install)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Delete ft_atoi.c (now provided by libft)
- Delete memory.c (ft_memcpy, ft_memset now from libft)
- Add format_helpers.c with format_id and float_to_str
- Update utils.h with new format helper declarations
- Include libft.h in minirt.h, remove ft_atoi declaration

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Use format_id instead of snprintf for sphere/plane/cylinder IDs
- Replace strcpy with ft_strlcpy in read_line
- Remove stdio.h/string.h includes where possible

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Use ft_memcpy instead of memcpy in object_list_grow
- Use ft_bzero instead of memset in scene_create
- Remove string.h includes

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Use ft_bzero for struct initialization
- Include libft.h instead of string.h

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
gdtknight and others added 28 commits February 9, 2026 14:58
Initialize camera cache as invalid when parsing camera from scene file.
Ensures cache is properly computed on first use.

Changes:
- Set cache.valid = 0 after camera parsing
  Location: src/parser/parse_elements.c:110
  Marks cache as invalid, triggering initial computation

Technical notes:
- Complements camera caching optimization (P2)
- Ensures correct behavior for fresh scene loads
- Cache will be computed on first create_camera_ray() call

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update optimization plan documentation to reflect implemented changes
and clarify terminology.

Changes:
- Update implementation status for completed optimizations
- Clarify BVH skip rate terminology (matches code metrics)
- Document actual implementation patterns

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Changes:
- Create parse_vector_validation.c with validate_vector_range()
- Check vector components in [-1,1] range before normalization
- Apply to camera direction, plane normal, cylinder axis
- Add invalid test scenes for each vector type

Location:
- src/parser/parse_vector_validation.c: New file + function
- src/parser/parse_elements.c: Camera direction validation
- src/parser/parse_objects.c: Plane normal validation
- src/parser/parse_cylinder.c: Cylinder axis validation
- includes/parser.h: Function declaration
- Makefile: Add new source file
- scenes/invalid/: 3 new test cases

Testing:
- invalid_plane_normal_out_of_range.rt: Error (y=2.0)
- invalid_cylinder_axis_out_of_range.rt: Error (x=5.0)
- invalid_camera_direction_out_of_range.rt: Error (y=1.5)
- All valid scenes still pass

Technical notes:
- Validation order: parse -> range -> zero -> normalize
- Uses existing in_range() helper and PARSE_ERR_RANGE
- Norm compliant: New file with 1 function (10 lines)
- Prevents accepting (5,0,0) which normalizes to (1,0,0)

Subject reference:
- "3D normalized orientation/normal/axis vector"
- "in the range [-1,1] for each x,y,z axis"
- miniRT.md lines 172, 205, 216

Co-Authored-By: Claude <noreply@anthropic.com>
Related commit: ab8cad5 perf(shadow): add object count threshold

Documentation:
- 031-shadow-bvh-optimization-plan.md: Implementation plan
- 031-shadow-bvh-optimization-tasks.md: Task breakdown
- p1-shadow-bvh-analysis.md: Analysis and research

Co-Authored-By: Claude <noreply@anthropic.com>
Related commits: b4459ff, b328a48, 1a4c6cf, 4bfae8a, 0c10a17

Documentation:
- 031-performance-review-report-2026-02-08.md: Performance review
- perf-optimization-implementation-report.md: Implementation details
- perf-priority-plan.md: Priority planning (P0-P9)
- optimization-unified-report.md: Unified optimization summary

Results: 14.3% performance improvement on S3 benchmark

Co-Authored-By: Claude <noreply@anthropic.com>
Documentation:
- optimization-metrics-review-report.md: Metrics review analysis
- optimization-metrics-setup-report.md: Metrics setup guide
- optimization-research-report-current.md: Current research findings
- optimization-research-report.md: Research documentation

Co-Authored-By: Claude <noreply@anthropic.com>
Related commit: 670c0d3 fix(parser): Add vector range validation

Documentation:
- vector-range-validation-plan.md: Implementation plan
- vector-range-validation-tasks.md: Task checklist

Subject compliance: [-1,1] range validation for direction vectors

Co-Authored-By: Claude <noreply@anthropic.com>
Documentation:
- cleanup-proposal-report.md: Cleanup proposals
- code-review-report.md: Code review findings
- codebase-structure-review-2026-02-08.md: Structure analysis
- structure-cleanup-direction-report.md: Cleanup direction
- update-031-plan.md: Sprint 031 plan update

Co-Authored-By: Claude <noreply@anthropic.com>
Add t_plane_refs struct (indices array + count) to spatial.h and
extend t_bvh with plane_refs field to store plane object indices
separately from the BVH tree.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace fill_object_refs() with count_planes() and
fill_separated_refs() to filter OBJ_PLANE objects out of BVH.
Rewrite scene_build_bvh() to build BVH with bounded objects only
and store plane indices in bvh->plane_refs for separate traversal.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Initialize plane_refs.indices=NULL and count=0 in bvh_create().
Free plane_refs.indices in bvh_destroy() before freeing BVH struct.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add intersect_planes() to test ray against planes stored in
bvh->plane_refs after BVH traversal. Modify trace_ray() to combine
BVH hit and plane hit results for correct rendering with separated
planes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add check_plane_shadow() for plane-specific shadow testing
  - Iterate over bvh->plane_refs.indices for plane objects only
  - Early exit on first plane shadow hit for performance
  - Track shadow intersect metrics per plane test
- Modify is_in_shadow() to combine BVH any-hit + plane shadow
  - Call check_plane_shadow() after BVH shadow traversal
  - Return shadow if either BVH or plane test finds occlusion

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Reduce SHADOW_BVH_THRESHOLD 20 -> 5
  - Enable BVH acceleration for shadow rays in 6+ object scenes
  - Keep brute-force for very small scenes (<=5 objects)
  - Combined with plane BVH separation: perf_all_objects -75.9%

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add RENDER_ENABLE_METRICS_PRINT flag to initial state_flags
  - Render metrics output enabled by default for benchmarking
  - Combined with RENDER_DIRTY for first-frame rendering

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add Round 4 (PA+PB) benchmark data for 4 scenes
  - Frame time comparison: R1 only / PA only / PA+PB configurations
  - Shadow tests and BVH skip rate tables
  - Raw metrics output for all scenes
- Document key findings:
  - PA+PB coupling: plane separation + threshold required together
  - perf_all_objects: 25,192ms -> 6,067ms (-75.9%)
  - Cumulative improvement from baseline: 139,876ms -> 6,067ms (-95.7%)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- spec.md: Round 2 scope (PA plane BVH separation, PB threshold)
- plan.md: implementation plan for Phase 8-10
- tasks.md: T042-T065 task definitions with completion status
- research.md: plane AABB contamination analysis
- data-model.md: t_plane_refs struct design
- quickstart.md: build/test instructions with Round 2 results
- checklists/requirements.md: requirement verification checklist

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Round 2 Performance Optimization (PA + PB):
- PA: Plane BVH separation (remove infinite AABB contamination)
- PB: Shadow BVH threshold 20 -> 5

Key result: perf_all_objects 25,192ms -> 6,067ms (-75.9%)
Cumulative from baseline: 139,876ms -> 6,067ms (-95.7%)
Extract alloc_bvh_refs() to handle allocation with proper cleanup:
- Free existing plane_refs.indices before realloc (R2 leak fix)
- Validate both mallocs, clean up partial allocs on failure (R1)
- Block fill_separated_refs() call on allocation failure

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Change in_range(fov, 0, 180) to in_range(fov, 1, 179) to reject
FOV=0 (tan(0)=0, all rays identical) and FOV=180 (tan(pi/2)~1e16,
numerical singularity).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rewrite set_shadow_samples() to free existing LUT and call
init_shadow_offset_lut() after updating sample count, preventing
heap overread when samples increase beyond original allocation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add spec, plan, research, tasks, quickstart, and data-model
documents for the 4 review issue fixes (R1-R4).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fix 4 code review issues from 031:
- R1: malloc failure NULL dereference guard (bvh_init.c)
- R2: plane_refs.indices leak on BVH rebuild (bvh_init.c)
- R3: FOV 0/180 boundary rejection (parse_elements.c)
- R4: shadow offset LUT regeneration on sample change (shadow_config.c)
The stack-allocated line buffer in line_reader_next was passed to
ft_strlcpy without null-termination, causing ft_strlen to read
uninitialised memory (172 valgrind errors). Add line[len] = '\0'
before the copy. Also add a valgrind suppression file for the
known still-reachable leaks from X11/MiniLibX internals.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
After parse_line() fails, line_reader_next() is called which may
allocate a new line, then the while loop exits without freeing it.
Add free(line) after the loop to prevent the leak.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@gdtknight gdtknight changed the title Develop v2.2.0 - Parser Robustness, Code Hardening & Libft Integration Feb 10, 2026
@gdtknight gdtknight merged commit 416c9ae into main Feb 10, 2026
22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant