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