| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497 |
- // Copyright 2016 The G3N Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style
- // license that can be found in the LICENSE file.
- package collada
- import (
- "encoding/xml"
- "fmt"
- "io"
- "strconv"
- )
- //
- // LibraryGeometries
- //
- type LibraryGeometries struct {
- Asset *Asset
- Geometry []*Geometry
- }
- // Dump prints out information about the LibraryGeometries
- func (lg *LibraryGeometries) Dump(out io.Writer, indent int) {
- if lg == nil {
- return
- }
- fmt.Fprintf(out, "%sLibraryGeometries:\n", sIndent(indent))
- ind := indent + step
- if lg.Asset != nil {
- lg.Asset.Dump(out, ind)
- }
- for _, g := range lg.Geometry {
- g.Dump(out, ind)
- }
- }
- //
- // Geometry
- //
- type Geometry struct {
- Id string // Geometry id (optional)
- Name string // Geometry name (optional)
- GeometricElement interface{} // Geometry type object (Mesh|others)
- }
- // Dump prints out information about the Geometry
- func (g *Geometry) Dump(out io.Writer, indent int) {
- fmt.Fprintf(out, "%sGeometry id:%s name:%s\n", sIndent(indent), g.Id, g.Name)
- ind := indent + step
- switch gt := g.GeometricElement.(type) {
- case *Mesh:
- gt.Dump(out, ind)
- break
- }
- }
- //
- // Mesh
- //
- type Mesh struct {
- Source []*Source // One or more sources Sources
- Vertices Vertices // Vertices positions
- PrimitiveElements []interface{} // Geometry primitives (polylist|others)
- }
- // Dump prints out information about the Mesh
- func (m *Mesh) Dump(out io.Writer, indent int) {
- fmt.Fprintf(out, "%sMesh:\n", sIndent(indent))
- ind := indent + step
- for _, s := range m.Source {
- s.Dump(out, ind)
- }
- m.Vertices.Dump(out, ind)
- for _, pe := range m.PrimitiveElements {
- switch pt := pe.(type) {
- case *Lines:
- pt.Dump(out, ind)
- case *Polylist:
- pt.Dump(out, ind)
- }
- }
- }
- //
- // Vertices
- //
- type Vertices struct {
- Id string
- Name string
- Input []Input
- }
- // Dump prints out information about the Vertices
- func (v *Vertices) Dump(out io.Writer, indent int) {
- fmt.Fprintf(out, "%sVertices id:%s name:%s\n", sIndent(indent), v.Id, v.Name)
- for _, inp := range v.Input {
- inp.Dump(out, indent+step)
- }
- }
- //
- // Input
- //
- type Input struct {
- Semantic string
- Source string // source URL
- }
- // Dump prints out information about the Input
- func (i *Input) Dump(out io.Writer, indent int) {
- fmt.Fprintf(out, "%sInput semantic:%s source:%s\n", sIndent(indent), i.Semantic, i.Source)
- }
- //
- // Polylist
- //
- type Polylist struct {
- Name string
- Count int
- Material string
- Input []InputShared
- Vcount []int
- P []int
- }
- // Dump prints out information about the Polylist
- func (pl *Polylist) Dump(out io.Writer, indent int) {
- fmt.Fprintf(out, "%sPolylist name:%s count:%d material:%s\n", sIndent(indent), pl.Name, pl.Count, pl.Material)
- ind := indent + step
- for _, is := range pl.Input {
- is.Dump(out, ind)
- }
- fmt.Fprintf(out, "%sVcount(%d):%v\n", sIndent(ind), len(pl.Vcount), intsToString(pl.Vcount, 20))
- fmt.Fprintf(out, "%sP(%d):%v\n", sIndent(ind), len(pl.P), intsToString(pl.P, 20))
- }
- //
- // InputShared
- //
- type InputShared struct {
- Offset int
- Semantic string
- Source string // source URL
- Set int
- }
- //
- // Triangles
- //
- type Triangles struct {
- Name string
- Count int
- Material string
- Input []InputShared
- P []int
- }
- //
- // Lines
- //
- type Lines struct {
- Name string
- Count int
- Material string
- Input []InputShared
- P []int
- }
- // Dump prints out information about the Lines
- func (ln *Lines) Dump(out io.Writer, indent int) {
- fmt.Fprintf(out, "%sLines name:%s count:%d material:%s\n", sIndent(indent), ln.Name, ln.Count, ln.Material)
- ind := indent + step
- for _, is := range ln.Input {
- is.Dump(out, ind)
- }
- fmt.Fprintf(out, "%sP(%d):%v\n", sIndent(ind), len(ln.P), intsToString(ln.P, 20))
- }
- //
- // LineStrips
- //
- type LineStrips struct {
- Name string
- Count int
- Material string
- Input []InputShared
- P []int
- }
- //
- // Trifans
- //
- type Trifans struct {
- Name string
- Count int
- Material string
- Input []InputShared
- P []int
- }
- //
- // Tristrips
- //
- type Tristrips struct {
- Name string
- Count int
- Material string
- Input []InputShared
- P []int
- }
- // Dump prints out information about the Tristrips
- func (is *InputShared) Dump(out io.Writer, indent int) {
- fmt.Fprintf(out, "%sInputShared offset:%d semantic:%s source:%s set:%d\n",
- sIndent(indent), is.Offset, is.Semantic, is.Source, is.Set)
- }
- // Decodes "library_geometry" children
- func (d *Decoder) decLibraryGeometries(start xml.StartElement, dom *Collada) error {
- lg := new(LibraryGeometries)
- dom.LibraryGeometries = lg
- for {
- // Get next child START
- child, _, err := d.decNextChild(start)
- if err != nil || child.Name.Local == "" {
- return err
- }
- // Decode optional asset
- if child.Name.Local == "asset" {
- lg.Asset = new(Asset)
- err = d.decAsset(child, lg.Asset)
- if err != nil {
- return err
- }
- continue
- }
- //log.Debug("decLibraryGeometries: %s", child.Name.Local)
- // Decode geometry
- if child.Name.Local == "geometry" {
- err = d.decGeometry(child, lg)
- if err != nil {
- return err
- }
- continue
- }
- }
- }
- // decGeometry receives the start element of a geometry and
- // decodes all its children and appends the decoded geometry
- // to the specified slice.
- func (d *Decoder) decGeometry(start xml.StartElement, lg *LibraryGeometries) error {
- // Get geometry id and name attributes
- geom := &Geometry{}
- geom.Id = findAttrib(start, "id").Value
- geom.Name = findAttrib(start, "name").Value
- lg.Geometry = append(lg.Geometry, geom)
- // Decodes geometry children
- for {
- // Get next child
- child, _, err := d.decNextChild(start)
- if err != nil || child.Name.Local == "" {
- return err
- }
- // Decode mesh
- if child.Name.Local == "mesh" {
- err = d.decMesh(child, geom)
- if err != nil {
- return err
- }
- continue
- }
- }
- }
- // decMesh decodes the mesh from the specified geometry
- func (d *Decoder) decMesh(start xml.StartElement, geom *Geometry) error {
- // Associates this mesh to the parent geometry
- mesh := &Mesh{}
- geom.GeometricElement = mesh
- // Decodes mesh children
- for {
- // Get next child
- child, _, err := d.decNextChild(start)
- if err != nil || child.Name.Local == "" {
- return err
- }
- //log.Debug("decMesh(%s): %s", start.Name.Local, child.Name.Local)
- // Decodes source
- if child.Name.Local == "source" {
- source, err := d.decSource(child)
- if err != nil {
- return err
- }
- mesh.Source = append(mesh.Source, source)
- continue
- }
- // Decodes vertices
- if child.Name.Local == "vertices" {
- err = d.decVertices(child, mesh)
- if err != nil {
- return err
- }
- continue
- }
- // Decodes lines
- if child.Name.Local == "lines" {
- err = d.decLines(child, mesh)
- if err != nil {
- return err
- }
- continue
- }
- // Decodes polylist
- if child.Name.Local == "polylist" {
- err = d.decPolylist(child, mesh)
- if err != nil {
- return err
- }
- continue
- }
- }
- }
- func (d *Decoder) decVertices(start xml.StartElement, mesh *Mesh) error {
- mesh.Vertices.Id = findAttrib(start, "id").Value
- mesh.Vertices.Name = findAttrib(start, "name").Value
- for {
- // Get next child
- child, _, err := d.decNextChild(start)
- if err != nil || child.Name.Local == "" {
- return err
- }
- // input
- if child.Name.Local == "input" {
- inp, err := d.decInput(child)
- if err != nil {
- return err
- }
- mesh.Vertices.Input = append(mesh.Vertices.Input, inp)
- }
- }
- }
- func (d *Decoder) decInput(start xml.StartElement) (Input, error) {
- var inp Input
- inp.Semantic = findAttrib(start, "semantic").Value
- inp.Source = findAttrib(start, "source").Value
- return inp, nil
- }
- func (d *Decoder) decLines(start xml.StartElement, mesh *Mesh) error {
- ln := &Lines{}
- ln.Name = findAttrib(start, "name").Value
- ln.Count, _ = strconv.Atoi(findAttrib(start, "count").Value)
- ln.Material = findAttrib(start, "material").Value
- mesh.PrimitiveElements = append(mesh.PrimitiveElements, ln)
- for {
- // Get next child
- child, data, err := d.decNextChild(start)
- if err != nil || child.Name.Local == "" {
- return err
- }
- // Decode input shared
- if child.Name.Local == "input" {
- inp, err := d.decInputShared(child)
- if err != nil {
- return err
- }
- ln.Input = append(ln.Input, inp)
- continue
- }
- // Decode p (primitive)
- if child.Name.Local == "p" {
- p, err := d.decPrimitive(child, data)
- if err != nil {
- return err
- }
- ln.P = p
- }
- }
- }
- func (d *Decoder) decPolylist(start xml.StartElement, mesh *Mesh) error {
- pl := &Polylist{}
- pl.Name = findAttrib(start, "name").Value
- pl.Count, _ = strconv.Atoi(findAttrib(start, "count").Value)
- pl.Material = findAttrib(start, "material").Value
- mesh.PrimitiveElements = append(mesh.PrimitiveElements, pl)
- for {
- // Get next child
- child, data, err := d.decNextChild(start)
- if err != nil || child.Name.Local == "" {
- return err
- }
- // Decode input shared
- if child.Name.Local == "input" {
- inp, err := d.decInputShared(child)
- if err != nil {
- return err
- }
- pl.Input = append(pl.Input, inp)
- continue
- }
- // Decode vcount
- if child.Name.Local == "vcount" {
- vc, err := d.decVcount(child, data, pl.Count)
- if err != nil {
- return err
- }
- pl.Vcount = vc
- continue
- }
- // Decode p (primitive)
- if child.Name.Local == "p" {
- p, err := d.decPrimitive(child, data)
- if err != nil {
- return err
- }
- pl.P = p
- }
- }
- }
- func (d *Decoder) decInputShared(start xml.StartElement) (InputShared, error) {
- var inp InputShared
- inp.Offset, _ = strconv.Atoi(findAttrib(start, "offset").Value)
- inp.Semantic = findAttrib(start, "semantic").Value
- inp.Source = findAttrib(start, "source").Value
- inp.Set, _ = strconv.Atoi(findAttrib(start, "set").Value)
- return inp, nil
- }
- func (d *Decoder) decVcount(start xml.StartElement, data []byte, size int) ([]int, error) {
- vcount := make([]int, size)
- var br bytesReader
- br.Init(data)
- idx := 0
- for {
- tok := br.TokenNext()
- if tok == nil {
- break
- }
- v, err := strconv.Atoi(string(tok))
- if err != nil {
- return nil, err
- }
- vcount[idx] = v
- idx++
- }
- return vcount, nil
- }
- func (d *Decoder) decPrimitive(start xml.StartElement, data []byte) ([]int, error) {
- p := make([]int, 0)
- var br bytesReader
- br.Init(data)
- idx := 0
- for {
- tok := br.TokenNext()
- if tok == nil {
- break
- }
- v, err := strconv.Atoi(string(tok))
- if err != nil {
- return nil, err
- }
- p = append(p, v)
- idx++
- }
- return p, nil
- }
|