loader.go 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986
  1. // Copyright 2016 The G3N Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package gltf
  5. import (
  6. "bytes"
  7. "encoding/base64"
  8. "encoding/binary"
  9. "encoding/json"
  10. "fmt"
  11. "image"
  12. "image/draw"
  13. "io"
  14. "io/ioutil"
  15. "os"
  16. "path/filepath"
  17. "strings"
  18. "unsafe"
  19. "github.com/g3n/engine/camera"
  20. "github.com/g3n/engine/core"
  21. "github.com/g3n/engine/geometry"
  22. "github.com/g3n/engine/gls"
  23. "github.com/g3n/engine/graphic"
  24. "github.com/g3n/engine/material"
  25. "github.com/g3n/engine/math32"
  26. "github.com/g3n/engine/texture"
  27. "github.com/g3n/engine/animation"
  28. )
  29. // ParseJSON parses the glTF data from the specified JSON file
  30. // and returns a pointer to the parsed structure.
  31. func ParseJSON(filename string) (*GLTF, error) {
  32. // Open file
  33. f, err := os.Open(filename)
  34. if err != nil {
  35. return nil, err
  36. }
  37. // Extract path from file
  38. path := filepath.Dir(filename)
  39. defer f.Close()
  40. return ParseJSONReader(f, path)
  41. }
  42. // ParseJSONReader parses the glTF JSON data from the specified reader
  43. // and returns a pointer to the parsed structure
  44. func ParseJSONReader(r io.Reader, path string) (*GLTF, error) {
  45. g := new(GLTF)
  46. g.path = path
  47. dec := json.NewDecoder(r)
  48. err := dec.Decode(g)
  49. if err != nil {
  50. return nil, err
  51. }
  52. return g, nil
  53. }
  54. // ParseBin parses the glTF data from the specified binary file
  55. // and returns a pointer to the parsed structure.
  56. func ParseBin(filename string) (*GLTF, error) {
  57. // Open file
  58. f, err := os.Open(filename)
  59. if err != nil {
  60. return nil, err
  61. }
  62. // Extract path from file
  63. path := filepath.Dir(filename)
  64. defer f.Close()
  65. return ParseBinReader(f, path)
  66. }
  67. // ParseBinReader parses the glTF data from the specified binary reader
  68. // and returns a pointer to the parsed structure
  69. func ParseBinReader(r io.Reader, path string) (*GLTF, error) {
  70. // Read header
  71. var header GLBHeader
  72. err := binary.Read(r, binary.LittleEndian, &header)
  73. if err != nil {
  74. return nil, err
  75. }
  76. // Check magic and version
  77. if header.Magic != GLBMagic {
  78. return nil, fmt.Errorf("invalid GLB Magic field")
  79. }
  80. if header.Version < 2 {
  81. return nil, fmt.Errorf("GLB version:%v not supported", header.Version)
  82. }
  83. // Read first chunk (JSON)
  84. buf, err := readChunk(r, GLBJson)
  85. if err != nil {
  86. return nil, err
  87. }
  88. // Parse JSON into gltf object
  89. bb := bytes.NewBuffer(buf)
  90. gltf, err := ParseJSONReader(bb, path)
  91. if err != nil {
  92. return nil, err
  93. }
  94. // Check for and read second chunk (binary, optional)
  95. data, err := readChunk(r, GLBBin)
  96. if err != nil {
  97. return nil, err
  98. }
  99. gltf.data = data
  100. return gltf, nil
  101. }
  102. // readChunk reads a GLB chunk with the specified type and returns the data in a byte array.
  103. func readChunk(r io.Reader, chunkType uint32) ([]byte, error) {
  104. // Read chunk header
  105. var chunk GLBChunk
  106. err := binary.Read(r, binary.LittleEndian, &chunk)
  107. if err != nil {
  108. if err == io.EOF {
  109. return nil, nil
  110. }
  111. return nil, err
  112. }
  113. // Check chunk type
  114. if chunk.Type != chunkType {
  115. return nil, fmt.Errorf("expected GLB chunk type [%v] but found [%v]", chunkType, chunk.Type)
  116. }
  117. // Read chunk data
  118. data := make([]byte, chunk.Length)
  119. err = binary.Read(r, binary.LittleEndian, &data)
  120. if err != nil {
  121. return nil, err
  122. }
  123. return data, nil
  124. }
  125. // NewScene creates a parent Node which contains all nodes contained by
  126. // the specified scene index from the GLTF Scenes array.
  127. func (g *GLTF) NewScene(si int) (core.INode, error) {
  128. log.Debug("Loading Scene %d", si)
  129. // Check if provided scene index is valid
  130. if si < 0 || si >= len(g.Scenes) {
  131. return nil, fmt.Errorf("invalid scene index")
  132. }
  133. s := g.Scenes[si]
  134. scene := core.NewNode()
  135. scene.SetName(s.Name)
  136. for _, ni := range s.Nodes {
  137. child, err := g.NewNode(ni)
  138. if err != nil {
  139. return nil, err
  140. }
  141. scene.Add(child)
  142. }
  143. return scene, nil
  144. }
  145. // NewNode creates and returns a new Node described by the specified index
  146. // in the decoded GLTF Nodes array.
  147. func (g *GLTF) NewNode(i int) (core.INode, error) {
  148. log.Debug("Loading Node %d", i)
  149. var in core.INode
  150. var err error
  151. nodeData := g.Nodes[i]
  152. // Check if the node is a Mesh (triangles, lines, etc...)
  153. if nodeData.Mesh != nil {
  154. in, err = g.NewMesh(*nodeData.Mesh)
  155. if err != nil {
  156. return nil, err
  157. }
  158. // Check if the node is Camera
  159. } else if nodeData.Camera != nil {
  160. in, err = g.NewCamera(*nodeData.Camera)
  161. if err != nil {
  162. return nil, err
  163. }
  164. // Other cases, return empty node
  165. } else {
  166. log.Debug("Empty Node")
  167. in = core.NewNode()
  168. }
  169. // Cache inode in nodeData
  170. g.Nodes[i].node = in
  171. // Get *core.Node from core.INode
  172. node := in.GetNode()
  173. node.SetName(nodeData.Name)
  174. // If defined, set node local transformation matrix
  175. if nodeData.Matrix != nil {
  176. node.SetMatrix((*math32.Matrix4)(nodeData.Matrix))
  177. // Otherwise, check rotation, scale and translation fields
  178. } else {
  179. // Rotation quaternion
  180. if nodeData.Rotation != nil {
  181. node.SetQuaternion(nodeData.Rotation[0], nodeData.Rotation[1], nodeData.Rotation[2], nodeData.Rotation[3])
  182. }
  183. // Scale
  184. if nodeData.Scale != nil {
  185. node.SetScale(nodeData.Scale[0], nodeData.Scale[1], nodeData.Scale[2])
  186. }
  187. // Translation
  188. if nodeData.Translation != nil {
  189. node.SetPosition(nodeData.Translation[0], nodeData.Translation[1], nodeData.Translation[2])
  190. }
  191. }
  192. // Recursively load node children and add them to the parent
  193. for _, ci := range nodeData.Children {
  194. child, err := g.NewNode(ci)
  195. if err != nil {
  196. return nil, err
  197. }
  198. node.Add(child)
  199. }
  200. return in, nil
  201. }
  202. // NewAnimation creates an Animation for the specified
  203. // the animation index from the GLTF Animations array.
  204. func (g *GLTF) NewAnimation(i int) (*animation.Animation, error) {
  205. log.Debug("Loading Animation %d", i)
  206. // Check if provided scene index is valid
  207. if i < 0 || i >= len(g.Animations) {
  208. return nil, fmt.Errorf("invalid animation index")
  209. }
  210. a := g.Animations[i]
  211. anim := animation.NewAnimation()
  212. anim.SetName(a.Name)
  213. for i := 0; i < len(a.Channels); i++ {
  214. chData := a.Channels[i]
  215. target := chData.Target
  216. sampler := a.Samplers[chData.Sampler]
  217. node := g.Nodes[target.Node].node
  218. // TODO Instantiate node if not exists ?
  219. var validTypes []string
  220. var validComponentTypes []int
  221. var ch animation.IChannel
  222. if target.Path == "translation" {
  223. ch = animation.NewPositionChannel(node)
  224. validTypes = []string{VEC3}
  225. validComponentTypes = []int{FLOAT}
  226. } else if target.Path == "rotation" {
  227. ch = animation.NewRotationChannel(node)
  228. validTypes = []string{VEC4}
  229. validComponentTypes = []int{FLOAT, BYTE, UNSIGNED_BYTE, SHORT, UNSIGNED_SHORT}
  230. } else if target.Path == "scale" {
  231. ch = animation.NewScaleChannel(node)
  232. validTypes = []string{VEC3}
  233. validComponentTypes = []int{FLOAT}
  234. } else if target.Path == "weights" {
  235. validTypes = []string{SCALAR}
  236. validComponentTypes = []int{FLOAT, BYTE, UNSIGNED_BYTE, SHORT, UNSIGNED_SHORT}
  237. return nil, fmt.Errorf("morph animation (with 'weights' path) not supported yet")
  238. // TODO
  239. // for _, child := range node.GetNode().Children() {
  240. // gr, ok := child.(graphic.Graphic)
  241. // if ok {
  242. // gr.geom
  243. // }
  244. // }
  245. // ch = animation.NewMorphChannel(TODO)
  246. }
  247. // TODO what if Input and Output accessors are interleaved? probably de-interleave in these 2 cases
  248. keyframes, err := g.loadAccessorF32(sampler.Input, "Input", []string{SCALAR}, []int{FLOAT})
  249. if err != nil {
  250. return nil, err
  251. }
  252. values, err := g.loadAccessorF32(sampler.Output, "Output", validTypes, validComponentTypes)
  253. if err != nil {
  254. return nil, err
  255. }
  256. ch.SetBuffers(keyframes, values)
  257. ch.SetInterpolationType(animation.InterpolationType(sampler.Interpolation))
  258. anim.AddChannel(ch)
  259. }
  260. return anim, nil
  261. }
  262. // NewCamera creates and returns a Camera Node
  263. // from the specified GLTF.Cameras index.
  264. func (g *GLTF) NewCamera(ci int) (core.INode, error) {
  265. log.Debug("Loading Camera %d", ci)
  266. camDesc := g.Cameras[ci]
  267. if camDesc.Type == "perspective" {
  268. desc := camDesc.Perspective
  269. fov := 360 * (desc.Yfov) / 2 * math32.Pi
  270. aspect := float32(2) // TODO how to get the current aspect ratio of the viewport from here ?
  271. if desc.AspectRatio != nil {
  272. aspect = *desc.AspectRatio
  273. }
  274. far := float32(2E6)
  275. if desc.Zfar != nil {
  276. far = *desc.Zfar
  277. }
  278. cam := camera.NewPerspective(fov, aspect, desc.Znear, far)
  279. return cam, nil
  280. }
  281. if camDesc.Type == "orthographic" {
  282. desc := camDesc.Orthographic
  283. cam := camera.NewOrthographic(desc.Xmag/-2, desc.Xmag/2, desc.Ymag/2, desc.Ymag/-2, desc.Znear, desc.Zfar)
  284. return cam, nil
  285. }
  286. return nil, fmt.Errorf("unsupported camera type: %s", camDesc.Type)
  287. }
  288. // NewMesh creates and returns a Graphic Node (graphic.Mesh, graphic.Lines, graphic.Points, etc)
  289. // from the specified GLTF.Meshes index.
  290. func (g *GLTF) NewMesh(mi int) (core.INode, error) {
  291. log.Debug("Loading Mesh %d", mi)
  292. var err error
  293. meshData := g.Meshes[mi]
  294. // Create container node
  295. meshNode := core.NewNode()
  296. for i := 0; i < len(meshData.Primitives); i++ {
  297. // Get primitive information
  298. p := meshData.Primitives[i]
  299. // Indexed Geometry
  300. indices := math32.NewArrayU32(0, 0)
  301. if p.Indices != nil {
  302. pidx, err := g.loadIndices(*p.Indices)
  303. if err != nil {
  304. return nil, err
  305. }
  306. indices = append(indices, pidx...)
  307. } else {
  308. // Non-indexed primitive
  309. // indices array stay empty
  310. }
  311. // Load primitive material
  312. var grMat material.IMaterial
  313. if p.Material != nil {
  314. grMat, err = g.NewMaterial(*p.Material)
  315. if err != nil {
  316. return nil, err
  317. }
  318. } else {
  319. grMat = g.newDefaultMaterial()
  320. }
  321. // Create geometry
  322. geom := geometry.NewGeometry()
  323. // Indices of buffer views
  324. interleavedVBOs := make(map[int]*gls.VBO, 0)
  325. // Load primitive attributes
  326. for name, aci := range p.Attributes {
  327. accessor := g.Accessors[aci]
  328. // Validate that accessor is compatible with attribute
  329. err = g.validateAccessorAttribute(accessor, name)
  330. if err != nil {
  331. return nil, err
  332. }
  333. // Load data and add it to geometry's VBO
  334. if g.isInterleaved(accessor) {
  335. bvIdx := *accessor.BufferView
  336. // Check if we already loaded this buffer view
  337. vbo, ok := interleavedVBOs[bvIdx]
  338. if ok {
  339. // Already created VBO for this buffer view
  340. // Add attribute with correct byteOffset
  341. g.addAttributeToVBO(vbo, name, uint32(*accessor.ByteOffset))
  342. } else {
  343. // Load data and create vbo
  344. buf, err := g.loadBufferView(g.BufferViews[bvIdx])
  345. if err != nil {
  346. return nil, err
  347. }
  348. data := g.bytesToArrayF32(buf, g.BufferViews[bvIdx].ByteLength)
  349. vbo := gls.NewVBO(data)
  350. g.addAttributeToVBO(vbo, name, 0)
  351. // Save reference to VBO keyed by index of the buffer view
  352. interleavedVBOs[bvIdx] = vbo
  353. // Add VBO to geometry
  354. geom.AddVBO(vbo)
  355. }
  356. } else {
  357. buf, err := g.loadAccessorBytes(accessor)
  358. if err != nil {
  359. return nil, err
  360. }
  361. data := g.bytesToArrayF32(buf, accessor.Count*TypeSizes[accessor.Type])
  362. vbo := gls.NewVBO(data)
  363. g.addAttributeToVBO(vbo, name, 0)
  364. // Add VBO to geometry
  365. geom.AddVBO(vbo)
  366. }
  367. }
  368. // Creates Geometry and add attribute VBO
  369. if len(indices) > 0 {
  370. geom.SetIndices(indices)
  371. }
  372. // Default mode is 4 (TRIANGLES)
  373. mode := TRIANGLES
  374. if p.Mode != nil {
  375. mode = *p.Mode
  376. }
  377. // Create Mesh
  378. if mode == TRIANGLES {
  379. primitiveMesh := graphic.NewMesh(geom, nil)
  380. primitiveMesh.AddMaterial(grMat, 0, 0)
  381. meshNode.Add(primitiveMesh)
  382. } else if mode == LINES {
  383. meshNode.Add(graphic.NewLines(geom, grMat))
  384. } else if mode == LINE_STRIP {
  385. meshNode.Add(graphic.NewLineStrip(geom, grMat))
  386. } else if mode == POINTS {
  387. meshNode.Add(graphic.NewPoints(geom, grMat))
  388. } else {
  389. return nil, fmt.Errorf("Unsupported primitive:%v", mode)
  390. }
  391. }
  392. return meshNode, nil
  393. }
  394. // loadIndices loads the indices stored in the specified accessor.
  395. func (g *GLTF) loadIndices(ai int) (math32.ArrayU32, error) {
  396. return g.loadAccessorU32(ai, "indices", []string{SCALAR}, []int{UNSIGNED_BYTE, UNSIGNED_SHORT, UNSIGNED_INT}) // TODO check that it's ELEMENT_ARRAY_BUFFER
  397. }
  398. // addAttributeToVBO adds the appropriate attribute to the provided vbo based on the glTF attribute name.
  399. func (g *GLTF) addAttributeToVBO(vbo *gls.VBO, attribName string, byteOffset uint32) {
  400. if attribName == "POSITION" {
  401. vbo.AddAttribOffset(gls.VertexPosition, byteOffset)
  402. } else if attribName == "NORMAL" {
  403. vbo.AddAttribOffset(gls.VertexNormal, byteOffset)
  404. } else if attribName == "TANGENT" {
  405. vbo.AddAttribOffset(gls.VertexTangent, byteOffset)
  406. } else if attribName == "TEXCOORD_0" {
  407. vbo.AddAttribOffset(gls.VertexTexcoord, byteOffset)
  408. } else if attribName == "COLOR_0" { // TODO glTF spec says COLOR can be VEC3 or VEC4
  409. vbo.AddAttribOffset(gls.VertexColor, byteOffset)
  410. } else if attribName == "JOINTS_0" {
  411. // TODO
  412. } else if attribName == "WEIGHTS_0" {
  413. // TODO
  414. } else {
  415. panic(fmt.Sprintf("Attribute %v is not supported!", attribName))
  416. }
  417. }
  418. // validateAccessorAttribute validates the specified accessor for the given attribute name.
  419. func (g *GLTF) validateAccessorAttribute(ac Accessor, attribName string) error {
  420. parts := strings.Split(attribName, "_")
  421. semantic := parts[0]
  422. usage := "attribute " + attribName
  423. if attribName == "POSITION" {
  424. return g.validateAccessor(ac, usage, []string{VEC3}, []int{FLOAT})
  425. } else if attribName == "NORMAL" {
  426. return g.validateAccessor(ac, usage, []string{VEC3}, []int{FLOAT})
  427. } else if attribName == "TANGENT" {
  428. return g.validateAccessor(ac, usage, []string{VEC4}, []int{FLOAT})
  429. } else if semantic == "TEXCOORD" {
  430. return g.validateAccessor(ac, usage, []string{VEC2}, []int{FLOAT, UNSIGNED_BYTE, UNSIGNED_SHORT})
  431. } else if semantic == "COLOR" {
  432. return g.validateAccessor(ac, usage, []string{VEC3, VEC4}, []int{FLOAT, UNSIGNED_BYTE, UNSIGNED_SHORT})
  433. } else if semantic == "JOINTS" {
  434. return g.validateAccessor(ac, usage, []string{VEC4}, []int{UNSIGNED_BYTE, UNSIGNED_SHORT})
  435. } else if semantic == "WEIGHTS" {
  436. return g.validateAccessor(ac, usage, []string{VEC4}, []int{FLOAT, UNSIGNED_BYTE, UNSIGNED_SHORT})
  437. } else {
  438. return fmt.Errorf("attribute %v is not supported", attribName)
  439. }
  440. }
  441. // validateAccessor validates the specified attribute accessor with the specified allowed types and component types.
  442. func (g *GLTF) validateAccessor(ac Accessor, usage string, validTypes []string, validComponentTypes []int) error {
  443. // Validate accessor type
  444. validType := false
  445. for _, vType := range validTypes {
  446. if ac.Type == vType {
  447. validType = true
  448. break
  449. }
  450. }
  451. if !validType {
  452. return fmt.Errorf("invalid Accessor.Type %v for %s", ac.Type, usage)
  453. }
  454. // Validate accessor component type
  455. validComponentType := false
  456. for _, vComponentType := range validComponentTypes {
  457. if ac.ComponentType == vComponentType {
  458. validComponentType = true
  459. break
  460. }
  461. }
  462. if !validComponentType {
  463. return fmt.Errorf("invalid Accessor.ComponentType %v for %s", ac.ComponentType, usage)
  464. }
  465. return nil
  466. }
  467. // newDefaultMaterial creates and returns the default material.
  468. func (g *GLTF) newDefaultMaterial() material.IMaterial {
  469. return material.NewStandard(&math32.Color{0.5, 0.5, 0.5})
  470. }
  471. // NewMaterial creates and returns a new material based on the material data with the specified index.
  472. func (g *GLTF) NewMaterial(mi int) (material.IMaterial, error) {
  473. log.Debug("Loading Material %d", mi)
  474. matData := g.Materials[mi]
  475. // Check for material extensions
  476. if matData.Extensions != nil {
  477. for ext, v := range matData.Extensions {
  478. if ext == "KHR_materials_common" {
  479. return g.loadMaterialCommon(v)
  480. } else {
  481. return nil, fmt.Errorf("unsupported extension:%s", ext)
  482. }
  483. }
  484. return nil, fmt.Errorf("empty material extensions")
  485. } else {
  486. // Material is normally PBR
  487. return g.loadMaterialPBR(&matData)
  488. }
  489. }
  490. // NewTexture loads the texture specified by its index.
  491. func (g *GLTF) NewTexture(texi int) (*texture.Texture2D, error) {
  492. log.Debug("Loading Texture %d", texi)
  493. // loads texture image
  494. texDesc := g.Textures[texi]
  495. img, err := g.NewImage(texDesc.Source)
  496. if err != nil {
  497. return nil, err
  498. }
  499. tex := texture.NewTexture2DFromRGBA(img)
  500. // Get sampler and apply texture parameters
  501. if texDesc.Sampler != nil {
  502. sampler := g.Samplers[*texDesc.Sampler]
  503. g.applySampler(sampler, tex)
  504. }
  505. return tex, nil
  506. }
  507. // applySamplers applies the specified Sampler to the provided texture.
  508. func (g *GLTF) applySampler(sampler Sampler, tex *texture.Texture2D) {
  509. // Magnification filter
  510. magFilter := gls.LINEAR
  511. if sampler.MagFilter != nil {
  512. magFilter = *sampler.MagFilter
  513. }
  514. tex.SetMagFilter(uint32(magFilter))
  515. // Minification filter
  516. minFilter := gls.LINEAR_MIPMAP_LINEAR
  517. if sampler.MinFilter != nil {
  518. minFilter = *sampler.MinFilter
  519. }
  520. tex.SetMinFilter(uint32(minFilter))
  521. // S coordinate wrapping mode
  522. wrapS := gls.REPEAT
  523. if sampler.WrapS != nil {
  524. wrapS = *sampler.WrapS
  525. }
  526. tex.SetWrapS(uint32(wrapS))
  527. // T coordinate wrapping mode
  528. wrapT := gls.REPEAT
  529. if sampler.WrapT != nil {
  530. wrapT = *sampler.WrapT
  531. }
  532. tex.SetWrapT(uint32(wrapT))
  533. }
  534. // NewImage loads the image specified by the index of GLTF.Images.
  535. // Image can be loaded from binary chunk file or data URI or external file..
  536. func (g *GLTF) NewImage(ii int) (*image.RGBA, error) {
  537. log.Debug("Loading Image %d", ii)
  538. imgDesc := g.Images[ii]
  539. var data []byte
  540. var err error
  541. // If Uri is empty, load image from GLB binary chunk
  542. if imgDesc.Uri == "" {
  543. bvi := imgDesc.BufferView
  544. if bvi == nil {
  545. return nil, fmt.Errorf("image has empty URI and no BufferView")
  546. }
  547. bv := g.BufferViews[*bvi]
  548. offset := 0
  549. if bv.ByteOffset != nil {
  550. offset = *bv.ByteOffset
  551. }
  552. data = g.data[offset : offset+bv.ByteLength]
  553. // Checks if image URI is data URL
  554. } else if isDataURL(imgDesc.Uri) {
  555. data, err = loadDataURL(imgDesc.Uri)
  556. if err != nil {
  557. return nil, err
  558. }
  559. // Load image data from file
  560. } else {
  561. fpath := filepath.Join(g.path, imgDesc.Uri)
  562. f, err := os.Open(fpath)
  563. if err != nil {
  564. return nil, err
  565. }
  566. defer f.Close()
  567. data, err = ioutil.ReadAll(f)
  568. if err != nil {
  569. return nil, err
  570. }
  571. }
  572. // Decodes image data
  573. bb := bytes.NewBuffer(data)
  574. img, _, err := image.Decode(bb)
  575. if err != nil {
  576. return nil, err
  577. }
  578. // Converts image to RGBA format
  579. rgba := image.NewRGBA(img.Bounds())
  580. if rgba.Stride != rgba.Rect.Size().X*4 {
  581. return nil, fmt.Errorf("unsupported stride")
  582. }
  583. draw.Draw(rgba, rgba.Bounds(), img, image.Point{0, 0}, draw.Src)
  584. return rgba, nil
  585. }
  586. // bytesToArrayU32 converts a byte array to ArrayU32.
  587. func (g *GLTF) bytesToArrayU32(data []byte, componentType, count int) (math32.ArrayU32, error) {
  588. // If component is UNSIGNED_INT nothing to do
  589. if componentType == UNSIGNED_INT {
  590. arr := (*[1 << 30]uint32)(unsafe.Pointer(&data[0]))[:count]
  591. return math32.ArrayU32(arr), nil
  592. }
  593. // Converts UNSIGNED_SHORT to UNSIGNED_INT
  594. if componentType == UNSIGNED_SHORT {
  595. out := math32.NewArrayU32(count, count)
  596. for i := 0; i < count; i++ {
  597. out[i] = uint32(data[i*2]) + uint32(data[i*2+1])*256
  598. }
  599. return out, nil
  600. }
  601. // Converts UNSIGNED_BYTE indices to UNSIGNED_INT
  602. if componentType == UNSIGNED_BYTE {
  603. out := math32.NewArrayU32(count, count)
  604. for i := 0; i < count; i++ {
  605. out[i] = uint32(data[i])
  606. }
  607. return out, nil
  608. }
  609. return nil, fmt.Errorf("Unsupported Accessor ComponentType:%v", componentType)
  610. }
  611. // bytesToArrayF32 converts a byte array to ArrayF32.
  612. func (g *GLTF) bytesToArrayF32(data []byte, size int) math32.ArrayF32 {
  613. return (*[1 << 30]float32)(unsafe.Pointer(&data[0]))[:size]
  614. }
  615. // loadAccessorU32 loads data from the specified accessor and performs validation of the Type and ComponentType.
  616. func (g *GLTF) loadAccessorU32(ai int, usage string, validTypes []string, validComponentTypes []int) (math32.ArrayU32, error) {
  617. // Get Accessor for the specified index
  618. ac := g.Accessors[ai]
  619. if ac.BufferView == nil {
  620. return nil, fmt.Errorf("Accessor.BufferView == nil NOT SUPPORTED YET") // TODO
  621. }
  622. // Validate type and component type
  623. err := g.validateAccessor(ac, usage, validTypes, validComponentTypes)
  624. if err != nil {
  625. return nil, err
  626. }
  627. // Load bytes
  628. data, err := g.loadAccessorBytes(ac)
  629. if err != nil {
  630. return nil, err
  631. }
  632. return g.bytesToArrayU32(data, ac.ComponentType, ac.Count)
  633. }
  634. // loadAccessorF32 loads data from the specified accessor and performs validation of the Type and ComponentType.
  635. func (g *GLTF) loadAccessorF32(ai int, usage string, validTypes []string, validComponentTypes []int) (math32.ArrayF32, error) {
  636. // Get Accessor for the specified index
  637. ac := g.Accessors[ai]
  638. if ac.BufferView == nil {
  639. return nil, fmt.Errorf("Accessor.BufferView == nil NOT SUPPORTED")
  640. }
  641. // Validate type and component type
  642. err := g.validateAccessor(ac, usage, validTypes, validComponentTypes)
  643. if err != nil {
  644. return nil, err
  645. }
  646. // Load bytes
  647. data, err := g.loadAccessorBytes(ac)
  648. if err != nil {
  649. return nil, err
  650. }
  651. return g.bytesToArrayF32(data, ac.Count*TypeSizes[ac.Type]), nil
  652. }
  653. // loadAccessorBytes returns the base byte array used by an accessor.
  654. func (g *GLTF) loadAccessorBytes(ac Accessor) ([]byte, error) {
  655. // Get the Accessor's BufferView
  656. if ac.BufferView == nil {
  657. return nil, fmt.Errorf("Accessor has nil BufferView") // TODO
  658. }
  659. bv := g.BufferViews[*ac.BufferView]
  660. // Loads data from associated BufferView
  661. data, err := g.loadBufferView(bv)
  662. if err != nil {
  663. return nil, err
  664. }
  665. // Accessor offset into BufferView
  666. offset := 0
  667. if ac.ByteOffset != nil {
  668. offset = *ac.ByteOffset
  669. }
  670. data = data[offset:]
  671. // Check if interleaved and de-interleave if necessary ? TODO
  672. // Calculate the size in bytes of a complete attribute
  673. itemSize := TypeSizes[ac.Type]
  674. itemBytes := int(gls.FloatSize) * itemSize
  675. // If the BufferView stride is equal to the item size, the buffer is not interleaved
  676. if (bv.ByteStride != nil) && (*bv.ByteStride != itemBytes) {
  677. // BufferView data is interleaved, de-interleave
  678. // TODO
  679. return nil, fmt.Errorf("data is interleaved - not supported for animation yet")
  680. }
  681. return data, nil
  682. }
  683. // isInterleaves returns whether the BufferView used by the provided accessor is interleaved.
  684. func (g *GLTF) isInterleaved(accessor Accessor) bool {
  685. // Get the Accessor's BufferView
  686. if accessor.BufferView == nil {
  687. return false
  688. }
  689. bv := g.BufferViews[*accessor.BufferView]
  690. // Calculates the size in bytes of a complete attribute
  691. itemSize := TypeSizes[accessor.Type]
  692. itemBytes := int(gls.FloatSize) * itemSize
  693. // If the BufferView stride is equal to the item size, the buffer is not interleaved
  694. if bv.ByteStride == nil {
  695. return false
  696. }
  697. if *bv.ByteStride == itemBytes {
  698. return false
  699. }
  700. return true
  701. }
  702. // loadBufferView loads and returns a byte slice with data from the specified BufferView.
  703. func (g *GLTF) loadBufferView(bv BufferView) ([]byte, error) {
  704. // Load buffer view buffer
  705. buf, err := g.loadBuffer(bv.Buffer)
  706. if err != nil {
  707. return nil, err
  708. }
  709. // Establish offset
  710. offset := 0
  711. if bv.ByteOffset != nil {
  712. offset = *bv.ByteOffset
  713. }
  714. // Compute and return offset slice
  715. return buf[offset : offset+bv.ByteLength], nil
  716. }
  717. // loadBuffer loads and returns the data from the specified GLTF Buffer index
  718. func (g *GLTF) loadBuffer(bi int) ([]byte, error) {
  719. buf := &g.Buffers[bi]
  720. // If Buffer URI use the chunk data field
  721. if buf.Uri == "" {
  722. return g.data, nil
  723. }
  724. // If buffer already loaded:
  725. log.Debug("loadBuffer cache:%v", len(buf.data))
  726. if len(buf.data) > 0 {
  727. return buf.data, nil
  728. }
  729. // Checks if buffer URI is a data URI
  730. var data []byte
  731. var err error
  732. if isDataURL(buf.Uri) {
  733. data, err = loadDataURL(buf.Uri)
  734. if err != nil {
  735. return nil, err
  736. }
  737. // Loads external buffer file
  738. } else {
  739. log.Debug("loadBuffer: loading file")
  740. // Try to load buffer from file
  741. fpath := filepath.Join(g.path, buf.Uri)
  742. f, err := os.Open(fpath)
  743. if err != nil {
  744. return nil, err
  745. }
  746. defer f.Close()
  747. data, err = ioutil.ReadAll(f)
  748. if err != nil {
  749. return nil, err
  750. }
  751. }
  752. // Checks data length
  753. if len(data) != buf.ByteLength {
  754. return nil, fmt.Errorf("Buffer:%d read data length:%d expected:%d", bi, len(data), buf.ByteLength)
  755. }
  756. // Cache buffer data
  757. buf.data = data
  758. log.Debug("cache data:%v", len(buf.data))
  759. return data, nil
  760. }
  761. // dataURL describes a decoded data url string.
  762. type dataURL struct {
  763. MediaType string
  764. Encoding string
  765. Data string
  766. }
  767. const (
  768. dataURLprefix = "data:"
  769. mimeBIN = "application/octet-stream"
  770. mimePNG = "image/png"
  771. mimeJPEG = "image/jpeg"
  772. )
  773. var validMediaTypes = []string{mimeBIN, mimePNG, mimeJPEG}
  774. // isDataURL checks if the specified string has the prefix of data URL.
  775. func isDataURL(url string) bool {
  776. if strings.HasPrefix(url, dataURLprefix) {
  777. return true
  778. }
  779. return false
  780. }
  781. // loadDataURL decodes the specified data URI string (base64).
  782. func loadDataURL(url string) ([]byte, error) {
  783. var du dataURL
  784. err := parseDataURL(url, &du)
  785. if err != nil {
  786. return nil, err
  787. }
  788. // Checks for valid media type
  789. found := false
  790. for i := 0; i < len(validMediaTypes); i++ {
  791. if validMediaTypes[i] == du.MediaType {
  792. found = true
  793. break
  794. }
  795. }
  796. if !found {
  797. return nil, fmt.Errorf("data URI media type:%s not supported", du.MediaType)
  798. }
  799. // Checks encoding
  800. if du.Encoding != "base64" {
  801. return nil, fmt.Errorf("data URI encoding:%s not supported", du.Encoding)
  802. }
  803. // Decodes data from BASE64
  804. data, err := base64.StdEncoding.DecodeString(du.Data)
  805. if err != nil {
  806. return nil, err
  807. }
  808. return data, nil
  809. }
  810. // parseDataURL tries to parse the specified string as a data URL with the format:
  811. // data:[<mediatype>][;base64],<data>
  812. // and if successfull returns true and updates the specified pointer with the parsed fields.
  813. func parseDataURL(url string, du *dataURL) error {
  814. // Check prefix
  815. if !isDataURL(url) {
  816. return fmt.Errorf("specified string is not a data URL")
  817. }
  818. // Separate header from data
  819. body := url[len(dataURLprefix):]
  820. parts := strings.Split(body, ",")
  821. if len(parts) != 2 {
  822. return fmt.Errorf("data URI contains more than one ','")
  823. }
  824. du.Data = parts[1]
  825. // Separate media type from optional encoding
  826. res := strings.Split(parts[0], ";")
  827. du.MediaType = res[0]
  828. if len(res) < 2 {
  829. return nil
  830. }
  831. if len(res) >= 2 {
  832. du.Encoding = res[1]
  833. }
  834. return nil
  835. }