loader.go 32 KB

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