library_effects.go 14 KB

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