gltf2.monkey2 16 KB

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