1
+ function elem = checkerLeft(t )
2
+ % vis.checker A grid of rectangles
3
+ % Detailed explanation goes here
4
+
5
+ elem = t .Node .Net .subscriptableOrigin(' checker' );
6
+
7
+ %% make initial layers to be used as templates
8
+ maskTemplate = vis .emptyLayer();
9
+ maskTemplate.isPeriodic = false ;
10
+ maskTemplate.interpolation = ' nearest' ;
11
+ maskTemplate.show = true ;
12
+ maskTemplate.colourMask = [false false false true ];
13
+
14
+ maskTemplate.textureId = ' checkerMaskPixel' ;
15
+ [maskTemplate .rgba , maskTemplate .rgbaSize ] = vis .rgba(0 , 0 );
16
+ maskTemplate.blending = ' 1-source' ; % allows us to lay down our zero alpha value
17
+
18
+ stencilTemplate = maskTemplate ;
19
+ stencilTemplate.textureId = ' checkerStencilPixel' ;
20
+ [stencilTemplate .rgba , stencilTemplate .rgbaSize ] = vis .rgba(1 , 1 );
21
+ stencilTemplate.blending = ' none' ;
22
+
23
+ % pattern layer uses the alpha values laid down by mask layers
24
+ patternLayer = vis .emptyLayer();
25
+ patternLayer.textureId = sprintf(' ~checker%i ' , randi(2 ^ 32 ));
26
+ patternLayer.isPeriodic = false ;
27
+ patternLayer.interpolation = ' nearest' ;
28
+ patternLayer.blending = ' destination' ; % use the alpha mask gets laid down before this
29
+
30
+ %% construct signals used to assemble layers
31
+ % N rows by cols signal is derived from the size of the pattern array but
32
+ % we skip repeats so that pattern changes don't update the mask layers
33
+ % unless the size has acutally changed
34
+ nRowsByCols = elem .pattern .flatten().map(@size ).skipRepeats();
35
+ aziRange = elem .azimuthRange .flatten();
36
+ altRange = elem .altitudeRange .flatten();
37
+ sizeFrac = elem .rectSizeFrac .flatten();
38
+ % signal containing the masking layers
39
+ gridMaskLayers = mapn(nRowsByCols , aziRange , altRange , sizeFrac , ...
40
+ maskTemplate , stencilTemplate , @gridMask );
41
+ % signal contain the checker layer
42
+ checkerLayer = scan(elem .pattern .flatten(), @updatePattern ,...
43
+ elem .colour .flatten(), @updateColour ,...
44
+ elem .azimuthRange .flatten(), @updateAzi ,...
45
+ elem .altitudeRange .flatten(), @updateAlt ,...
46
+ elem .show .flatten(), @updateShow ,...
47
+ patternLayer ); % initial value
48
+ %% set default attribute values
49
+ elem.layers = [gridMaskLayers checkerLayer ];
50
+ elem.azimuthRange = [-135 0 ];
51
+ elem.altitudeRange = [-37.5 37.5 ];
52
+ elem.rectSizeFrac = [1 1 ]; % horizontal and vertical size of each rectangle
53
+ elem.pattern = [
54
+ 1 - 1 1 - 1
55
+ - 1 0 0 0
56
+ 1 0 0 0
57
+ - 1 1 - 1 1 ];
58
+ elem.show = true ;
59
+ end
60
+
61
+ %% helper functions
62
+ function layer = updatePattern(layer , pattern )
63
+ % map pattern from -1 -> 1 range to 0->255, cast to 8 bit integers, then
64
+ % convert to RGBA texture format.
65
+ [layer .rgba , layer .rgbaSize ] = vis .rgbaFromUint8(uint8(127.5 *(1 + pattern )), 1 );
66
+ end
67
+
68
+ function layer = updateColour(layer , colour )
69
+ layer.maxColour = [colour 1 ];
70
+ end
71
+
72
+ function layer = updateAzi(layer , aziRange )
73
+ layer .size(1 ) = abs(diff(aziRange ));
74
+ layer .texOffset(1 ) = mean(aziRange );
75
+ end
76
+
77
+ function layer = updateAlt(layer , altRange )
78
+ layer .size(2 ) = abs(diff(altRange ));
79
+ layer .texOffset(2 ) = mean(altRange );
80
+ end
81
+
82
+ function layer = updateShow(layer , show )
83
+ layer.show = show ;
84
+ end
85
+
86
+ function layers = gridMask(nRowsByCols , aziRange , altRange , sizeFrac , mask , stencil )
87
+ gridDims = [abs(diff(aziRange )) abs(diff(altRange ))];
88
+ cellSize = gridDims ./ flip(nRowsByCols );
89
+ nCols = nRowsByCols(2 ) + 1 ;
90
+ nRows = nRowsByCols(1 ) + 1 ;
91
+ midAzi = mean(aziRange );
92
+ midAlt = mean(altRange );
93
+ %% base layer to imprint area the checker can draw on (by applying an alpha mask)
94
+ stencil.texOffset = [midAzi midAlt ];
95
+ stencil.size = gridDims ;
96
+ if any(sizeFrac < 1 )
97
+ %% layers for lines making up mask grid - masks out margins around each square
98
+ % make layers for vertical lines
99
+ if nCols > 1
100
+ azi = linspace(aziRange(1 ), aziRange(2 ), nCols );
101
+ else
102
+ azi = midAzi ;
103
+ end
104
+ collayers = repmat(mask , 1 , nCols );
105
+ for vi = 1 : nCols
106
+ collayers(vi ).texOffset = [azi(vi ) midAlt ];
107
+ end
108
+ [collayers .size ] = deal([(1 - sizeFrac(1 ))*cellSize(1 ) gridDims(2 )]);
109
+ % make layers for horizontal lines
110
+ if nRows > 1
111
+ alt = linspace(altRange(1 ), altRange(2 ), nRows );
112
+ else
113
+ alt = midAlt ;
114
+ end
115
+ rowlayers = repmat(mask , 1 , nRows );
116
+ for hi = 1 : nRows
117
+ rowlayers(hi ).texOffset = [midAzi alt(hi )];
118
+ end
119
+ [rowlayers .size ] = deal([gridDims(1 ) (1 - sizeFrac(2 ))*cellSize(2 )]);
120
+ %% combine the layers and return
121
+ layers = [stencil collayers rowlayers ];
122
+ else % no mask grid needed as each cell is full size
123
+ layers = stencil ;
124
+ end
125
+
126
+ end
0 commit comments