Mercurial > gemma
view cmd/tin2octree/builder.go @ 943:532c8392048f v1-uat1
client: replace arrow image
* Use an arrow image that has the same color and is a triangle.
author | Bernhard Reiter <bernhard@intevation.de> |
---|---|
date | Tue, 09 Oct 2018 19:55:33 +0200 |
parents | b0bd242ff821 |
children |
line wrap: on
line source
package main import ( "encoding/binary" "io" "log" "gemma.intevation.de/gemma/pkg/octree" ) type treeBuilder struct { t *tin nodes int leaves int index []int32 } var cubes = [8][2]octree.Vertex{ makeCube(0), makeCube(1), makeCube(2), makeCube(3), makeCube(4), makeCube(5), makeCube(6), makeCube(7), } func makeCube(i int) [2]octree.Vertex { var d octree.Vertex if i&1 == 1 { d.X = 0.5 } if i&2 == 2 { d.Y = 0.5 } if i&4 == 4 { d.Z = 0.5 } return [2]octree.Vertex{ octree.Vertex{0.0, 0.0, 0.0}.Add(d), octree.Vertex{0.5, 0.5, 0.5}.Add(d), } } func (tb *treeBuilder) build() { triangles := make([]int32, len(tb.t.triangles)) for i := range triangles { triangles[i] = int32(i) } tb.index = append(tb.index, 0) tb.buildRecursive(triangles, tb.t.min, tb.t.max, 0) tb.index[0] = int32(len(tb.index)) log.Printf("num nodes: %d\n", tb.index[0]) log.Printf("nodes: %d leaves: %d index %d\n", tb.nodes, tb.leaves, tb.index[0]) } func (tb *treeBuilder) buildRecursive( triangles []int32, min, max octree.Vertex, depth int, ) int32 { if len(triangles) <= 16 || depth > 8 { pos := len(tb.index) tb.index = append(tb.index, int32(len(triangles))) tb.index = append(tb.index, triangles...) //log.Printf("leaf entries: %d (%d)\n", len(triangles), depth) tb.leaves++ return int32(-(pos + 1)) } pos := len(tb.index) tb.index = append(tb.index, 0, 0, 0, 0, 0, 0, 0, 0) bbox := octree.Interpolate(min, max) bboxes := make([][2]octree.Vertex, len(cubes)) for i := range cubes { bboxes[i] = [2]octree.Vertex{ bbox(cubes[i][0]), bbox(cubes[i][1]), } } var quandrants [8][]int32 for _, tri := range triangles { triangle := tb.t.triangles[tri] v0 := tb.t.vertices[triangle[0]] v1 := tb.t.vertices[triangle[1]] v2 := tb.t.vertices[triangle[2]] l := v0 l.Minimize(v1) l.Minimize(v2) h := v0 h.Maximize(v1) h.Maximize(v2) for i := range bboxes { if !(h.Less(bboxes[i][0]) || bboxes[i][1].Less(l)) { quandrants[i] = append(quandrants[i], tri) } } } for i := range quandrants { if len(quandrants[i]) > 0 { child := tb.buildRecursive( quandrants[i], bboxes[i][0], bboxes[i][1], depth+1) tb.index[pos+i] = child } } tb.nodes++ return int32(pos) } func (tb *treeBuilder) Serialize(w io.Writer) error { var buf [binary.MaxVarintLen32]byte if err := binary.Write(w, binary.LittleEndian, tb.index[0]); err != nil { return err } var last int32 var written int for _, x := range tb.index[1:] { delta := x - last n := binary.PutVarint(buf[:], int64(delta)) for p := buf[:n]; len(p) > 0; p = p[n:] { var err error if n, err = w.Write(p); err != nil { return err } written += n } last = x } log.Printf("compressed octree index in bytes: %d (%d)\n", written, 4*len(tb.index)) return nil }