-
Notifications
You must be signed in to change notification settings - Fork 0
/
tpm2net_handler.go
110 lines (83 loc) · 2.38 KB
/
tpm2net_handler.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package main
import (
"github.com/e-asphyx/tpm2net"
"log"
)
type TPMHandler struct {
VirtualWidth int
VirtualHeight int
Oversample int
Layout Layout
Output OutputDevice
frameBuffer []uint8
outputBuffer []Color
cellMap []map[int]float64
}
func (hnd *TPMHandler) HandlePacket(pkt *tpm2net.Packet) {
numLeds := hnd.Layout.NumCells()
bufSz := hnd.VirtualWidth * hnd.VirtualHeight * 3
if len(hnd.frameBuffer) < bufSz {
hnd.frameBuffer = make([]uint8, bufSz)
}
copy(hnd.frameBuffer, pkt.Data)
if len(hnd.outputBuffer) < numLeds {
hnd.outputBuffer = make([]Color, numLeds)
}
if len(hnd.cellMap) < numLeds {
hnd.initMap()
}
for i := range hnd.outputBuffer {
acc := [3]float64{}
for offs, coeff := range hnd.cellMap[i] {
acc[0] += float64(hnd.frameBuffer[offs*3]) * coeff
acc[1] += float64(hnd.frameBuffer[offs*3+1]) * coeff
acc[2] += float64(hnd.frameBuffer[offs*3+2]) * coeff
}
for c := range acc {
if acc[c] > 255.0 {
acc[c] = 255.0
}
}
hnd.outputBuffer[i] = RGB(uint8(acc[0]+0.5), uint8(acc[1]+0.5), uint8(acc[2]+0.5))
}
if _, err := hnd.Output.Write(hnd.outputBuffer); err != nil {
log.Println(err)
}
}
func (hnd *TPMHandler) initMap() {
hnd.cellMap = make([]map[int]float64, hnd.Layout.NumCells())
layoutWidth := hnd.Layout.Width()
layoutHeight := hnd.Layout.Height()
virtualWidth := hnd.VirtualWidth * hnd.Oversample
virtualHeight := hnd.VirtualHeight * hnd.Oversample
xstep := layoutWidth / float64(virtualWidth)
ystep := layoutHeight / float64(virtualHeight)
for i := range hnd.cellMap {
poly := hnd.Layout.Cell(i)
tl, br := poly.BoundingBox()
x0 := int(tl.X / layoutWidth * float64(virtualWidth))
x1 := int(br.X / layoutWidth * float64(virtualWidth))
y0 := int(tl.Y / layoutHeight * float64(virtualHeight))
y1 := int(br.Y / layoutHeight * float64(virtualHeight))
cnt := make(map[int]int)
sum := 0
for y := y0; y <= y1; y++ {
for x := x0; x <= x1; x++ {
center := Point{float64(x)*xstep + xstep/2.0, float64(y)*ystep + ystep/2.0}
if poly.PointInside(center) &&
x >= 0 && y >= 0 &&
x < virtualWidth && y < virtualHeight {
xx := x / hnd.Oversample
yy := y / hnd.Oversample
offs := (yy*hnd.VirtualWidth + xx)
cnt[offs]++
sum++
}
}
}
hnd.cellMap[i] = make(map[int]float64)
for offs, c := range cnt {
hnd.cellMap[i][offs] = float64(c) / float64(sum)
}
}
}