library_effects.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708
  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. }
  292. func (d *Decoder) decEffect(start xml.StartElement, le *LibraryEffects) error {
  293. e := new(Effect)
  294. e.Id = findAttrib(start, "id").Value
  295. e.Name = findAttrib(start, "name").Value
  296. le.Effect = append(le.Effect, e)
  297. for {
  298. // Get next child element
  299. child, _, err := d.decNextChild(start)
  300. if err != nil || child.Name.Local == "" {
  301. return err
  302. }
  303. if child.Name.Local == "profile_COMMON" {
  304. err := d.decEffectProfileCommon(child, e)
  305. if err != nil {
  306. return err
  307. }
  308. continue
  309. }
  310. }
  311. }
  312. func (d *Decoder) decEffectProfileCommon(start xml.StartElement, e *Effect) error {
  313. pc := new(ProfileCOMMON)
  314. pc.Id = findAttrib(start, "id").Value
  315. e.Profile = append(e.Profile, pc)
  316. for {
  317. // Get next child element
  318. child, _, err := d.decNextChild(start)
  319. if err != nil || child.Name.Local == "" {
  320. return err
  321. }
  322. if child.Name.Local == "newparam" {
  323. err := d.decProfileCommonNewparam(child, pc)
  324. if err != nil {
  325. return err
  326. }
  327. continue
  328. }
  329. if child.Name.Local == "technique" {
  330. err := d.decProfileCommonTechnique(child, pc)
  331. if err != nil {
  332. return err
  333. }
  334. continue
  335. }
  336. }
  337. }
  338. func (d *Decoder) decProfileCommonNewparam(start xml.StartElement, pc *ProfileCOMMON) error {
  339. np := new(Newparam)
  340. np.Sid = findAttrib(start, "sid").Value
  341. pc.Newparam = append(pc.Newparam, np)
  342. for {
  343. child, _, err := d.decNextChild(start)
  344. if err != nil || child.Name.Local == "" {
  345. return err
  346. }
  347. if child.Name.Local == "surface" {
  348. err := d.decSurface(child, np)
  349. if err != nil {
  350. return err
  351. }
  352. continue
  353. }
  354. if child.Name.Local == "sampler2D" {
  355. err := d.decSampler2D(child, np)
  356. if err != nil {
  357. return err
  358. }
  359. continue
  360. }
  361. }
  362. }
  363. func (d *Decoder) decSurface(start xml.StartElement, np *Newparam) error {
  364. sf := new(Surface)
  365. sf.Type = findAttrib(start, "type").Value
  366. np.ParameterType = sf
  367. for {
  368. child, data, err := d.decNextChild(start)
  369. if err != nil || child.Name.Local == "" {
  370. return err
  371. }
  372. if child.Name.Local == "init_from" {
  373. sf.Init = InitFrom{string(data)}
  374. continue
  375. }
  376. }
  377. }
  378. func (d *Decoder) decSampler2D(start xml.StartElement, np *Newparam) error {
  379. sp := new(Sampler2D)
  380. np.ParameterType = sp
  381. for {
  382. child, data, err := d.decNextChild(start)
  383. if err != nil || child.Name.Local == "" {
  384. return err
  385. }
  386. if child.Name.Local == "source" {
  387. sp.Source = string(data)
  388. continue
  389. }
  390. }
  391. }
  392. func (d *Decoder) decProfileCommonTechnique(start xml.StartElement, pc *ProfileCOMMON) error {
  393. pc.Technique.Id = findAttrib(start, "id").Value
  394. pc.Technique.Sid = findAttrib(start, "sid").Value
  395. for {
  396. child, _, err := d.decNextChild(start)
  397. if err != nil || child.Name.Local == "" {
  398. return err
  399. }
  400. if child.Name.Local == "blinn" {
  401. err := d.decBlinn(child, pc)
  402. if err != nil {
  403. return err
  404. }
  405. continue
  406. }
  407. if child.Name.Local == "constant" {
  408. log.Warn("CONSTANT not implemented yet")
  409. continue
  410. }
  411. if child.Name.Local == "lambert" {
  412. log.Warn("LAMBERT not implemented yet")
  413. continue
  414. }
  415. if child.Name.Local == "phong" {
  416. err := d.decPhong(child, pc)
  417. if err != nil {
  418. return err
  419. }
  420. continue
  421. }
  422. }
  423. }
  424. func (d *Decoder) decBlinn(start xml.StartElement, pc *ProfileCOMMON) error {
  425. bl := new(Blinn)
  426. pc.Technique.ShaderElement = bl
  427. for {
  428. child, _, err := d.decNextChild(start)
  429. if err != nil || child.Name.Local == "" {
  430. return err
  431. }
  432. if child.Name.Local == "emission" {
  433. err := d.decColorOrTexture(child, &bl.Emission)
  434. if err != nil {
  435. return err
  436. }
  437. continue
  438. }
  439. if child.Name.Local == "ambient" {
  440. err := d.decColorOrTexture(child, &bl.Ambient)
  441. if err != nil {
  442. return err
  443. }
  444. continue
  445. }
  446. if child.Name.Local == "diffuse" {
  447. err := d.decColorOrTexture(child, &bl.Diffuse)
  448. if err != nil {
  449. return err
  450. }
  451. continue
  452. }
  453. if child.Name.Local == "specular" {
  454. err := d.decColorOrTexture(child, &bl.Specular)
  455. if err != nil {
  456. return err
  457. }
  458. continue
  459. }
  460. if child.Name.Local == "shininess" {
  461. err := d.decFloatOrParam(child, &bl.Shininess)
  462. if err != nil {
  463. return err
  464. }
  465. continue
  466. }
  467. if child.Name.Local == "reflective" {
  468. err := d.decFloatOrParam(child, &bl.Reflective)
  469. if err != nil {
  470. return err
  471. }
  472. continue
  473. }
  474. if child.Name.Local == "reflectivity" {
  475. err := d.decFloatOrParam(child, &bl.Reflectivity)
  476. if err != nil {
  477. return err
  478. }
  479. continue
  480. }
  481. if child.Name.Local == "transparent" {
  482. // not supported
  483. continue
  484. }
  485. if child.Name.Local == "transparency" {
  486. err := d.decFloatOrParam(child, &bl.Transparency)
  487. if err != nil {
  488. return err
  489. }
  490. continue
  491. }
  492. if child.Name.Local == "index_of_refraction" {
  493. err := d.decFloatOrParam(child, &bl.IndexOfRefraction)
  494. if err != nil {
  495. return err
  496. }
  497. continue
  498. }
  499. }
  500. }
  501. func (d *Decoder) decPhong(start xml.StartElement, pc *ProfileCOMMON) error {
  502. ph := new(Phong)
  503. pc.Technique.ShaderElement = ph
  504. for {
  505. child, _, err := d.decNextChild(start)
  506. if err != nil || child.Name.Local == "" {
  507. return err
  508. }
  509. if child.Name.Local == "emission" {
  510. err := d.decColorOrTexture(child, &ph.Emission)
  511. if err != nil {
  512. return err
  513. }
  514. continue
  515. }
  516. if child.Name.Local == "ambient" {
  517. err := d.decColorOrTexture(child, &ph.Ambient)
  518. if err != nil {
  519. return err
  520. }
  521. continue
  522. }
  523. if child.Name.Local == "diffuse" {
  524. err := d.decColorOrTexture(child, &ph.Diffuse)
  525. if err != nil {
  526. return err
  527. }
  528. continue
  529. }
  530. if child.Name.Local == "specular" {
  531. err := d.decColorOrTexture(child, &ph.Specular)
  532. if err != nil {
  533. return err
  534. }
  535. continue
  536. }
  537. if child.Name.Local == "shininess" {
  538. err := d.decFloatOrParam(child, &ph.Shininess)
  539. if err != nil {
  540. return err
  541. }
  542. continue
  543. }
  544. if child.Name.Local == "reflective" {
  545. err := d.decFloatOrParam(child, &ph.Reflective)
  546. if err != nil {
  547. return err
  548. }
  549. continue
  550. }
  551. if child.Name.Local == "reflectivity" {
  552. err := d.decFloatOrParam(child, &ph.Reflectivity)
  553. if err != nil {
  554. return err
  555. }
  556. continue
  557. }
  558. if child.Name.Local == "transparent" {
  559. // not supported
  560. continue
  561. }
  562. if child.Name.Local == "transparency" {
  563. err := d.decFloatOrParam(child, &ph.Transparency)
  564. if err != nil {
  565. return err
  566. }
  567. continue
  568. }
  569. if child.Name.Local == "index_of_refraction" {
  570. err := d.decFloatOrParam(child, &ph.IndexOfRefraction)
  571. if err != nil {
  572. return err
  573. }
  574. continue
  575. }
  576. }
  577. }
  578. func (d *Decoder) decColorOrTexture(start xml.StartElement, dest *interface{}) error {
  579. child, cdata, err := d.decNextChild(start)
  580. if err != nil || child.Name.Local == "" {
  581. return err
  582. }
  583. if child.Name.Local == "color" {
  584. c := &Color{}
  585. c.Sid = findAttrib(child, "sid").Value
  586. *dest = c
  587. var br bytesReader
  588. br.Init(cdata)
  589. idx := 0
  590. for {
  591. tok := br.TokenNext()
  592. if tok == nil || len(tok) == 0 {
  593. break
  594. }
  595. v, err := strconv.ParseFloat(string(tok), 32)
  596. if err != nil {
  597. return err
  598. }
  599. c.Data[idx] = float32(v)
  600. idx++
  601. }
  602. return nil
  603. }
  604. if child.Name.Local == "texture" {
  605. t := &Texture{}
  606. t.Texture = findAttrib(child, "texture").Value
  607. t.Texcoord = findAttrib(child, "texcoord").Value
  608. *dest = t
  609. return nil
  610. }
  611. if child.Name.Local == "param" {
  612. return fmt.Errorf("not supported")
  613. }
  614. return nil
  615. }
  616. func (d *Decoder) decFloatOrParam(start xml.StartElement, dest *interface{}) error {
  617. child, cdata, err := d.decNextChild(start)
  618. if err != nil || child.Name.Local == "" {
  619. return err
  620. }
  621. if child.Name.Local == "float" {
  622. f := &Float{}
  623. f.Sid = findAttrib(child, "sid").Value
  624. *dest = f
  625. v, err := strconv.ParseFloat(string(cdata), 32)
  626. if err != nil {
  627. return err
  628. }
  629. f.Data = float32(v)
  630. return nil
  631. }
  632. return nil
  633. }