loader.go 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213
  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/animation"
  20. "github.com/g3n/engine/camera"
  21. "github.com/g3n/engine/core"
  22. "github.com/g3n/engine/geometry"
  23. "github.com/g3n/engine/gls"
  24. "github.com/g3n/engine/graphic"
  25. "github.com/g3n/engine/material"
  26. "github.com/g3n/engine/math32"
  27. "github.com/g3n/engine/texture"
  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. // TODO Check for extensions used and extensions required
  53. return g, nil
  54. }
  55. // ParseBin parses the glTF data from the specified binary file
  56. // and returns a pointer to the parsed structure.
  57. func ParseBin(filename string) (*GLTF, error) {
  58. // Open file
  59. f, err := os.Open(filename)
  60. if err != nil {
  61. return nil, err
  62. }
  63. // Extract path from file
  64. path := filepath.Dir(filename)
  65. defer f.Close()
  66. return ParseBinReader(f, path)
  67. }
  68. // ParseBinReader parses the glTF data from the specified binary reader
  69. // and returns a pointer to the parsed structure
  70. func ParseBinReader(r io.Reader, path string) (*GLTF, error) {
  71. // Read header
  72. var header GLBHeader
  73. err := binary.Read(r, binary.LittleEndian, &header)
  74. if err != nil {
  75. return nil, err
  76. }
  77. // Check magic and version
  78. if header.Magic != GLBMagic {
  79. return nil, fmt.Errorf("invalid GLB Magic field")
  80. }
  81. if header.Version < 2 {
  82. return nil, fmt.Errorf("GLB version:%v not supported", header.Version)
  83. }
  84. // Read first chunk (JSON)
  85. buf, err := readChunk(r, GLBJson)
  86. if err != nil {
  87. return nil, err
  88. }
  89. // Parse JSON into gltf object
  90. bb := bytes.NewBuffer(buf)
  91. gltf, err := ParseJSONReader(bb, path)
  92. if err != nil {
  93. return nil, err
  94. }
  95. // Check for and read second chunk (binary, optional)
  96. data, err := readChunk(r, GLBBin)
  97. if err != nil {
  98. return nil, err
  99. }
  100. gltf.data = data
  101. return gltf, nil
  102. }
  103. // readChunk reads a GLB chunk with the specified type and returns the data in a byte array.
  104. func readChunk(r io.Reader, chunkType uint32) ([]byte, error) {
  105. // Read chunk header
  106. var chunk GLBChunk
  107. err := binary.Read(r, binary.LittleEndian, &chunk)
  108. if err != nil {
  109. if err == io.EOF {
  110. return nil, nil
  111. }
  112. return nil, err
  113. }
  114. // Check chunk type
  115. if chunk.Type != chunkType {
  116. return nil, fmt.Errorf("expected GLB chunk type [%v] but found [%v]", chunkType, chunk.Type)
  117. }
  118. // Read chunk data
  119. data := make([]byte, chunk.Length)
  120. err = binary.Read(r, binary.LittleEndian, &data)
  121. if err != nil {
  122. return nil, err
  123. }
  124. return data, nil
  125. }
  126. // LoadScene creates a parent Node which contains all nodes contained by
  127. // the specified scene index from the GLTF Scenes array.
  128. func (g *GLTF) LoadScene(sceneIdx int) (core.INode, error) {
  129. // Check if provided scene index is valid
  130. if sceneIdx < 0 || sceneIdx >= len(g.Scenes) {
  131. return nil, fmt.Errorf("invalid scene index")
  132. }
  133. log.Debug("Loading Scene %d", sceneIdx)
  134. sceneData := g.Scenes[sceneIdx]
  135. scene := core.NewNode()
  136. scene.SetName(sceneData.Name)
  137. // Load all nodes
  138. for _, ni := range sceneData.Nodes {
  139. child, err := g.LoadNode(ni)
  140. if err != nil {
  141. return nil, err
  142. }
  143. scene.Add(child)
  144. }
  145. return scene, nil
  146. }
  147. // LoadNode creates and returns a new Node described by the specified index
  148. // in the decoded GLTF Nodes array.
  149. func (g *GLTF) LoadNode(nodeIdx int) (core.INode, error) {
  150. // Check if provided node index is valid
  151. if nodeIdx < 0 || nodeIdx >= len(g.Nodes) {
  152. return nil, fmt.Errorf("invalid node index")
  153. }
  154. nodeData := g.Nodes[nodeIdx]
  155. // Return cached if available
  156. if nodeData.cache != nil {
  157. log.Debug("Fetching Node %d (cached)", nodeIdx)
  158. return nodeData.cache, nil
  159. }
  160. log.Debug("Loading Node %d", nodeIdx)
  161. var in core.INode
  162. var err error
  163. // Check if the node is a Mesh (triangles, lines, etc...)
  164. if nodeData.Mesh != nil {
  165. in, err = g.LoadMesh(*nodeData.Mesh)
  166. if err != nil {
  167. return nil, err
  168. }
  169. if nodeData.Skin != nil {
  170. mesh, ok := in.(*graphic.Mesh)
  171. if !ok {
  172. children := in.GetNode().Children()
  173. if len(children) > 1 {
  174. return nil, fmt.Errorf("skinning/rigging meshes with more than a single primitive is not supported")
  175. }
  176. mesh = children[0].(*graphic.Mesh)
  177. }
  178. // Create RiggedMesh
  179. rm := graphic.NewRiggedMesh(mesh)
  180. skeleton, err := g.LoadSkin(*nodeData.Skin)
  181. if err != nil {
  182. return nil, err
  183. }
  184. rm.SetSkeleton(skeleton)
  185. in = rm
  186. }
  187. // Check if the node is Camera
  188. } else if nodeData.Camera != nil {
  189. in, err = g.LoadCamera(*nodeData.Camera)
  190. if err != nil {
  191. return nil, err
  192. }
  193. // Other cases, return empty node
  194. } else {
  195. log.Debug("Empty Node")
  196. in = core.NewNode()
  197. }
  198. // Get *core.Node from core.INode
  199. node := in.GetNode()
  200. node.SetName(nodeData.Name)
  201. // If defined, set node local transformation matrix
  202. if nodeData.Matrix != nil {
  203. node.SetMatrix((*math32.Matrix4)(nodeData.Matrix))
  204. // Otherwise, check rotation, scale and translation fields
  205. } else {
  206. // Rotation quaternion
  207. if nodeData.Rotation != nil {
  208. node.SetQuaternion(nodeData.Rotation[0], nodeData.Rotation[1], nodeData.Rotation[2], nodeData.Rotation[3])
  209. }
  210. // Scale
  211. if nodeData.Scale != nil {
  212. node.SetScale(nodeData.Scale[0], nodeData.Scale[1], nodeData.Scale[2])
  213. }
  214. // Translation
  215. if nodeData.Translation != nil {
  216. node.SetPosition(nodeData.Translation[0], nodeData.Translation[1], nodeData.Translation[2])
  217. }
  218. }
  219. // Cache node
  220. g.Nodes[nodeIdx].cache = in
  221. // Recursively load node children and add them to the parent
  222. for _, ci := range nodeData.Children {
  223. child, err := g.LoadNode(ci)
  224. if err != nil {
  225. return nil, err
  226. }
  227. node.Add(child)
  228. }
  229. return in, nil
  230. }
  231. // LoadSkin loads the skin with specified index.
  232. func (g *GLTF) LoadSkin(skinIdx int) (*graphic.Skeleton, error) {
  233. // Check if provided skin index is valid
  234. if skinIdx < 0 || skinIdx >= len(g.Skins) {
  235. return nil, fmt.Errorf("invalid skin index")
  236. }
  237. skinData := g.Skins[skinIdx]
  238. // Return cached if available
  239. if skinData.cache != nil {
  240. log.Debug("Fetching Skin %d (cached)", skinIdx)
  241. return skinData.cache, nil
  242. }
  243. log.Debug("Loading Skin %d", skinIdx)
  244. // Create Skeleton and set it on Rigged mesh
  245. skeleton := graphic.NewSkeleton()
  246. // Load inverseBindMatrices
  247. ibmData, err := g.loadAccessorF32(skinData.InverseBindMatrices, "ibm", []string{MAT4}, []int{FLOAT})
  248. if err != nil {
  249. return nil, err
  250. }
  251. // Add bones
  252. for i := range skinData.Joints {
  253. jointNode, err := g.LoadNode(skinData.Joints[i])
  254. if err != nil {
  255. return nil, err
  256. }
  257. var ibm math32.Matrix4
  258. ibmData.GetMatrix4(16*i, &ibm)
  259. skeleton.AddBone(jointNode.GetNode(), &ibm)
  260. }
  261. // Cache skin
  262. g.Skins[skinIdx].cache = skeleton
  263. return skeleton, nil
  264. }
  265. // LoadAnimationByName loads the animations with specified name.
  266. // If there are multiple animations with the same name it loads the first occurrence.
  267. func (g *GLTF) LoadAnimationByName(animName string) (*animation.Animation, error) {
  268. for i := range g.Animations {
  269. if g.Animations[i].Name == animName {
  270. return g.LoadAnimation(i)
  271. }
  272. }
  273. return nil, fmt.Errorf("could not find animation named %v", animName)
  274. }
  275. // LoadAnimation creates an Animation for the specified
  276. // animation index from the GLTF Animations array.
  277. func (g *GLTF) LoadAnimation(animIdx int) (*animation.Animation, error) {
  278. // Check if provided animation index is valid
  279. if animIdx < 0 || animIdx >= len(g.Animations) {
  280. return nil, fmt.Errorf("invalid animation index")
  281. }
  282. log.Debug("Loading Animation %d", animIdx)
  283. animData := g.Animations[animIdx]
  284. anim := animation.NewAnimation()
  285. anim.SetName(animData.Name)
  286. for i := 0; i < len(animData.Channels); i++ {
  287. chData := animData.Channels[i]
  288. target := chData.Target
  289. sampler := animData.Samplers[chData.Sampler]
  290. node, err := g.LoadNode(target.Node)
  291. if err != nil {
  292. return nil, err
  293. }
  294. var validTypes []string
  295. var validComponentTypes []int
  296. var ch animation.IChannel
  297. if target.Path == "translation" {
  298. validTypes = []string{VEC3}
  299. validComponentTypes = []int{FLOAT}
  300. ch = animation.NewPositionChannel(node)
  301. } else if target.Path == "rotation" {
  302. validTypes = []string{VEC4}
  303. validComponentTypes = []int{FLOAT, BYTE, UNSIGNED_BYTE, SHORT, UNSIGNED_SHORT}
  304. ch = animation.NewRotationChannel(node)
  305. } else if target.Path == "scale" {
  306. validTypes = []string{VEC3}
  307. validComponentTypes = []int{FLOAT}
  308. ch = animation.NewScaleChannel(node)
  309. } else if target.Path == "weights" {
  310. validTypes = []string{SCALAR}
  311. validComponentTypes = []int{FLOAT, BYTE, UNSIGNED_BYTE, SHORT, UNSIGNED_SHORT}
  312. children := node.GetNode().Children()
  313. if len(children) > 1 {
  314. return nil, fmt.Errorf("animating meshes with more than a single primitive is not supported")
  315. }
  316. morphGeom := children[0].(graphic.IGraphic).IGeometry().(*geometry.MorphGeometry)
  317. ch = animation.NewMorphChannel(morphGeom)
  318. }
  319. // TODO what if Input and Output accessors are interleaved? probably de-interleave in these 2 cases
  320. keyframes, err := g.loadAccessorF32(sampler.Input, "Input", []string{SCALAR}, []int{FLOAT})
  321. if err != nil {
  322. return nil, err
  323. }
  324. values, err := g.loadAccessorF32(sampler.Output, "Output", validTypes, validComponentTypes)
  325. if err != nil {
  326. return nil, err
  327. }
  328. ch.SetBuffers(keyframes, values)
  329. ch.SetInterpolationType(animation.InterpolationType(sampler.Interpolation))
  330. anim.AddChannel(ch)
  331. }
  332. return anim, nil
  333. }
  334. // LoadCamera creates and returns a Camera Node
  335. // from the specified GLTF.Cameras index.
  336. func (g *GLTF) LoadCamera(camIdx int) (core.INode, error) {
  337. // Check if provided camera index is valid
  338. if camIdx < 0 || camIdx >= len(g.Cameras) {
  339. return nil, fmt.Errorf("invalid camera index")
  340. }
  341. log.Debug("Loading Camera %d", camIdx)
  342. camData := g.Cameras[camIdx]
  343. if camData.Type == "perspective" {
  344. desc := camData.Perspective
  345. fov := 360 * (desc.Yfov) / 2 * math32.Pi
  346. aspect := float32(2) // TODO how to get the current aspect ratio of the viewport from here ?
  347. if desc.AspectRatio != nil {
  348. aspect = *desc.AspectRatio
  349. }
  350. far := float32(2E6)
  351. if desc.Zfar != nil {
  352. far = *desc.Zfar
  353. }
  354. cam := camera.NewPerspective(fov, aspect, desc.Znear, far)
  355. return cam, nil
  356. }
  357. if camData.Type == "orthographic" {
  358. desc := camData.Orthographic
  359. cam := camera.NewOrthographic(desc.Xmag/-2, desc.Xmag/2, desc.Ymag/2, desc.Ymag/-2, desc.Znear, desc.Zfar)
  360. return cam, nil
  361. }
  362. return nil, fmt.Errorf("unsupported camera type: %s", camData.Type)
  363. }
  364. // LoadMesh creates and returns a Graphic Node (graphic.Mesh, graphic.Lines, graphic.Points, etc)
  365. // from the specified GLTF.Meshes index.
  366. func (g *GLTF) LoadMesh(meshIdx int) (core.INode, error) {
  367. // Check if provided mesh index is valid
  368. if meshIdx < 0 || meshIdx >= len(g.Meshes) {
  369. return nil, fmt.Errorf("invalid mesh index")
  370. }
  371. meshData := g.Meshes[meshIdx]
  372. // Return cached if available
  373. if meshData.cache != nil {
  374. // TODO CLONE/REINSTANCE INSTEAD
  375. //log.Debug("Instancing Mesh %d (from cached)", meshIdx)
  376. //return meshData.cache, nil
  377. }
  378. log.Debug("Loading Mesh %d", meshIdx)
  379. var err error
  380. // Create container node
  381. var meshNode core.INode
  382. meshNode = core.NewNode()
  383. for i := 0; i < len(meshData.Primitives); i++ {
  384. // Get primitive information
  385. p := meshData.Primitives[i]
  386. // Indexed Geometry
  387. indices := math32.NewArrayU32(0, 0)
  388. if p.Indices != nil {
  389. pidx, err := g.loadIndices(*p.Indices)
  390. if err != nil {
  391. return nil, err
  392. }
  393. indices = append(indices, pidx...)
  394. } else {
  395. // Non-indexed primitive
  396. // indices array stay empty
  397. }
  398. // Load primitive material
  399. var grMat material.IMaterial
  400. if p.Material != nil {
  401. grMat, err = g.LoadMaterial(*p.Material)
  402. if err != nil {
  403. return nil, err
  404. }
  405. } else {
  406. grMat = g.newDefaultMaterial()
  407. }
  408. // Create geometry
  409. var igeom geometry.IGeometry
  410. igeom = geometry.NewGeometry()
  411. geom := igeom.GetGeometry()
  412. err = g.loadAttributes(geom, p.Attributes, indices)
  413. if err != nil {
  414. return nil, err
  415. }
  416. // If primitive has targets then the geometry should be a morph geometry
  417. if len(p.Targets) > 0 {
  418. morphGeom := geometry.NewMorphGeometry(geom)
  419. // TODO Load morph target names if present in extras under "targetNames"
  420. // TODO Update morph target weights if present in Mesh.Weights
  421. // Load targets
  422. for i := range p.Targets {
  423. tGeom := geometry.NewGeometry()
  424. attributes := p.Targets[i]
  425. err = g.loadAttributes(tGeom, attributes, indices)
  426. if err != nil {
  427. return nil, err
  428. }
  429. morphGeom.AddMorphTargetDeltas(tGeom)
  430. }
  431. igeom = morphGeom
  432. }
  433. // Default mode is 4 (TRIANGLES)
  434. mode := TRIANGLES
  435. if p.Mode != nil {
  436. mode = *p.Mode
  437. }
  438. // Create Mesh
  439. // TODO materials for LINES, etc need to be different...
  440. if mode == TRIANGLES {
  441. meshNode.GetNode().Add(graphic.NewMesh(igeom, grMat))
  442. } else if mode == LINES {
  443. meshNode.GetNode().Add(graphic.NewLines(igeom, grMat))
  444. } else if mode == LINE_STRIP {
  445. meshNode.GetNode().Add(graphic.NewLineStrip(igeom, grMat))
  446. } else if mode == POINTS {
  447. meshNode.GetNode().Add(graphic.NewPoints(igeom, grMat))
  448. } else {
  449. return nil, fmt.Errorf("unsupported primitive:%v", mode)
  450. }
  451. }
  452. children := meshNode.GetNode().Children()
  453. if len(children) == 1 {
  454. meshNode = children[0]
  455. }
  456. // Cache mesh
  457. g.Meshes[meshIdx].cache = meshNode
  458. return meshNode, nil
  459. }
  460. // loadAttributes loads the provided list of vertex attributes as VBO(s) into the specified geometry.
  461. func (g *GLTF) loadAttributes(geom *geometry.Geometry, attributes map[string]int, indices math32.ArrayU32) error {
  462. // Indices of buffer views
  463. interleavedVBOs := make(map[int]*gls.VBO, 0)
  464. // Load primitive attributes
  465. for name, aci := range attributes {
  466. accessor := g.Accessors[aci]
  467. // Validate that accessor is compatible with attribute
  468. err := g.validateAccessorAttribute(accessor, name)
  469. if err != nil {
  470. return err
  471. }
  472. // Load data and add it to geometry's VBO
  473. if g.isInterleaved(accessor) {
  474. bvIdx := *accessor.BufferView
  475. // Check if we already loaded this buffer view
  476. vbo, ok := interleavedVBOs[bvIdx]
  477. if ok {
  478. // Already created VBO for this buffer view
  479. // Add attribute with correct byteOffset
  480. g.addAttributeToVBO(vbo, name, uint32(*accessor.ByteOffset))
  481. } else {
  482. // Load data and create vbo
  483. buf, err := g.loadBufferView(bvIdx)
  484. if err != nil {
  485. return err
  486. }
  487. data, err := g.bytesToArrayF32(buf, accessor.ComponentType, accessor.Count*TypeSizes[accessor.Type])
  488. if err != nil {
  489. return err
  490. }
  491. vbo := gls.NewVBO(data)
  492. g.addAttributeToVBO(vbo, name, 0)
  493. // Save reference to VBO keyed by index of the buffer view
  494. interleavedVBOs[bvIdx] = vbo
  495. // Add VBO to geometry
  496. geom.AddVBO(vbo)
  497. }
  498. } else {
  499. buf, err := g.loadAccessorBytes(accessor)
  500. if err != nil {
  501. return err
  502. }
  503. data, err := g.bytesToArrayF32(buf, accessor.ComponentType, accessor.Count*TypeSizes[accessor.Type])
  504. if err != nil {
  505. return err
  506. }
  507. vbo := gls.NewVBO(data)
  508. g.addAttributeToVBO(vbo, name, 0)
  509. // Add VBO to geometry
  510. geom.AddVBO(vbo)
  511. }
  512. }
  513. // Set indices
  514. if len(indices) > 0 {
  515. geom.SetIndices(indices)
  516. }
  517. return nil
  518. }
  519. // loadIndices loads the indices stored in the specified accessor.
  520. func (g *GLTF) loadIndices(ai int) (math32.ArrayU32, error) {
  521. return g.loadAccessorU32(ai, "indices", []string{SCALAR}, []int{UNSIGNED_BYTE, UNSIGNED_SHORT, UNSIGNED_INT}) // TODO verify that it's ELEMENT_ARRAY_BUFFER
  522. }
  523. // addAttributeToVBO adds the appropriate attribute to the provided vbo based on the glTF attribute name.
  524. func (g *GLTF) addAttributeToVBO(vbo *gls.VBO, attribName string, byteOffset uint32) {
  525. aType, ok := AttributeName[attribName]
  526. if !ok {
  527. log.Warn(fmt.Sprintf("Attribute %v is not supported!", attribName))
  528. return
  529. }
  530. vbo.AddAttribOffset(aType, byteOffset)
  531. }
  532. // validateAccessorAttribute validates the specified accessor for the given attribute name.
  533. func (g *GLTF) validateAccessorAttribute(ac Accessor, attribName string) error {
  534. parts := strings.Split(attribName, "_")
  535. semantic := parts[0]
  536. usage := "attribute " + attribName
  537. if attribName == "POSITION" {
  538. return g.validateAccessor(ac, usage, []string{VEC3}, []int{FLOAT})
  539. } else if attribName == "NORMAL" {
  540. return g.validateAccessor(ac, usage, []string{VEC3}, []int{FLOAT})
  541. } else if attribName == "TANGENT" {
  542. // Note that morph targets only support VEC3 whereas normal attributes only support VEC4.
  543. return g.validateAccessor(ac, usage, []string{VEC3, VEC4}, []int{FLOAT})
  544. } else if semantic == "TEXCOORD" {
  545. return g.validateAccessor(ac, usage, []string{VEC2}, []int{FLOAT, UNSIGNED_BYTE, UNSIGNED_SHORT})
  546. } else if semantic == "COLOR" {
  547. return g.validateAccessor(ac, usage, []string{VEC3, VEC4}, []int{FLOAT, UNSIGNED_BYTE, UNSIGNED_SHORT})
  548. } else if semantic == "JOINTS" {
  549. return g.validateAccessor(ac, usage, []string{VEC4}, []int{UNSIGNED_BYTE, UNSIGNED_SHORT})
  550. } else if semantic == "WEIGHTS" {
  551. return g.validateAccessor(ac, usage, []string{VEC4}, []int{FLOAT, UNSIGNED_BYTE, UNSIGNED_SHORT})
  552. } else {
  553. return fmt.Errorf("attribute %v is not supported", attribName)
  554. }
  555. }
  556. // validateAccessor validates the specified attribute accessor with the specified allowed types and component types.
  557. func (g *GLTF) validateAccessor(ac Accessor, usage string, validTypes []string, validComponentTypes []int) error {
  558. // Validate accessor type
  559. validType := false
  560. for _, vType := range validTypes {
  561. if ac.Type == vType {
  562. validType = true
  563. break
  564. }
  565. }
  566. if !validType {
  567. return fmt.Errorf("invalid Accessor.Type %v for %s", ac.Type, usage)
  568. }
  569. // Validate accessor component type
  570. validComponentType := false
  571. for _, vComponentType := range validComponentTypes {
  572. if ac.ComponentType == vComponentType {
  573. validComponentType = true
  574. break
  575. }
  576. }
  577. if !validComponentType {
  578. return fmt.Errorf("invalid Accessor.ComponentType %v for %s", ac.ComponentType, usage)
  579. }
  580. return nil
  581. }
  582. // newDefaultMaterial creates and returns the default material.
  583. func (g *GLTF) newDefaultMaterial() material.IMaterial {
  584. return material.NewStandard(&math32.Color{0.5, 0.5, 0.5})
  585. }
  586. // LoadMaterial creates and returns a new material based on the material data with the specified index.
  587. func (g *GLTF) LoadMaterial(matIdx int) (material.IMaterial, error) {
  588. // Check if provided material index is valid
  589. if matIdx < 0 || matIdx >= len(g.Materials) {
  590. return nil, fmt.Errorf("invalid material index")
  591. }
  592. matData := g.Materials[matIdx]
  593. // Return cached if available
  594. if matData.cache != nil {
  595. log.Debug("Fetching Material %d (cached)", matIdx)
  596. return matData.cache, nil
  597. }
  598. log.Debug("Loading Material %d", matIdx)
  599. var err error
  600. var imat material.IMaterial
  601. // Check for material extensions
  602. if matData.Extensions != nil {
  603. for ext, extData := range matData.Extensions {
  604. if ext == KhrMaterialsCommon {
  605. imat, err = g.loadMaterialCommon(extData)
  606. } else if ext == KhrMaterialsUnlit {
  607. //imat, err = g.loadMaterialUnlit(matData, extData)
  608. //} else if ext == KhrMaterialsPbrSpecularGlossiness {
  609. } else {
  610. return nil, fmt.Errorf("unsupported extension:%s", ext)
  611. }
  612. }
  613. } else {
  614. // Material is normally PBR
  615. imat, err = g.loadMaterialPBR(&matData)
  616. }
  617. // Cache material
  618. g.Materials[matIdx].cache = imat
  619. return imat, err
  620. }
  621. // LoadTexture loads the texture specified by its index.
  622. func (g *GLTF) LoadTexture(texIdx int) (*texture.Texture2D, error) {
  623. // Check if provided texture index is valid
  624. if texIdx < 0 || texIdx >= len(g.Textures) {
  625. return nil, fmt.Errorf("invalid texture index")
  626. }
  627. texData := g.Textures[texIdx]
  628. // NOTE: Textures can't be cached because they have their own uniforms
  629. log.Debug("Loading Texture %d", texIdx)
  630. // Load texture image
  631. img, err := g.LoadImage(texData.Source)
  632. if err != nil {
  633. return nil, err
  634. }
  635. tex := texture.NewTexture2DFromRGBA(img)
  636. // Get sampler and apply texture parameters
  637. if texData.Sampler != nil {
  638. err = g.applySampler(*texData.Sampler, tex)
  639. if err != nil {
  640. return nil, err
  641. }
  642. }
  643. return tex, nil
  644. }
  645. // applySamplers applies the specified Sampler to the provided texture.
  646. func (g *GLTF) applySampler(samplerIdx int, tex *texture.Texture2D) error {
  647. log.Debug("Applying Sampler %d", samplerIdx)
  648. // Check if provided sampler index is valid
  649. if samplerIdx < 0 || samplerIdx >= len(g.Samplers) {
  650. return fmt.Errorf("invalid sampler index")
  651. }
  652. sampler := g.Samplers[samplerIdx]
  653. // Magnification filter
  654. magFilter := gls.LINEAR
  655. if sampler.MagFilter != nil {
  656. magFilter = *sampler.MagFilter
  657. }
  658. tex.SetMagFilter(uint32(magFilter))
  659. // Minification filter
  660. minFilter := gls.LINEAR_MIPMAP_LINEAR
  661. if sampler.MinFilter != nil {
  662. minFilter = *sampler.MinFilter
  663. }
  664. tex.SetMinFilter(uint32(minFilter))
  665. // S coordinate wrapping mode
  666. wrapS := gls.REPEAT
  667. if sampler.WrapS != nil {
  668. wrapS = *sampler.WrapS
  669. }
  670. tex.SetWrapS(uint32(wrapS))
  671. // T coordinate wrapping mode
  672. wrapT := gls.REPEAT
  673. if sampler.WrapT != nil {
  674. wrapT = *sampler.WrapT
  675. }
  676. tex.SetWrapT(uint32(wrapT))
  677. return nil
  678. }
  679. // LoadImage loads the image specified by the index of GLTF.Images.
  680. // Image can be loaded from binary chunk file or data URI or external file..
  681. func (g *GLTF) LoadImage(imgIdx int) (*image.RGBA, error) {
  682. // Check if provided image index is valid
  683. if imgIdx < 0 || imgIdx >= len(g.Images) {
  684. return nil, fmt.Errorf("invalid image index")
  685. }
  686. imgData := g.Images[imgIdx]
  687. // Return cached if available
  688. if imgData.cache != nil {
  689. log.Debug("Fetching Image %d (cached)", imgIdx)
  690. return imgData.cache, nil
  691. }
  692. log.Debug("Loading Image %d", imgIdx)
  693. var data []byte
  694. var err error
  695. // If Uri is empty, load image from GLB binary chunk
  696. if imgData.Uri == "" {
  697. if imgData.BufferView == nil {
  698. return nil, fmt.Errorf("image has empty URI and no BufferView")
  699. }
  700. data, err = g.loadBufferView(*imgData.BufferView)
  701. } else if isDataURL(imgData.Uri) {
  702. // Checks if image URI is data URL
  703. data, err = loadDataURL(imgData.Uri)
  704. } else {
  705. // Load image data from file
  706. data, err = g.loadFileBytes(imgData.Uri)
  707. }
  708. if err != nil {
  709. return nil, err
  710. }
  711. // Decodes image data
  712. bb := bytes.NewBuffer(data)
  713. img, _, err := image.Decode(bb)
  714. if err != nil {
  715. return nil, err
  716. }
  717. // Converts image to RGBA format
  718. rgba := image.NewRGBA(img.Bounds())
  719. if rgba.Stride != rgba.Rect.Size().X*4 {
  720. return nil, fmt.Errorf("unsupported stride")
  721. }
  722. draw.Draw(rgba, rgba.Bounds(), img, image.Point{0, 0}, draw.Src)
  723. // Cache image
  724. g.Images[imgIdx].cache = rgba
  725. return rgba, nil
  726. }
  727. // bytesToArrayU32 converts a byte array to ArrayU32.
  728. func (g *GLTF) bytesToArrayU32(data []byte, componentType, count int) (math32.ArrayU32, error) {
  729. // If component is UNSIGNED_INT nothing to do
  730. if componentType == UNSIGNED_INT {
  731. arr := (*[1 << 30]uint32)(unsafe.Pointer(&data[0]))[:count]
  732. return math32.ArrayU32(arr), nil
  733. }
  734. // Converts UNSIGNED_SHORT or SHORT to UNSIGNED_INT
  735. if componentType == UNSIGNED_SHORT || componentType == SHORT {
  736. out := math32.NewArrayU32(count, count)
  737. for i := 0; i < count; i++ {
  738. out[i] = uint32(data[i*2]) + uint32(data[i*2+1])*256
  739. }
  740. return out, nil
  741. }
  742. // Converts UNSIGNED_BYTE or BYTE to UNSIGNED_INT
  743. if componentType == UNSIGNED_BYTE || componentType == BYTE {
  744. out := math32.NewArrayU32(count, count)
  745. for i := 0; i < count; i++ {
  746. out[i] = uint32(data[i])
  747. }
  748. return out, nil
  749. }
  750. return nil, fmt.Errorf("unsupported Accessor ComponentType:%v", componentType)
  751. }
  752. // bytesToArrayF32 converts a byte array to ArrayF32.
  753. func (g *GLTF) bytesToArrayF32(data []byte, componentType, count int) (math32.ArrayF32, error) {
  754. // If component is UNSIGNED_INT nothing to do
  755. if componentType == UNSIGNED_INT {
  756. arr := (*[1 << 30]float32)(unsafe.Pointer(&data[0]))[:count]
  757. return math32.ArrayF32(arr), nil
  758. }
  759. // Converts UNSIGNED_SHORT or SHORT to UNSIGNED_INT
  760. if componentType == UNSIGNED_SHORT || componentType == SHORT {
  761. out := math32.NewArrayF32(count, count)
  762. for i := 0; i < count; i++ {
  763. out[i] = float32(data[i*2]) + float32(data[i*2+1])*256
  764. }
  765. return out, nil
  766. }
  767. // Converts UNSIGNED_BYTE or BYTE to UNSIGNED_INT
  768. if componentType == UNSIGNED_BYTE || componentType == BYTE {
  769. out := math32.NewArrayF32(count, count)
  770. for i := 0; i < count; i++ {
  771. out[i] = float32(data[i])
  772. }
  773. return out, nil
  774. }
  775. return (*[1 << 30]float32)(unsafe.Pointer(&data[0]))[:count], nil
  776. }
  777. // loadAccessorU32 loads data from the specified accessor and performs validation of the Type and ComponentType.
  778. func (g *GLTF) loadAccessorU32(ai int, usage string, validTypes []string, validComponentTypes []int) (math32.ArrayU32, error) {
  779. // Get Accessor for the specified index
  780. ac := g.Accessors[ai]
  781. if ac.BufferView == nil {
  782. return nil, fmt.Errorf("accessor.BufferView == nil NOT SUPPORTED YET") // TODO
  783. }
  784. // Validate type and component type
  785. err := g.validateAccessor(ac, usage, validTypes, validComponentTypes)
  786. if err != nil {
  787. return nil, err
  788. }
  789. // Load bytes
  790. data, err := g.loadAccessorBytes(ac)
  791. if err != nil {
  792. return nil, err
  793. }
  794. return g.bytesToArrayU32(data, ac.ComponentType, ac.Count*TypeSizes[ac.Type])
  795. }
  796. // loadAccessorF32 loads data from the specified accessor and performs validation of the Type and ComponentType.
  797. func (g *GLTF) loadAccessorF32(ai int, usage string, validTypes []string, validComponentTypes []int) (math32.ArrayF32, error) {
  798. // Get Accessor for the specified index
  799. ac := g.Accessors[ai]
  800. if ac.BufferView == nil {
  801. return nil, fmt.Errorf("accessor.BufferView == nil NOT SUPPORTED YET") // TODO
  802. }
  803. // Validate type and component type
  804. err := g.validateAccessor(ac, usage, validTypes, validComponentTypes)
  805. if err != nil {
  806. return nil, err
  807. }
  808. // Load bytes
  809. data, err := g.loadAccessorBytes(ac)
  810. if err != nil {
  811. return nil, err
  812. }
  813. return g.bytesToArrayF32(data, ac.ComponentType, ac.Count*TypeSizes[ac.Type])
  814. }
  815. // loadAccessorBytes returns the base byte array used by an accessor.
  816. func (g *GLTF) loadAccessorBytes(ac Accessor) ([]byte, error) {
  817. // Get the Accessor's BufferView
  818. if ac.BufferView == nil {
  819. return nil, fmt.Errorf("accessor.BufferView == nil NOT SUPPORTED YET") // TODO
  820. }
  821. bv := g.BufferViews[*ac.BufferView]
  822. // Loads data from associated BufferView
  823. data, err := g.loadBufferView(*ac.BufferView)
  824. if err != nil {
  825. return nil, err
  826. }
  827. // Accessor offset into BufferView
  828. offset := 0
  829. if ac.ByteOffset != nil {
  830. offset = *ac.ByteOffset
  831. }
  832. data = data[offset:]
  833. // TODO check if interleaved and de-interleave if necessary?
  834. // Calculate the size in bytes of a complete attribute
  835. itemSize := TypeSizes[ac.Type]
  836. itemBytes := int(gls.FloatSize) * itemSize
  837. // If the BufferView stride is equal to the item size, the buffer is not interleaved
  838. if (bv.ByteStride != nil) && (*bv.ByteStride != itemBytes) {
  839. // BufferView data is interleaved, de-interleave
  840. // TODO
  841. return nil, fmt.Errorf("data is interleaved - not supported for animation yet")
  842. }
  843. // TODO Sparse accessor
  844. return data, nil
  845. }
  846. // isInterleaves returns whether the BufferView used by the provided accessor is interleaved.
  847. func (g *GLTF) isInterleaved(accessor Accessor) bool {
  848. // Get the Accessor's BufferView
  849. if accessor.BufferView == nil {
  850. return false
  851. }
  852. bv := g.BufferViews[*accessor.BufferView]
  853. // Calculates the size in bytes of a complete attribute
  854. itemSize := TypeSizes[accessor.Type]
  855. itemBytes := int(gls.FloatSize) * itemSize
  856. // If the BufferView stride is equal to the item size, the buffer is not interleaved
  857. if bv.ByteStride == nil {
  858. return false
  859. }
  860. if *bv.ByteStride == itemBytes {
  861. return false
  862. }
  863. return true
  864. }
  865. // loadBufferView loads and returns a byte slice with data from the specified BufferView.
  866. func (g *GLTF) loadBufferView(bvIdx int) ([]byte, error) {
  867. // Check if provided buffer view index is valid
  868. if bvIdx < 0 || bvIdx >= len(g.BufferViews) {
  869. return nil, fmt.Errorf("invalid buffer view index")
  870. }
  871. bvData := g.BufferViews[bvIdx]
  872. // Return cached if available
  873. if bvData.cache != nil {
  874. log.Debug("Fetching BufferView %d (cached)", bvIdx)
  875. return bvData.cache, nil
  876. }
  877. log.Debug("Loading BufferView %d", bvIdx)
  878. // Load buffer view buffer
  879. buf, err := g.loadBuffer(bvData.Buffer)
  880. if err != nil {
  881. return nil, err
  882. }
  883. // Establish offset
  884. offset := 0
  885. if bvData.ByteOffset != nil {
  886. offset = *bvData.ByteOffset
  887. }
  888. // Compute and return offset slice
  889. bvBytes := buf[offset : offset+bvData.ByteLength]
  890. // Cache buffer view
  891. g.BufferViews[bvIdx].cache = bvBytes
  892. return bvBytes, nil
  893. }
  894. // loadBuffer loads and returns the data from the specified GLTF Buffer index
  895. func (g *GLTF) loadBuffer(bufIdx int) ([]byte, error) {
  896. // Check if provided buffer index is valid
  897. if bufIdx < 0 || bufIdx >= len(g.Buffers) {
  898. return nil, fmt.Errorf("invalid buffer index")
  899. }
  900. bufData := &g.Buffers[bufIdx]
  901. // Return cached if available
  902. if bufData.cache != nil {
  903. log.Debug("Fetching Buffer %d (cached)", bufIdx)
  904. return bufData.cache, nil
  905. }
  906. log.Debug("Loading Buffer %d", bufIdx)
  907. // If buffer URI use the chunk data field
  908. if bufData.Uri == "" {
  909. return g.data, nil
  910. }
  911. // Checks if buffer URI is a data URI
  912. var data []byte
  913. var err error
  914. if isDataURL(bufData.Uri) {
  915. data, err = loadDataURL(bufData.Uri)
  916. } else {
  917. // Try to load buffer from file
  918. data, err = g.loadFileBytes(bufData.Uri)
  919. }
  920. if err != nil {
  921. return nil, err
  922. }
  923. // Checks data length
  924. if len(data) != bufData.ByteLength {
  925. return nil, fmt.Errorf("buffer:%d read data length:%d expected:%d", bufIdx, len(data), bufData.ByteLength)
  926. }
  927. // Cache buffer data
  928. g.Buffers[bufIdx].cache = data
  929. log.Debug("cache data:%v", len(bufData.cache))
  930. return data, nil
  931. }
  932. // loadFileBytes loads the file with specified path as a byte array.
  933. func (g *GLTF) loadFileBytes(uri string) ([]byte, error) {
  934. log.Debug("Loading File: %v", uri)
  935. fpath := filepath.Join(g.path, uri)
  936. f, err := os.Open(fpath)
  937. if err != nil {
  938. return nil, err
  939. }
  940. defer f.Close()
  941. data, err := ioutil.ReadAll(f)
  942. if err != nil {
  943. return nil, err
  944. }
  945. return data, nil
  946. }
  947. // dataURL describes a decoded data url string.
  948. type dataURL struct {
  949. MediaType string
  950. Encoding string
  951. Data string
  952. }
  953. const (
  954. dataURLprefix = "data:"
  955. mimeBIN = "application/octet-stream"
  956. mimePNG = "image/png"
  957. mimeJPEG = "image/jpeg"
  958. )
  959. var validMediaTypes = []string{mimeBIN, mimePNG, mimeJPEG}
  960. // isDataURL checks if the specified string has the prefix of data URL.
  961. func isDataURL(url string) bool {
  962. if strings.HasPrefix(url, dataURLprefix) {
  963. return true
  964. }
  965. return false
  966. }
  967. // loadDataURL decodes the specified data URI string (base64).
  968. func loadDataURL(url string) ([]byte, error) {
  969. var du dataURL
  970. err := parseDataURL(url, &du)
  971. if err != nil {
  972. return nil, err
  973. }
  974. // Checks for valid media type
  975. found := false
  976. for i := 0; i < len(validMediaTypes); i++ {
  977. if validMediaTypes[i] == du.MediaType {
  978. found = true
  979. break
  980. }
  981. }
  982. if !found {
  983. return nil, fmt.Errorf("data URI media type:%s not supported", du.MediaType)
  984. }
  985. // Checks encoding
  986. if du.Encoding != "base64" {
  987. return nil, fmt.Errorf("data URI encoding:%s not supported", du.Encoding)
  988. }
  989. // Decodes data from BASE64
  990. data, err := base64.StdEncoding.DecodeString(du.Data)
  991. if err != nil {
  992. return nil, err
  993. }
  994. return data, nil
  995. }
  996. // parseDataURL tries to parse the specified string as a data URL with the format:
  997. // data:[<mediatype>][;base64],<data>
  998. // and if successfull returns true and updates the specified pointer with the parsed fields.
  999. func parseDataURL(url string, du *dataURL) error {
  1000. // Check prefix
  1001. if !isDataURL(url) {
  1002. return fmt.Errorf("specified string is not a data URL")
  1003. }
  1004. // Separate header from data
  1005. body := url[len(dataURLprefix):]
  1006. parts := strings.Split(body, ",")
  1007. if len(parts) != 2 {
  1008. return fmt.Errorf("data URI contains more than one ','")
  1009. }
  1010. du.Data = parts[1]
  1011. // Separate media type from optional encoding
  1012. res := strings.Split(parts[0], ";")
  1013. du.MediaType = res[0]
  1014. if len(res) < 2 {
  1015. return nil
  1016. }
  1017. if len(res) >= 2 {
  1018. du.Encoding = res[1]
  1019. }
  1020. return nil
  1021. }