Unify obj and collada loading under a common models umbrella loader
parent
9adfda095f
commit
e1223e056f
|
@ -8,11 +8,9 @@ io io.encodings.ascii io.files io.files.temp kernel locals math
|
||||||
math.matrices math.vectors.simd math.parser math.vectors
|
math.matrices math.vectors.simd math.parser math.vectors
|
||||||
method-chains namespaces sequences splitting threads ui ui.gadgets
|
method-chains namespaces sequences splitting threads ui ui.gadgets
|
||||||
ui.gadgets.worlds ui.pixel-formats specialized-arrays
|
ui.gadgets.worlds ui.pixel-formats specialized-arrays
|
||||||
specialized-vectors literals game.models.collada fry xml xml.traversal sequences.deep
|
specialized-vectors literals game.models.collada fry xml
|
||||||
|
xml.traversal sequences.deep destructors math.bitwise opengl.gl
|
||||||
math.bitwise
|
prettyprint game.models.obj game.models.loader ;
|
||||||
opengl.gl
|
|
||||||
prettyprint ;
|
|
||||||
FROM: alien.c-types => float ;
|
FROM: alien.c-types => float ;
|
||||||
SPECIALIZED-ARRAY: float
|
SPECIALIZED-ARRAY: float
|
||||||
SPECIALIZED-VECTOR: uint
|
SPECIALIZED-VECTOR: uint
|
||||||
|
@ -95,36 +93,40 @@ VERTEX-FORMAT: debug-vertex
|
||||||
{ "POSITION" float-components 3 f }
|
{ "POSITION" float-components 3 f }
|
||||||
{ "COLOR" float-components 3 f } ;
|
{ "COLOR" float-components 3 f } ;
|
||||||
|
|
||||||
|
TUPLE: vbo vertex-buffer index-buffer index-count vertex-format ;
|
||||||
|
|
||||||
: <collada-buffers> ( models -- buffers )
|
: <collada-buffers> ( models -- buffers )
|
||||||
! drop
|
|
||||||
! float-array{ -0.5 0 0 1 0 0 0 1 0 0 1 0 0.5 0 0 0 0 1 }
|
|
||||||
! uint-array{ 0 1 2 }
|
|
||||||
! f model boa 1array
|
|
||||||
[
|
[
|
||||||
|
{
|
||||||
[ attribute-buffer>> underlying>> static-upload draw-usage vertex-buffer byte-array>buffer ]
|
[ attribute-buffer>> underlying>> static-upload draw-usage vertex-buffer byte-array>buffer ]
|
||||||
[ index-buffer>> underlying>> static-upload draw-usage index-buffer byte-array>buffer ]
|
[ index-buffer>> underlying>> static-upload draw-usage index-buffer byte-array>buffer ]
|
||||||
[ index-buffer>> length ] tri 3array
|
[ index-buffer>> length ]
|
||||||
|
[ vertex-format>> ]
|
||||||
|
} cleave vbo boa
|
||||||
] map ;
|
] map ;
|
||||||
|
|
||||||
: fill-collada-state ( collada-state -- )
|
: fill-collada-state ( collada-state -- )
|
||||||
dup models>> <collada-buffers>
|
dup models>> <collada-buffers>
|
||||||
[
|
[
|
||||||
[
|
[
|
||||||
first collada-program <program-instance> collada-vertex buffer>vertex-array
|
[ vertex-buffer>> collada-program <program-instance> ]
|
||||||
|
[ vertex-format>> ] bi buffer>vertex-array
|
||||||
] map >>vertex-arrays drop
|
] map >>vertex-arrays drop
|
||||||
]
|
]
|
||||||
[
|
[
|
||||||
[
|
[
|
||||||
[ second ] [ third ] bi
|
[ index-buffer>> ] [ index-count>> ] bi
|
||||||
'[ _ 0 <buffer-ptr> _ uint-indexes <index-elements> ] call
|
'[ _ 0 <buffer-ptr> _ uint-indexes <index-elements> ] call
|
||||||
] map >>index-vectors drop
|
] map >>index-vectors drop
|
||||||
] 2bi ;
|
] 2bi ;
|
||||||
|
|
||||||
|
: model-files ( -- files )
|
||||||
|
{ "C:/Users/erikc/Downloads/test2.dae"
|
||||||
|
"C:/Users/erikc/Downloads/Sponza.obj" } ;
|
||||||
|
|
||||||
: <collada-state> ( -- collada-state )
|
: <collada-state> ( -- collada-state )
|
||||||
collada-state new
|
collada-state new
|
||||||
"C:/Users/erikc/Downloads/test2.dae"
|
model-files [ load-models ] [ append ] map-reduce >>models ;
|
||||||
#! "/Users/erikc/Documents/mech.dae"
|
|
||||||
file>xml "mesh" deep-tags-named [ mesh>models ] map flatten >>models ;
|
|
||||||
|
|
||||||
M: collada-world begin-game-world
|
M: collada-world begin-game-world
|
||||||
init-gpu
|
init-gpu
|
||||||
|
@ -168,8 +170,9 @@ M: collada-world begin-game-world
|
||||||
{ GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT GL_STENCIL_BUFFER_BIT } flags glClear
|
{ GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT GL_STENCIL_BUFFER_BIT } flags glClear
|
||||||
|
|
||||||
[
|
[
|
||||||
#! triangle-lines dup t <triangle-state> set-gpu-state
|
triangle-fill dup t <triangle-state> set-gpu-state
|
||||||
face-ccw cull-back <triangle-cull-state> set-gpu-state
|
face-ccw cull-back <triangle-cull-state> set-gpu-state
|
||||||
|
|
||||||
cmp-less <depth-state> set-gpu-state
|
cmp-less <depth-state> set-gpu-state
|
||||||
[ collada>> vertex-arrays>> ]
|
[ collada>> vertex-arrays>> ]
|
||||||
[ collada>> index-vectors>> ]
|
[ collada>> index-vectors>> ]
|
||||||
|
@ -200,10 +203,7 @@ M: collada-world wasd-far-plane drop 1024.0 ;
|
||||||
GAME: collada-game {
|
GAME: collada-game {
|
||||||
{ world-class collada-world }
|
{ world-class collada-world }
|
||||||
{ title "Collada Viewer" }
|
{ title "Collada Viewer" }
|
||||||
{ pixel-format-attributes {
|
{ pixel-format-attributes { windowed double-buffered } }
|
||||||
windowed
|
|
||||||
double-buffered
|
|
||||||
} }
|
|
||||||
{ grab-input? t }
|
{ grab-input? t }
|
||||||
{ use-game-input? t }
|
{ use-game-input? t }
|
||||||
{ pref-dim { 1024 768 } }
|
{ pref-dim { 1024 768 } }
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: help.markup help.crossref help.stylesheet help.topics help.syntax
|
USING: help.markup help.crossref help.stylesheet help.topics help.syntax
|
||||||
definitions io prettyprint summary arrays math sequences vocabs strings
|
definitions io prettyprint summary arrays math sequences vocabs strings
|
||||||
see xml.data hashtables assocs ;
|
see xml.data hashtables assocs game.models.collada.private game.models.util ;
|
||||||
IN: game.models.collada
|
IN: game.models.collada
|
||||||
|
|
||||||
ABOUT: "game.models.collada"
|
ABOUT: "game.models.collada"
|
||||||
|
@ -10,9 +10,6 @@ ABOUT: "game.models.collada"
|
||||||
ARTICLE: "game.models.collada" "Conversion of COLLADA assets"
|
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" } "." ;
|
"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
|
HELP: source
|
||||||
{ $class-description "Tuple of a vertex attribute semantic, offset in triangle index buffer and float data for a single vertex attribute." } ;
|
{ $class-description "Tuple of a vertex attribute semantic, offset in triangle index buffer and float data for a single vertex attribute." } ;
|
||||||
|
|
||||||
|
@ -22,13 +19,6 @@ HELP: up-axis
|
||||||
HELP: unit-ratio
|
HELP: unit-ratio
|
||||||
{ $description "Scaling ratio for the coordinates of the tags being read." } ;
|
{ $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 )
|
HELP: string>numbers ( string -- number-seq )
|
||||||
{ $values { "string" string } { "number-seq" sequence } }
|
{ $values { "string" string } { "number-seq" sequence } }
|
||||||
{ $description "Splits a string on whitespace and converts the elements to a number sequence." } ;
|
{ $description "Splits a string on whitespace and converts the elements to a number sequence." } ;
|
||||||
|
@ -77,10 +67,6 @@ HELP: largest-offset+1
|
||||||
{ $values { "source-seq" sequence } { "largest-offset+1" number } }
|
{ $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 } "." } ;
|
{ $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
|
HELP: pack-attributes
|
||||||
{ $values { "source-indices" sequence } { "sources" sequence } { "attributes" sequence } }
|
{ $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." } ;
|
{ $description "Packs the attributes for a single vertex into a sequence from a set of source data streams." } ;
|
||||||
|
|
|
@ -5,62 +5,25 @@ locals math math.parser sequences sequences.deep
|
||||||
specialized-arrays.instances.alien.c-types.float
|
specialized-arrays.instances.alien.c-types.float
|
||||||
specialized-arrays.instances.alien.c-types.uint splitting xml
|
specialized-arrays.instances.alien.c-types.uint splitting xml
|
||||||
xml.data xml.traversal math.order
|
xml.data xml.traversal math.order
|
||||||
namespaces combinators images gpu.shaders io make ;
|
namespaces combinators images gpu.shaders io make
|
||||||
|
game.models.util io.encodings.ascii game.models.loader ;
|
||||||
IN: game.models.collada
|
IN: game.models.collada
|
||||||
|
|
||||||
TUPLE: model attribute-buffer index-buffer vertex-format ;
|
SINGLETON: collada-models
|
||||||
TUPLE: source semantic offset data ;
|
"dae" ascii collada-models register-models-class
|
||||||
|
|
||||||
SYMBOLS: up-axis unit-ratio ;
|
|
||||||
|
|
||||||
ERROR: missing-attr tag attr ;
|
ERROR: missing-attr tag attr ;
|
||||||
ERROR: missing-child tag child-name ;
|
ERROR: missing-child tag child-name ;
|
||||||
|
|
||||||
TUPLE: indexed-seq dseq iseq rassoc ;
|
<PRIVATE
|
||||||
INSTANCE: indexed-seq sequence
|
TUPLE: source semantic offset data ;
|
||||||
|
SYMBOLS: up-axis unit-ratio ;
|
||||||
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 )
|
: string>numbers ( string -- number-seq )
|
||||||
" \t\n" split [ "" = ] trim [ string>number ] map ;
|
" \t\n" split harvest [ string>number ] map ;
|
||||||
|
|
||||||
: string>floats ( string -- float-seq )
|
: string>floats ( string -- float-seq )
|
||||||
" \t\n" split [ "" = ] trim [ string>float ] map ;
|
" \t\n" split harvest [ string>float ] map ;
|
||||||
|
|
||||||
: x/ ( tag child-name -- child-tag )
|
: x/ ( tag child-name -- child-tag )
|
||||||
[ tag-named ]
|
[ tag-named ]
|
||||||
|
@ -78,7 +41,6 @@ M: indexed-seq new-resizable
|
||||||
[ tags-named ] dip map ; inline
|
[ tags-named ] dip map ; inline
|
||||||
|
|
||||||
SINGLETONS: x-up y-up z-up ;
|
SINGLETONS: x-up y-up z-up ;
|
||||||
|
|
||||||
UNION: rh-up x-up y-up z-up ;
|
UNION: rh-up x-up y-up z-up ;
|
||||||
|
|
||||||
GENERIC: >y-up-axis! ( seq from-axis -- seq )
|
GENERIC: >y-up-axis! ( seq from-axis -- seq )
|
||||||
|
@ -159,19 +121,10 @@ M: z-up >y-up-axis!
|
||||||
: largest-offset+1 ( source-seq -- largest-offset+1 )
|
: largest-offset+1 ( source-seq -- largest-offset+1 )
|
||||||
[ offset>> ] [ max ] map-reduce 1 + ;
|
[ offset>> ] [ max ] map-reduce 1 + ;
|
||||||
|
|
||||||
: <model> ( attribute-buffer index-buffer sources -- model )
|
VERTEX-FORMAT: collada-vertex-format
|
||||||
[ flatten >float-array ]
|
{ "POSITION" float-components 3 f }
|
||||||
[ flatten >uint-array ]
|
{ "NORMAL" float-components 3 f }
|
||||||
[
|
{ "TEXCOORD" float-components 2 f } ;
|
||||||
[
|
|
||||||
{
|
|
||||||
[ semantic>> ]
|
|
||||||
[ drop float-components ]
|
|
||||||
[ data>> first length ]
|
|
||||||
[ drop f ]
|
|
||||||
} cleave vertex-attribute boa
|
|
||||||
] map
|
|
||||||
] tri* model boa ;
|
|
||||||
|
|
||||||
: pack-attributes ( source-indices sources -- attributes )
|
: pack-attributes ( source-indices sources -- attributes )
|
||||||
[
|
[
|
||||||
|
@ -184,9 +137,7 @@ M: z-up >y-up-axis!
|
||||||
] V{ } make flatten ;
|
] V{ } make flatten ;
|
||||||
|
|
||||||
:: soa>aos ( triangles-indices sources -- attribute-buffer index-buffer )
|
:: soa>aos ( triangles-indices sources -- attribute-buffer index-buffer )
|
||||||
[ triangles-indices [ [
|
[ triangles-indices [ [ sources pack-attributes , ] each ] each ]
|
||||||
sources pack-attributes ,
|
|
||||||
] each ] each ]
|
|
||||||
V{ } V{ } H{ } <indexed-seq> make [ dseq>> ] [ iseq>> ] bi ;
|
V{ } V{ } H{ } <indexed-seq> make [ dseq>> ] [ iseq>> ] bi ;
|
||||||
|
|
||||||
: triangles>model ( sources vertices triangles-tag -- model )
|
: triangles>model ( sources vertices triangles-tag -- model )
|
||||||
|
@ -198,7 +149,10 @@ M: z-up >y-up-axis!
|
||||||
group-indices
|
group-indices
|
||||||
]
|
]
|
||||||
[
|
[
|
||||||
[ soa>aos ] keep <model>
|
soa>aos
|
||||||
|
[ flatten >float-array ]
|
||||||
|
[ flatten >uint-array ]
|
||||||
|
bi* collada-vertex-format model boa
|
||||||
] bi ;
|
] bi ;
|
||||||
|
|
||||||
: mesh>triangles ( sources vertices mesh-tag -- models )
|
: mesh>triangles ( sources vertices mesh-tag -- models )
|
||||||
|
@ -206,9 +160,13 @@ M: z-up >y-up-axis!
|
||||||
|
|
||||||
: mesh>models ( mesh-tag -- models )
|
: mesh>models ( mesh-tag -- models )
|
||||||
[
|
[
|
||||||
{ { up-axis y-up } { unit-ratio 0.5 } } [
|
{ { up-axis y-up } { unit-ratio 1 } } [
|
||||||
mesh>sources
|
mesh>sources
|
||||||
] bind
|
] bind
|
||||||
]
|
]
|
||||||
[ mesh>vertices ]
|
[ mesh>vertices ]
|
||||||
[ mesh>triangles ] tri ;
|
[ mesh>triangles ] tri ;
|
||||||
|
PRIVATE>
|
||||||
|
|
||||||
|
M: collada-models stream>models
|
||||||
|
drop read-xml "mesh" deep-tags-named [ mesh>models ] map flatten ;
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
! Copyright (C) 2010 Your name.
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
|
USING: accessors assocs byte-arrays combinators game.models
|
||||||
|
io.encodings.ascii io.files io.pathnames io.streams.byte-array
|
||||||
|
kernel namespaces sequences splitting
|
||||||
|
strings unicode.case arrays io.encodings ;
|
||||||
|
IN: game.models.loader
|
||||||
|
|
||||||
|
ERROR: unknown-models-extension extension ;
|
||||||
|
|
||||||
|
<PRIVATE
|
||||||
|
|
||||||
|
SYMBOL: types
|
||||||
|
types [ H{ } clone ] initialize
|
||||||
|
|
||||||
|
: models-class ( path -- class )
|
||||||
|
file-extension >lower types get ?at
|
||||||
|
[ unknown-models-extension ] unless second ;
|
||||||
|
|
||||||
|
: models-encoding ( path -- encoding )
|
||||||
|
file-extension >lower types get ?at
|
||||||
|
[ unknown-models-extension ] unless first ;
|
||||||
|
|
||||||
|
: open-models-file ( path encoding -- stream )
|
||||||
|
<file-reader> ;
|
||||||
|
|
||||||
|
PRIVATE>
|
||||||
|
|
||||||
|
GENERIC# load-models* 2 ( obj encoding class -- models )
|
||||||
|
|
||||||
|
GENERIC: stream>models ( stream class -- models )
|
||||||
|
|
||||||
|
: register-models-class ( extension encoding class -- )
|
||||||
|
2array swap types get set-at ;
|
||||||
|
|
||||||
|
: load-models ( path -- models )
|
||||||
|
[ dup models-encoding open-models-file ] [ models-encoding ] [ models-class ] tri load-models* ;
|
||||||
|
|
||||||
|
M: byte-array load-models*
|
||||||
|
[ <byte-reader> ] dip stream>models ;
|
||||||
|
|
||||||
|
M: decoder load-models* nip stream>models ;
|
||||||
|
|
||||||
|
M: string load-models* [ open-models-file ] dip stream>models ;
|
||||||
|
|
||||||
|
M: pathname load-models* [ open-models-file ] dip stream>models ;
|
|
@ -0,0 +1,9 @@
|
||||||
|
! 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 ;
|
||||||
|
IN: game.models
|
||||||
|
|
||||||
|
HELP: model
|
||||||
|
{ $class-description "Tuple of a packed attribute buffer, index buffer and vertex format suitable for a single OpenGL draw call." } ;
|
|
@ -0,0 +1,7 @@
|
||||||
|
! Copyright (C) 2010 Your name.
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
|
USING: ;
|
||||||
|
IN: game.models
|
||||||
|
|
||||||
|
TUPLE: model attribute-buffer index-buffer vertex-format ;
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
! Copyright (C) 2010 Your name.
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
|
USING: io io.encodings.ascii math.parser sequences splitting kernel
|
||||||
|
assocs io.files combinators math.order math namespaces
|
||||||
|
arrays sequences.deep accessors
|
||||||
|
specialized-arrays.instances.alien.c-types.float
|
||||||
|
specialized-arrays.instances.alien.c-types.uint
|
||||||
|
game.models.util gpu.shaders images game.models.loader ;
|
||||||
|
IN: game.models.obj
|
||||||
|
|
||||||
|
SINGLETON: obj-models
|
||||||
|
"obj" ascii obj-models register-models-class
|
||||||
|
|
||||||
|
<PRIVATE
|
||||||
|
SYMBOLS: v vt vn i ;
|
||||||
|
|
||||||
|
VERTEX-FORMAT: obj-vertex-format
|
||||||
|
{ "POSITION" float-components 3 f }
|
||||||
|
{ "TEXCOORD" float-components 2 f }
|
||||||
|
{ "NORMAL" float-components 3 f } ;
|
||||||
|
|
||||||
|
: string>floats ( x -- y )
|
||||||
|
[ string>float ] map ;
|
||||||
|
|
||||||
|
: string>faces ( x -- y )
|
||||||
|
[ "/" split [ string>number ] map ] map ;
|
||||||
|
|
||||||
|
: 3face>aos ( x -- y )
|
||||||
|
dup length {
|
||||||
|
{ 3
|
||||||
|
[
|
||||||
|
first3
|
||||||
|
[ 1 - v get nth ]
|
||||||
|
[ 1 - vt get nth ]
|
||||||
|
[ 1 - vn get nth ] tri* 3array flatten
|
||||||
|
] }
|
||||||
|
{ 2
|
||||||
|
[
|
||||||
|
first2
|
||||||
|
[ 1 - v get nth ]
|
||||||
|
[ 1 - vt get nth ] bi* 2array flatten
|
||||||
|
] }
|
||||||
|
} case ;
|
||||||
|
|
||||||
|
|
||||||
|
: 4face>aos ( x -- y z )
|
||||||
|
[ 3 head [ 3face>aos 1array ] map ]
|
||||||
|
[ [ 0 swap nth ] [ 2 swap nth ] [ 3 swap nth ] tri 3array [ 3face>aos 1array ] map ]
|
||||||
|
bi
|
||||||
|
;
|
||||||
|
|
||||||
|
: faces>aos ( x -- y )
|
||||||
|
dup length
|
||||||
|
{
|
||||||
|
{ 3 [ [ 3face>aos 1array ] map 1array ] }
|
||||||
|
{ 4 [ 4face>aos 2array ] }
|
||||||
|
} case ;
|
||||||
|
|
||||||
|
: push* ( x z -- y )
|
||||||
|
[ push ] keep ;
|
||||||
|
|
||||||
|
: line>obj ( line -- )
|
||||||
|
" \t\n" split harvest dup
|
||||||
|
length 1 >
|
||||||
|
[
|
||||||
|
[ rest ] [ first ] bi
|
||||||
|
{
|
||||||
|
{ "#" [ drop ] }
|
||||||
|
{ "v" [ string>floats 3 head v [ push* ] change ] }
|
||||||
|
{ "vt" [ string>floats 2 head vt [ push* ] change ] }
|
||||||
|
{ "vn" [ string>floats 3 head vn [ push* ] change ] }
|
||||||
|
{ "f" [ string>faces faces>aos [ [ i [ push* ] change ] each ] each ] }
|
||||||
|
{ "o" [ drop ] }
|
||||||
|
{ "g" [ drop ] }
|
||||||
|
{ "s" [ drop ] }
|
||||||
|
{ "mtllib" [ drop ] }
|
||||||
|
{ "usemtl" [ drop ] }
|
||||||
|
} case
|
||||||
|
]
|
||||||
|
[ drop ] if ;
|
||||||
|
|
||||||
|
PRIVATE>
|
||||||
|
|
||||||
|
M: obj-models stream>models
|
||||||
|
drop
|
||||||
|
[
|
||||||
|
V{ }
|
||||||
|
[ clone v set ]
|
||||||
|
[ clone vt set ]
|
||||||
|
[ clone vn set ] tri
|
||||||
|
V{ } V{ } H{ } <indexed-seq> i set
|
||||||
|
] H{ } make-assoc
|
||||||
|
[
|
||||||
|
[ line>obj ] each-stream-line i get
|
||||||
|
] bind
|
||||||
|
[ dseq>> flatten >float-array ]
|
||||||
|
[ iseq>> flatten >uint-array ] bi obj-vertex-format model boa 1array ;
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
! 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.util
|
||||||
|
|
||||||
|
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." } ;
|
|
@ -0,0 +1,14 @@
|
||||||
|
USING: game.models.util tools.test make accessors kernel ;
|
||||||
|
IN: game.models.util.tests
|
||||||
|
|
||||||
|
[ V{ 1 2 3 4 } ] [
|
||||||
|
[ 1 , 1 , 2 , 3 , 3 , 4 , ]
|
||||||
|
V{ } V{ } H{ } <indexed-seq> make
|
||||||
|
dseq>>
|
||||||
|
] unit-test
|
||||||
|
|
||||||
|
[ V{ 0 0 1 2 2 3 } ] [
|
||||||
|
[ 1 , 1 , 2 , 3 , 3 , 4 , ]
|
||||||
|
V{ } V{ } H{ } <indexed-seq> make
|
||||||
|
iseq>>
|
||||||
|
] unit-test
|
|
@ -0,0 +1,46 @@
|
||||||
|
! Copyright (C) 2010 Your name.
|
||||||
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
|
USING: sequences accessors kernel locals assocs ;
|
||||||
|
IN: game.models.util
|
||||||
|
|
||||||
|
TUPLE: model attribute-buffer index-buffer vertex-format ;
|
||||||
|
|
||||||
|
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 ;
|
||||||
|
|
Loading…
Reference in New Issue