common.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442
  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. "bytes"
  7. "encoding/xml"
  8. "fmt"
  9. "io"
  10. "strconv"
  11. "strings"
  12. )
  13. //
  14. // Source
  15. //
  16. type Source struct {
  17. Id string // Source id
  18. Name string // Source name
  19. ArrayElement interface{} // Array element (FloatArray|others)
  20. TechniqueCommon struct {
  21. Accessor Accessor
  22. }
  23. }
  24. // Dump prints out information about the Source
  25. func (s *Source) Dump(out io.Writer, indent int) {
  26. fmt.Fprintf(out, "%sSource id:%s name:%s\n", sIndent(indent), s.Id, s.Name)
  27. ind := indent + step
  28. switch at := s.ArrayElement.(type) {
  29. case *FloatArray:
  30. at.Dump(out, ind)
  31. case *NameArray:
  32. at.Dump(out, ind)
  33. }
  34. fmt.Fprintf(out, "%sTechniqueCommon\n", sIndent(ind))
  35. s.TechniqueCommon.Accessor.Dump(out, ind+3)
  36. }
  37. //
  38. // NameArray
  39. //
  40. type NameArray struct {
  41. Id string
  42. Name string
  43. Count int
  44. Data []string
  45. }
  46. // Dump prints out information about the NameArray
  47. func (na *NameArray) Dump(out io.Writer, indent int) {
  48. fmt.Fprintf(out, "%sNameArray id:%s count:%d\n", sIndent(indent), na.Id, na.Count)
  49. ind := indent + step
  50. fmt.Fprintf(out, "%sData(%d):%s\n", sIndent(ind), len(na.Data), na.Data)
  51. }
  52. //
  53. // FloatArray
  54. //
  55. type FloatArray struct {
  56. Id string
  57. Count int
  58. Data []float32
  59. }
  60. // Dump prints out information about the FloatArray
  61. func (fa *FloatArray) Dump(out io.Writer, indent int) {
  62. fmt.Fprintf(out, "%sFloatArray id:%s count:%d\n", sIndent(indent), fa.Id, fa.Count)
  63. ind := indent + step
  64. fmt.Fprintf(out, "%sData(%d):%s\n", sIndent(ind), len(fa.Data), f32sToString(fa.Data, 20))
  65. }
  66. //
  67. // Accessor
  68. //
  69. type Accessor struct {
  70. Source string
  71. Count int
  72. Stride int
  73. Params []Param
  74. }
  75. // Dump prints out information about the Accessor
  76. func (ac *Accessor) Dump(out io.Writer, indent int) {
  77. fmt.Fprintf(out, "%sAccessor source:%s count:%d stride:%d\n",
  78. sIndent(indent), ac.Source, ac.Count, ac.Stride)
  79. ind := indent + step
  80. for _, p := range ac.Params {
  81. p.Dump(out, ind)
  82. }
  83. }
  84. //
  85. // Param for <bind_material> and <accessor>
  86. //
  87. type Param struct {
  88. Name string
  89. Type string
  90. }
  91. // Dump prints out information about the Param
  92. func (p *Param) Dump(out io.Writer, indent int) {
  93. fmt.Fprintf(out, "%sParam name:%s type:%s\n", sIndent(indent), p.Name, p.Type)
  94. }
  95. // decSource decodes the source from the specified mesh
  96. func (d *Decoder) decSource(start xml.StartElement) (*Source, error) {
  97. // Create source and adds it to the mesh
  98. source := new(Source)
  99. source.Id = findAttrib(start, "id").Value
  100. source.Name = findAttrib(start, "name").Value
  101. // Decodes source children
  102. for {
  103. // Get next child
  104. child, data, err := d.decNextChild(start)
  105. if err != nil || child.Name.Local == "" {
  106. return source, err
  107. }
  108. if child.Name.Local == "float_array" {
  109. err = d.decFloatArray(child, data, source)
  110. if err != nil {
  111. return nil, err
  112. }
  113. continue
  114. }
  115. if child.Name.Local == "Name_array" {
  116. err = d.decNameArray(child, data, source)
  117. if err != nil {
  118. return nil, err
  119. }
  120. continue
  121. }
  122. // Decodes technique_common which should contain an Acessor
  123. if child.Name.Local == "technique_common" {
  124. err = d.decSourceTechniqueCommon(child, source)
  125. if err != nil {
  126. return nil, err
  127. }
  128. continue
  129. }
  130. }
  131. }
  132. // decSource decodes the float array from the specified source
  133. func (d *Decoder) decFloatArray(start xml.StartElement, data []byte, source *Source) error {
  134. // Create float array and associates it to the parent source
  135. farray := &FloatArray{}
  136. farray.Id = findAttrib(start, "id").Value
  137. farray.Count, _ = strconv.Atoi(findAttrib(start, "count").Value)
  138. source.ArrayElement = farray
  139. // Allocates memory for array
  140. farray.Data = make([]float32, farray.Count, farray.Count)
  141. // Reads the numbers from the data
  142. err := decFloat32Sequence(data, farray.Data)
  143. if err != nil {
  144. return err
  145. }
  146. return nil
  147. }
  148. func (d *Decoder) decNameArray(start xml.StartElement, data []byte, source *Source) error {
  149. narray := new(NameArray)
  150. narray.Id = findAttrib(start, "id").Value
  151. narray.Count, _ = strconv.Atoi(findAttrib(start, "count").Value)
  152. source.ArrayElement = narray
  153. // Allocates memory for array
  154. narray.Data = make([]string, narray.Count, narray.Count)
  155. // Reads the strings from the data
  156. err := decStringSequence(data, narray.Data)
  157. if err != nil {
  158. return err
  159. }
  160. return nil
  161. }
  162. func (d *Decoder) decSourceTechniqueCommon(start xml.StartElement, source *Source) error {
  163. // Decodes source technique common children
  164. for {
  165. // Get next child
  166. child, _, err := d.decNextChild(start)
  167. if err != nil || child.Name.Local == "" {
  168. return err
  169. }
  170. //log.Debug("decSourceTechniqueCommon(%s): %s", start.Name.Local, child.Name.Local)
  171. if child.Name.Local == "accessor" {
  172. err = d.decAcessor(child, source)
  173. if err != nil {
  174. return err
  175. }
  176. continue
  177. }
  178. }
  179. }
  180. // decAcessore decodes the acessor from the specified source
  181. func (d *Decoder) decAcessor(start xml.StartElement, source *Source) error {
  182. // Sets accessor fields
  183. source.TechniqueCommon.Accessor.Source = findAttrib(start, "source").Value
  184. source.TechniqueCommon.Accessor.Count, _ = strconv.Atoi(findAttrib(start, "count").Value)
  185. source.TechniqueCommon.Accessor.Stride, _ = strconv.Atoi(findAttrib(start, "stride").Value)
  186. // Decodes accessor children
  187. for {
  188. // Get next child
  189. child, _, err := d.decNextChild(start)
  190. if err != nil || child.Name.Local == "" {
  191. return err
  192. }
  193. // param
  194. if child.Name.Local == "param" {
  195. err = d.decParam(child, &source.TechniqueCommon.Accessor)
  196. if err != nil {
  197. return err
  198. }
  199. }
  200. }
  201. }
  202. func (d *Decoder) decParam(start xml.StartElement, accessor *Accessor) error {
  203. p := Param{}
  204. p.Name = findAttrib(start, "name").Value
  205. p.Type = findAttrib(start, "type").Value
  206. accessor.Params = append(accessor.Params, p)
  207. return nil
  208. }
  209. func (d *Decoder) decNextChild(parent xml.StartElement) (xml.StartElement, []byte, error) {
  210. for {
  211. var tok interface{}
  212. var err error
  213. // Reads next token
  214. if d.lastToken == nil {
  215. tok, err = d.xmldec.Token()
  216. if err != nil {
  217. return xml.StartElement{}, nil, err
  218. }
  219. } else {
  220. tok = d.lastToken
  221. d.lastToken = nil
  222. }
  223. // Checks if it is the end element of this parent
  224. el, ok := tok.(xml.EndElement)
  225. if ok {
  226. if el.Name.Local == parent.Name.Local {
  227. return xml.StartElement{}, nil, nil
  228. }
  229. continue
  230. }
  231. // Checks if it is a start element
  232. start, ok := tok.(xml.StartElement)
  233. if !ok {
  234. continue
  235. }
  236. // Get this start element optional char data (should be next token)
  237. tok, err = d.xmldec.Token()
  238. if err != nil {
  239. return xml.StartElement{}, nil, err
  240. }
  241. // If token read is CharData, return the start element and its CharData
  242. cdata, ok := tok.(xml.CharData)
  243. if ok {
  244. return start, cdata, nil
  245. }
  246. // Token read was not CharData and was not processed
  247. // Save it into "lastToken" to be processed at the next call
  248. d.lastToken = tok
  249. return start, nil, nil
  250. }
  251. }
  252. func findAttrib(s xml.StartElement, name string) xml.Attr {
  253. for _, attr := range s.Attr {
  254. if attr.Name.Local == name {
  255. return attr
  256. }
  257. }
  258. return xml.Attr{}
  259. }
  260. const tokenSep string = " \r\n\t"
  261. type bytesReader struct {
  262. pos int
  263. source []byte
  264. }
  265. func (br *bytesReader) Init(source []byte) {
  266. br.pos = 0
  267. br.source = source
  268. }
  269. func (br *bytesReader) TokenNext() []byte {
  270. // Skip leading separators
  271. for br.pos < len(br.source) {
  272. if bytes.IndexByte([]byte(tokenSep), br.source[br.pos]) < 0 {
  273. break
  274. }
  275. br.pos++
  276. }
  277. if br.pos >= len(br.source) {
  278. return nil
  279. }
  280. // Advance till the end of the token
  281. start := br.pos
  282. for br.pos < len(br.source) {
  283. if bytes.IndexByte([]byte(tokenSep), br.source[br.pos]) >= 0 {
  284. break
  285. }
  286. br.pos++
  287. }
  288. res := br.source[start:br.pos]
  289. if len(res) == 0 {
  290. return nil
  291. }
  292. return res
  293. }
  294. const step = 3
  295. func sIndent(indent int) string {
  296. return strings.Repeat(" ", indent)
  297. }
  298. // decFloat32Sequence receives a byte slice with float numbers separated
  299. // by spaces and a preallocated destination slice.
  300. // It reads numbers from the source byte slice, converts them to float32 and
  301. // stores in the destination array.
  302. func decFloat32Sequence(cdata []byte, dest []float32) error {
  303. var br bytesReader
  304. br.Init(cdata)
  305. idx := 0
  306. for {
  307. tok := br.TokenNext()
  308. if tok == nil {
  309. break
  310. }
  311. if idx >= len(dest) {
  312. return fmt.Errorf("To much float array data")
  313. }
  314. v, err := strconv.ParseFloat(string(tok), 32)
  315. if err != nil {
  316. return err
  317. }
  318. dest[idx] = float32(v)
  319. idx++
  320. }
  321. if idx < len(dest)-1 {
  322. return fmt.Errorf("Expected %d floats, got %d", len(dest), idx)
  323. }
  324. return nil
  325. }
  326. // decStringSequence receives a byte slice with strings separated
  327. // by spaces and a preallocated destination slice.
  328. // It reads strings from the source byte slice and
  329. // stores in the destination array.
  330. func decStringSequence(cdata []byte, dest []string) error {
  331. var br bytesReader
  332. br.Init(cdata)
  333. idx := 0
  334. for {
  335. tok := br.TokenNext()
  336. if tok == nil {
  337. break
  338. }
  339. if idx >= len(dest) {
  340. return fmt.Errorf("To many string array data")
  341. }
  342. dest[idx] = string(tok)
  343. idx++
  344. }
  345. if idx < len(dest)-1 {
  346. return fmt.Errorf("Expected %d strings, got %d", len(dest), idx)
  347. }
  348. return nil
  349. }
  350. func f32sToString(a []float32, max int) string {
  351. parts := []string{"["}
  352. if len(a) > max {
  353. for i := 0; i < max/2; i++ {
  354. parts = append(parts, strconv.FormatFloat(float64(a[i]), 'f', -1, 32))
  355. }
  356. parts = append(parts, " ... ")
  357. for i := len(a) - max/2; i < len(a); i++ {
  358. parts = append(parts, strconv.FormatFloat(float64(a[i]), 'f', -1, 32))
  359. }
  360. } else {
  361. for i := 0; i < len(a); i++ {
  362. parts = append(parts, strconv.FormatFloat(float64(a[i]), 'f', -1, 32))
  363. }
  364. }
  365. parts = append(parts, "]")
  366. return strings.Join(parts, " ")
  367. }
  368. func intsToString(a []int, max int) string {
  369. parts := []string{"["}
  370. if len(a) > max {
  371. for i := 0; i < max/2; i++ {
  372. parts = append(parts, strconv.FormatInt(int64(a[i]), 10))
  373. }
  374. parts = append(parts, " ... ")
  375. for i := len(a) - max/2; i < len(a); i++ {
  376. parts = append(parts, strconv.FormatInt(int64(a[i]), 10))
  377. }
  378. } else {
  379. for i := 0; i < len(a); i++ {
  380. parts = append(parts, strconv.FormatInt(int64(a[i]), 10))
  381. }
  382. }
  383. parts = append(parts, "]")
  384. return strings.Join(parts, " ")
  385. }