]> gitweb.factorcode.org Git - factor.git/blob - extra/game/models/collada/collada.factor
change ERROR: words from throw-foo back to foo.
[factor.git] / extra / game / models / collada / collada.factor
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
11
12 SINGLETON: collada-models
13 "dae" ascii collada-models register-models-class
14
15 ERROR: missing-attr tag attr ;
16 ERROR: missing-child tag child-name ;
17
18 <PRIVATE
19 TUPLE: source semantic offset data ;
20 SYMBOLS: up-axis unit-ratio ;
21
22 : string>numbers ( string -- number-seq )
23     " \t\n" split harvest [ string>number ] map ;
24
25 : x/ ( tag child-name -- child-tag )
26     [ tag-named ]
27     [ rot dup [ drop missing-child ] unless 2nip ]
28     2bi ; inline
29
30 : x@ ( tag attr-name -- attr-value )
31     [ attr ]
32     [ rot dup [ drop missing-attr ] unless 2nip ]
33     2bi ; inline
34
35 : xt ( tag -- content ) children>string ;
36
37 : x* ( tag child-name quot -- seq )
38     [ tags-named ] dip map ; inline
39
40 SINGLETONS: x-up y-up z-up ;
41 UNION: rh-up x-up y-up z-up ;
42
43 GENERIC: >y-up-axis! ( seq from-axis -- seq )
44 M: x-up >y-up-axis!
45     drop dup
46     [
47         [ 0 swap nth ]
48         [ 1 swap nth neg ]
49         [ 2 swap nth ] tri
50         swap -rot
51     ] [
52         [ 2 swap set-nth ]
53         [ 1 swap set-nth ]
54         [ 0 swap set-nth ] tri
55     ] bi ;
56 M: y-up >y-up-axis! drop ;
57 M: z-up >y-up-axis!
58     drop dup
59     [
60         [ 0 swap nth ]
61         [ 1 swap nth neg ]
62         [ 2 swap nth ] tri
63         swap
64     ] [
65         [ 2 swap set-nth ]
66         [ 1 swap set-nth ]
67         [ 0 swap set-nth ] tri
68     ] bi ;
69
70 : source>sequence ( source-tag up-axis scale -- sequence )
71     rot
72     [ "float_array" x/ xt string>numbers [ * ] with map ]
73     [ nip "technique_common" x/ "accessor" x/ "stride" x@ string>number ] 2bi
74     group
75     [ swap over length 2 > [ >y-up-axis! ] [ drop ] if ] with map ;
76
77 : source>pair ( source-tag -- pair )
78     [ "id" x@ ]
79     [ up-axis get unit-ratio get source>sequence ] bi 2array ;
80
81 : mesh>sources ( mesh-tag -- hashtable )
82     "source" [ source>pair ] x* >hashtable ;
83
84 : mesh>vertices ( mesh-tag -- pair )
85     "vertices" x/
86     [ "id" x@ ]
87     [ "input"
88       [
89           [ "semantic" x@ ]
90           [ "source" x@ ] bi 2array
91       ] x*
92     ] bi 2array ;
93
94 :: collect-sources ( sources vertices inputs -- seq )
95     inputs
96     [| input |
97         input "source" x@ rest vertices first =
98         [
99             vertices second [| vertex |
100                 vertex first
101                 input "offset" x@ string>number
102                 vertex second rest sources at source boa
103             ] map
104         ]
105         [
106             input [ "semantic" x@ ]
107                   [ "offset" x@ string>number ]
108                   [ "source" x@ rest sources at ] tri source boa
109         ] if
110     ] map flatten ;
111
112 : group-indices ( index-stride triangle-count indices -- grouped-indices )
113     dup length rot / group swap [ group ] curry map ;
114
115 : triangles>numbers ( triangles-tag -- number-seq )
116     "p" x/ children>string " \t\n" split [ string>number ] map ;
117
118 : largest-offset+1 ( source-seq -- largest-offset+1 )
119     [ offset>> ] [ max ] map-reduce 1 + ;
120
121 VERTEX-FORMAT: collada-vertex-format
122     { "POSITION" float-components 3 f }
123     { "NORMAL" float-components 3 f }
124     { "TEXCOORD" float-components 2 f } ;
125
126 : pack-attributes ( source-indices sources -- attributes )
127     [
128         [
129             [
130                 [ data>> ] [ offset>> ] bi
131                 rot = [ nth ] [ 2drop f ] if
132             ] 2with map sift flatten ,
133         ] curry each-index
134     ] V{ } make flatten ;
135
136 :: soa>aos ( triangles-indices sources -- attribute-buffer index-buffer )
137     [ triangles-indices [ [ sources pack-attributes , ] each ] each ]
138     V{ } V{ } H{ } <indexed-seq> make [ dseq>> ] [ iseq>> ] bi ;
139
140 : triangles>model ( sources vertices triangles-tag -- model )
141     [ "input" tags-named collect-sources ] keep swap
142
143     [
144         largest-offset+1 swap
145         [ "count" x@ string>number ] [ triangles>numbers ] bi
146         group-indices
147     ]
148     [
149         soa>aos
150         [ flatten c:float >c-array ]
151         [ flatten c:uint >c-array ]
152         bi* collada-vertex-format f model boa
153     ] bi ;
154
155 : mesh>triangles ( sources vertices mesh-tag -- models )
156     "triangles" tags-named [ triangles>model ] 2with map ;
157
158 : mesh>models ( mesh-tag -- models )
159     [
160         { { up-axis y-up } { unit-ratio 1 } } [
161             mesh>sources
162         ] with-variables
163     ]
164     [ mesh>vertices ]
165     [ mesh>triangles ] tri ;
166 PRIVATE>
167
168 M: collada-models stream>models
169     drop read-xml "mesh" deep-tags-named [ mesh>models ] map flatten ;