loader.go 24 KB

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