loader.go 29 KB

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