(define positions (list #(-50 50 50) #(50 50 50) #(-50 -50 50) #(50 -50 50) #(-50 50 -50) #(50 50 -50) #(-50 -50 -50) #(50 -50 -50))) (define normals (list #(0 0 1) #(0 0 1) #(0 0 1) #(0 0 1) #(0 1 0) #(0 1 0) #(0 1 0) #(0 1 0) #(0 -1 0) #(0 -1 0) #(0 -1 0) #(0 -1 0) #(-1 0 0) #(-1 0 0) #(-1 0 0) #(-1 0 0) #(1 0 0) #(1 0 0) #(1 0 0) #(1 0 0) #(0 0 -1) #(0 0 -1) #(0 0 -1) #(0 0 -1))) (define tex (list #(1 1) #(0 1))) (define indices (list 0 0 0 2 1 1 3 2 1 0 0 1 3 2 1 1 3 1 0 4 1 1 5 1 5 6 1 0 4 1 5 6 1 4 7 1 6 8 1 7 9 1 3 10 1 6 8 1 3 10 1 2 11 1 0 12 1 4 13 1 6 14 1 0 12 1 6 14 1 2 15 1 3 16 1 7 17 1 5 18 1 3 16 1 5 18 1 1 19 1 5 20 1 7 21 1 6 22 1 5 20 1 6 22 1 4 23 1)) ;; look for a key in a simple set (define (set-find set key) (cond ((null? set) #f) ((equal? (car set) key) #t) (else (set-find (cdr set) key)))) ;; groups the flat index list into multiple lists ;; of position/normal/tex coord etc indices (define (group-indices indices stride) (define (loop indices size count current group) (cond ((null? indices) (cons (reverse current) group)) ((eq? count size) (loop (cdr indices) size 1 (list (car indices)) (cons (reverse current) group))) (else (loop (cdr indices) size (+ count 1) (cons (car indices) current) group)))) (reverse (loop indices stride 0 '() '()))) ;; removes sets of indices which are duplicated (define (get-unique-indices indices set) (foldl (lambda (index set) (if (not (member index set)) (cons index set) set)) '() (reverse indices))) ;; calculates the new indices from the unique lists of multiple indices (define (get-new-indices original-indices unique-indices) (map (lambda (index-list) (- (length unique-indices) (length (member index-list unique-indices)))) original-indices)) ;; reorder vertex data to fit with the new indices (duplicates where required) (define (reorder-vertex-data indices data) (define (loop-vertex-data vertex-data n dst) (cond ((null? vertex-data) dst) (else (loop-vertex-data (cdr vertex-data) (+ n 1) (cons (map (lambda (indices) (let ((data-index (list-ref indices n))) ; the actual index for this data type (list-ref (car vertex-data) data-index))) indices) dst))))) (reverse (loop-vertex-data data 0 '()))) ;; collapses the multiple indices per vertex type into one index shared ;; between position/normals/texture coord etc etc. fluxus uses this, as it ;; is closer to the underlying interface (define (unify-indices/data indices data) (let* ((grouped (group-indices indices (length data))) (unique-indices (get-unique-indices grouped '())) (new-indices (get-new-indices grouped unique-indices))) (list new-indices (reorder-vertex-data unique-indices data)))) (display (unify-indices/data indices (list positions normals tex)))(newline)