+++ /dev/null
-! Copyright (C) 2010 Erik Charlebois
-! See http://factorcode.org/license.txt for BSD license.
-USING: help.markup help.crossref help.stylesheet help.topics help.syntax
-definitions io prettyprint summary arrays math sequences vocabs strings
-see xml.data hashtables ;
-IN: collada
-
-ABOUT: "collada"
-
-ARTICLE: "collada" "Conversion of COLLADA assets"
-"The " { $vocab-link "collada" } " vocabulary implements words for converting COLLADA assets to data suitable for use with OpenGL. See the COLLADA documentation at " { $url "http://collada.org" } "." ;
-
-HELP: model
-{ $class-description "Tuple of a packed attribute buffer, index buffer and vertex format suitable for a single OpenGL draw call." } ;
-
-HELP: source
-{ $class-description "Tuple of a vertex attribute semantic, offset in triangle index buffer and float data for a single vertex attribute." } ;
-
-HELP: up-axis
-{ $description "Dynamically-scoped variable with the up axis of the tags being read." } ;
-
-HELP: unit-ratio
-{ $description "Scaling ratio for the coordinates of the tags being read." } ;
-
-HELP: missing-attr
-{ $description "An error thrown when an attribute is missing from a tag." } ;
-
-HELP: missing-child
-{ $description "An error thrown when a child is missing from a tag." } ;
-
-HELP: string>numbers ( string -- number-seq )
-{ $values { "string" string } { "number-seq" sequence } }
-{ $description "Splits a string on whitespace and converts the elements to a number sequence" } ;
-
-HELP: x-up { $class-description "Right-handed 3D coordinate system where X is up." } ;
-HELP: y-up { $class-description "Right-handed 3D coordinate system where Y is up." } ;
-HELP: z-up { $class-description "Right-handed 3D coordinate system where Z is up." } ;
-
-HELP: >y-up-axis!
-{ $values { "sequence" sequence } { "from-axis" rh-up } { "sequence" sequence } }
-{ $description "Destructively swizzles the first three elements of the input sequence to a right-handed 3D coordinate system where Y is up and returns the modified sequence." } ;
-
-HELP: source>seq
-{ $values { "source-tag" tag } { "up-axis" rh-up } { "scale" number } { "sequence" sequence } }
-{ $description "Convert the " { $emphasis "float_array" } " in a " { $emphasis "source tag" } " to a sequence of number sequences according to the element stride. The values are scaled according to " { $emphasis "scale" } " and swizzled from " { $emphasis "up-axis" } " so that the Y coordinate points up." } ;
-
-HELP: source>pair
-{ $values { "source-tag" tag } { "pair" pair } }
-{ $description "Convert the source tag to an id and number sequence pair." } ;
-
-HELP: mesh>sources
-{ $values { "mesh-tag" tag } { "hashtable" pair } }
-{ $description "Convert the mesh tag's source elements to a hashtable from id to number sequence." } ;
-
-HELP: mesh>vertices
-{ $values { "mesh-tag" tag } { "pair" pair } }
-{ $description "Convert the mesh tag's vertices element to a pair for further lookup in " { $link collect-sources } ". " } ;
-
-HELP: collect-sources
-{ $values { "sources" hashtable } { "vertices" pair } { "inputs" tag sequence } { "soures" sequence } }
-{ $description "Look up the sources for these " { $emphasis "input" } " elements and return a sequence of " { $link source } " tuples." } ;
-
-HELP: group-indices
-{ $values { "index-stride" number } { "triangle-count" number } { indices "sequence" } { "grouped-indices" sequence } }
-{ $description "Groups the index sequence by triangle and then groups each triangle's indices by vertex." } ;
-
-HELP: triangles>numbers
-{ $values { "triangles-tag" tag } { "number-seq" sequence } }
-{ $description "Converts the triangle data in a triangles tag from string form to a sequence of numbers." } ;
-
-HELP: largest-offset+1
-{ $values { "source-seq" sequence } { "largest-offset+1" number } }
-{ $description "Finds the largest offset in the sequence of " { $link source } " tuples and adds 1, which is the index stride for " { $link group-indices } "." } ;
-
-HELP: <model>
-{ $values { "attribute-buffer" sequence } { "index-buffer" sequence } { "sources" sequence } { "model" model } }
-{ $description "Converts the inputs to a form suitable for use with " { $vocab-link "gpu" } " and constructs a " { $link model } "." } ;
-
-HELP: soa>aos
-{ $values { "triangles-indices" sequence } { "sources" sequence } { "attribute-buffer" sequence } { "index-buffer" sequence } }
-{ $description "Swizzles the input sources from a structure of arrays form to an array of structures form and generates a new index buffer." } ;
-
-HELP: triangles>model
-{ $values { "sources" sequence } { "vertices" pair } { "triangles-tag" tag } { "model" model } }
-{ $description "Creates a " { $link model } " tuple from the given triangles tag, source set and vertices pair." } ;
-
-HELP: mesh>triangles
-{ $values { "souces" sequence } { "vertices" pair } { "mesh-tag" tag } { "models" sequence } }
-{ $description "Creates a sequence of models from the triangles in the mesh tag." } ;
-
-HELP: mesh>models
-{ $values { "mesh-tag" tag } { "models" sequence } }
-{ $description "Converts a triangle mesh to a set of models suitable for rendering with OpenGL." } ;
+++ /dev/null
-! Copyright (C) 2010 Erik Charlebois
-! See http://factorcode.org/license.txt for BSD license.
-USING: accessors arrays assocs grouping hashtables kernel
-locals math math.parser sequences sequences.deep
-specialized-arrays.instances.alien.c-types.float
-specialized-arrays.instances.alien.c-types.uint splitting xml
-xml.data xml.traversal math.order
-namespaces combinators images gpu.shaders io ;
-IN: collada
-
-TUPLE: model attribute-buffer index-buffer vertex-format ;
-TUPLE: source semantic offset data ;
-
-SYMBOLS: up-axis unit-ratio ;
-
-ERROR: missing-attr tag attr ;
-ERROR: missing-child tag child-name ;
-
-: string>numbers ( string -- number-seq )
- " \t\n" split [ string>number ] map ;
-
-: x/ ( tag child-name -- child-tag )
- [ tag-named ]
- [ rot dup [ drop missing-child ] unless 2nip ]
- 2bi ; inline
-
-: x@ ( tag attr-name -- attr-value )
- [ attr ]
- [ rot dup [ drop missing-attr ] unless 2nip ]
- 2bi ; inline
-
-: xt ( tag -- content ) children>string ;
-
-: x* ( tag child-name quot -- seq )
- [ tags-named ] dip map ; inline
-
-SINGLETONS: x-up y-up z-up ;
-
-UNION: rh-up x-up y-up z-up ;
-
-GENERIC: >y-up-axis! ( seq from-axis -- seq )
-M: x-up >y-up-axis!
- drop dup
- [
- [ 0 swap nth ]
- [ 1 swap nth neg ]
- [ 2 swap nth ] tri
- swap -rot
- ] [
- [ 2 swap set-nth ]
- [ 1 swap set-nth ]
- [ 0 swap set-nth ] tri
- ] bi ;
-M: y-up >y-up-axis! drop ;
-M: z-up >y-up-axis!
- drop dup
- [
- [ 0 swap nth ]
- [ 1 swap nth neg ]
- [ 2 swap nth ] tri
- swap
- ] [
- [ 2 swap set-nth ]
- [ 1 swap set-nth ]
- [ 0 swap set-nth ] tri
- ] bi ;
-
-: source>seq ( source-tag up-axis scale -- sequence )
- rot
- [ "float_array" x/ xt string>numbers [ * ] with map ]
- [ nip "technique_common" x/ "accessor" x/ "stride" x@ string>number ] 2bi
- <groups>
- [ swap >y-up-axis! ] with map ;
-
-: source>pair ( source-tag -- pair )
- [ "id" x@ ]
- [ up-axis get unit-ratio get source>seq ] bi 2array ;
-
-: mesh>sources ( mesh-tag -- hashtable )
- "source" [ source>pair ] x* >hashtable ;
-
-: mesh>vertices ( mesh-tag -- pair )
- "vertices" x/
- [ "id" x@ ]
- [ "input"
- [
- [ "semantic" x@ ]
- [ "source" x@ ] bi 2array
- ] x*
- ] bi 2array ;
-
-:: collect-sources ( sources vertices inputs -- sources )
- inputs
- [| input |
- input "source" x@ rest vertices first =
- [
- vertices second [| vertex |
- vertex first
- input "offset" x@ string>number
- vertex second rest sources at source boa
- ] map
- ]
- [
- input [ "semantic" x@ ]
- [ "offset" x@ string>number ]
- [ "source" x@ rest sources at ] tri source boa
- ] if
- ] map flatten ;
-
-: group-indices ( index-stride triangle-count indices -- grouped-indices )
- dup length rot / <groups> swap [ <groups> ] curry map ;
-
-: triangles>numbers ( triangles-tag -- number-seq )
- "p" x/ children>string " \t\n" split [ string>number ] map ;
-
-: largest-offset+1 ( source-seq -- largest-offset+1 )
- [ offset>> ] [ max ] map-reduce 1 + ;
-
-: <model> ( attribute-buffer index-buffer sources -- model )
- [ flatten >float-array ]
- [ flatten >uint-array ]
- [
- [
- {
- [ semantic>> ]
- [ drop float-components ]
- [ data>> first length ]
- [ drop f ]
- } cleave vertex-attribute boa
- ] map
- ] tri* model boa ;
-
-:: soa>aos ( triangles-indices sources -- attribute-buffer index-buffer )
- V{ } clone :> attribute-buffer
- V{ } clone :> index-buffer
- H{ } clone :> inverse-attribute-buffer
- triangles-indices [
- [
- [| triangle-index triangle-offset |
- triangle-index triangle-offset sources
- [| index offset source |
- source offset>> offset = [
- index source data>> nth
- ] [ f ] if
- ] with with map sift flatten :> attributes
-
- attributes inverse-attribute-buffer at [
- index-buffer push
- ] [
- attribute-buffer length
- [ attributes inverse-attribute-buffer set-at ]
- [ index-buffer push ] bi
- attributes attribute-buffer push
- ] if*
- ] each-index
- ] each
- ] each
- attribute-buffer index-buffer ;
-
-: triangles>model ( sources vertices triangles-tag -- model )
- [ "input" tags-named collect-sources ] keep swap
-
- [
- largest-offset+1 swap
- [ "count" x@ string>number ] [ triangles>numbers ] bi
- group-indices
- ]
- [
- [ soa>aos ] keep <model>
- ] bi ;
-
-: mesh>triangles ( sources vertices mesh-tag -- models )
- "triangles" tags-named [ triangles>model ] with with map ;
-
-: mesh>models ( mesh-tag -- models )
- [
- { { up-axis z-up } { unit-ratio 0.5 } } [
- mesh>sources
- ] bind
- ]
- [ mesh>vertices ]
- [ mesh>triangles ] tri ;
math.matrices math.vectors.simd math.parser math.vectors
method-chains namespaces sequences splitting threads ui ui.gadgets
ui.gadgets.worlds ui.pixel-formats specialized-arrays
-specialized-vectors literals collada fry xml xml.traversal sequences.deep
+specialized-vectors literals game.models.collada fry xml xml.traversal sequences.deep
+math.bitwise
opengl.gl
prettyprint ;
FROM: alien.c-types => float ;
attribute vec3 POSITION;
attribute vec3 NORMAL;
+attribute vec2 TEXCOORD;
+
+varying vec2 texit;
+varying vec3 norm;
void main()
{
vec4 position = mv_matrix * vec4(POSITION, 1.0);
gl_Position = p_matrix * position;
+ texit = TEXCOORD;
+ norm = NORMAL;
}
;
GLSL-SHADER: collada-fragment-shader fragment-shader
+varying vec2 texit;
+varying vec3 norm;
void main()
{
- gl_FragColor = vec4(1, 1, 0, 1);
+ gl_FragColor = vec4(texit, 0, 1) + vec4(norm, 1);
}
;
{ collada collada-state } ;
VERTEX-FORMAT: collada-vertex
- { "POSITION" float-components 3 f }
- { "NORMAL" float-components 3 f } ;
+ { "POSITION" float-components 3 f }
+ { "NORMAL" float-components 3 f }
+ { "TEXCOORD" float-components 2 f } ;
VERTEX-FORMAT: debug-vertex
{ "POSITION" float-components 3 f }
: <collada-state> ( -- collada-state )
collada-state new
- #! "C:/Users/erikc/Downloads/mech.dae"
- "/Users/erikc/Documents/mech.dae"
+ "C:/Users/erikc/Downloads/test2.dae"
+ #! "/Users/erikc/Documents/mech.dae"
file>xml "mesh" deep-tags-named [ mesh>models ] map flatten >>models ;
M: collada-world begin-game-world
{ 0 0 0 } { 0 0 1 } { 0 0 1 } } draw-lines ;
: draw-collada ( world -- )
- GL_COLOR_BUFFER_BIT glClear
+ 0 0 0 0 glClearColor
+ 1 glClearDepth
+ HEX: ffffffff glClearStencil
+ { GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT GL_STENCIL_BUFFER_BIT } flags glClear
[
- triangle-lines dup t <triangle-state> set-gpu-state
+ #! triangle-lines dup t <triangle-state> set-gpu-state
+ face-ccw cull-back <triangle-cull-state> set-gpu-state
+ cmp-less <depth-state> set-gpu-state
[ collada>> vertex-arrays>> ]
[ collada>> index-vectors>> ]
[ <collada-uniforms> ]
] curry 2each
]
[
+ cmp-always <depth-state> set-gpu-state
draw-axes
]
bi ;
M: collada-world draw-world*
draw-collada ;
-M: collada-world wasd-movement-speed drop 1/16. ;
+M: collada-world wasd-movement-speed drop 1/4. ;
M: collada-world wasd-near-plane drop 1/32. ;
M: collada-world wasd-far-plane drop 1024.0 ;
--- /dev/null
+Erik Charlebois
--- /dev/null
+! Copyright (C) 2010 Erik Charlebois
+! See http://factorcode.org/license.txt for BSD license.
+USING: help.markup help.crossref help.stylesheet help.topics help.syntax
+definitions io prettyprint summary arrays math sequences vocabs strings
+see xml.data hashtables assocs ;
+IN: game.models.collada
+
+ABOUT: "game.models.collada"
+
+ARTICLE: "game.models.collada" "Conversion of COLLADA assets"
+"The " { $vocab-link "game.models.collada" } " vocabulary implements words for converting COLLADA assets to data suitable for use with OpenGL. See the COLLADA documentation at " { $url "http://collada.org" } "." ;
+
+HELP: model
+{ $class-description "Tuple of a packed attribute buffer, index buffer and vertex format suitable for a single OpenGL draw call." } ;
+
+HELP: source
+{ $class-description "Tuple of a vertex attribute semantic, offset in triangle index buffer and float data for a single vertex attribute." } ;
+
+HELP: up-axis
+{ $description "Dynamically-scoped variable with the up axis of the tags being read." } ;
+
+HELP: unit-ratio
+{ $description "Scaling ratio for the coordinates of the tags being read." } ;
+
+HELP: indexed-seq
+{ $class-description "A sequence described by a sequence of unique elements and a sequence of indices. The sequence can only be appended to. An associative map is used as a reverse lookup table when appending." } ;
+
+HELP: <indexed-seq>
+{ $values { "dseq-exemplar" sequence } { "iseq-examplar" sequence } { "rassoc-examplar" assoc } }
+{ $class-description "Construct an " { $link indexed-seq } " using the given examplars for the underlying data structures." } ;
+
+HELP: string>numbers ( string -- number-seq )
+{ $values { "string" string } { "number-seq" sequence } }
+{ $description "Splits a string on whitespace and converts the elements to a number sequence" } ;
+
+HELP: x-up { $class-description "Right-handed 3D coordinate system where X is up." } ;
+HELP: y-up { $class-description "Right-handed 3D coordinate system where Y is up." } ;
+HELP: z-up { $class-description "Right-handed 3D coordinate system where Z is up." } ;
+
+HELP: >y-up-axis!
+{ $values { "seq" sequence } { "from-axis" rh-up } { "seq" sequence } }
+{ $description "Destructively swizzles the first three elements of the input sequence to a right-handed 3D coordinate system where Y is up and returns the modified sequence." } ;
+
+HELP: source>seq
+{ $values { "source-tag" tag } { "up-axis" rh-up } { "scale" number } { "sequence" sequence } }
+{ $description "Convert the " { $emphasis "float_array" } " in a " { $emphasis "source tag" } " to a sequence of number sequences according to the element stride. The values are scaled according to " { $emphasis "scale" } " and swizzled from " { $emphasis "up-axis" } " so that the Y coordinate points up." } ;
+
+HELP: source>pair
+{ $values { "source-tag" tag } { "pair" pair } }
+{ $description "Convert the source tag to an id and number sequence pair." } ;
+
+HELP: mesh>sources
+{ $values { "mesh-tag" tag } { "hashtable" pair } }
+{ $description "Convert the mesh tag's source elements to a hashtable from id to number sequence." } ;
+
+HELP: mesh>vertices
+{ $values { "mesh-tag" tag } { "pair" pair } }
+{ $description "Convert the mesh tag's vertices element to a pair for further lookup in " { $link collect-sources } ". " } ;
+
+HELP: collect-sources
+{ $values { "sources" hashtable } { "vertices" pair } { "inputs" tag sequence } { "sources" sequence } }
+{ $description "Look up the sources for these " { $emphasis "input" } " elements and return a sequence of " { $link source } " tuples." } ;
+
+HELP: group-indices
+{ $values { "index-stride" number } { "triangle-count" number } { "indices" sequence } { "grouped-indices" sequence } }
+{ $description "Groups the index sequence by triangle and then groups each triangle's indices by vertex." } ;
+
+HELP: triangles>numbers
+{ $values { "triangles-tag" tag } { "number-seq" sequence } }
+{ $description "Converts the triangle data in a triangles tag from string form to a sequence of numbers." } ;
+
+HELP: largest-offset+1
+{ $values { "source-seq" sequence } { "largest-offset+1" number } }
+{ $description "Finds the largest offset in the sequence of " { $link source } " tuples and adds 1, which is the index stride for " { $link group-indices } "." } ;
+
+HELP: <model>
+{ $values { "attribute-buffer" sequence } { "index-buffer" sequence } { "sources" sequence } { "model" model } }
+{ $description "Converts the inputs to a form suitable for use with " { $vocab-link "gpu" } " and constructs a " { $link model } "." } ;
+
+HELP: pack-attributes
+{ $values { "source-indices" sequence } { "sources" sequence } { "attributes" sequence } }
+{ $description "Packs the attributes for a single vertex into a sequence from a set of source data streams." } ;
+
+HELP: soa>aos
+{ $values { "triangles-indices" sequence } { "sources" sequence } { "attribute-buffer" sequence } { "index-buffer" sequence } }
+{ $description "Swizzles the input sources from a structure of arrays form to an array of structures form and generates a new index buffer." } ;
+
+HELP: triangles>model
+{ $values { "sources" sequence } { "vertices" pair } { "triangles-tag" tag } { "model" model } }
+{ $description "Creates a " { $link model } " tuple from the given triangles tag, source set and vertices pair." } ;
+
+HELP: mesh>triangles
+{ $values { "sources" sequence } { "vertices" pair } { "mesh-tag" tag } { "models" sequence } }
+{ $description "Creates a sequence of models from the triangles in the mesh tag." } ;
+
+HELP: mesh>models
+{ $values { "mesh-tag" tag } { "models" sequence } }
+{ $description "Converts a triangle mesh to a set of models suitable for rendering with OpenGL." } ;
--- /dev/null
+! Copyright (C) 2010 Erik Charlebois
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors arrays assocs grouping hashtables kernel
+locals math math.parser sequences sequences.deep
+specialized-arrays.instances.alien.c-types.float
+specialized-arrays.instances.alien.c-types.uint splitting xml
+xml.data xml.traversal math.order
+namespaces combinators images gpu.shaders io make ;
+IN: game.models.collada
+
+TUPLE: model attribute-buffer index-buffer vertex-format ;
+TUPLE: source semantic offset data ;
+
+SYMBOLS: up-axis unit-ratio ;
+
+ERROR: missing-attr tag attr ;
+ERROR: missing-child tag child-name ;
+
+TUPLE: indexed-seq dseq iseq rassoc ;
+INSTANCE: indexed-seq sequence
+
+M: indexed-seq length
+ iseq>> length ; inline
+
+M: indexed-seq nth
+ [ iseq>> nth ] keep dseq>> nth ; inline
+
+M:: indexed-seq set-nth ( elt n seq -- )
+ seq dseq>> :> dseq
+ seq iseq>> :> iseq
+ seq rassoc>> :> rassoc
+ seq length n = not [ seq immutable ] when
+ elt rassoc at
+ [
+ iseq push
+ ]
+ [
+ dseq length
+ [ elt rassoc set-at ]
+ [ iseq push ] bi
+ elt dseq push
+ ] if* ; inline
+
+: <indexed-seq> ( dseq-examplar iseq-exampler rassoc-examplar -- indexed-seq )
+ indexed-seq new
+ swap clone >>rassoc
+ swap clone >>iseq
+ swap clone >>dseq ;
+
+M: indexed-seq new-resizable
+ [ dseq>> ] [ iseq>> ] [ rassoc>> ] tri <indexed-seq>
+ dup -rot
+ [ [ dseq>> new-resizable ] keep (>>dseq) ]
+ [ [ iseq>> new-resizable ] keep (>>iseq) ]
+ [ [ rassoc>> clone nip ] keep (>>rassoc) ]
+ 2tri ;
+
+
+: string>numbers ( string -- number-seq )
+ " \t\n" split [ "" = ] trim [ string>number ] map ;
+
+: x/ ( tag child-name -- child-tag )
+ [ tag-named ]
+ [ rot dup [ drop missing-child ] unless 2nip ]
+ 2bi ; inline
+
+: x@ ( tag attr-name -- attr-value )
+ [ attr ]
+ [ rot dup [ drop missing-attr ] unless 2nip ]
+ 2bi ; inline
+
+: xt ( tag -- content ) children>string ;
+
+: x* ( tag child-name quot -- seq )
+ [ tags-named ] dip map ; inline
+
+SINGLETONS: x-up y-up z-up ;
+
+UNION: rh-up x-up y-up z-up ;
+
+GENERIC: >y-up-axis! ( seq from-axis -- seq )
+M: x-up >y-up-axis!
+ drop dup
+ [
+ [ 0 swap nth ]
+ [ 1 swap nth neg ]
+ [ 2 swap nth ] tri
+ swap -rot
+ ] [
+ [ 2 swap set-nth ]
+ [ 1 swap set-nth ]
+ [ 0 swap set-nth ] tri
+ ] bi ;
+M: y-up >y-up-axis! drop ;
+M: z-up >y-up-axis!
+ drop dup
+ [
+ [ 0 swap nth ]
+ [ 1 swap nth neg ]
+ [ 2 swap nth ] tri
+ swap
+ ] [
+ [ 2 swap set-nth ]
+ [ 1 swap set-nth ]
+ [ 0 swap set-nth ] tri
+ ] bi ;
+
+: source>seq ( source-tag up-axis scale -- sequence )
+ rot
+ [ "float_array" x/ xt string>numbers [ * ] with map ]
+ [ nip "technique_common" x/ "accessor" x/ "stride" x@ string>number ] 2bi
+ group
+ [ swap over length 2 > [ >y-up-axis! ] [ drop ] if ] with map ;
+
+: source>pair ( source-tag -- pair )
+ [ "id" x@ ]
+ [ up-axis get unit-ratio get source>seq ] bi 2array ;
+
+: mesh>sources ( mesh-tag -- hashtable )
+ "source" [ source>pair ] x* >hashtable ;
+
+: mesh>vertices ( mesh-tag -- pair )
+ "vertices" x/
+ [ "id" x@ ]
+ [ "input"
+ [
+ [ "semantic" x@ ]
+ [ "source" x@ ] bi 2array
+ ] x*
+ ] bi 2array ;
+
+:: collect-sources ( sources vertices inputs -- sources )
+ inputs
+ [| input |
+ input "source" x@ rest vertices first =
+ [
+ vertices second [| vertex |
+ vertex first
+ input "offset" x@ string>number
+ vertex second rest sources at source boa
+ ] map
+ ]
+ [
+ input [ "semantic" x@ ]
+ [ "offset" x@ string>number ]
+ [ "source" x@ rest sources at ] tri source boa
+ ] if
+ ] map flatten ;
+
+: group-indices ( index-stride triangle-count indices -- grouped-indices )
+ dup length rot / group swap [ group ] curry map ;
+
+: triangles>numbers ( triangles-tag -- number-seq )
+ "p" x/ children>string " \t\n" split [ string>number ] map ;
+
+: largest-offset+1 ( source-seq -- largest-offset+1 )
+ [ offset>> ] [ max ] map-reduce 1 + ;
+
+: <model> ( attribute-buffer index-buffer sources -- model )
+ [ flatten >float-array ]
+ [ flatten >uint-array ]
+ [
+ [
+ {
+ [ semantic>> ]
+ [ drop float-components ]
+ [ data>> first length ]
+ [ drop f ]
+ } cleave vertex-attribute boa
+ ] map
+ ] tri* model boa ;
+
+: pack-attributes ( source-indices sources -- attributes )
+ [
+ [
+ [
+ [ data>> ] [ offset>> ] bi
+ rot = [ nth ] [ 2drop f ] if
+ ] with with map sift flatten ,
+ ] curry each-index
+ ] V{ } make flatten ;
+
+:: soa>aos ( triangles-indices sources -- attribute-buffer index-buffer )
+ [ triangles-indices [ [
+ sources pack-attributes ,
+ ] each ] each ]
+ V{ } V{ } H{ } <indexed-seq> make [ dseq>> ] [ iseq>> ] bi ;
+
+: triangles>model ( sources vertices triangles-tag -- model )
+ [ "input" tags-named collect-sources ] keep swap
+
+ [
+ largest-offset+1 swap
+ [ "count" x@ string>number ] [ triangles>numbers ] bi
+ group-indices
+ ]
+ [
+ [ soa>aos ] keep <model>
+ ] bi ;
+
+: mesh>triangles ( sources vertices mesh-tag -- models )
+ "triangles" tags-named [ triangles>model ] with with map ;
+
+: mesh>models ( mesh-tag -- models )
+ [
+ { { up-axis y-up } { unit-ratio 0.5 } } [
+ mesh>sources
+ ] bind
+ ]
+ [ mesh>vertices ]
+ [ mesh>triangles ] tri ;
--- /dev/null
+Conversion of COLLADA geometry assets to OpenGL vertex and index buffers