Created
February 10, 2020 00:54
-
-
Save cortical-iv/e11e8519fea00ba41b36a412354946bf to your computer and use it in GitHub Desktop.
two textures superimposing rather than showing in series with 0/1 key press
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sys | |
import numpy as np | |
from direct.showbase.ShowBase import ShowBase | |
from direct.showbase import ShowBaseGlobal #global vars defined by p3d | |
from panda3d.core import Texture, CardMaker, TextureStage, KeyboardButton | |
from panda3d.core import WindowProperties | |
from direct.task import Task | |
class SinGreyTex: | |
""" | |
RGB sinusoidal grating stimulus class, used by ShowBase. | |
""" | |
def __init__(self, texture_size = 512, texture_name = "sin_grey", spatial_frequency = 10): | |
self.frequency = spatial_frequency | |
self.texture_size = texture_size | |
self.texture_name = texture_name | |
# Create texture stage | |
self.texture_array = self.create_texture() | |
self.texture = Texture(self.texture_name) | |
self.texture.setup2dTexture(self.texture_size, self.texture_size, | |
Texture.T_unsigned_byte, | |
Texture.F_luminance) | |
self.texture.setRamImageAs(self.texture_array, "L") | |
self.texture_stage = TextureStage(self.texture_name) | |
def create_texture(self): | |
x = np.linspace(0, 2*np.pi, self.texture_size + 1) | |
y = np.linspace(0, 2*np.pi, self.texture_size + 1) | |
array, Y = np.meshgrid(x[: self.texture_size],y[: self.texture_size]) | |
sin_float = np.sin(self.frequency*array) | |
sin_transformed = (sin_float + 1)*127.5; #from 0-255 | |
return np.uint8(sin_transformed) | |
class KeyboardToggleStim(ShowBase): | |
""" | |
toggles between different stim: enter 0 for one, 1 for the other | |
""" | |
def __init__(self, stim_classes, stim_params, window_size = 512): | |
super().__init__() | |
self.stim_classes = stim_classes | |
self.current_stim_num = 0 | |
self.stim_params = stim_params | |
self.window_size = window_size | |
self.bgcolor = (1, 1, 1, 1) | |
self.stimulus_initialized = False | |
#Set up key control mechanism | |
self.zero_button = KeyboardButton.ascii_key('0') | |
self.one_button = KeyboardButton.ascii_key('1') | |
#Window properties | |
self.window_props = WindowProperties() | |
self.window_props.setSize(self.window_size, self.window_size) | |
#Create scenegraph | |
cm = CardMaker('card') | |
cm.setFrameFullscreenQuad() | |
self.card = self.aspect2d.attachNewNode(cm.generate()) | |
self.card.setScale(np.sqrt(2)) #so it can handle arbitrary rotations | |
self.card.setColor(self.bgcolor) | |
#Set initial texture | |
self.set_stimulus(str(self.current_stim_num)) | |
# Set up event handlers and tasks | |
self.accept('0', self.set_stimulus, ['0']) #event handler | |
self.accept('1', self.set_stimulus, ['1']) | |
self.taskMgr.add(self.move_texture_task, "move_texture") #task | |
@property | |
def current_stim_params(self): | |
""" | |
returns actual value of current stimulus | |
""" | |
return self.stim_params[self.current_stim_num] | |
def set_stimulus(self, data): | |
# If first texture hasn't been shown, don't clear previous texture | |
if not self.stimulus_initialized: | |
self.self_initialized = True | |
else: | |
self.card.clearTexture(self.stim.texture_stage) #turn off stage | |
self.window_props.setTitle(data) | |
ShowBaseGlobal.base.win.requestProperties(self.window_props) #base is a panda3d global | |
if data == '0': | |
self.current_stim_num = 0 | |
elif data == '1': | |
self.current_stim_num = 1 | |
self.stim = self.stim_classes[self.current_stim_num] | |
self.card.setColor(self.bgcolor) | |
self.card.setTexture(self.stim.texture_stage, self.stim.texture) | |
self.card.setR(self.current_stim_params['angle']) #set angle | |
return | |
def move_texture_task(self, task): | |
if self.current_stim_params['velocity'] == 0: | |
pass | |
else: | |
new_position = -task.time*self.current_stim_params['velocity'] | |
self.card.setTexPos(self.stim.texture_stage, new_position, 0, 0) #u, v, w | |
return task.cont | |
if __name__ == '__main__': | |
stim1 = SinGreyTex(spatial_frequency = 10) | |
stim2 = SinGreyTex(spatial_frequency = 5) | |
stim_classes = [stim1, stim2] | |
stim_params = [{'angle': 45, 'velocity': 0.1}, | |
{'angle': -45, 'velocity': -0.1}] | |
toggle_show = KeyboardToggleStim(stim_classes, stim_params) | |
toggle_show.run() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment