loader.go 26 KB

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