1 ;;; guile-assimp, foreign interface to libassimp
2 ;;; Copyright (C) 2014 by Javier Sancho Fernandez <jsf at jsancho dot org>
4 ;;; This program is free software: you can redistribute it and/or modify
5 ;;; it under the terms of the GNU General Public License as published by
6 ;;; the Free Software Foundation, either version 3 of the License, or
7 ;;; (at your option) any later version.
9 ;;; This program is distributed in the hope that it will be useful,
10 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 ;;; GNU General Public License for more details.
14 ;;; You should have received a copy of the GNU General Public License
15 ;;; along with this program. If not, see <http://www.gnu.org/licenses/>.
18 (define-module (assimp assimp)
19 #:use-module (assimp low-level scene)
20 #:use-module (ice-9 iconv)
21 #:use-module (rnrs bytevectors)
22 #:use-module (system foreign))
24 (define libassimp (dynamic-link "libassimp"))
27 (pointer->procedure '*
28 (dynamic-func "aiImportFile" libassimp)
29 (list '* unsigned-int)))
34 (define-syntax define-type
36 (define (mk-string . args)
41 (symbol->string (syntax->datum a))))
43 (define (mk-symbol . args)
46 (apply mk-string args))))
48 ((_ name (field field-proc) ...)
49 (with-syntax ((type? (mk-symbol #'name "?"))
50 (wrap-type (mk-symbol "wrap-" #'name))
51 (unwrap-type (mk-symbol "unwrap-" #'name))
52 (output-string (mk-string "#<" #'name " ~x>"))
53 (type-contents (mk-symbol #'name "-contents")))
55 (define-wrapped-pointer-type name
59 (format p output-string
60 (pointer-address (unwrap-type x)))))
61 (define (type-contents wrapped)
62 (let ((unwrapped (unwrap-type wrapped)))
63 (cond ((= (pointer-address unwrapped) 0)
68 (not (null? (cdr f))))
69 (list (cons 'field (field-proc unwrapped))
73 (define (bv-uint-ref pointer index)
75 (pointer->bytevector pointer 4 index)
80 (define (get-aiString index)
82 (let* ((length (bv-uint-ref pointer index))
83 (data (pointer->bytevector pointer length (+ index 4))))
84 (bytevector->string data (fluid-ref %default-port-encoding)))))
86 (define* (get-pointer index #:optional wrap-proc)
88 (let ((p (bv-uint-ref pointer index)))
91 (let ((p2 (make-pointer p)))
93 (cond (wrap-proc (wrap-proc p2))
96 (define (get-array num-index root-index type)
98 (let ((num (bv-uint-ref pointer num-index))
99 (rootp (make-pointer (bv-uint-ref pointer root-index))))
102 (pointer->bytevector rootp num 0 type)))
106 (define* (get-structs-array num-index root-index struct-size #:optional wrap-proc)
108 (let ((num (bv-uint-ref pointer num-index))
109 (rootp (bv-uint-ref pointer root-index)))
110 (let loop ((i (- num 1)))
114 (let* ((p (make-pointer (+ rootp (* i struct-size))))
115 (wp (if wrap-proc (wrap-proc p) p)))
116 (cons wp (loop (- i 1))))))))))
118 (define* (get-pointer-of-pointers num-index root-index #:optional wrap-proc)
120 (let* ((num (bv-uint-ref pointer num-index))
121 (rootp (make-pointer (bv-uint-ref pointer root-index))))
126 (let* ((p (make-pointer (bv-uint-ref rootp (* 4 i))))
127 (wp (if wrap-proc (wrap-proc p) p)))
128 (cons wp (loop (+ i 1))))))))))
133 (flags (lambda (p) (bv-uint-ref p 0)))
134 (root-node (lambda (p) (wrap-node (make-pointer (bv-uint-ref p 4)))))
135 (meshes (get-pointer-of-pointers 8 12 wrap-mesh))
136 (materials (get-pointer-of-pointers 16 20 wrap-material))
137 (animations (get-pointer-of-pointers 24 28))
138 (textures (get-pointer-of-pointers 32 36))
139 (lights (get-pointer-of-pointers 40 44))
140 (cameras (get-pointer-of-pointers 48 52)))
142 (define (load-scene filename flags)
144 (aiImportFile (string->pointer filename)
147 (define (load-scene filename flags)
151 (aiImportFile (string->pointer filename)
164 (name (get-aiString 0))
165 (transformation (lambda (p) (array->list (pointer->bytevector p 16 1028 'f32))))
166 (parent (get-pointer 1092 wrap-node))
167 (children (get-pointer-of-pointers 1096 1100 wrap-node))
168 (meshes (get-array 1104 1108 'u32)))
176 (define AI_MAX_NUMBER_OF_COLOR_SETS 8)
179 (num-primitive-types (lambda (p) (bv-uint-ref p 0)))
180 (vertices (get-pointer-of-pointers 4 12))
181 (faces (get-structs-array 8 124 8 wrap-face))
182 (normals (lambda (p) (bv-uint-ref p 16)))
183 (tangents (lambda (p) (bv-uint-ref p 20)))
184 (bitangents (lambda (p) (bv-uint-ref p 24)))
185 (colors (lambda (p) (bv-uint-ref p 28))) ;AI_MAX_NUMBER_OF_COLOR_SETS
186 (texture-coords (lambda (p) (bv-uint-ref p 60))) ;AI_MAX_NUMBER_OF_TEXTURECOORDS
187 (num-uv-components (lambda (p) (bv-uint-ref p 92))) ;AI_MAX_NUMBER_OF_TEXTURECOORDS
188 (bones (get-pointer-of-pointers 128 132))
189 (material-index (lambda (p) (bv-uint-ref p 136))))
197 (define-type material
198 (properties (get-pointer-of-pointers 4 0))
199 (allocated (lambda (p) (bv-uint-ref p 8))))
208 (indices (get-array 0 4 'u32)))