From 06ac67fd332c3be6ea9793809d393675b3156de0 Mon Sep 17 00:00:00 2001 From: David Thompson Date: Fri, 25 Oct 2019 08:49:31 -0400 Subject: render: model: Correctly handle faces with 4 elements in OBJ loader. --- chickadee/render/model.scm | 50 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/chickadee/render/model.scm b/chickadee/render/model.scm index 1a9356d..42bfc9a 100644 --- a/chickadee/render/model.scm +++ b/chickadee/render/model.scm @@ -317,24 +317,44 @@ (let ((new-indices (make-array-list))) (hash-set! face-indices-map material new-indices) new-indices))) + (define (deduplicate-face-element e) + ;; Faces are often redundant, so we deduplicate in order to + ;; make the VBOs we build later as small as possible. + (or (hash-ref face-map e) + (let ((i (array-list-size faces))) + (array-list-push! faces (parse-face-element e)) + (hash-set! face-map e i) + i))) + (define (push-face material e) + (array-list-push! (indices-for-material material) + (deduplicate-face-element e))) (define (parse-face args material) (match args - ((and (_ _ _ . _) args) - (for-each (lambda (e) - ;; Faces may very well be redundant, so we - ;; deduplicate in order to make the VBOs we - ;; build later as small as possible. - (let ((cached-index (hash-ref face-map e)) - (face-indices (indices-for-material material))) - (if cached-index - (array-list-push! face-indices cached-index) - (let ((i (array-list-size faces))) - (array-list-push! faces (parse-face-element e)) - (array-list-push! face-indices i) - (hash-set! face-map e i))))) - args)) + ;; Simple triangle + ((a b c) + (push-face material a) + (push-face material b) + (push-face material c)) + ;; Quadrilateral, need to split into 2 triangles + ;; + ;; d-------c + ;; | /| + ;; | / | + ;; | / | + ;; |/ | + ;; a-------b + ;; + ;; triangle 1: a b c + ;; triangle 2: a c d + ((a b c d) + (push-face material a) + (push-face material b) + (push-face material c) + (push-face material a) + (push-face material c) + (push-face material d)) (_ - (parse-error "wrong number of face arguments" args)))) + (parse-error "unsupported number of face elements" args)))) ;; Register default material (hash-set! material-map "default" default-phong-material) ;; Parse file. -- cgit v1.2.3