1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package s2
16
17 import (
18 "errors"
19 "fmt"
20
21 "github.com/golang/geo/r3"
22 )
23
24
25
26 const maxEncodedVertices = 50000000
27
28
29
30
31
32 type xyzFaceSiTi struct {
33 xyz Point
34 face int
35 si, ti uint32
36 level int
37 }
38
39 const derivativeEncodingOrder = 2
40
41 func appendFace(faces []faceRun, face int) []faceRun {
42 if len(faces) == 0 || faces[len(faces)-1].face != face {
43 return append(faces, faceRun{face, 1})
44 }
45 faces[len(faces)-1].count++
46 return faces
47 }
48
49
50 func encodePointsCompressed(e *encoder, vertices []xyzFaceSiTi, level int) {
51 var faces []faceRun
52 for _, v := range vertices {
53 faces = appendFace(faces, v.face)
54 }
55 encodeFaces(e, faces)
56
57 type piQi struct {
58 pi, qi uint32
59 }
60 verticesPiQi := make([]piQi, len(vertices))
61 for i, v := range vertices {
62 verticesPiQi[i] = piQi{siTitoPiQi(v.si, level), siTitoPiQi(v.ti, level)}
63 }
64 piCoder, qiCoder := newNthDerivativeCoder(derivativeEncodingOrder), newNthDerivativeCoder(derivativeEncodingOrder)
65 for i, v := range verticesPiQi {
66 f := encodePointCompressed
67 if i == 0 {
68
69
70
71
72 f = encodeFirstPointFixedLength
73 }
74 f(e, v.pi, v.qi, level, piCoder, qiCoder)
75 }
76
77 var offCenter []int
78 for i, v := range vertices {
79 if v.level != level {
80 offCenter = append(offCenter, i)
81 }
82 }
83 e.writeUvarint(uint64(len(offCenter)))
84 for _, idx := range offCenter {
85 e.writeUvarint(uint64(idx))
86 e.writeFloat64(vertices[idx].xyz.X)
87 e.writeFloat64(vertices[idx].xyz.Y)
88 e.writeFloat64(vertices[idx].xyz.Z)
89 }
90 }
91
92 func encodeFirstPointFixedLength(e *encoder, pi, qi uint32, level int, piCoder, qiCoder *nthDerivativeCoder) {
93
94 codedPi, codedQi := piCoder.encode(int32(pi)), qiCoder.encode(int32(qi))
95
96 interleaved := interleaveUint32(uint32(codedPi), uint32(codedQi))
97
98
99 bytesRequired := (level + 7) / 8 * 2
100 for i := 0; i < bytesRequired; i++ {
101 e.writeUint8(uint8(interleaved))
102 interleaved >>= 8
103 }
104 }
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141 func encodePointCompressed(e *encoder, pi, qi uint32, level int, piCoder, qiCoder *nthDerivativeCoder) {
142
143
144 zzPi := zigzagEncode(piCoder.encode(int32(pi)))
145 zzQi := zigzagEncode(qiCoder.encode(int32(qi)))
146
147 interleaved := interleaveUint32(zzPi, zzQi)
148 e.writeUvarint(interleaved)
149 }
150
151 type faceRun struct {
152 face, count int
153 }
154
155 func decodeFaceRun(d *decoder) faceRun {
156 faceAndCount := d.readUvarint()
157 ret := faceRun{
158 face: int(faceAndCount % NumFaces),
159 count: int(faceAndCount / NumFaces),
160 }
161 if ret.count <= 0 && d.err == nil {
162 d.err = errors.New("non-positive count for face run")
163 }
164 return ret
165 }
166
167 func decodeFaces(numVertices int, d *decoder) []faceRun {
168 var frs []faceRun
169 for nparsed := 0; nparsed < numVertices; {
170 fr := decodeFaceRun(d)
171 if d.err != nil {
172 return nil
173 }
174 frs = append(frs, fr)
175 nparsed += fr.count
176 }
177 return frs
178 }
179
180
181 func encodeFaceRun(e *encoder, fr faceRun) {
182
183
184
185 coded := NumFaces*uint64(fr.count) + uint64(fr.face)
186 e.writeUvarint(coded)
187 }
188
189 func encodeFaces(e *encoder, frs []faceRun) {
190 for _, fr := range frs {
191 encodeFaceRun(e, fr)
192 }
193 }
194
195 type facesIterator struct {
196 faces []faceRun
197
198 numCurrentFaceShown int
199 curFace int
200 }
201
202 func (fi *facesIterator) next() (ok bool) {
203 if len(fi.faces) == 0 {
204 return false
205 }
206 fi.curFace = fi.faces[0].face
207 fi.numCurrentFaceShown++
208
209
210 if fi.faces[0].count <= fi.numCurrentFaceShown {
211 fi.faces = fi.faces[1:]
212 fi.numCurrentFaceShown = 0
213 }
214
215 return true
216 }
217
218 func decodePointsCompressed(d *decoder, level int, target []Point) {
219 faces := decodeFaces(len(target), d)
220
221 piCoder := newNthDerivativeCoder(derivativeEncodingOrder)
222 qiCoder := newNthDerivativeCoder(derivativeEncodingOrder)
223
224 iter := facesIterator{faces: faces}
225 for i := range target {
226 decodeFn := decodePointCompressed
227 if i == 0 {
228 decodeFn = decodeFirstPointFixedLength
229 }
230 pi, qi := decodeFn(d, level, piCoder, qiCoder)
231 if ok := iter.next(); !ok && d.err == nil {
232 d.err = fmt.Errorf("ran out of faces at target %d", i)
233 return
234 }
235 target[i] = Point{facePiQitoXYZ(iter.curFace, pi, qi, level)}
236 }
237
238 numOffCenter := int(d.readUvarint())
239 if d.err != nil {
240 return
241 }
242 if numOffCenter > len(target) {
243 d.err = fmt.Errorf("numOffCenter = %d, should be at most len(target) = %d", numOffCenter, len(target))
244 return
245 }
246 for i := 0; i < numOffCenter; i++ {
247 idx := int(d.readUvarint())
248 if d.err != nil {
249 return
250 }
251 if idx >= len(target) {
252 d.err = fmt.Errorf("off center index = %d, should be < len(target) = %d", idx, len(target))
253 return
254 }
255 target[idx].X = d.readFloat64()
256 target[idx].Y = d.readFloat64()
257 target[idx].Z = d.readFloat64()
258 }
259 }
260
261 func decodeFirstPointFixedLength(d *decoder, level int, piCoder, qiCoder *nthDerivativeCoder) (pi, qi uint32) {
262 bytesToRead := (level + 7) / 8 * 2
263 var interleaved uint64
264 for i := 0; i < bytesToRead; i++ {
265 rr := d.readUint8()
266 interleaved |= (uint64(rr) << uint(i*8))
267 }
268
269 piCoded, qiCoded := deinterleaveUint32(interleaved)
270
271 return uint32(piCoder.decode(int32(piCoded))), uint32(qiCoder.decode(int32(qiCoded)))
272 }
273
274 func zigzagEncode(x int32) uint32 {
275 return (uint32(x) << 1) ^ uint32(x>>31)
276 }
277
278 func zigzagDecode(x uint32) int32 {
279 return int32((x >> 1) ^ uint32((int32(x&1)<<31)>>31))
280 }
281
282 func decodePointCompressed(d *decoder, level int, piCoder, qiCoder *nthDerivativeCoder) (pi, qi uint32) {
283 interleavedZigZagEncodedDerivPiQi := d.readUvarint()
284 piZigzag, qiZigzag := deinterleaveUint32(interleavedZigZagEncodedDerivPiQi)
285 return uint32(piCoder.decode(zigzagDecode(piZigzag))), uint32(qiCoder.decode(zigzagDecode(qiZigzag)))
286 }
287
288
289
290
291
292
293
294
295
296
297
298
299 func stToPiQi(s float64, level uint) uint32 {
300 return uint32(s * float64(int(1)<<level))
301 }
302
303
304
305
306
307
308 func siTitoPiQi(siTi uint32, level int) uint32 {
309 s := uint(siTi)
310 const max = maxSiTi - 1
311 if s > max {
312 s = max
313 }
314
315 return uint32(s >> (MaxLevel + 1 - uint(level)))
316 }
317
318
319 func piQiToST(pi uint32, level int) float64 {
320
321
322
323
324 return (float64(pi) + 0.5) / float64(int(1)<<uint(level))
325 }
326
327 func facePiQitoXYZ(face int, pi, qi uint32, level int) r3.Vector {
328 return faceUVToXYZ(face, stToUV(piQiToST(pi, level)), stToUV(piQiToST(qi, level))).Normalize()
329 }
330
View as plain text