loader.go 32 KB

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