gltf2.monkey2 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713
  1. Namespace mojo3d.gltf2
  2. Const GLTF_BYTE:=5120
  3. Const GLTF_UNSIGNED_BYTE:=5121
  4. Const GLTF_SHORT:=5122
  5. Const GLTF_UNSIGNED_SHORT:=5123
  6. Const GLTF_INT:=5124
  7. Const GLTF_UNSIGNED_INT:=5125
  8. Const GLTF_FLOAT:=5126
  9. #rem monkeydoc @hidden
  10. #end
  11. Class Gltf2Buffer
  12. Field uri:String
  13. Field byteLength:Int
  14. End
  15. #rem monkeydoc @hidden
  16. #end
  17. Class Gltf2BufferView
  18. Field buffer:Gltf2Buffer
  19. Field byteOffset:Int
  20. Field byteLength:Int
  21. Field byteStride:Int
  22. Field target:Int
  23. End
  24. #rem monkeydoc @hidden
  25. #end
  26. Class Gltf2Accessor
  27. Field bufferView:Gltf2BufferView
  28. Field byteOffset:Int
  29. Field componentType:Int
  30. Field count:Int
  31. Field type:String
  32. Field sizeInBytes:Int
  33. Field numberOfComponents:Int
  34. End
  35. #rem monkeydoc @hidden
  36. #end
  37. Class Gltf2Image
  38. Field uri:String
  39. Field bufferView:Gltf2BufferView
  40. Field mimeType:String
  41. End
  42. #rem monkeydoc @hidden
  43. #end
  44. Class Gltf2Sampler
  45. Field magFilter:Int
  46. Field minFilter:Int
  47. Field wrapS:Int
  48. Field wrapT:Int
  49. End
  50. #rem monkeydoc @hidden
  51. #end
  52. Class Gltf2Texture
  53. Field sampler:Gltf2Sampler
  54. Field source:Gltf2Image
  55. End
  56. #rem monkeydoc @hidden
  57. #end
  58. Class Gltf2Material
  59. Field name:String
  60. Field baseColorTexture:Gltf2Texture
  61. Field baseColorFactor:Vec4f=New Vec4f(1)
  62. Field metallicRoughnessTexture:Gltf2Texture
  63. Field metallicFactor:Float=1
  64. Field roughnessFactor:Float=1
  65. Field emissiveTexture:Gltf2Texture
  66. Field emissiveFactor:Vec3f=New Vec3f(0)
  67. Field occlusionTexture:Gltf2Texture
  68. Field normalTexture:Gltf2Texture
  69. Field alphaMode:String
  70. End
  71. #rem monkeydoc @hidden
  72. #end
  73. Class Gltf2Primitive
  74. Field POSITION:Gltf2Accessor
  75. Field NORMAL:Gltf2Accessor
  76. Field TANGENT:Gltf2Accessor
  77. Field COLOR_0:Gltf2Accessor
  78. Field TEXCOORD_0:Gltf2Accessor
  79. Field JOINTS_0:Gltf2Accessor
  80. Field WEIGHTS_0:Gltf2Accessor
  81. Field indices:Gltf2Accessor
  82. Field material:Gltf2Material
  83. Field mode:Int
  84. End
  85. #rem monkeydoc @hidden
  86. #end
  87. Class Gltf2Mesh
  88. Field name:String
  89. Field primitives:Gltf2Primitive[]
  90. End
  91. #rem monkeydoc @hidden
  92. #end
  93. Class Gltf2Node
  94. Field name:String
  95. Field parent:Gltf2Node
  96. Field children:Gltf2Node[]
  97. Field translation:Vec3f=New Vec3f(0)
  98. Field rotation:Quatf=New Quatf
  99. Field scale:Vec3f=New Vec3f(1)
  100. Field matrix:Mat4f=New Mat4f
  101. Field mesh:Gltf2Mesh
  102. Field hasMatrix:Bool
  103. End
  104. #rem monkeydoc @hidden
  105. #end
  106. Class Gltf2Animation
  107. Field name:String
  108. Field channels:Gltf2AnimationChannel[]
  109. End
  110. #rem monkeydoc @hidden
  111. #end
  112. Class Gltf2AnimationChannel
  113. Field sampler:Gltf2AnimationSampler 'for shared samplers (nice).
  114. Field targetNode:Gltf2Node
  115. Field targetPath:String
  116. End
  117. #rem monkeydoc @hidden
  118. #end
  119. Class Gltf2AnimationSampler
  120. Field input:Gltf2Accessor 'time
  121. Field output:Gltf2Accessor 'post/rot etc
  122. Field interpolation:String
  123. End
  124. #rem monkeydoc @hidden
  125. #end
  126. Class Gltf2Skin
  127. Field inverseBindMatrices:Gltf2Accessor 'array of mat4fs
  128. Field joints:Gltf2Node[]
  129. Field skeleton:Gltf2Node
  130. End
  131. #rem monkeydoc @hidden
  132. #end
  133. Class Gltf2Scene
  134. Field name:String
  135. Field nodes:Gltf2Node[]
  136. End
  137. #rem monkeydoc @hidden
  138. #end
  139. Class Gltf2Asset
  140. Field buffers:Gltf2Buffer[]
  141. Field bufferViews:Gltf2BufferView[]
  142. Field accessors:Gltf2Accessor[]
  143. Field images:Gltf2Image[]
  144. Field samplers:Gltf2Sampler[]
  145. Field textures:Gltf2Texture[]
  146. Field materials:Gltf2Material[]
  147. Field meshes:Gltf2Mesh[]
  148. Field nodes:Gltf2Node[]
  149. Field animations:Gltf2Animation[]
  150. Field skins:Gltf2Skin[]
  151. Field scenes:Gltf2Scene[]
  152. Field scene:Gltf2Scene
  153. Function Load:Gltf2Asset( path:String )
  154. Local root:=JsonObject.Load( path )
  155. If Not root Return Null
  156. Local asset:=New Gltf2Asset( root )
  157. If Not asset.LoadAsset() Return Null
  158. Return asset
  159. End
  160. Function Parse:Gltf2Asset( json:String )
  161. Local root:=JsonObject.Parse( json )
  162. If Not root Return Null
  163. Local asset:=New Gltf2Asset( root )
  164. If Not asset.LoadAsset() Return Null
  165. Return asset
  166. End
  167. Private
  168. Field root:JsonObject
  169. Method New( root:JsonObject )
  170. Self.root=root
  171. End
  172. Method GetQuatf:Quatf( jval:JsonArray )
  173. Return New Quatf( jval.GetNumber(0),jval.GetNumber(1),jval.GetNumber(2),jval.GetNumber(3) )
  174. End
  175. Method GetVec4f:Vec4f( jval:JsonArray )
  176. Return New Vec4f( jval.GetNumber(0),jval.GetNumber(1),jval.GetNumber(2),jval.GetNumber(3) )
  177. End
  178. Method GetVec3f:Vec3f( jval:JsonArray )
  179. Return New Vec3f( jval.GetNumber(0),jval.GetNumber(1),jval.GetNumber(2) )
  180. End
  181. Method GetMat4f:Mat4f( jval:JsonArray )
  182. Return New Mat4f(
  183. New Vec4f( jval.GetNumber(0), jval.GetNumber(1), jval.GetNumber(2), jval.GetNumber(3) ),
  184. New Vec4f( jval.GetNumber(4), jval.GetNumber(5), jval.GetNumber(6), jval.GetNumber(7) ),
  185. New Vec4f( jval.GetNumber(8), jval.GetNumber(9), jval.GetNumber(10), jval.GetNumber(11) ),
  186. New Vec4f( jval.GetNumber(12), jval.GetNumber(13), jval.GetNumber(14), jval.GetNumber(15) ) )
  187. End
  188. Method LoadBuffers:Bool()
  189. Local jbuffers:=root.GetArray( "buffers" )
  190. If Not jbuffers Return True
  191. buffers=New Gltf2Buffer[jbuffers.Length]
  192. For Local i:=0 Until buffers.Length
  193. Local jbuffer:=jbuffers.GetObject( i )
  194. Local buffer:=New Gltf2Buffer
  195. buffers[i]=buffer
  196. buffer.byteLength=jbuffer.GetNumber( "byteLength" )
  197. buffer.uri=jbuffer.GetString( "uri" )
  198. Next
  199. Return True
  200. End
  201. Method LoadBufferViews:Bool()
  202. Local jbufferViews:=root.GetArray( "bufferViews" )
  203. If Not jbufferViews Return True
  204. bufferViews=New Gltf2BufferView[jbufferViews.Length]
  205. For Local i:=0 Until bufferViews.Length
  206. Local jbufferView:=jbufferViews.GetObject( i )
  207. Local bufferView:=New Gltf2BufferView
  208. bufferViews[i]=bufferView
  209. bufferView.buffer=buffers[jbufferView.GetNumber( "buffer" )]
  210. bufferView.byteLength=jbufferView.GetNumber( "byteLength" )
  211. bufferView.byteOffset=jbufferView.GetNumber( "byteOffset" )
  212. bufferView.byteStride=jbufferView.GetNumber( "byteStride" )
  213. bufferView.target=jbufferView.GetNumber( "target" )
  214. Next
  215. Return True
  216. End
  217. Method LoadAccessors:Bool()
  218. Local jaccessors:=root.GetArray( "accessors" )
  219. If Not jaccessors Return True
  220. accessors=New Gltf2Accessor[ jaccessors.Length ]
  221. For Local i:=0 Until accessors.Length
  222. Local jaccessor:=jaccessors.GetObject( i )
  223. Local accessor:=New Gltf2Accessor
  224. accessors[i]=accessor
  225. accessor.bufferView=bufferViews[jaccessor.GetNumber( "bufferView" )]
  226. accessor.byteOffset=jaccessor.GetNumber( "byteOffset" )
  227. accessor.componentType=jaccessor.GetNumber( "componentType" )
  228. accessor.count=jaccessor.GetNumber( "count" )
  229. accessor.type=jaccessor.GetString( "type" )
  230. Next
  231. Return True
  232. End
  233. Method LoadImages:Bool()
  234. Local jimages:=root.GetArray( "images" )
  235. If Not jimages Return True
  236. images=New Gltf2Image[jimages.Length]
  237. For Local i:=0 Until images.Length
  238. Local jimage:=jimages.GetObject( i )
  239. Local image:=New Gltf2Image
  240. images[i]=image
  241. If jimage.Contains( "uri" )
  242. image.uri=jimage.GetString( "uri" )
  243. Else If jimage.Contains( "bufferView" )
  244. image.bufferView=bufferViews[ jimage.GetNumber( "bufferView" ) ]
  245. image.mimeType=jimage.GetString( "mimeType" )
  246. Endif
  247. Next
  248. Return True
  249. End
  250. Method LoadSamplers:Bool()
  251. Local jsamplers:=root.GetArray( "samplers" )
  252. If Not jsamplers Return True
  253. samplers=New Gltf2Sampler[jsamplers.Length]
  254. For Local i:=0 Until samplers.Length
  255. Local jsampler:=jsamplers.GetObject( i )
  256. Local sampler:=New Gltf2Sampler
  257. samplers[i]=sampler
  258. sampler.magFilter=jsampler.GetNumber( "magFilter" )
  259. sampler.minFilter=jsampler.GetNumber( "minFilter" )
  260. sampler.wrapS=jsampler.GetNumber( "wrapS" )
  261. sampler.wrapT=jsampler.GetNumber( "wrapT" )
  262. Next
  263. Return True
  264. End
  265. Method LoadTextures:Bool()
  266. Local jtextures:=root.GetArray( "textures" )
  267. If Not jtextures Return True
  268. textures=New Gltf2Texture[jtextures.Length]
  269. For Local i:=0 Until textures.Length
  270. Local jtexture:=jtextures.GetObject( i )
  271. Local texture:=New Gltf2Texture
  272. textures[i]=texture
  273. If Not jtexture.Contains( "source" ) Return False
  274. texture.source=images[jtexture.GetNumber( "source" )]
  275. If jtexture.Contains( "sampler" )
  276. texture.sampler=samplers[jtexture.GetNumber( "sampler" ) ]
  277. Endif
  278. Next
  279. Return True
  280. End
  281. Method LoadMaterials:Bool()
  282. Local jmaterials:=root.GetArray( "materials" )
  283. If Not jmaterials Return True
  284. materials=New Gltf2Material[jmaterials.Length]
  285. For Local i:=0 Until materials.Length
  286. Local jmaterial:=jmaterials.GetObject( i )
  287. Local material:=New Gltf2Material
  288. materials[i]=material
  289. material.name=jmaterial.GetString( "name" )
  290. Local jpbr:=jmaterial.GetObject( "pbrMetallicRoughness" )
  291. If jpbr
  292. Local jobj:=jpbr.GetObject( "baseColorTexture" )
  293. If jobj
  294. material.baseColorTexture=textures[jobj.GetNumber( "index" )]
  295. Endif
  296. Local jarr:=jpbr.GetArray( "baseColorFactor" )
  297. If jarr
  298. material.baseColorFactor=GetVec4f( jarr )
  299. Endif
  300. jobj=jpbr.GetObject( "metallicRoughnessTexture" )
  301. If jobj
  302. material.metallicRoughnessTexture=textures[jobj.GetNumber( "index" )]
  303. Endif
  304. If jpbr.Contains( "metallicFactor" )
  305. material.metallicFactor=jpbr.GetNumber( "metallicFactor" )
  306. Endif
  307. If jpbr.Contains( "roughnessFactor" )
  308. material.roughnessFactor=jpbr.GetNumber( "roughnessFactor" )
  309. Endif
  310. End
  311. Local jobj:=jmaterial.GetObject( "emissiveTexture" )
  312. If jobj
  313. material.emissiveTexture=textures[jobj.GetNumber( "index" )]
  314. Endif
  315. Local jarr:=jmaterial.GetArray( "emissiveFactor" )
  316. If jarr
  317. material.emissiveFactor=GetVec3f( jarr )
  318. Endif
  319. jobj=jmaterial.GetObject( "occlusionTexture" )
  320. If jobj
  321. material.occlusionTexture=textures[jobj.GetNumber( "index" )]
  322. Endif
  323. jobj=jmaterial.GetObject( "normalTexture" )
  324. If jobj
  325. material.normalTexture=textures[jobj.GetNumber( "index" )]
  326. Endif
  327. material.alphaMode=jmaterial.GetString( "alphaMode" )
  328. Next
  329. Return True
  330. End
  331. Method LoadMeshes:Bool()
  332. Local jmeshes:=root.GetArray( "meshes" )
  333. If Not jmeshes Return True
  334. meshes=New Gltf2Mesh[jmeshes.Length]
  335. For Local i:=0 Until meshes.Length
  336. Local mesh:=New Gltf2Mesh
  337. meshes[i]=mesh
  338. Local jmesh:=jmeshes.GetObject( i )
  339. mesh.name=jmesh.GetString( "name" )
  340. Local jprims:=jmesh.GetArray( "primitives" )
  341. mesh.primitives=New Gltf2Primitive[jprims.Length]
  342. For Local j:=0 Until jprims.Length
  343. Local prim:=New Gltf2Primitive
  344. mesh.primitives[j]=prim
  345. Local jprim:=jprims.GetObject( j )
  346. Local jattribs:=jprim.GetObject( "attributes" )
  347. If jattribs.Contains( "POSITION" )
  348. prim.POSITION=accessors[jattribs.GetNumber( "POSITION" )]
  349. Endif
  350. If jattribs.Contains( "NORMAL" )
  351. prim.NORMAL=accessors[jattribs.GetNumber( "NORMAL" )]
  352. Endif
  353. If jattribs.Contains( "TANGENT" )
  354. prim.TANGENT=accessors[jattribs.GetNumber( "TANGENT" )]
  355. Endif
  356. If jattribs.Contains( "COLOR_0" )
  357. prim.COLOR_0=accessors[jattribs.GetNumber( "COLOR_0" )]
  358. Endif
  359. If jattribs.Contains( "TEXCOORD_0" )
  360. prim.TEXCOORD_0=accessors[jattribs.GetNumber( "TEXCOORD_0" )]
  361. Endif
  362. If jattribs.Contains( "JOINTS_0" )
  363. prim.JOINTS_0=accessors[jattribs.GetNumber( "JOINTS_0" )]
  364. Endif
  365. If jattribs.Contains( "WEIGHTS_0" )
  366. prim.WEIGHTS_0=accessors[jattribs.GetNumber( "WEIGHTS_0" )]
  367. Endif
  368. If jprim.Contains( "indices" )
  369. prim.indices=accessors[jprim.GetNumber( "indices" )]
  370. Endif
  371. If jprim.Contains( "material" )
  372. prim.material=materials[jprim.GetNumber( "material" )]
  373. Endif
  374. If jprim.Contains( "mode" )
  375. prim.mode=jprim.GetNumber( "mode" )
  376. Else
  377. prim.mode=4
  378. Endif
  379. Next
  380. Next
  381. Return True
  382. End
  383. Method LoadSkins:Bool()
  384. Local jskins:=root.GetArray( "skins" )
  385. If Not jskins Return True
  386. skins=New Gltf2Skin[jskins.Length]
  387. For Local i:=0 Until skins.Length
  388. Local jskin:=jskins.GetObject( i )
  389. Local skin:=New Gltf2Skin
  390. skins[i]=skin
  391. If jskin.Contains( "inverseBindMatrices" )
  392. skin.inverseBindMatrices=accessors[jskin.GetNumber( "inverseBindMatrices" )]
  393. Endif
  394. If jskin.Contains( "skeleton" )
  395. skin.skeleton=nodes[jskin.GetNumber("skeleton")]
  396. Endif
  397. Local jjoints:=jskin.GetArray( "joints" )
  398. skin.joints=New Gltf2Node[jjoints.Length]
  399. For Local i:=0 Until jjoints.Length
  400. skin.joints[i]=nodes[jjoints.GetNumber(i)]
  401. Next
  402. Next
  403. Return True
  404. End
  405. Method LoadAnimations:Bool()
  406. Local janimations:=root.GetArray( "animations" )
  407. If Not janimations Return True
  408. animations=New Gltf2Animation[ janimations.Length ]
  409. For Local i:=0 Until animations.Length
  410. Local animation:=New Gltf2Animation
  411. animations[i]=animation
  412. Local janimation:=janimations.GetObject( i )
  413. animation.name=janimation.GetString( "name" )
  414. Local jsamplers:=janimation.GetArray( "samplers" )
  415. Local samplers:=New Gltf2AnimationSampler[ jsamplers.Length ]
  416. For Local i:=0 Until samplers.Length
  417. Local sampler:=New Gltf2AnimationSampler
  418. samplers[i]=sampler
  419. Local jsampler:=jsamplers.GetObject( i )
  420. sampler.input=accessors[jsampler.GetNumber( "input" )]
  421. sampler.output=accessors[jsampler.GetNumber( "output" )]
  422. sampler.interpolation=jsampler.GetString( "interpolation" )
  423. Next
  424. Local jchannels:=janimation.GetArray( "channels" )
  425. animation.channels=New Gltf2AnimationChannel[ jchannels.Length ]
  426. For Local i:=0 Until animation.channels.Length
  427. Local channel:=New Gltf2AnimationChannel
  428. animation.channels[i]=channel
  429. Local jchannel:=jchannels.GetObject( i )
  430. channel.sampler=samplers[jchannel.GetNumber( "sampler" )]
  431. Local jtarget:=jchannel.GetObject( "target" )
  432. channel.targetNode=nodes[jtarget.GetNumber( "node" )]
  433. channel.targetPath=jtarget.GetString( "path" )
  434. Next
  435. Next
  436. Return True
  437. End
  438. Method LoadNodes:Bool()
  439. Local jnodes:=root.GetArray( "nodes" )
  440. If Not jnodes Return True
  441. nodes=New Gltf2Node[ jnodes.Length ]
  442. For Local i:=0 Until nodes.Length
  443. nodes[i]=New Gltf2Node
  444. Next
  445. For Local i:=0 Until jnodes.Length
  446. Local jnode:=jnodes.GetObject( i )
  447. Local node:=nodes[i]
  448. node.name=jnode.GetString( "name" )
  449. Local jchildren:=jnode.GetArray( "children" )
  450. If jchildren
  451. node.children=New Gltf2Node[jchildren.Length]
  452. For Local j:=0 Until jchildren.Length
  453. Local child:=nodes[jchildren.GetNumber( j )]
  454. node.children[j]=child
  455. child.parent=node
  456. Next
  457. Endif
  458. If jnode.Contains( "translation" )
  459. node.translation=GetVec3f( jnode.GetArray( "translation" ) )
  460. Endif
  461. If jnode.Contains( "rotation" )
  462. node.rotation=GetQuatf( jnode.GetArray( "rotation" ) )
  463. Endif
  464. If jnode.Contains( "scale" )
  465. node.scale=GetVec3f( jnode.GetArray( "scale" ) )
  466. node.scale.x=Abs( node.scale.x )
  467. node.scale.y=Abs( node.scale.y )
  468. node.scale.z=Abs( node.scale.z )
  469. Endif
  470. If jnode.Contains( "matrix" )
  471. node.matrix=GetMat4f( jnode.GetArray( "matrix" ) )
  472. Else
  473. node.matrix=Mat4f.Translation( node.translation ) * Mat4f.Rotation( node.rotation ) * Mat4f.Scaling( node.scale )
  474. Endif
  475. If jnode.Contains( "mesh" )
  476. node.mesh=meshes[jnode.GetNumber( "mesh" )]
  477. Endif
  478. Next
  479. Return True
  480. End
  481. Method LoadScenes:Bool()
  482. Local jscenes:=root.GetArray( "scenes" )
  483. If Not jscenes Return True
  484. scenes=New Gltf2Scene[jscenes.Length]
  485. For Local i:=0 Until jscenes.Length
  486. Local jscene:=jscenes.GetObject( i )
  487. Local scene:=New Gltf2Scene
  488. scenes[i]=scene
  489. scene.name=jscene.GetString( "name" )
  490. Local jnodes:=jscene.GetArray( "nodes" )
  491. scene.nodes=New Gltf2Node[jnodes.Length]
  492. For Local j:=0 Until jnodes.Length
  493. scene.nodes[j]=nodes[jnodes.GetNumber( j )]
  494. Next
  495. Next
  496. scene=scenes[root.GetNumber( "scene" )]
  497. Return True
  498. End
  499. Method LoadAsset:Bool()
  500. Local asset:=root.GetObject( "asset" )
  501. If Not asset Return False
  502. Local version:=asset.GetString( "version" )
  503. ' Print "Gltf2 version="+version
  504. If Not LoadBuffers() Return False
  505. If Not LoadBufferViews() Return False
  506. If Not LoadAccessors() Return False
  507. If Not LoadImages() Return False
  508. If Not LoadSamplers() Return False
  509. If Not LoadTextures() Return False
  510. If Not LoadMaterials() Return False
  511. If Not LoadMeshes() Return False
  512. If Not LoadNodes() Return False
  513. If Not LoadAnimations() Return False
  514. If Not LoadSkins() Return False
  515. If Not LoadScenes() Return False
  516. Return True
  517. End
  518. End