loader.go 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964
  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 obtained chunk type [%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("Creating 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("Creating 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.loadMesh(*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.loadCamera(*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 a parent Node which contains all nodes contained by
  203. // the specified scene index from the GLTF Scenes array
  204. func (g *GLTF) NewAnimation(i int) (*animation.Animation, error) {
  205. log.Debug("Creating 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 ch animation.IChannel
  220. if target.Path == "translation" {
  221. ch = animation.NewPositionChannel(node)
  222. } else if target.Path == "rotation" {
  223. ch = animation.NewRotationChannel(node)
  224. } else if target.Path == "scale" {
  225. ch = animation.NewScaleChannel(node)
  226. }
  227. keyframes, err := g.loadAccessorF32(sampler.Input, []string{}, []int{})
  228. if err != nil {
  229. return nil, err
  230. }
  231. values, err := g.loadAccessorF32(sampler.Output, []string{}, []int{})
  232. if err != nil {
  233. return nil, err
  234. }
  235. ch.SetBuffers(keyframes, values)
  236. ch.SetInterpolationType(animation.InterpolationType(sampler.Interpolation))
  237. //ch.SetInterpolationType(animation.STEP)//animation.InterpolationType(sampler.Interpolation))
  238. anim.AddChannel(ch)
  239. }
  240. return anim, nil
  241. }
  242. // loadCamera creates and returns a Camera Node
  243. // from the specified GLTF.Cameras index
  244. func (g *GLTF) loadCamera(ci int) (core.INode, error) {
  245. log.Debug("Loading Camera %d", ci)
  246. camDesc := g.Cameras[ci]
  247. if camDesc.Type == "perspective" {
  248. desc := camDesc.Perspective
  249. fov := 360 * (desc.Yfov) / 2 * math32.Pi
  250. aspect := float32(2) // TODO how to get the current aspect ratio of the viewport from here ?
  251. if desc.AspectRatio != nil {
  252. aspect = *desc.AspectRatio
  253. }
  254. far := float32(2E6)
  255. if desc.Zfar != nil {
  256. far = *desc.Zfar
  257. }
  258. cam := camera.NewPerspective(fov, aspect, desc.Znear, far)
  259. return cam, nil
  260. }
  261. if camDesc.Type == "orthographic" {
  262. desc := camDesc.Orthographic
  263. cam := camera.NewOrthographic(desc.Xmag/-2, desc.Xmag/2, desc.Ymag/2, desc.Ymag/-2, desc.Znear, desc.Zfar)
  264. return cam, nil
  265. }
  266. return nil, fmt.Errorf("unsupported camera type: %s", camDesc.Type)
  267. }
  268. // loadMesh creates and returns a Graphic Node (graphic.Mesh, graphic.Lines, graphic.Points, etc)
  269. // from the specified GLTF Mesh index
  270. func (g *GLTF) loadMesh(mi int) (core.INode, error) {
  271. log.Debug("Loading Mesh %d", mi)
  272. var err error
  273. m := g.Meshes[mi]
  274. // Create container node
  275. meshNode := core.NewNode()
  276. for i := 0; i < len(m.Primitives); i++ {
  277. // Get primitive information
  278. p := m.Primitives[i]
  279. // Indexed Geometry
  280. indices := math32.NewArrayU32(0, 0)
  281. if p.Indices != nil {
  282. pidx, err := g.loadIndices(*p.Indices)
  283. if err != nil {
  284. return nil, err
  285. }
  286. indices = append(indices, pidx...)
  287. } else {
  288. // Non-indexed primitive
  289. // indices array stay empty
  290. }
  291. // Load primitive material
  292. var grMat material.IMaterial
  293. if p.Material != nil {
  294. grMat, err = g.loadMaterial(*p.Material)
  295. if err != nil {
  296. return nil, err
  297. }
  298. } else {
  299. grMat = g.newDefaultMaterial()
  300. }
  301. // Create geometry
  302. geom := geometry.NewGeometry()
  303. // Load primitive attributes
  304. for name, aci := range p.Attributes {
  305. // TODO
  306. //interleaved := g.isInterleaved(aci)
  307. //if interleaved {
  308. // buf, err := g.loadBufferView(*g.Accessors[aci].BufferView)
  309. // if err != nil {
  310. // return nil, err
  311. // }
  312. //}
  313. if name == "POSITION" {
  314. ppos, err := g.loadPositions(aci)
  315. if err != nil {
  316. return nil, err
  317. }
  318. vbo := gls.NewVBO().AddAttrib("VertexPosition", 3).SetBuffer(ppos)
  319. geom.AddVBO(vbo)
  320. continue
  321. }
  322. if name == "NORMAL" {
  323. pnorms, err := g.loadNormals(aci)
  324. if err != nil {
  325. return nil, err
  326. }
  327. vbo := gls.NewVBO().AddAttrib("VertexNormal", 3).SetBuffer(pnorms)
  328. geom.AddVBO(vbo)
  329. continue
  330. }
  331. if name == "TANGENT" {
  332. // TODO
  333. log.Error("TANGENT attribute not supported yet.")
  334. continue
  335. }
  336. attrib := strings.Split(name, "_")
  337. semantic := attrib[0]
  338. //set := attrib[1] TODO
  339. if semantic == "TEXCOORD" {
  340. puvs, err := g.loadTexcoords(aci)
  341. if err != nil {
  342. return nil, err
  343. }
  344. vbo := gls.NewVBO().AddAttrib("VertexTexcoord", 2).SetBuffer(puvs)
  345. geom.AddVBO(vbo)
  346. continue
  347. }
  348. if semantic == "COLOR" {
  349. // TODO
  350. }
  351. if semantic == "JOINTS" {
  352. // TODO
  353. }
  354. if semantic == "WEIGHTS" {
  355. // TODO
  356. }
  357. }
  358. // Creates Geometry and add attribute VBO
  359. if len(indices) > 0 {
  360. geom.SetIndices(indices)
  361. }
  362. //log.Debug("positions:%v", positions)
  363. //log.Debug("indices..:%v", indices)
  364. //log.Debug("normals..:%v", normals)
  365. //log.Debug("uvs0.....:%v", uvs0)
  366. //log.Debug("VBUF size in number of floats:%v", len(vbuf))
  367. // Default mode is 4 (TRIANGLES)
  368. mode := TRIANGLES
  369. if p.Mode != nil {
  370. mode = *p.Mode
  371. }
  372. // Create Mesh
  373. if mode == TRIANGLES {
  374. primitiveMesh := graphic.NewMesh(geom, nil)
  375. primitiveMesh.AddMaterial(grMat, 0, 0)
  376. meshNode.Add(primitiveMesh)
  377. }
  378. // Create Lines
  379. if mode == LINES {
  380. primitiveMesh := graphic.NewLines(geom, grMat)
  381. meshNode.Add(primitiveMesh)
  382. }
  383. // Create LineStrip
  384. if mode == LINE_STRIP {
  385. primitiveMesh := graphic.NewLineStrip(geom, grMat)
  386. meshNode.Add(primitiveMesh)
  387. }
  388. // Create Points
  389. if mode == POINTS {
  390. primitiveMesh := graphic.NewPoints(geom, grMat)
  391. meshNode.Add(primitiveMesh)
  392. }
  393. // TODO error when primitive is unsupported
  394. // fmt.Errorf("Unsupported primitive:%v", mode)
  395. }
  396. return meshNode, nil
  397. }
  398. func (g *GLTF) newDefaultMaterial() material.IMaterial {
  399. return material.NewStandard(&math32.Color{0.5, 0.5, 0.5})
  400. }
  401. // loadMaterials loads the material specified by the material index
  402. func (g *GLTF) loadMaterial(mi int) (material.IMaterial, error) {
  403. matData := g.Materials[mi]
  404. // Checks for material extensions
  405. if matData.Extensions != nil {
  406. for ext, v := range matData.Extensions {
  407. if ext == "KHR_materials_common" {
  408. return g.loadMaterialCommon(v)
  409. } else {
  410. return nil, fmt.Errorf("Unsupported extension:%s", ext)
  411. }
  412. }
  413. return nil, fmt.Errorf("Empty material extensions")
  414. // Material should be PBR
  415. } else {
  416. return g.loadMaterialPBR(&matData)
  417. }
  418. }
  419. // loadTextureInfo loads the texture specified by the TextureInfo pointer
  420. func (g *GLTF) loadTextureInfo(ti *TextureInfo) (*texture.Texture2D, error) {
  421. return g.loadTexture(ti.Index)
  422. }
  423. // loadTexture loads the texture specified by its index
  424. func (g *GLTF) loadTexture(texi int) (*texture.Texture2D, error) {
  425. // loads texture image
  426. texDesc := g.Textures[texi]
  427. img, err := g.loadImage(texDesc.Source)
  428. if err != nil {
  429. return nil, err
  430. }
  431. tex := texture.NewTexture2DFromRGBA(img)
  432. // Get sampler and apply texture parameters
  433. if texDesc.Sampler != nil {
  434. sampler := g.Samplers[*texDesc.Sampler]
  435. g.applySampler(sampler, tex)
  436. }
  437. return tex, nil
  438. }
  439. func (g *GLTF) applySampler(sampler Sampler, tex *texture.Texture2D) {
  440. // Magnification filter
  441. magFilter := gls.NEAREST
  442. if sampler.MagFilter != nil {
  443. magFilter = *sampler.MagFilter
  444. }
  445. tex.SetMagFilter(uint32(magFilter))
  446. // Minification filter
  447. minFilter := gls.NEAREST
  448. if sampler.MinFilter != nil {
  449. minFilter = *sampler.MinFilter
  450. }
  451. tex.SetMinFilter(uint32(minFilter))
  452. // S coordinate wrapping mode
  453. wrapS := gls.REPEAT
  454. if sampler.WrapS != nil {
  455. wrapS = *sampler.WrapS
  456. }
  457. tex.SetWrapS(uint32(wrapS))
  458. // T coordinate wrapping mode
  459. wrapT := gls.REPEAT
  460. if sampler.WrapT != nil {
  461. wrapT = *sampler.WrapT
  462. }
  463. tex.SetWrapT(uint32(wrapT))
  464. }
  465. // loadImage loads the image specified by the index of GLTF.Images
  466. // Image can be loaded from binary chunk file or data URI or external file.
  467. func (g *GLTF) loadImage(ii int) (*image.RGBA, error) {
  468. log.Error("loadImage:%v", ii)
  469. imgDesc := g.Images[ii]
  470. var data []byte
  471. var err error
  472. // If Uri is empty, load image from GLB binary chunk
  473. if imgDesc.Uri == "" {
  474. bvi := imgDesc.BufferView
  475. if bvi == nil {
  476. return nil, fmt.Errorf("Image has empty URI and no BufferView")
  477. }
  478. bv := g.BufferViews[*bvi]
  479. offset := 0
  480. if bv.ByteOffset != nil {
  481. offset = *bv.ByteOffset
  482. }
  483. data = g.data[offset : offset+bv.ByteLength]
  484. // Checks if image URI is data URL
  485. } else if isDataURL(imgDesc.Uri) {
  486. data, err = loadDataURL(imgDesc.Uri)
  487. if err != nil {
  488. return nil, err
  489. }
  490. // Load image data from file
  491. } else {
  492. fpath := filepath.Join(g.path, imgDesc.Uri)
  493. f, err := os.Open(fpath)
  494. if err != nil {
  495. return nil, err
  496. }
  497. defer f.Close()
  498. data, err = ioutil.ReadAll(f)
  499. if err != nil {
  500. return nil, err
  501. }
  502. }
  503. // Decodes image data
  504. bb := bytes.NewBuffer(data)
  505. img, _, err := image.Decode(bb)
  506. if err != nil {
  507. return nil, err
  508. }
  509. // Converts image to RGBA format
  510. rgba := image.NewRGBA(img.Bounds())
  511. if rgba.Stride != rgba.Rect.Size().X*4 {
  512. return nil, fmt.Errorf("unsupported stride")
  513. }
  514. draw.Draw(rgba, rgba.Bounds(), img, image.Point{0, 0}, draw.Src)
  515. return rgba, nil
  516. }
  517. // loadAccessorData loads the indices array specified by the Accessor index.
  518. func (g *GLTF) loadAccessorU32(ai int, validTypes []string, validComponentTypes []int) (math32.ArrayU32, error) {
  519. // Get Accessor for the specified index
  520. ac := g.Accessors[ai]
  521. if ac.BufferView == nil {
  522. return nil, fmt.Errorf("Accessor.BufferView == nil NOT SUPPORTED YET") // TODO
  523. }
  524. // Validate type and component type
  525. err := g.validateAccessor(ac, validTypes, validComponentTypes)
  526. if err != nil {
  527. return nil, err
  528. }
  529. // Load bytes
  530. data, err := g.loadAccessorBytes(ac)
  531. if err != nil {
  532. return nil, err
  533. }
  534. // If component is UNSIGNED_INT nothing to do
  535. if ac.ComponentType == UNSIGNED_INT {
  536. arr := (*[1 << 30]uint32)(unsafe.Pointer(&data[0]))[:ac.Count]
  537. return math32.ArrayU32(arr), nil
  538. }
  539. // Converts UNSIGNED_SHORT to UNSIGNED_INT
  540. if ac.ComponentType == UNSIGNED_SHORT {
  541. out := math32.NewArrayU32(ac.Count, ac.Count)
  542. for i := 0; i < ac.Count; i++ {
  543. out[i] = uint32(data[i*2]) + uint32(data[i*2+1])*256
  544. }
  545. return out, nil
  546. }
  547. // Converts UNSIGNED_BYTE indices to UNSIGNED_INT
  548. if ac.ComponentType == UNSIGNED_BYTE {
  549. out := math32.NewArrayU32(ac.Count, ac.Count)
  550. for i := 0; i < ac.Count; i++ {
  551. out[i] = uint32(data[i])
  552. }
  553. return out, nil
  554. }
  555. return nil, fmt.Errorf("Unsupported Accessor ComponentType:%v", ac.ComponentType)
  556. }
  557. func (g *GLTF) loadAccessorF32(ai int, validTypes []string, validComponentTypes []int) (math32.ArrayF32, error) {
  558. // Get Accessor for the specified index
  559. ac := g.Accessors[ai]
  560. if ac.BufferView == nil {
  561. return nil, fmt.Errorf("Accessor.BufferView == nil NOT SUPPORTED")
  562. }
  563. // Validate type and component type
  564. err := g.validateAccessor(ac, validTypes, validComponentTypes)
  565. if err != nil {
  566. return nil, err
  567. }
  568. // Load bytes
  569. data, err := g.loadAccessorBytes(ac)
  570. if err != nil {
  571. return nil, err
  572. }
  573. arr := (*[1 << 30]float32)(unsafe.Pointer(&data[0]))[:ac.Count*TypeSizes[ac.Type]]
  574. return math32.ArrayF32(arr), nil
  575. }
  576. // TODO
  577. func (g *GLTF) validateAccessor(ac Accessor, validTypes []string, validComponentTypes []int) error {
  578. // Check if points to a valid buffer view
  579. //if ac.BufferView == nil {
  580. // return fmt.Errorf("Accessor.BufferView == nil NOT SUPPORTED")
  581. //}
  582. //
  583. //// Check accessor ComponentType
  584. //if ac.ComponentType != FLOAT {
  585. // return fmt.Errorf("Accessor.ComponentType != FLOAT NOT SUPPORTED")
  586. //}
  587. //
  588. //// Check accessor Type
  589. //if ac.Type != VEC3 {
  590. // return fmt.Errorf("Accessor.ComponentType != VEC3 NOT SUPPORTED")
  591. //}
  592. return nil
  593. }
  594. // loadAccessorBytes
  595. func (g *GLTF) loadAccessorBytes(ac Accessor) ([]byte, error) {
  596. // Get the Accessor's BufferView
  597. if ac.BufferView == nil {
  598. return nil, fmt.Errorf("Accessor has nil BufferView") // TODO
  599. }
  600. bv := g.BufferViews[*ac.BufferView]
  601. // Loads data from associated BufferView
  602. data, err := g.loadBufferView(bv)
  603. if err != nil {
  604. return nil, err
  605. }
  606. // Accessor offset into BufferView
  607. offset := 0
  608. if ac.ByteOffset != nil {
  609. offset = *ac.ByteOffset
  610. }
  611. data = data[offset:]
  612. // Check if interleaved and de-interleave if necessary
  613. // Calculate the size in bytes of a complete attribute
  614. itemSize := TypeSizes[ac.Type]
  615. itemBytes := int(gls.FloatSize) * itemSize
  616. // If the BufferView stride is equal to the item size, the buffer is not interleaved
  617. if (bv.ByteStride != nil) && (*bv.ByteStride != itemBytes) {
  618. // BufferView data is interleaved, de-interleave
  619. // TODO
  620. log.Error("DATA IS INTERLEAVED - NOT SUPPORTED YET!")
  621. }
  622. return data, nil
  623. }
  624. // isInterleaves checks if the BufferView used by the specified Accessor index is
  625. // interleaved or not
  626. func (g *GLTF) isInterleaved(aci int) bool {
  627. // Get the Accessor's BufferView
  628. accessor := g.Accessors[aci]
  629. if accessor.BufferView == nil {
  630. return false
  631. }
  632. bv := g.BufferViews[*accessor.BufferView]
  633. // Calculates the size in bytes of a complete attribute
  634. itemSize := TypeSizes[accessor.Type]
  635. itemBytes := int(gls.FloatSize) * itemSize
  636. // If the BufferView stride is equal to the item size, the buffer is not interleaved
  637. if bv.ByteStride == nil {
  638. return false
  639. }
  640. if *bv.ByteStride == itemBytes {
  641. return false
  642. }
  643. return true
  644. }
  645. // loadPosition load array of float32 values from the specified accessor index.
  646. // The acesssor must have type of VEC3 and component type of FLOAT
  647. func (g *GLTF) loadPositions(ai int) (math32.ArrayF32, error) {
  648. return g.loadAccessorF32(ai, []string{VEC3}, []int{FLOAT})
  649. }
  650. //
  651. func (g *GLTF) loadNormals(ai int) (math32.ArrayF32, error) {
  652. return g.loadAccessorF32(ai, []string{VEC3}, []int{FLOAT})
  653. }
  654. //
  655. func (g *GLTF) loadTangents(ai int) (math32.ArrayF32, error) {
  656. return g.loadAccessorF32(ai, []string{VEC4}, []int{FLOAT})
  657. }
  658. //
  659. func (g *GLTF) loadTexcoords(ai int) (math32.ArrayF32, error) {
  660. return g.loadAccessorF32(ai, []string{VEC3}, []int{FLOAT, UNSIGNED_BYTE, UNSIGNED_SHORT})
  661. }
  662. //
  663. func (g *GLTF) loadColors(ai int) (math32.ArrayF32, error) {
  664. return g.loadAccessorF32(ai, []string{VEC3, VEC4}, []int{FLOAT, UNSIGNED_BYTE, UNSIGNED_SHORT})
  665. }
  666. //
  667. func (g *GLTF) loadJoints(ai int) (math32.ArrayF32, error) {
  668. return g.loadAccessorF32(ai, []string{VEC4}, []int{UNSIGNED_BYTE, UNSIGNED_SHORT})
  669. }
  670. //
  671. func (g *GLTF) loadWeights(ai int) (math32.ArrayF32, error) {
  672. return g.loadAccessorF32(ai, []string{VEC4}, []int{FLOAT, UNSIGNED_BYTE, UNSIGNED_SHORT})
  673. }
  674. //
  675. func (g *GLTF) loadIndices(ai int) (math32.ArrayU32, error) {
  676. return g.loadAccessorU32(ai, []string{SCALAR}, []int{UNSIGNED_BYTE, UNSIGNED_SHORT, UNSIGNED_INT}) // TODO check that it's ELEMENT_ARRAY_BUFFER
  677. }
  678. // loadBufferView loads and returns a byte slice with data from the specified BufferView index
  679. func (g *GLTF) loadBufferView(bv BufferView) ([]byte, error) {
  680. // Load buffer view buffer
  681. buf, err := g.loadBuffer(bv.Buffer)
  682. if err != nil {
  683. return nil, err
  684. }
  685. // Establish offset
  686. offset := 0
  687. if bv.ByteOffset != nil {
  688. offset = *bv.ByteOffset
  689. }
  690. // Compute and return offset slice
  691. return buf[offset : offset+bv.ByteLength], nil
  692. }
  693. // loadBuffer loads and returns the data from the specified GLTF Buffer index
  694. func (g *GLTF) loadBuffer(bi int) ([]byte, error) {
  695. buf := &g.Buffers[bi]
  696. // If Buffer URI use the chunk data field
  697. if buf.Uri == "" {
  698. return g.data, nil
  699. }
  700. // If buffer already loaded:
  701. log.Debug("loadBuffer cache:%v", len(buf.data))
  702. if len(buf.data) > 0 {
  703. return buf.data, nil
  704. }
  705. // Checks if buffer URI is a data URI
  706. var data []byte
  707. var err error
  708. if isDataURL(buf.Uri) {
  709. data, err = loadDataURL(buf.Uri)
  710. if err != nil {
  711. return nil, err
  712. }
  713. // Loads external buffer file
  714. } else {
  715. log.Debug("loadBuffer: loading file")
  716. // Try to load buffer from file
  717. fpath := filepath.Join(g.path, buf.Uri)
  718. f, err := os.Open(fpath)
  719. if err != nil {
  720. return nil, err
  721. }
  722. defer f.Close()
  723. data, err = ioutil.ReadAll(f)
  724. if err != nil {
  725. return nil, err
  726. }
  727. }
  728. // Checks data length
  729. if len(data) != buf.ByteLength {
  730. return nil, fmt.Errorf("Buffer:%d read data length:%d expected:%d", bi, len(data), buf.ByteLength)
  731. }
  732. // Cache buffer data
  733. buf.data = data
  734. log.Debug("cache data:%v", len(buf.data))
  735. return data, nil
  736. }
  737. // dataURL describes a decoded data url string
  738. type dataURL struct {
  739. MediaType string
  740. Encoding string
  741. Data string
  742. }
  743. const (
  744. dataURLprefix = "data:"
  745. mimeBIN = "application/octet-stream"
  746. mimePNG = "image/png"
  747. mimeJPEG = "image/jpeg"
  748. )
  749. var validMediaTypes = []string{mimeBIN, mimePNG, mimeJPEG}
  750. // isDataURL checks if the specified string has the prefix of data URL
  751. func isDataURL(url string) bool {
  752. if strings.HasPrefix(url, dataURLprefix) {
  753. return true
  754. }
  755. return false
  756. }
  757. // loadDataURL decodes the specified data URI string (base64)
  758. func loadDataURL(url string) ([]byte, error) {
  759. var du dataURL
  760. err := parseDataURL(url, &du)
  761. if err != nil {
  762. return nil, err
  763. }
  764. // Checks for valid media type
  765. found := false
  766. for i := 0; i < len(validMediaTypes); i++ {
  767. if validMediaTypes[i] == du.MediaType {
  768. found = true
  769. break
  770. }
  771. }
  772. if !found {
  773. return nil, fmt.Errorf("Data URI media type:%s not supported", du.MediaType)
  774. }
  775. // Checks encoding
  776. if du.Encoding != "base64" {
  777. return nil, fmt.Errorf("Data URI encoding:%s not supported", du.Encoding)
  778. }
  779. // Decodes data from BASE64
  780. data, err := base64.StdEncoding.DecodeString(du.Data)
  781. if err != nil {
  782. return nil, err
  783. }
  784. return data, nil
  785. }
  786. // parseDataURL tries to parse the specified string as a data URL with the format:
  787. // data:[<mediatype>][;base64],<data>
  788. // and if successfull returns true and updates the specified pointer with the parsed fields.
  789. func parseDataURL(url string, du *dataURL) error {
  790. // Checks prefix
  791. if !isDataURL(url) {
  792. return fmt.Errorf("Specified string is not a data URL")
  793. }
  794. // Separates header from data
  795. body := url[len(dataURLprefix):]
  796. parts := strings.Split(body, ",")
  797. if len(parts) != 2 {
  798. return fmt.Errorf("Data URI contains more than one ','")
  799. }
  800. du.Data = parts[1]
  801. // Separates media type from optional encoding
  802. res := strings.Split(parts[0], ";")
  803. du.MediaType = res[0]
  804. if len(res) < 2 {
  805. return nil
  806. }
  807. if len(res) >= 2 {
  808. du.Encoding = res[1]
  809. }
  810. return nil
  811. }