loader.go 31 KB

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