library_geometries.go 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  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 collada
  5. import (
  6. "encoding/xml"
  7. "fmt"
  8. "io"
  9. "strconv"
  10. )
  11. //
  12. // Library Geometries
  13. //
  14. type LibraryGeometries struct {
  15. Asset *Asset
  16. Geometry []*Geometry
  17. }
  18. func (lg *LibraryGeometries) Dump(out io.Writer, indent int) {
  19. if lg == nil {
  20. return
  21. }
  22. fmt.Fprintf(out, "%sLibraryGeometries:\n", sIndent(indent))
  23. ind := indent + step
  24. if lg.Asset != nil {
  25. lg.Asset.Dump(out, ind)
  26. }
  27. for _, g := range lg.Geometry {
  28. g.Dump(out, ind)
  29. }
  30. }
  31. //
  32. // Geometry
  33. //
  34. type Geometry struct {
  35. Id string // Geometry id (optional)
  36. Name string // Geometry name (optional)
  37. GeometricElement interface{} // Geometry type object (Mesh|others)
  38. }
  39. func (g *Geometry) Dump(out io.Writer, indent int) {
  40. fmt.Fprintf(out, "%sGeometry id:%s name:%s\n", sIndent(indent), g.Id, g.Name)
  41. ind := indent + step
  42. switch gt := g.GeometricElement.(type) {
  43. case *Mesh:
  44. gt.Dump(out, ind)
  45. break
  46. }
  47. }
  48. //
  49. // Mesh
  50. //
  51. type Mesh struct {
  52. Source []*Source // One or more sources Sources
  53. Vertices Vertices // Vertices positions
  54. PrimitiveElements []interface{} // Geometry primitives (polylist|others)
  55. }
  56. func (m *Mesh) Dump(out io.Writer, indent int) {
  57. fmt.Fprintf(out, "%sMesh:\n", sIndent(indent))
  58. ind := indent + step
  59. for _, s := range m.Source {
  60. s.Dump(out, ind)
  61. }
  62. m.Vertices.Dump(out, ind)
  63. for _, pe := range m.PrimitiveElements {
  64. switch pt := pe.(type) {
  65. case *Lines:
  66. pt.Dump(out, ind)
  67. case *Polylist:
  68. pt.Dump(out, ind)
  69. }
  70. }
  71. }
  72. //
  73. // Vertices
  74. //
  75. type Vertices struct {
  76. Id string
  77. Name string
  78. Input []Input
  79. }
  80. func (v *Vertices) Dump(out io.Writer, indent int) {
  81. fmt.Fprintf(out, "%sVertices id:%s name:%s\n", sIndent(indent), v.Id, v.Name)
  82. for _, inp := range v.Input {
  83. inp.Dump(out, indent+step)
  84. }
  85. }
  86. //
  87. // Input
  88. //
  89. type Input struct {
  90. Semantic string
  91. Source string // source URL
  92. }
  93. func (i *Input) Dump(out io.Writer, indent int) {
  94. fmt.Fprintf(out, "%sInput semantic:%s source:%s\n", sIndent(indent), i.Semantic, i.Source)
  95. }
  96. //
  97. // Polylist
  98. //
  99. type Polylist struct {
  100. Name string
  101. Count int
  102. Material string
  103. Input []InputShared
  104. Vcount []int
  105. P []int
  106. }
  107. func (pl *Polylist) Dump(out io.Writer, indent int) {
  108. fmt.Fprintf(out, "%sPolylist name:%s count:%d material:%s\n", sIndent(indent), pl.Name, pl.Count, pl.Material)
  109. ind := indent + step
  110. for _, is := range pl.Input {
  111. is.Dump(out, ind)
  112. }
  113. fmt.Fprintf(out, "%sVcount(%d):%v\n", sIndent(ind), len(pl.Vcount), intsToString(pl.Vcount, 20))
  114. fmt.Fprintf(out, "%sP(%d):%v\n", sIndent(ind), len(pl.P), intsToString(pl.P, 20))
  115. }
  116. //
  117. // InputShared
  118. //
  119. type InputShared struct {
  120. Offset int
  121. Semantic string
  122. Source string // source URL
  123. Set int
  124. }
  125. //
  126. // Triangles
  127. //
  128. type Triangles struct {
  129. Name string
  130. Count int
  131. Material string
  132. Input []InputShared
  133. P []int
  134. }
  135. //
  136. // Lines
  137. //
  138. type Lines struct {
  139. Name string
  140. Count int
  141. Material string
  142. Input []InputShared
  143. P []int
  144. }
  145. func (ln *Lines) Dump(out io.Writer, indent int) {
  146. fmt.Fprintf(out, "%sLines name:%s count:%d material:%s\n", sIndent(indent), ln.Name, ln.Count, ln.Material)
  147. ind := indent + step
  148. for _, is := range ln.Input {
  149. is.Dump(out, ind)
  150. }
  151. fmt.Fprintf(out, "%sP(%d):%v\n", sIndent(ind), len(ln.P), intsToString(ln.P, 20))
  152. }
  153. //
  154. // LineStrips
  155. //
  156. type LineStrips struct {
  157. Name string
  158. Count int
  159. Material string
  160. Input []InputShared
  161. P []int
  162. }
  163. //
  164. // Trifans
  165. //
  166. type Trifans struct {
  167. Name string
  168. Count int
  169. Material string
  170. Input []InputShared
  171. P []int
  172. }
  173. //
  174. // Tristrips
  175. //
  176. type Tristrips struct {
  177. Name string
  178. Count int
  179. Material string
  180. Input []InputShared
  181. P []int
  182. }
  183. func (is *InputShared) Dump(out io.Writer, indent int) {
  184. fmt.Fprintf(out, "%sInputShared offset:%d semantic:%s source:%s set:%d\n",
  185. sIndent(indent), is.Offset, is.Semantic, is.Source, is.Set)
  186. }
  187. // Decodes "library_geometry" children
  188. func (d *Decoder) decLibraryGeometries(start xml.StartElement, dom *Collada) error {
  189. lg := new(LibraryGeometries)
  190. dom.LibraryGeometries = lg
  191. for {
  192. // Get next child START
  193. child, _, err := d.decNextChild(start)
  194. if err != nil || child.Name.Local == "" {
  195. return err
  196. }
  197. // Decode optional asset
  198. if child.Name.Local == "asset" {
  199. lg.Asset = new(Asset)
  200. err = d.decAsset(child, lg.Asset)
  201. if err != nil {
  202. return err
  203. }
  204. continue
  205. }
  206. //log.Debug("decLibraryGeometries: %s", child.Name.Local)
  207. // Decode geometry
  208. if child.Name.Local == "geometry" {
  209. err = d.decGeometry(child, lg)
  210. if err != nil {
  211. return err
  212. }
  213. continue
  214. }
  215. }
  216. return nil
  217. }
  218. // decGeometry receives the start element of a geometry and
  219. // decodes all its children and appends the decoded geometry
  220. // to the specified slice.
  221. func (d *Decoder) decGeometry(start xml.StartElement, lg *LibraryGeometries) error {
  222. // Get geometry id and name attributes
  223. geom := &Geometry{}
  224. geom.Id = findAttrib(start, "id").Value
  225. geom.Name = findAttrib(start, "name").Value
  226. lg.Geometry = append(lg.Geometry, geom)
  227. // Decodes geometry children
  228. for {
  229. // Get next child
  230. child, _, err := d.decNextChild(start)
  231. if err != nil || child.Name.Local == "" {
  232. return err
  233. }
  234. // Decode mesh
  235. if child.Name.Local == "mesh" {
  236. err = d.decMesh(child, geom)
  237. if err != nil {
  238. return err
  239. }
  240. continue
  241. }
  242. }
  243. return nil
  244. }
  245. // decMesh decodes the mesh from the specified geometry
  246. func (d *Decoder) decMesh(start xml.StartElement, geom *Geometry) error {
  247. // Associates this mesh to the parent geometry
  248. mesh := &Mesh{}
  249. geom.GeometricElement = mesh
  250. // Decodes mesh children
  251. for {
  252. // Get next child
  253. child, _, err := d.decNextChild(start)
  254. if err != nil || child.Name.Local == "" {
  255. return err
  256. }
  257. //log.Debug("decMesh(%s): %s", start.Name.Local, child.Name.Local)
  258. // Decodes source
  259. if child.Name.Local == "source" {
  260. source, err := d.decSource(child)
  261. if err != nil {
  262. return err
  263. }
  264. mesh.Source = append(mesh.Source, source)
  265. continue
  266. }
  267. // Decodes vertices
  268. if child.Name.Local == "vertices" {
  269. err = d.decVertices(child, mesh)
  270. if err != nil {
  271. return err
  272. }
  273. continue
  274. }
  275. // Decodes lines
  276. if child.Name.Local == "lines" {
  277. err = d.decLines(child, mesh)
  278. if err != nil {
  279. return err
  280. }
  281. continue
  282. }
  283. // Decodes polylist
  284. if child.Name.Local == "polylist" {
  285. err = d.decPolylist(child, mesh)
  286. if err != nil {
  287. return err
  288. }
  289. continue
  290. }
  291. }
  292. return nil
  293. }
  294. func (d *Decoder) decVertices(start xml.StartElement, mesh *Mesh) error {
  295. mesh.Vertices.Id = findAttrib(start, "id").Value
  296. mesh.Vertices.Name = findAttrib(start, "name").Value
  297. for {
  298. // Get next child
  299. child, _, err := d.decNextChild(start)
  300. if err != nil || child.Name.Local == "" {
  301. return err
  302. }
  303. // input
  304. if child.Name.Local == "input" {
  305. inp, err := d.decInput(child)
  306. if err != nil {
  307. return err
  308. }
  309. mesh.Vertices.Input = append(mesh.Vertices.Input, inp)
  310. }
  311. }
  312. return nil
  313. }
  314. func (d *Decoder) decInput(start xml.StartElement) (Input, error) {
  315. var inp Input
  316. inp.Semantic = findAttrib(start, "semantic").Value
  317. inp.Source = findAttrib(start, "source").Value
  318. return inp, nil
  319. }
  320. func (d *Decoder) decLines(start xml.StartElement, mesh *Mesh) error {
  321. ln := &Lines{}
  322. ln.Name = findAttrib(start, "name").Value
  323. ln.Count, _ = strconv.Atoi(findAttrib(start, "count").Value)
  324. ln.Material = findAttrib(start, "material").Value
  325. mesh.PrimitiveElements = append(mesh.PrimitiveElements, ln)
  326. for {
  327. // Get next child
  328. child, data, err := d.decNextChild(start)
  329. if err != nil || child.Name.Local == "" {
  330. return err
  331. }
  332. // Decode input shared
  333. if child.Name.Local == "input" {
  334. inp, err := d.decInputShared(child)
  335. if err != nil {
  336. return err
  337. }
  338. ln.Input = append(ln.Input, inp)
  339. continue
  340. }
  341. // Decode p (primitive)
  342. if child.Name.Local == "p" {
  343. p, err := d.decPrimitive(child, data)
  344. if err != nil {
  345. return err
  346. }
  347. ln.P = p
  348. }
  349. }
  350. return nil
  351. }
  352. func (d *Decoder) decPolylist(start xml.StartElement, mesh *Mesh) error {
  353. pl := &Polylist{}
  354. pl.Name = findAttrib(start, "name").Value
  355. pl.Count, _ = strconv.Atoi(findAttrib(start, "count").Value)
  356. pl.Material = findAttrib(start, "material").Value
  357. mesh.PrimitiveElements = append(mesh.PrimitiveElements, pl)
  358. for {
  359. // Get next child
  360. child, data, err := d.decNextChild(start)
  361. if err != nil || child.Name.Local == "" {
  362. return err
  363. }
  364. // Decode input shared
  365. if child.Name.Local == "input" {
  366. inp, err := d.decInputShared(child)
  367. if err != nil {
  368. return err
  369. }
  370. pl.Input = append(pl.Input, inp)
  371. continue
  372. }
  373. // Decode vcount
  374. if child.Name.Local == "vcount" {
  375. vc, err := d.decVcount(child, data, pl.Count)
  376. if err != nil {
  377. return err
  378. }
  379. pl.Vcount = vc
  380. continue
  381. }
  382. // Decode p (primitive)
  383. if child.Name.Local == "p" {
  384. p, err := d.decPrimitive(child, data)
  385. if err != nil {
  386. return err
  387. }
  388. pl.P = p
  389. }
  390. }
  391. return nil
  392. }
  393. func (d *Decoder) decInputShared(start xml.StartElement) (InputShared, error) {
  394. var inp InputShared
  395. inp.Offset, _ = strconv.Atoi(findAttrib(start, "offset").Value)
  396. inp.Semantic = findAttrib(start, "semantic").Value
  397. inp.Source = findAttrib(start, "source").Value
  398. inp.Set, _ = strconv.Atoi(findAttrib(start, "set").Value)
  399. return inp, nil
  400. }
  401. func (d *Decoder) decVcount(start xml.StartElement, data []byte, size int) ([]int, error) {
  402. vcount := make([]int, size)
  403. var br bytesReader
  404. br.Init(data)
  405. idx := 0
  406. for {
  407. tok := br.TokenNext()
  408. if tok == nil {
  409. break
  410. }
  411. v, err := strconv.Atoi(string(tok))
  412. if err != nil {
  413. return nil, err
  414. }
  415. vcount[idx] = v
  416. idx++
  417. }
  418. return vcount, nil
  419. }
  420. func (d *Decoder) decPrimitive(start xml.StartElement, data []byte) ([]int, error) {
  421. p := make([]int, 0)
  422. var br bytesReader
  423. br.Init(data)
  424. idx := 0
  425. for {
  426. tok := br.TokenNext()
  427. if tok == nil {
  428. break
  429. }
  430. v, err := strconv.Atoi(string(tok))
  431. if err != nil {
  432. return nil, err
  433. }
  434. p = append(p, v)
  435. idx++
  436. }
  437. return p, nil
  438. }