148 :length(fn)
149 if ~matches(fn{j}, me.ignoreProperties) %create a temporary dynamic property
150 p = addprop(me, [fn{j} 'Out']);
151 if strcmp(fn{j},
'sf'); p.SetMethod = @
set_sfOut; end
152 if strcmp(fn{j},'tf')
154 p.SetObservable = true;
155 addlistener(me, [fn{j} 'Out'], 'PostSet', @me.calculatePhaseIncrement);
156 end
157 if strcmp(fn{j},'driftDirection')
159 p.SetObservable = true;
160 addlistener(me, [fn{j} 'Out'], 'PostSet', @me.calculatePhaseIncrement);
161 end
162 if strcmp(fn{j},'size')
164 p.SetObservable = true;
165 addlistener(me, [fn{j} 'Out'], 'PostSet', @me.calculateScale);
166 end
169 me.([fn{j} 'Out']) = me.(fn{j}); %copy our property value to our tempory copy
170 end
171 end
172
174
175 if ~isprop(me,'rotateMode'); addprop(me,'rotateMode'); end
176 if me.rotationMethod==1
177 me.rotateMode = kPsychUseTextureMatrixForRotation;
178 else
179 me.rotateMode = [];
180 end
181
182 if ~isprop(me,'gratingSize'); addprop(me,'gratingSize'); end
183 me.gratingSize = round(me.ppd*me.size);
184
185 if ~isprop(me,'phaseIncrement'); addprop(me,'phaseIncrement'); end
186
187 if ~isprop(me,'driftPhase'); addprop(me,'driftPhase'); end
188 if me.correctPhase
189 ps = me.calculatePhase;
190 me.driftPhase = me.phaseOut-ps;
191 else
192 me.driftPhase = me.phaseOut;
193 end
194
195 if ~isprop(me,'res'); addprop(me,'res'); end
196 me.res = [me.gratingSize me.gratingSize];
197
198 if me.phaseReverseTime > 0
199 me.phaseCounter = round(me.phaseReverseTime / me.sM.screenVals.ifi);
200 end
201
202 if me.aspectRatio == 1
203 nonSymmetric = 0;
204 else
205 nonSymmetric = 1;
206 end
207 me.texture = CreateProceduralGabor(me.sM.win, me.res(1),...
208 me.res(2), nonSymmetric, me.colourOut, me.disableNorm,...
209 me.contrastMult);
210
211 me.inSetup = false; me.isSetup = true;
212
213 notify(me,'changeScale');
216
218 me.xPositionOut = value * me.ppd;
219 end
221 me.yPositionOut = value * me.ppd;
222 end
224 if me.sfRecurse == false
225 me.sfCache = (value / me.ppd);
226 me.sfOut = me.sfCache * me.scale;
227 else
228 me.sfOut = value;
229 me.sfRecurse = false;
230 end
231 %fprintf('\nSET SFOut: %d | cachce: %d | in: %d\n', me.sfOut, me.sfCache, value);
232 end
234 me.tfOut = value;
235 end
237 me.driftDirectionOut = value;
238 end
240 me.sizeOut = value * me.ppd;
241 me.szPx = me.sizeOut;
242 end
243
244 end
245
246 % ===================================================================
247 %> @brief Update this stimulus object for display
248 %>
249 % ===================================================================
252 if me.correctPhase
253 ps=me.calculatePhase;
254 me.driftPhase=me.phaseOut-ps;
255 else
256 me.driftPhase=me.phaseOut;
257 end
260 end
261
262 % ===================================================================
263 %> @brief Draw this stimulus object for display
264 %>
265 %>
266 % ===================================================================
268 if me.isVisible && me.tick >= me.delayTicks && me.tick < me.offTicks
269 Screen('DrawTexture', me.sM.win, me.texture, [],me.mvRect,...
270 me.angleOut, [], [], [], [], 2,...
271 [me.driftPhase, me.sfOut, me.spatialConstantOut,...
272 me.contrastOut, me.aspectRatioOut, 0, 0, 0]);
273 me.drawTick = me.drawTick + 1;
274 end
275 if me.isVisible; me.tick = me.tick + 1; end
276 end
277
278 % ===================================================================
280 %>
281 % ===================================================================
283 if me.isVisible && me.tick >= me.delayTicks
284 if me.mouseOverride
286 if me.mouseValid
287 me.mvRect = CenterRectOnPointd(me.mvRect, me.mouseX, me.mouseY);
288 end
289 end
290 if me.doMotion == true
291 me.mvRect=OffsetRect(me.mvRect,me.dX_,me.dY_);
292 end
293 if me.doDrift == true
294 me.driftPhase = me.driftPhase + me.phaseIncrement;
295 end
296 if mod(me.tick,me.phaseCounter) == 0
297 me.driftPhase = me.driftPhase + me.phaseOfReverse;
298 end
299 end
300 end
301
302 % ===================================================================
304 %>
306 %> @return stimulus structure.
307 % ===================================================================
310 if isprop(me,'texture')
312 try Screen('Close',me.
texture); end %
#ok<*TRYNC>
313 end
314 me.texture = [];
315 end
317 end
318
319 % ===================================================================
320 %> @brief
sf Set method
321 %>
322 % ===================================================================
323 function set.sf(me,value)
324 if value <= 0
325 value = 0.05;
326 end
327 me.sf = value;
328 me.salutation(['set sf: ' num2str(value)],'Custom set method')
329 end
330
331 % ===================================================================
332 %> @brief calculate
phase offset
333 %>
334 % ===================================================================
337 if me.correctPhase > 0
339 size = (me.sizeOut/2); %divide by 2 to get the 0 point
340 sfTmp = (me.sfOut/me.scale)*me.ppd;
342 md=md-floor(md);
344 end
345 end
346
347 end %---END PUBLIC METHODS---%
348
349
350 %=======================================================================
351 methods ( Access = protected ) %-------PROTECTED METHODS-----%
352 %=======================================================================
353
354 % ===================================================================
356 %>
setRect makes the PsychRect based on the
texture and screen values
357 %> this is modified over parent method as gratings have slightly different
358 %> requirements.
359 % ===================================================================
361 me.dstRect=Screen('Rect',me.texture);
362 me.dstRect=ScaleRect(me.dstRect,me.scale,me.scale);
363 if me.mouseOverride
364 if me.mouseValid
365 me.dstRect = CenterRectOnPointd(me.dstRect, me.mouseX, me.mouseY);
366 end
367 else
368 if ~isprop(me,'directionOut')
369 [sx sy]=pol2cart(me.d2r(me.direction),me.startPosition);
370 else
371 [sx sy]=pol2cart(me.d2r(me.directionOut),me.startPosition);
372 end
373 me.dstRect=CenterRectOnPointd(me.dstRect,me.sM.xCenter,me.sM.yCenter);
374 if ~isprop(me,'xPositionOut')
376 else
378 end
379 end
383 end
384
385 end %---END PROTECTED METHODS---%
386
387 %=======================================================================
388 methods ( Access = protected ) %-------PROTECTED METHODS-----%
389 %=======================================================================
390
391 % ===================================================================
393 %> Use an event to recalculate
scale as get method is slower (called
394 %> many more times), than an event which is only called on
update
395 % ===================================================================
400 if isprop(me,'spatialConstantOut')
402 end
403 end
404
405 % ===================================================================
407 %> Use an event to recalculate as get method is slower (called
408 %> many more times), than an event which is only called on
update
409 % ===================================================================
411 if isprop(me,'tfOut')
413 if isprop(me,'driftDirectionOut') && me.driftDirectionOut == false
415 end
416 end
417 end
418
419 end
420end
function computePosition(in me)
compute xFinal and yFinal (in pixels) taking startPosition, xPosition, yPosition and direction/angle ...
Property size
Definition baseStimulus.m:46
function getMousePosition(in me)
get mouse position we make sure this is only called once per animation tick to improve performance an...
Property sM
our screen manager
Definition baseStimulus.m:165
Property szPx
computed size in pixels
Definition baseStimulus.m:113
function setAnimationDelta(in me)
Property ppd
pixels per degree (normally inhereted from screenManager)
Definition baseStimulus.m:139
function resetTicks(in me)
reset the various tick counters for our stimulus
Property texture
Our texture pointer for texture-based stimuli.
Definition baseStimulus.m:159
Property yPosition
Definition baseStimulus.m:42
Property screenVals
screen settings generated by sM on setup
Definition baseStimulus.m:171
Property mvRect
Definition baseStimulus.m:102
function removeTmpProperties(in me)
Finds and removes dynamic properties.
Property dstRect
initial screen rectangle position [LEFT TOP RIGHT BOTTOM]
Definition baseStimulus.m:184
function addRuntimeProperties(in me)
These are transient properties that specify actions during runtime.
Property xPosition
Definition baseStimulus.m:38
Property sfCache
Definition gaborStimulus.m:93
function set_yPositionOut(in me, in value)
function calculateScale(in me, in ignoredArg, in ignoredArg)
calculateScale Use an event to recalculate scale as get method is slower (called many more times),...
function calculatePhase(in me)
calculate phase offset
function draw(in me)
Draw this stimulus object for display.
function reset(in me)
Reset an structure for runExperiment.
function set_sizeOut(in me, in value)
function calculatePhaseIncrement(in me, in ignoredArg, in ignoredArg)
calculatePhaseIncrement Use an event to recalculate as get method is slower (called many more times),...
Property sfRecurse
to stop a loop between set method and an event
Definition gaborStimulus.m:96
Property phase
phase of grating
Definition gaborStimulus.m:36
function set_tfOut(in me, in value)
function set_sfOut(in me, in value)
Property scale
scale is used when changing size as an independent variable to keep sf accurate
Definition gaborStimulus.m:78
Property sf
spatial frequency
Definition gaborStimulus.m:27
Property phaseIncrement
the phase amount we need to add for each frame of animation
Definition gaborStimulus.m:81
function set_xPositionOut(in me, in value)
function update(in me)
Update this stimulus object for display.
function set_driftDirectionOut(in me, in value)
function setRect(in me)
setRect setRect makes the PsychRect based on the texture and screen values this is modified over pare...
Property spatialConstant
a divisor for the size for the gaussian envelope for a gabor
Definition gaborStimulus.m:57
function animate(in me)
Animate this object for runExperiment.
The main experiment manager.
Definition runExperiment.m:3