library_lights.go 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  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 Lights
  13. //
  14. type LibraryLights struct {
  15. Id string
  16. Name string
  17. Asset *Asset
  18. Light []*Light
  19. }
  20. func (ll *LibraryLights) Dump(out io.Writer, indent int) {
  21. if ll == nil {
  22. return
  23. }
  24. fmt.Fprintf(out, "%sLibraryLights id:%s name:%s\n", sIndent(indent), ll.Id, ll.Name)
  25. for _, light := range ll.Light {
  26. light.Dump(out, indent+step)
  27. }
  28. }
  29. //
  30. // Light
  31. //
  32. type Light struct {
  33. Id string
  34. Name string
  35. TechniqueCommon struct {
  36. Type interface{}
  37. }
  38. }
  39. func (li *Light) Dump(out io.Writer, indent int) {
  40. fmt.Fprintf(out, "%sLights id:%s name:%s\n", sIndent(indent), li.Id, li.Name)
  41. ind := indent + step
  42. fmt.Fprintf(out, "%sTechniqueCommon\n", sIndent(ind))
  43. ind += step
  44. switch lt := li.TechniqueCommon.Type.(type) {
  45. case *Ambient:
  46. lt.Dump(out, ind)
  47. case *Directional:
  48. lt.Dump(out, ind)
  49. case *Point:
  50. lt.Dump(out, ind)
  51. case *Spot:
  52. lt.Dump(out, ind)
  53. }
  54. }
  55. //
  56. // Ambient
  57. //
  58. type Ambient struct {
  59. Color LightColor
  60. }
  61. func (amb *Ambient) Dump(out io.Writer, indent int) {
  62. fmt.Fprintf(out, "%sAmbient\n", sIndent(indent))
  63. ind := indent + step
  64. amb.Color.Dump(out, ind)
  65. }
  66. //
  67. // Directional
  68. //
  69. type Directional struct {
  70. Color LightColor
  71. }
  72. func (dir *Directional) Dump(out io.Writer, indent int) {
  73. fmt.Fprintf(out, "%sDirectional\n", sIndent(indent))
  74. ind := indent + step
  75. dir.Color.Dump(out, ind)
  76. }
  77. //
  78. // Point
  79. //
  80. type Point struct {
  81. Color LightColor
  82. ConstantAttenuation *FloatValue
  83. LinearAttenuation *FloatValue
  84. QuadraticAttenuation *FloatValue
  85. }
  86. func (pl *Point) Dump(out io.Writer, indent int) {
  87. fmt.Fprintf(out, "%sPoint\n", sIndent(indent))
  88. indent += step
  89. pl.Color.Dump(out, indent)
  90. pl.ConstantAttenuation.Dump("ConstantAttenuation", out, indent)
  91. pl.LinearAttenuation.Dump("LinearAttenuation", out, indent)
  92. pl.QuadraticAttenuation.Dump("QuadraticAttenuation", out, indent)
  93. }
  94. //
  95. // Spot
  96. //
  97. type Spot struct {
  98. Color LightColor
  99. ConstantAttenuation *FloatValue
  100. LinearAttenuation *FloatValue
  101. QuadraticAttenuation *FloatValue
  102. FalloffAngle *FloatValue
  103. FalloffExponent *FloatValue
  104. }
  105. func (sl *Spot) Dump(out io.Writer, indent int) {
  106. fmt.Fprintf(out, "%sSpot\n", sIndent(indent))
  107. indent += step
  108. sl.Color.Dump(out, indent)
  109. sl.ConstantAttenuation.Dump("ConstantAttenuation", out, indent)
  110. sl.LinearAttenuation.Dump("LinearAttenuation", out, indent)
  111. sl.QuadraticAttenuation.Dump("QuadraticAttenuation", out, indent)
  112. sl.FalloffAngle.Dump("FalloffAngle", out, indent)
  113. sl.FalloffExponent.Dump("FalloffExponent", out, indent)
  114. }
  115. //
  116. // FloatValue
  117. //
  118. type FloatValue struct {
  119. Sid string
  120. Value float32
  121. }
  122. func (fv *FloatValue) Dump(name string, out io.Writer, indent int) {
  123. if fv == nil {
  124. return
  125. }
  126. fmt.Fprintf(out, "%s%s sid:%s value:%v\n", sIndent(indent), name, fv.Sid, fv.Value)
  127. }
  128. //
  129. // LightColor
  130. //
  131. type LightColor struct {
  132. Sid string
  133. Data [3]float32
  134. }
  135. func (lc *LightColor) Dump(out io.Writer, indent int) {
  136. fmt.Fprintf(out, "%sColor sid:%s data:%v\n", sIndent(indent), lc.Sid, lc.Data)
  137. }
  138. func (d *Decoder) decLibraryLights(start xml.StartElement, dom *Collada) error {
  139. ll := new(LibraryLights)
  140. dom.LibraryLights = ll
  141. ll.Id = findAttrib(start, "id").Value
  142. ll.Name = findAttrib(start, "name").Value
  143. for {
  144. child, _, err := d.decNextChild(start)
  145. if err != nil || child.Name.Local == "" {
  146. return err
  147. }
  148. if child.Name.Local == "light" {
  149. err := d.decLight(child, ll)
  150. if err != nil {
  151. return err
  152. }
  153. continue
  154. }
  155. }
  156. return nil
  157. }
  158. func (d *Decoder) decLight(start xml.StartElement, ll *LibraryLights) error {
  159. light := new(Light)
  160. ll.Light = append(ll.Light, light)
  161. light.Id = findAttrib(start, "id").Value
  162. light.Name = findAttrib(start, "name").Value
  163. for {
  164. child, _, err := d.decNextChild(start)
  165. if err != nil || child.Name.Local == "" {
  166. return err
  167. }
  168. if child.Name.Local == "technique_common" {
  169. err := d.decLightTechniqueCommon(child, light)
  170. if err != nil {
  171. return err
  172. }
  173. continue
  174. }
  175. }
  176. return nil
  177. }
  178. func (d *Decoder) decLightTechniqueCommon(start xml.StartElement, li *Light) error {
  179. child, _, err := d.decNextChild(start)
  180. if err != nil || child.Name.Local == "" {
  181. return err
  182. }
  183. if child.Name.Local == "ambient" {
  184. err := d.decAmbient(child, li)
  185. if err != nil {
  186. return err
  187. }
  188. }
  189. if child.Name.Local == "directional" {
  190. err := d.decDirectional(child, li)
  191. if err != nil {
  192. return err
  193. }
  194. }
  195. if child.Name.Local == "point" {
  196. err := d.decPoint(child, li)
  197. if err != nil {
  198. return err
  199. }
  200. }
  201. if child.Name.Local == "spot" {
  202. err := d.decSpot(child, li)
  203. if err != nil {
  204. return err
  205. }
  206. }
  207. return nil
  208. }
  209. func (d *Decoder) decAmbient(start xml.StartElement, li *Light) error {
  210. amb := new(Ambient)
  211. li.TechniqueCommon.Type = amb
  212. child, cdata, err := d.decNextChild(start)
  213. if err != nil || child.Name.Local == "" {
  214. return err
  215. }
  216. if child.Name.Local == "color" {
  217. err := d.decLightColor(child, cdata, &amb.Color)
  218. if err != nil {
  219. return err
  220. }
  221. }
  222. return nil
  223. }
  224. func (d *Decoder) decDirectional(start xml.StartElement, li *Light) error {
  225. dir := new(Directional)
  226. li.TechniqueCommon.Type = dir
  227. child, cdata, err := d.decNextChild(start)
  228. if err != nil || child.Name.Local == "" {
  229. return err
  230. }
  231. if child.Name.Local == "color" {
  232. err := d.decLightColor(child, cdata, &dir.Color)
  233. if err != nil {
  234. return err
  235. }
  236. }
  237. return nil
  238. }
  239. func (d *Decoder) decPoint(start xml.StartElement, li *Light) error {
  240. pl := new(Point)
  241. li.TechniqueCommon.Type = pl
  242. for {
  243. child, cdata, err := d.decNextChild(start)
  244. if err != nil || child.Name.Local == "" {
  245. return err
  246. }
  247. if child.Name.Local == "color" {
  248. err := d.decLightColor(child, cdata, &pl.Color)
  249. if err != nil {
  250. return err
  251. }
  252. continue
  253. }
  254. if child.Name.Local == "constant_attenuation" {
  255. fv, err := d.decFloatValue(child, cdata)
  256. if err != nil {
  257. return err
  258. }
  259. pl.ConstantAttenuation = fv
  260. continue
  261. }
  262. if child.Name.Local == "linear_attenuation" {
  263. fv, err := d.decFloatValue(child, cdata)
  264. if err != nil {
  265. return err
  266. }
  267. pl.LinearAttenuation = fv
  268. continue
  269. }
  270. if child.Name.Local == "quadratic_attenuation" {
  271. fv, err := d.decFloatValue(child, cdata)
  272. if err != nil {
  273. return err
  274. }
  275. pl.QuadraticAttenuation = fv
  276. continue
  277. }
  278. }
  279. return nil
  280. }
  281. func (d *Decoder) decSpot(start xml.StartElement, li *Light) error {
  282. sl := new(Spot)
  283. li.TechniqueCommon.Type = sl
  284. for {
  285. child, cdata, err := d.decNextChild(start)
  286. if err != nil || child.Name.Local == "" {
  287. return err
  288. }
  289. if child.Name.Local == "color" {
  290. err := d.decLightColor(child, cdata, &sl.Color)
  291. if err != nil {
  292. return err
  293. }
  294. continue
  295. }
  296. if child.Name.Local == "constant_attenuation" {
  297. fv, err := d.decFloatValue(child, cdata)
  298. if err != nil {
  299. return err
  300. }
  301. sl.ConstantAttenuation = fv
  302. continue
  303. }
  304. if child.Name.Local == "linear_attenuation" {
  305. fv, err := d.decFloatValue(child, cdata)
  306. if err != nil {
  307. return err
  308. }
  309. sl.LinearAttenuation = fv
  310. continue
  311. }
  312. if child.Name.Local == "quadratic_attenuation" {
  313. fv, err := d.decFloatValue(child, cdata)
  314. if err != nil {
  315. return err
  316. }
  317. sl.QuadraticAttenuation = fv
  318. continue
  319. }
  320. if child.Name.Local == "falloff_angle" {
  321. fv, err := d.decFloatValue(child, cdata)
  322. if err != nil {
  323. return err
  324. }
  325. sl.FalloffAngle = fv
  326. continue
  327. }
  328. if child.Name.Local == "falloff_exponent" {
  329. fv, err := d.decFloatValue(child, cdata)
  330. if err != nil {
  331. return err
  332. }
  333. sl.FalloffExponent = fv
  334. continue
  335. }
  336. }
  337. return nil
  338. }
  339. func (d *Decoder) decFloatValue(start xml.StartElement, cdata []byte) (*FloatValue, error) {
  340. fv := new(FloatValue)
  341. fv.Sid = findAttrib(start, "sid").Value
  342. v, err := strconv.ParseFloat(string(cdata), 32)
  343. if err != nil {
  344. return nil, err
  345. }
  346. fv.Value = float32(v)
  347. return fv, nil
  348. }
  349. func (d *Decoder) decLightColor(start xml.StartElement, cdata []byte, lc *LightColor) error {
  350. lc.Sid = findAttrib(start, "sid").Value
  351. return decFloat32Sequence(cdata, lc.Data[:])
  352. }