1 ! Copyright (C) 2010 Erik Charlebois
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors alien.c-types alien.data arrays assocs grouping
4 hashtables kernel locals math math.parser sequences sequences.deep
5 splitting xml xml.data xml.traversal math.order namespaces
6 combinators images gpu.shaders io make game.models game.models.util
7 io.encodings.ascii game.models.loader specialized-arrays ;
8 QUALIFIED-WITH: alien.c-types c
9 SPECIALIZED-ARRAYS: c:float c:uint ;
10 IN: game.models.collada
12 SINGLETON: collada-models
13 "dae" ascii collada-models register-models-class
15 ERROR: missing-attr tag attr ;
16 ERROR: missing-child tag child-name ;
19 TUPLE: source semantic offset data ;
20 SYMBOLS: up-axis unit-ratio ;
22 : string>numbers ( string -- number-seq )
23 " \t\n" split harvest [ string>number ] map ;
25 : string>floats ( string -- float-seq )
26 " \t\n" split harvest [ string>number ] map ;
28 : x/ ( tag child-name -- child-tag )
30 [ rot dup [ drop missing-child ] unless 2nip ]
33 : x@ ( tag attr-name -- attr-value )
35 [ rot dup [ drop missing-attr ] unless 2nip ]
38 : xt ( tag -- content ) children>string ;
40 : x* ( tag child-name quot -- seq )
41 [ tags-named ] dip map ; inline
43 SINGLETONS: x-up y-up z-up ;
44 UNION: rh-up x-up y-up z-up ;
46 GENERIC: >y-up-axis! ( seq from-axis -- seq )
57 [ 0 swap set-nth ] tri
59 M: y-up >y-up-axis! drop ;
70 [ 0 swap set-nth ] tri
73 : source>seq ( source-tag up-axis scale -- sequence )
75 [ "float_array" x/ xt string>floats [ * ] with map ]
76 [ nip "technique_common" x/ "accessor" x/ "stride" x@ string>number ] 2bi
78 [ swap over length 2 > [ >y-up-axis! ] [ drop ] if ] with map ;
80 : source>pair ( source-tag -- pair )
82 [ up-axis get unit-ratio get source>seq ] bi 2array ;
84 : mesh>sources ( mesh-tag -- hashtable )
85 "source" [ source>pair ] x* >hashtable ;
87 : mesh>vertices ( mesh-tag -- pair )
93 [ "source" x@ ] bi 2array
97 :: collect-sources ( sources vertices inputs -- seq )
100 input "source" x@ rest vertices first =
102 vertices second [| vertex |
104 input "offset" x@ string>number
105 vertex second rest sources at source boa
109 input [ "semantic" x@ ]
110 [ "offset" x@ string>number ]
111 [ "source" x@ rest sources at ] tri source boa
115 : group-indices ( index-stride triangle-count indices -- grouped-indices )
116 dup length rot / group swap [ group ] curry map ;
118 : triangles>numbers ( triangles-tag -- number-seq )
119 "p" x/ children>string " \t\n" split [ string>number ] map ;
121 : largest-offset+1 ( source-seq -- largest-offset+1 )
122 [ offset>> ] [ max ] map-reduce 1 + ;
124 VERTEX-FORMAT: collada-vertex-format
125 { "POSITION" float-components 3 f }
126 { "NORMAL" float-components 3 f }
127 { "TEXCOORD" float-components 2 f } ;
129 : pack-attributes ( source-indices sources -- attributes )
133 [ data>> ] [ offset>> ] bi
134 rot = [ nth ] [ 2drop f ] if
135 ] with with map sift flatten ,
137 ] V{ } make flatten ;
139 :: soa>aos ( triangles-indices sources -- attribute-buffer index-buffer )
140 [ triangles-indices [ [ sources pack-attributes , ] each ] each ]
141 V{ } V{ } H{ } <indexed-seq> make [ dseq>> ] [ iseq>> ] bi ;
143 : triangles>model ( sources vertices triangles-tag -- model )
144 [ "input" tags-named collect-sources ] keep swap
147 largest-offset+1 swap
148 [ "count" x@ string>number ] [ triangles>numbers ] bi
153 [ flatten c:float >c-array ]
154 [ flatten c:uint >c-array ]
155 bi* collada-vertex-format f model boa
158 : mesh>triangles ( sources vertices mesh-tag -- models )
159 "triangles" tags-named [ triangles>model ] with with map ;
161 : mesh>models ( mesh-tag -- models )
163 { { up-axis y-up } { unit-ratio 1 } } [
168 [ mesh>triangles ] tri ;
171 M: collada-models stream>models
172 drop read-xml "mesh" deep-tags-named [ mesh>models ] map flatten ;