# HG changeset patch # User Sascha L. Teichmann # Date 1707701261 -3600 # Node ID 6281c18b109f8964be49e72ec7f9821c68855929 # Parent 8ff84285843471748c9db3178272c2c1b72af6af Finsh serializing v2 meshes. diff -r 8ff842858434 -r 6281c18b109f pkg/common/delta.go --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/pkg/common/delta.go Mon Feb 12 02:27:41 2024 +0100 @@ -0,0 +1,32 @@ +// This is Free Software under GNU Affero General Public License v >= 3.0 +// without warranty, see README.md and license for details. +// +// SPDX-License-Identifier: AGPL-3.0-or-later +// License-Filename: LICENSES/AGPL-3.0.txt +// +// Copyright (C) 2024 by via donau +// – Österreichische Wasserstraßen-Gesellschaft mbH +// Software engineering by Intevation GmbH +// +// Author(s): +// * Sascha L. Teichmann + +package common + +// Delta returns a function which returns its argument when called +// the first time and the delta to the last call afterwards. +func Delta() func(int64) int64 { + var last int64 + first := true + return func(x int64) (y int64) { + if first { + first = false + y = x + last = x + } else { + y = x - last + last = x + } + return + } +} diff -r 8ff842858434 -r 6281c18b109f pkg/mesh/meshserialize_v2.go --- a/pkg/mesh/meshserialize_v2.go Mon Feb 12 01:31:48 2024 +0100 +++ b/pkg/mesh/meshserialize_v2.go Mon Feb 12 02:27:41 2024 +0100 @@ -22,8 +22,14 @@ "math" "slices" "sort" + + "gemma.intevation.de/gemma/pkg/common" ) +const quantScale = 1_000 + +func quant(x float64) int64 { return int64(math.Round(x * quantScale)) } + func (s *STRTree) serializeV2(w io.Writer) error { // Write header if _, err := w.Write([]byte(magicHeader)); err != nil { @@ -47,18 +53,118 @@ } func (t *Tin) serializeV2(w io.Writer) error { - // TODO: Implement me! - return errors.New("not implemented, yet") + if err := binary.Write(w, binary.LittleEndian, t.EPSG); err != nil { + return err + } + if err := t.Min.Write(w); err != nil { + return err + } + if err := t.Max.Write(w); err != nil { + return err + } + if err := t.serializeVerticesV2(w); err != nil { + return err + } + return t.serializeTrianglesV2(w) +} + +func zigZag(buf []byte, w io.Writer, x int64) error { + for b := buf[:binary.PutVarint(buf, x)]; len(b) > 0; { + m, err := w.Write(buf) + if err != nil { + return err + } + b = b[m:] + } + return nil +} + +func (t *Tin) serializeVerticesV2(w io.Writer) error { + vertices := t.Vertices + if err := binary.Write(w, binary.LittleEndian, uint32(len(vertices))); err != nil { + return err + } + m := t.Min + buf := make([]byte, binary.MaxVarintLen64) + for dim := range 3 { + delta := common.Delta() + for i := range vertices { + var v float64 + switch dim { + case 0: + v = vertices[i].X - m.X + case 1: + v = vertices[i].Y - m.Y + case 2: + v = vertices[i].Z - m.Z + } + q := quant(v) + d := delta(q) + if err := zigZag(buf, w, d); err != nil { + return err + } + } + } + return nil +} + +func (t *Tin) serializeTrianglesV2(w io.Writer) error { + triangles := t.Triangles + if err := binary.Write(w, binary.LittleEndian, uint32(len(triangles))); err != nil { + return err + } + buf := make([]byte, binary.MaxVarintLen64) + delta := common.Delta() + for _, tri := range triangles { + for _, idx := range tri { + d := delta(int64(idx)) + if err := zigZag(buf, w, d); err != nil { + return err + } + } + } + return nil } func (s *STRTree) serializeIndexV2(w io.Writer) error { - // TODO: Implement me! - return errors.New("not implemented, yet") + index := s.index + if err := binary.Write(w, binary.LittleEndian, uint32(len(index))); err != nil { + return err + } + buf := make([]byte, binary.MaxVarintLen64) + delta := common.Delta() + for _, idx := range index { + d := delta(int64(idx)) + if err := zigZag(buf, w, d); err != nil { + return err + } + } + return nil } func (s *STRTree) serializeBBoxesV2(w io.Writer) error { - // TODO: Implement me! - return errors.New("not implemented, yet") + boxes := s.bboxes + if err := binary.Write(w, binary.LittleEndian, uint32(len(boxes))); err != nil { + return err + } + var ( + m = s.Min() + x1 = func(b Box2D) int64 { return quant(b.X1 - m.X) } + y1 = func(b Box2D) int64 { return quant(b.Y1 - m.Y) } + width = func(b Box2D) int64 { return quant(b.X2 - b.X1) } + height = func(b Box2D) int64 { return quant(b.Y2 - b.Y1) } + buf = make([]byte, binary.MaxVarintLen64) + ) + for _, proj := range []func(Box2D) int64{x1, y1, width, height} { + delta := common.Delta() + for _, b := range boxes { + v := delta(proj(b)) + if err := zigZag(buf, w, v); err != nil { + return err + } + } + } + return nil } func (s *STRTree) deserializeV2(r *bufio.Reader) error {