library_visual_scenes.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  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. // LibraryVisualScenes
  13. //
  14. type LibraryVisualScenes struct {
  15. Asset *Asset
  16. VisualScene []*VisualScene
  17. }
  18. // Dump prints out information about the LibraryVisualScenes
  19. func (lv *LibraryVisualScenes) Dump(out io.Writer, indent int) {
  20. if lv == nil {
  21. return
  22. }
  23. fmt.Fprintf(out, "%sLibraryVisualScenes:\n", sIndent(indent))
  24. ind := indent + step
  25. if lv.Asset != nil {
  26. lv.Asset.Dump(out, ind)
  27. }
  28. for _, vs := range lv.VisualScene {
  29. vs.Dump(out, ind)
  30. }
  31. }
  32. //
  33. // VisualScene contains all the nodes of a visual scene
  34. //
  35. type VisualScene struct {
  36. Id string
  37. Name string
  38. Node []*Node // Array of nodes
  39. }
  40. // Dump prints out information about the VisualScene
  41. func (vs *VisualScene) Dump(out io.Writer, indent int) {
  42. fmt.Fprintf(out, "%sVisualScene id:%s name:%s\n", sIndent(indent), vs.Id, vs.Name)
  43. for _, n := range vs.Node {
  44. n.Dump(out, indent+step)
  45. }
  46. }
  47. //
  48. // Node is embedded in each node instance
  49. //
  50. type Node struct {
  51. Id string
  52. Name string
  53. Sid string
  54. Type string
  55. Layer []string
  56. TransformationElements []interface{} // Node instance type (may be nil)
  57. Instance interface{}
  58. Node []*Node // Array of children nodes
  59. }
  60. // Dump prints out information about the Node
  61. func (n *Node) Dump(out io.Writer, indent int) {
  62. fmt.Fprintf(out, "%sNode id:%s name:%s sid:%s type:%s layer:%v\n",
  63. sIndent(indent), n.Id, n.Name, n.Sid, n.Type, n.Layer)
  64. // Dump transformation elements
  65. for _, te := range n.TransformationElements {
  66. switch tt := te.(type) {
  67. case *Matrix:
  68. tt.Dump(out, indent+step)
  69. case *Rotate:
  70. tt.Dump(out, indent+step)
  71. case *Scale:
  72. tt.Dump(out, indent+step)
  73. case *Translate:
  74. tt.Dump(out, indent+step)
  75. }
  76. }
  77. // Dump instance type
  78. switch it := n.Instance.(type) {
  79. case *InstanceGeometry:
  80. it.Dump(out, indent+step)
  81. }
  82. // Dump node children
  83. for _, n := range n.Node {
  84. n.Dump(out, indent+step)
  85. }
  86. }
  87. //
  88. // Matrix
  89. //
  90. type Matrix struct {
  91. Sid string
  92. Data [16]float32
  93. }
  94. // Dump prints out information about the Matrix
  95. func (m *Matrix) Dump(out io.Writer, indent int) {
  96. fmt.Fprintf(out, "%sMatrix sid:%s data:%v\n", sIndent(indent), m.Sid, m.Data)
  97. }
  98. //
  99. // Rotate
  100. //
  101. type Rotate struct {
  102. Sid string
  103. Data [4]float32
  104. }
  105. // Dump prints out information about the Rotate
  106. func (r *Rotate) Dump(out io.Writer, indent int) {
  107. fmt.Fprintf(out, "%sRotate sid:%s data:%v\n", sIndent(indent), r.Sid, r.Data)
  108. }
  109. //
  110. // Translate
  111. //
  112. type Translate struct {
  113. Sid string
  114. Data [3]float32
  115. }
  116. // Dump prints out information about the Translate
  117. func (t *Translate) Dump(out io.Writer, indent int) {
  118. fmt.Fprintf(out, "%sTranslate sid:%s data:%v\n", sIndent(indent), t.Sid, t.Data)
  119. }
  120. //
  121. // Scale
  122. //
  123. type Scale struct {
  124. Sid string
  125. Data [3]float32
  126. }
  127. // Dump prints out information about the Scale
  128. func (s *Scale) Dump(out io.Writer, indent int) {
  129. fmt.Fprintf(out, "%sScale sid:%s data:%v\n", sIndent(indent), s.Sid, s.Data)
  130. }
  131. //
  132. // InstanceGeometry
  133. //
  134. type InstanceGeometry struct {
  135. Url string // Geometry URL (required) references the ID of a Geometry
  136. Name string // name of this element (optional)
  137. BindMaterial *BindMaterial
  138. }
  139. // Dump prints out information about the InstanceGeometry
  140. func (ig *InstanceGeometry) Dump(out io.Writer, indent int) {
  141. fmt.Fprintf(out, "%sInstanceGeometry url:%s name:%s\n", sIndent(indent), ig.Url, ig.Name)
  142. if ig.BindMaterial != nil {
  143. ig.BindMaterial.Dump(out, indent+step)
  144. }
  145. }
  146. //
  147. // BindMaterial
  148. //
  149. type BindMaterial struct {
  150. Params []Param
  151. TechniqueCommon struct {
  152. InstanceMaterial []*InstanceMaterial
  153. }
  154. }
  155. // Dump prints out information about the BindMaterial
  156. func (bm *BindMaterial) Dump(out io.Writer, indent int) {
  157. fmt.Fprintf(out, "%sBindMaterial\n", sIndent(indent))
  158. ind := indent + step
  159. fmt.Fprintf(out, "%sTechniqueCommon\n", sIndent(ind))
  160. ind += step
  161. for _, im := range bm.TechniqueCommon.InstanceMaterial {
  162. im.Dump(out, ind)
  163. }
  164. }
  165. //
  166. // InstanceMaterial
  167. //
  168. type InstanceMaterial struct {
  169. Sid string
  170. Name string
  171. Target string
  172. Symbol string
  173. Bind []Bind
  174. BindVertexInput []BindVertexInput
  175. }
  176. // Dump prints out information about the InstanceMaterial
  177. func (im *InstanceMaterial) Dump(out io.Writer, indent int) {
  178. fmt.Fprintf(out, "%sInstanceMaterial sid:%s name:%s target:%s symbol:%s\n",
  179. sIndent(indent), im.Sid, im.Name, im.Target, im.Symbol)
  180. ind := indent + step
  181. for _, bvi := range im.BindVertexInput {
  182. bvi.Dump(out, ind)
  183. }
  184. }
  185. //
  186. // Bind
  187. //
  188. type Bind struct {
  189. Semantic string
  190. Target string
  191. }
  192. //
  193. // BindVertexInput
  194. //
  195. type BindVertexInput struct {
  196. Semantic string
  197. InputSemantic string
  198. InputSet uint
  199. }
  200. // Dump prints out information about the BindVertexInput
  201. func (bvi *BindVertexInput) Dump(out io.Writer, indent int) {
  202. fmt.Fprintf(out, "%sBindVertexInput semantic:%s InputSemantic:%s InputSet:%d\n",
  203. sIndent(indent), bvi.Semantic, bvi.InputSemantic, bvi.InputSet)
  204. }
  205. func (d *Decoder) decLibraryVisualScenes(start xml.StartElement, dom *Collada) error {
  206. lv := new(LibraryVisualScenes)
  207. dom.LibraryVisualScenes = lv
  208. for {
  209. // Get next child element
  210. child, _, err := d.decNextChild(start)
  211. if err != nil || child.Name.Local == "" {
  212. return err
  213. }
  214. // Decodes VisualScene
  215. if child.Name.Local == "visual_scene" {
  216. err = d.decVisualScene(child, lv)
  217. if err != nil {
  218. return err
  219. }
  220. continue
  221. }
  222. }
  223. return nil
  224. }
  225. func (d *Decoder) decVisualScene(vsStart xml.StartElement, lv *LibraryVisualScenes) error {
  226. // Get attributes and appends new visual scene
  227. vs := &VisualScene{}
  228. vs.Id = findAttrib(vsStart, "id").Value
  229. vs.Name = findAttrib(vsStart, "name").Value
  230. vs.Node = make([]*Node, 0)
  231. lv.VisualScene = append(lv.VisualScene, vs)
  232. // Decodes visual scene children
  233. for {
  234. // Get next child element
  235. child, _, err := d.decNextChild(vsStart)
  236. if err != nil || child.Name.Local == "" {
  237. return err
  238. }
  239. // Decodes Node
  240. if child.Name.Local == "node" {
  241. err = d.decNode(child, &vs.Node)
  242. if err != nil {
  243. return err
  244. }
  245. }
  246. }
  247. return nil
  248. }
  249. func (d *Decoder) decNode(nodeStart xml.StartElement, parent *[]*Node) error {
  250. // Get node attributes and appends the new node to its parent
  251. n := &Node{}
  252. n.Id = findAttrib(nodeStart, "id").Value
  253. n.Name = findAttrib(nodeStart, "name").Value
  254. n.Sid = findAttrib(nodeStart, "name").Value
  255. n.Type = findAttrib(nodeStart, "type").Value
  256. n.Node = make([]*Node, 0)
  257. *parent = append(*parent, n)
  258. // Decodes node children
  259. for {
  260. // Get next child element
  261. child, data, err := d.decNextChild(nodeStart)
  262. if err != nil || child.Name.Local == "" {
  263. return err
  264. }
  265. if child.Name.Local == "matrix" {
  266. err = d.decMatrix(data, n)
  267. if err != nil {
  268. return err
  269. }
  270. continue
  271. }
  272. if child.Name.Local == "rotate" {
  273. err = d.decRotate(data, n)
  274. if err != nil {
  275. return err
  276. }
  277. continue
  278. }
  279. if child.Name.Local == "scale" {
  280. err = d.decScale(data, n)
  281. if err != nil {
  282. return err
  283. }
  284. continue
  285. }
  286. if child.Name.Local == "translate" {
  287. err = d.decTranslate(data, n)
  288. if err != nil {
  289. return err
  290. }
  291. continue
  292. }
  293. if child.Name.Local == "instance_geometry" {
  294. err = d.decInstanceGeometry(child, n)
  295. if err != nil {
  296. return err
  297. }
  298. continue
  299. }
  300. // Decodes child node recursively
  301. if child.Name.Local == "node" {
  302. err = d.decNode(child, &n.Node)
  303. if err != nil {
  304. return err
  305. }
  306. continue
  307. }
  308. }
  309. return nil
  310. }
  311. func (d *Decoder) decMatrix(cdata []byte, n *Node) error {
  312. mat := new(Matrix)
  313. n.TransformationElements = append(n.TransformationElements, mat)
  314. err := decFloat32Sequence(cdata, mat.Data[0:16])
  315. if err != nil {
  316. return err
  317. }
  318. return nil
  319. }
  320. func (d *Decoder) decRotate(cdata []byte, n *Node) error {
  321. rot := new(Rotate)
  322. n.TransformationElements = append(n.TransformationElements, rot)
  323. err := decFloat32Sequence(cdata, rot.Data[0:4])
  324. if err != nil {
  325. return err
  326. }
  327. return nil
  328. }
  329. func (d *Decoder) decTranslate(cdata []byte, n *Node) error {
  330. tr := new(Translate)
  331. n.TransformationElements = append(n.TransformationElements, tr)
  332. err := decFloat32Sequence(cdata, tr.Data[0:3])
  333. if err != nil {
  334. return err
  335. }
  336. return nil
  337. }
  338. func (d *Decoder) decScale(cdata []byte, n *Node) error {
  339. s := new(Scale)
  340. n.TransformationElements = append(n.TransformationElements, s)
  341. err := decFloat32Sequence(cdata, s.Data[0:3])
  342. if err != nil {
  343. return err
  344. }
  345. return nil
  346. }
  347. func (d *Decoder) decInstanceGeometry(start xml.StartElement, n *Node) error {
  348. // Creates new InstanceGeometry,sets its attributes and associates with node
  349. ig := new(InstanceGeometry)
  350. ig.Url = findAttrib(start, "url").Value
  351. ig.Name = findAttrib(start, "name").Value
  352. n.Instance = ig
  353. // Decodes instance geometry children
  354. for {
  355. // Get next child element
  356. child, _, err := d.decNextChild(start)
  357. if err != nil || child.Name.Local == "" {
  358. return err
  359. }
  360. // Decodes bind_material
  361. if child.Name.Local == "bind_material" {
  362. err := d.decBindMaterial(child, &ig.BindMaterial)
  363. if err != nil {
  364. return err
  365. }
  366. continue
  367. }
  368. }
  369. return nil
  370. }
  371. func (d *Decoder) decBindMaterial(start xml.StartElement, dest **BindMaterial) error {
  372. *dest = new(BindMaterial)
  373. for {
  374. // Get next child element
  375. child, _, err := d.decNextChild(start)
  376. if err != nil || child.Name.Local == "" {
  377. return err
  378. }
  379. if child.Name.Local == "technique_common" {
  380. err := d.decBindMaterialTechniqueCommon(child, *dest)
  381. if err != nil {
  382. return err
  383. }
  384. continue
  385. }
  386. }
  387. return nil
  388. }
  389. func (d *Decoder) decBindMaterialTechniqueCommon(start xml.StartElement, bm *BindMaterial) error {
  390. for {
  391. // Get next child element
  392. child, _, err := d.decNextChild(start)
  393. if err != nil || child.Name.Local == "" {
  394. return err
  395. }
  396. if child.Name.Local == "instance_material" {
  397. err := d.decInstanceMaterial(child, bm)
  398. if err != nil {
  399. return err
  400. }
  401. continue
  402. }
  403. }
  404. return nil
  405. }
  406. func (d *Decoder) decInstanceMaterial(start xml.StartElement, bm *BindMaterial) error {
  407. im := new(InstanceMaterial)
  408. im.Sid = findAttrib(start, "sid").Value
  409. im.Name = findAttrib(start, "name").Value
  410. im.Target = findAttrib(start, "target").Value
  411. im.Symbol = findAttrib(start, "symbol").Value
  412. bm.TechniqueCommon.InstanceMaterial = append(bm.TechniqueCommon.InstanceMaterial, im)
  413. for {
  414. child, _, err := d.decNextChild(start)
  415. if err != nil || child.Name.Local == "" {
  416. return err
  417. }
  418. if child.Name.Local == "bind_vertex_input" {
  419. var bvi BindVertexInput
  420. bvi.Semantic = findAttrib(child, "semantic").Value
  421. bvi.InputSemantic = findAttrib(child, "input_semantic").Value
  422. v, err := strconv.Atoi(findAttrib(child, "input_set").Value)
  423. if err != nil {
  424. return err
  425. }
  426. bvi.InputSet = uint(v)
  427. im.BindVertexInput = append(im.BindVertexInput, bvi)
  428. continue
  429. }
  430. }
  431. return nil
  432. }