loader.go 32 KB

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