library_effects.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717
  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. // LibraryEffects
  13. //
  14. type LibraryEffects struct {
  15. Id string
  16. Name string
  17. Asset *Asset
  18. Effect []*Effect
  19. }
  20. // Dump prints out information about the LibraryEffects
  21. func (le *LibraryEffects) Dump(out io.Writer, indent int) {
  22. if le == nil {
  23. return
  24. }
  25. fmt.Fprintf(out, "%sLibraryEffects id:%s name:%s\n", sIndent(indent), le.Id, le.Name)
  26. for _, ef := range le.Effect {
  27. ef.Dump(out, indent+step)
  28. }
  29. }
  30. //
  31. // Effect
  32. //
  33. type Effect struct {
  34. Id string
  35. Name string
  36. Asset *Asset
  37. Profile []interface{}
  38. }
  39. // Dump prints out information about the Effect
  40. func (ef *Effect) Dump(out io.Writer, indent int) {
  41. fmt.Printf("%sEffect id:%s name:%s\n", sIndent(indent), ef.Id, ef.Name)
  42. ind := indent + step
  43. for _, p := range ef.Profile {
  44. switch pt := p.(type) {
  45. case *ProfileCOMMON:
  46. pt.Dump(out, ind)
  47. break
  48. }
  49. }
  50. }
  51. //
  52. // ProfileCOMMON
  53. //
  54. type ProfileCOMMON struct {
  55. Id string
  56. Asset *Asset
  57. Newparam []*Newparam
  58. Technique struct {
  59. Id string
  60. Sid string
  61. Asset *Asset
  62. ShaderElement interface{} // Blinn|Constant|Lambert|Phong
  63. }
  64. }
  65. // Dump prints out information about the ProfileCOMMON
  66. func (pc *ProfileCOMMON) Dump(out io.Writer, indent int) {
  67. fmt.Printf("%sProfileCOMMON id:%s\n", sIndent(indent), pc.Id)
  68. ind := indent + step
  69. for _, np := range pc.Newparam {
  70. np.Dump(out, ind)
  71. }
  72. fmt.Printf("%sTechnique id:%s sid:%s\n", sIndent(ind), pc.Technique.Id, pc.Technique.Sid)
  73. ind += step
  74. switch sh := pc.Technique.ShaderElement.(type) {
  75. case *Phong:
  76. sh.Dump(out, ind)
  77. break
  78. }
  79. }
  80. //
  81. // Newparam
  82. //
  83. type Newparam struct {
  84. Sid string
  85. Semantic string
  86. ParameterType interface{}
  87. }
  88. // Dump prints out information about the Newparam
  89. func (np *Newparam) Dump(out io.Writer, indent int) {
  90. fmt.Printf("%sNewparam sid:%s\n", sIndent(indent), np.Sid)
  91. ind := indent + step
  92. switch pt := np.ParameterType.(type) {
  93. case *Surface:
  94. pt.Dump(out, ind)
  95. case *Sampler2D:
  96. pt.Dump(out, ind)
  97. }
  98. }
  99. //
  100. // Surface
  101. //
  102. type Surface struct {
  103. Type string
  104. Init interface{}
  105. }
  106. // Dump prints out information about the Surface
  107. func (sf *Surface) Dump(out io.Writer, indent int) {
  108. fmt.Printf("%sSurface type:%s\n", sIndent(indent), sf.Type)
  109. ind := indent + step
  110. switch it := sf.Init.(type) {
  111. case InitFrom:
  112. it.Dump(out, ind)
  113. }
  114. }
  115. //
  116. // Sampler2D
  117. //
  118. type Sampler2D struct {
  119. Source string
  120. }
  121. // Dump prints out information about the Sampler2D
  122. func (sp *Sampler2D) Dump(out io.Writer, indent int) {
  123. fmt.Printf("%sSampler2D\n", sIndent(indent))
  124. ind := indent + step
  125. fmt.Printf("%sSource:%s\n", sIndent(ind), sp.Source)
  126. }
  127. //
  128. // Blinn
  129. //
  130. type Blinn struct {
  131. Emission interface{}
  132. Ambient interface{}
  133. Diffuse interface{}
  134. Specular interface{}
  135. Shininess interface{}
  136. Reflective interface{}
  137. Reflectivity interface{}
  138. Transparent interface{}
  139. Transparency interface{}
  140. IndexOfRefraction interface{}
  141. }
  142. // Dump prints out information about the Blinn
  143. func (bl *Blinn) Dump(out io.Writer, indent int) {
  144. fmt.Fprintf(out, "%sBlinn\n", sIndent(indent))
  145. ind := indent + step
  146. DumpColorOrTexture("Emssion", bl.Emission, out, ind)
  147. DumpColorOrTexture("Ambient", bl.Ambient, out, ind)
  148. DumpColorOrTexture("Diffuse", bl.Diffuse, out, ind)
  149. DumpColorOrTexture("Specular", bl.Specular, out, ind)
  150. DumpFloatOrParam("Shininess", bl.Shininess, out, ind)
  151. DumpColorOrTexture("Reflective", bl.Reflective, out, ind)
  152. DumpFloatOrParam("Reflectivity", bl.Reflectivity, out, ind)
  153. DumpColorOrTexture("Transparent", bl.Transparent, out, ind)
  154. DumpFloatOrParam("Transparency", bl.Transparency, out, ind)
  155. DumpFloatOrParam("IndexOfRefraction", bl.IndexOfRefraction, out, ind)
  156. }
  157. //
  158. // Constant
  159. //
  160. type Constant struct {
  161. Emission interface{}
  162. Reflective interface{}
  163. Reflectivity interface{}
  164. Transparent interface{}
  165. Transparency interface{}
  166. IndexOfRefraction interface{}
  167. }
  168. //
  169. // Lambert
  170. //
  171. type Lambert struct {
  172. Emission interface{}
  173. Ambient interface{}
  174. Diffuse interface{}
  175. Reflective interface{}
  176. Reflectivity interface{}
  177. Transparent interface{}
  178. Transparency interface{}
  179. IndexOfRefraction interface{}
  180. }
  181. //
  182. // Phong
  183. //
  184. type Phong struct {
  185. Emission interface{}
  186. Ambient interface{}
  187. Diffuse interface{}
  188. Specular interface{}
  189. Shininess interface{}
  190. Reflective interface{}
  191. Reflectivity interface{}
  192. Transparent interface{}
  193. Transparency interface{}
  194. IndexOfRefraction interface{}
  195. }
  196. // Dump prints out information about the Phong
  197. func (ph *Phong) Dump(out io.Writer, indent int) {
  198. fmt.Fprintf(out, "%sPhong\n", sIndent(indent))
  199. ind := indent + step
  200. DumpColorOrTexture("Emission", ph.Emission, out, ind)
  201. DumpColorOrTexture("Ambient", ph.Ambient, out, ind)
  202. DumpColorOrTexture("Diffuse", ph.Diffuse, out, ind)
  203. DumpColorOrTexture("Specular", ph.Specular, out, ind)
  204. DumpFloatOrParam("Shininess", ph.Shininess, out, ind)
  205. DumpColorOrTexture("Reflective", ph.Reflective, out, ind)
  206. DumpFloatOrParam("Reflectivity", ph.Reflectivity, out, ind)
  207. DumpColorOrTexture("Transparent", ph.Transparent, out, ind)
  208. DumpFloatOrParam("Transparency", ph.Transparency, out, ind)
  209. DumpFloatOrParam("IndexOfRefraction", ph.IndexOfRefraction, out, ind)
  210. }
  211. // DumpColorOrTexture prints out information about the Color or Texture
  212. func DumpColorOrTexture(name string, v interface{}, out io.Writer, indent int) {
  213. if v == nil {
  214. return
  215. }
  216. fmt.Fprintf(out, "%s%s\n", sIndent(indent), name)
  217. ind := indent + step
  218. switch vt := v.(type) {
  219. case *Color:
  220. vt.Dump(out, ind)
  221. case *Texture:
  222. vt.Dump(out, ind)
  223. }
  224. }
  225. // DumpFloatOrParam prints out information about the Float or Param
  226. func DumpFloatOrParam(name string, v interface{}, out io.Writer, indent int) {
  227. if v == nil {
  228. return
  229. }
  230. fmt.Fprintf(out, "%s%s\n", sIndent(indent), name)
  231. ind := indent + step
  232. switch vt := v.(type) {
  233. case *Float:
  234. vt.Dump(out, ind)
  235. break
  236. }
  237. }
  238. //
  239. // Color
  240. //
  241. type Color struct {
  242. Sid string
  243. Data [4]float32
  244. }
  245. // Dump prints out information about the Color
  246. func (c *Color) Dump(out io.Writer, indent int) {
  247. fmt.Fprintf(out, "%sColor sid:%s data:%v\n", sIndent(indent), c.Sid, c.Data)
  248. }
  249. //
  250. // Float
  251. //
  252. type Float struct {
  253. Sid string
  254. Data float32
  255. }
  256. // Dump prints out information about the Float
  257. func (f *Float) Dump(out io.Writer, indent int) {
  258. fmt.Fprintf(out, "%sFloat sid:%s data:%v\n", sIndent(indent), f.Sid, f.Data)
  259. }
  260. //
  261. // Texture
  262. //
  263. type Texture struct {
  264. Texture string
  265. Texcoord string
  266. }
  267. // Dump prints out information about the Texture
  268. func (t *Texture) Dump(out io.Writer, indent int) {
  269. fmt.Fprintf(out, "%sTexture texture:%s texcoord:%v\n", sIndent(indent), t.Texture, t.Texcoord)
  270. }
  271. func (d *Decoder) decLibraryEffects(start xml.StartElement, dom *Collada) error {
  272. le := new(LibraryEffects)
  273. dom.LibraryEffects = le
  274. le.Id = findAttrib(start, "id").Value
  275. le.Name = findAttrib(start, "name").Value
  276. for {
  277. // Get next child element
  278. child, _, err := d.decNextChild(start)
  279. if err != nil || child.Name.Local == "" {
  280. return err
  281. }
  282. // Decodes <effect>
  283. if child.Name.Local == "effect" {
  284. err := d.decEffect(child, le)
  285. if err != nil {
  286. return err
  287. }
  288. continue
  289. }
  290. }
  291. return nil
  292. }
  293. func (d *Decoder) decEffect(start xml.StartElement, le *LibraryEffects) error {
  294. e := new(Effect)
  295. e.Id = findAttrib(start, "id").Value
  296. e.Name = findAttrib(start, "name").Value
  297. le.Effect = append(le.Effect, e)
  298. for {
  299. // Get next child element
  300. child, _, err := d.decNextChild(start)
  301. if err != nil || child.Name.Local == "" {
  302. return err
  303. }
  304. if child.Name.Local == "profile_COMMON" {
  305. err := d.decEffectProfileCommon(child, e)
  306. if err != nil {
  307. return err
  308. }
  309. continue
  310. }
  311. }
  312. return nil
  313. }
  314. func (d *Decoder) decEffectProfileCommon(start xml.StartElement, e *Effect) error {
  315. pc := new(ProfileCOMMON)
  316. pc.Id = findAttrib(start, "id").Value
  317. e.Profile = append(e.Profile, pc)
  318. for {
  319. // Get next child element
  320. child, _, err := d.decNextChild(start)
  321. if err != nil || child.Name.Local == "" {
  322. return err
  323. }
  324. if child.Name.Local == "newparam" {
  325. err := d.decProfileCommonNewparam(child, pc)
  326. if err != nil {
  327. return err
  328. }
  329. continue
  330. }
  331. if child.Name.Local == "technique" {
  332. err := d.decProfileCommonTechnique(child, pc)
  333. if err != nil {
  334. return err
  335. }
  336. continue
  337. }
  338. }
  339. return nil
  340. }
  341. func (d *Decoder) decProfileCommonNewparam(start xml.StartElement, pc *ProfileCOMMON) error {
  342. np := new(Newparam)
  343. np.Sid = findAttrib(start, "sid").Value
  344. pc.Newparam = append(pc.Newparam, np)
  345. for {
  346. child, _, err := d.decNextChild(start)
  347. if err != nil || child.Name.Local == "" {
  348. return err
  349. }
  350. if child.Name.Local == "surface" {
  351. err := d.decSurface(child, np)
  352. if err != nil {
  353. return err
  354. }
  355. continue
  356. }
  357. if child.Name.Local == "sampler2D" {
  358. err := d.decSampler2D(child, np)
  359. if err != nil {
  360. return err
  361. }
  362. continue
  363. }
  364. }
  365. return nil
  366. }
  367. func (d *Decoder) decSurface(start xml.StartElement, np *Newparam) error {
  368. sf := new(Surface)
  369. sf.Type = findAttrib(start, "type").Value
  370. np.ParameterType = sf
  371. for {
  372. child, data, err := d.decNextChild(start)
  373. if err != nil || child.Name.Local == "" {
  374. return err
  375. }
  376. if child.Name.Local == "init_from" {
  377. sf.Init = InitFrom{string(data)}
  378. continue
  379. }
  380. }
  381. return nil
  382. }
  383. func (d *Decoder) decSampler2D(start xml.StartElement, np *Newparam) error {
  384. sp := new(Sampler2D)
  385. np.ParameterType = sp
  386. for {
  387. child, data, err := d.decNextChild(start)
  388. if err != nil || child.Name.Local == "" {
  389. return err
  390. }
  391. if child.Name.Local == "source" {
  392. sp.Source = string(data)
  393. continue
  394. }
  395. }
  396. return nil
  397. }
  398. func (d *Decoder) decProfileCommonTechnique(start xml.StartElement, pc *ProfileCOMMON) error {
  399. pc.Technique.Id = findAttrib(start, "id").Value
  400. pc.Technique.Sid = findAttrib(start, "sid").Value
  401. for {
  402. child, _, err := d.decNextChild(start)
  403. if err != nil || child.Name.Local == "" {
  404. return err
  405. }
  406. if child.Name.Local == "blinn" {
  407. err := d.decBlinn(child, pc)
  408. if err != nil {
  409. return err
  410. }
  411. continue
  412. }
  413. if child.Name.Local == "constant" {
  414. log.Warn("CONSTANT not implemented yet")
  415. continue
  416. }
  417. if child.Name.Local == "lambert" {
  418. log.Warn("LAMBERT not implemented yet")
  419. continue
  420. }
  421. if child.Name.Local == "phong" {
  422. err := d.decPhong(child, pc)
  423. if err != nil {
  424. return err
  425. }
  426. continue
  427. }
  428. }
  429. return nil
  430. }
  431. func (d *Decoder) decBlinn(start xml.StartElement, pc *ProfileCOMMON) error {
  432. bl := new(Blinn)
  433. pc.Technique.ShaderElement = bl
  434. for {
  435. child, _, err := d.decNextChild(start)
  436. if err != nil || child.Name.Local == "" {
  437. return err
  438. }
  439. if child.Name.Local == "emission" {
  440. err := d.decColorOrTexture(child, &bl.Emission)
  441. if err != nil {
  442. return err
  443. }
  444. continue
  445. }
  446. if child.Name.Local == "ambient" {
  447. err := d.decColorOrTexture(child, &bl.Ambient)
  448. if err != nil {
  449. return err
  450. }
  451. continue
  452. }
  453. if child.Name.Local == "diffuse" {
  454. err := d.decColorOrTexture(child, &bl.Diffuse)
  455. if err != nil {
  456. return err
  457. }
  458. continue
  459. }
  460. if child.Name.Local == "specular" {
  461. err := d.decColorOrTexture(child, &bl.Specular)
  462. if err != nil {
  463. return err
  464. }
  465. continue
  466. }
  467. if child.Name.Local == "shininess" {
  468. err := d.decFloatOrParam(child, &bl.Shininess)
  469. if err != nil {
  470. return err
  471. }
  472. continue
  473. }
  474. if child.Name.Local == "reflective" {
  475. err := d.decFloatOrParam(child, &bl.Reflective)
  476. if err != nil {
  477. return err
  478. }
  479. continue
  480. }
  481. if child.Name.Local == "reflectivity" {
  482. err := d.decFloatOrParam(child, &bl.Reflectivity)
  483. if err != nil {
  484. return err
  485. }
  486. continue
  487. }
  488. if child.Name.Local == "transparent" {
  489. // not supported
  490. continue
  491. }
  492. if child.Name.Local == "transparency" {
  493. err := d.decFloatOrParam(child, &bl.Transparency)
  494. if err != nil {
  495. return err
  496. }
  497. continue
  498. }
  499. if child.Name.Local == "index_of_refraction" {
  500. err := d.decFloatOrParam(child, &bl.IndexOfRefraction)
  501. if err != nil {
  502. return err
  503. }
  504. continue
  505. }
  506. }
  507. return nil
  508. }
  509. func (d *Decoder) decPhong(start xml.StartElement, pc *ProfileCOMMON) error {
  510. ph := new(Phong)
  511. pc.Technique.ShaderElement = ph
  512. for {
  513. child, _, err := d.decNextChild(start)
  514. if err != nil || child.Name.Local == "" {
  515. return err
  516. }
  517. if child.Name.Local == "emission" {
  518. err := d.decColorOrTexture(child, &ph.Emission)
  519. if err != nil {
  520. return err
  521. }
  522. continue
  523. }
  524. if child.Name.Local == "ambient" {
  525. err := d.decColorOrTexture(child, &ph.Ambient)
  526. if err != nil {
  527. return err
  528. }
  529. continue
  530. }
  531. if child.Name.Local == "diffuse" {
  532. err := d.decColorOrTexture(child, &ph.Diffuse)
  533. if err != nil {
  534. return err
  535. }
  536. continue
  537. }
  538. if child.Name.Local == "specular" {
  539. err := d.decColorOrTexture(child, &ph.Specular)
  540. if err != nil {
  541. return err
  542. }
  543. continue
  544. }
  545. if child.Name.Local == "shininess" {
  546. err := d.decFloatOrParam(child, &ph.Shininess)
  547. if err != nil {
  548. return err
  549. }
  550. continue
  551. }
  552. if child.Name.Local == "reflective" {
  553. err := d.decFloatOrParam(child, &ph.Reflective)
  554. if err != nil {
  555. return err
  556. }
  557. continue
  558. }
  559. if child.Name.Local == "reflectivity" {
  560. err := d.decFloatOrParam(child, &ph.Reflectivity)
  561. if err != nil {
  562. return err
  563. }
  564. continue
  565. }
  566. if child.Name.Local == "transparent" {
  567. // not supported
  568. continue
  569. }
  570. if child.Name.Local == "transparency" {
  571. err := d.decFloatOrParam(child, &ph.Transparency)
  572. if err != nil {
  573. return err
  574. }
  575. continue
  576. }
  577. if child.Name.Local == "index_of_refraction" {
  578. err := d.decFloatOrParam(child, &ph.IndexOfRefraction)
  579. if err != nil {
  580. return err
  581. }
  582. continue
  583. }
  584. }
  585. return nil
  586. }
  587. func (d *Decoder) decColorOrTexture(start xml.StartElement, dest *interface{}) error {
  588. child, cdata, err := d.decNextChild(start)
  589. if err != nil || child.Name.Local == "" {
  590. return err
  591. }
  592. if child.Name.Local == "color" {
  593. c := &Color{}
  594. c.Sid = findAttrib(child, "sid").Value
  595. *dest = c
  596. var br bytesReader
  597. br.Init(cdata)
  598. idx := 0
  599. for {
  600. tok := br.TokenNext()
  601. if tok == nil || len(tok) == 0 {
  602. break
  603. }
  604. v, err := strconv.ParseFloat(string(tok), 32)
  605. if err != nil {
  606. return err
  607. }
  608. c.Data[idx] = float32(v)
  609. idx++
  610. }
  611. return nil
  612. }
  613. if child.Name.Local == "texture" {
  614. t := &Texture{}
  615. t.Texture = findAttrib(child, "texture").Value
  616. t.Texcoord = findAttrib(child, "texcoord").Value
  617. *dest = t
  618. return nil
  619. }
  620. if child.Name.Local == "param" {
  621. return fmt.Errorf("not supported")
  622. }
  623. return nil
  624. }
  625. func (d *Decoder) decFloatOrParam(start xml.StartElement, dest *interface{}) error {
  626. child, cdata, err := d.decNextChild(start)
  627. if err != nil || child.Name.Local == "" {
  628. return err
  629. }
  630. if child.Name.Local == "float" {
  631. f := &Float{}
  632. f.Sid = findAttrib(child, "sid").Value
  633. *dest = f
  634. v, err := strconv.ParseFloat(string(cdata), 32)
  635. if err != nil {
  636. return err
  637. }
  638. f.Data = float32(v)
  639. return nil
  640. }
  641. return nil
  642. }