psychopy 2024.2.1__py3-none-any.whl → 2024.2.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of psychopy might be problematic. Click here for more details.
- psychopy/.DS_Store +0 -0
- psychopy/GIT_SHA +1 -1
- psychopy/VERSION +1 -1
- psychopy/__init__.py +10 -1
- psychopy/__init__.py.orig +65 -0
- psychopy/app/{locale/ar_001/.DS_Store → .DS_Store} +0 -0
- psychopy/app/Resources/.DS_Store +0 -0
- psychopy/app/_psychopyApp.py +11 -3
- psychopy/app/appData.spec +1 -1
- psychopy/app/builder/builder.py +1 -1
- psychopy/app/builder/builder.py.orig +3932 -0
- psychopy/app/builder/dialogs/__init__.py.orig +1679 -0
- psychopy/app/builder/dialogs/paramCtrls.py +1 -1
- psychopy/app/builder/dialogs/paramCtrls.py.orig +713 -0
- psychopy/app/colorpicker/__init__.py.orig +411 -0
- psychopy/app/cortex.log +0 -0
- psychopy/app/jobs.py +8 -1
- psychopy/app/locale/ar_001/LC_MESSAGE/messages.po +2452 -1731
- psychopy/app/locale/zh_CN/LC_MESSAGE/zh_CN.mo +0 -0
- psychopy/app/locale/zh_CN/LC_MESSAGE/zh_CN.po +6127 -0
- psychopy/app/locale/zh_CN/LC_MESSAGE/zh_CN_allFlagged.mo +0 -0
- psychopy/app/locale/zh_CN/LC_MESSAGE/zh_CN_allFlagged.po +7366 -0
- psychopy/app/plugin_manager/dialog.py +9 -7
- psychopy/app/ribbon.py +2 -1
- psychopy/app/runner/runner.py +7 -5
- psychopy/clock.py +8 -4
- psychopy/core.py.orig +169 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/html/index.html +23 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/html/randomisedBlocks-legacy-browsers.js +423 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/html/randomisedBlocks.js +427 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/html/resources/chooseBlock.xlsx +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/html/resources/facesBlock.xlsx +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/html/resources/housesBlock.xlsx +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/html/resources/stims/face01.jpg +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/html/resources/stims/face02.jpg +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/html/resources/stims/face03.jpg +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/html/resources/stims/house01.jpg +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/html/resources/stims/house02.jpg +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/html/resources/stims/house03.jpg +0 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/randomisedBlocks.py +330 -0
- psychopy/demos/builder/Design Templates/randomisedBlocks/randomisedBlocks_lastrun.py +330 -0
- psychopy/demos/builder/Feature Demos/eyetracking/eyetracking.xml +298 -0
- psychopy/demos/builder/Feature Demos/eyetracking/eyetracking.xsd +120 -0
- psychopy/demos/builder/Tools/.DS_Store +0 -0
- psychopy/demos/builder/Tools/gammaCalibration/.DS_Store +0 -0
- psychopy/demos/builder/Tools/gammaCalibration/data/_gamma_correction_visual_2022-05-18_14h18.29.439.csv +38 -0
- psychopy/demos/builder/Tools/gammaCalibration/data/_gamma_correction_visual_2022-05-18_14h18.29.439.log +3418 -0
- psychopy/demos/builder/Tools/gammaCalibration/data/_gamma_correction_visual_2022-05-18_14h18.29.439.psydat +0 -0
- psychopy/demos/builder/Tools/gammaCalibration/data/x1_gamma_correction_visual_2022-05-17_13h59.42.928.csv +2 -0
- psychopy/demos/builder/Tools/gammaCalibration/data/x1_gamma_correction_visual_2022-05-17_13h59.42.928.log +15 -0
- psychopy/demos/builder/Tools/gammaCalibration/data/x1_gamma_correction_visual_2022-05-17_13h59.42.928.psydat +0 -0
- psychopy/demos/builder/Tools/gammaCalibration/gamma_correction_visual.psyexp +323 -0
- psychopy/demos/builder/Tools/gammaCalibration/gamma_correction_visual.py +562 -0
- psychopy/demos/builder/Tools/gammaCalibration/gamma_correction_visual_lastrun.py +562 -0
- psychopy/demos/builder/Tools/gammaCalibration/questStairs.xlsx +0 -0
- psychopy/demos/builder/Tools/gammaCalibration/readme.md +0 -0
- psychopy/demos/builder/Tools/gammaCalibration/resources/low_contrast.png +0 -0
- psychopy/demos/builder/Tools/gammaCalibration/resources/make_2nd_order_tex.py +59 -0
- psychopy/demos/builder/Tools/gammaCalibration/resources/second_order_tex.png +0 -0
- psychopy/demos/coder/.DS_Store +0 -0
- psychopy/demos/coder/experiment control/info_gamma.pickle +0 -0
- psychopy/demos/coder/iohub/.iohpid +1 -0
- psychopy/demos/coder/iohub/eyetracking/.iohpid +1 -0
- psychopy/demos/coder/iohub/wintab/.DS_Store +0 -0
- psychopy/demos/coder/stimuli/.DS_Store +0 -0
- psychopy/demos/coder/stimuli/radialGratingContracting.py +29 -0
- psychopy/experiment/_experiment.py.orig +1032 -0
- psychopy/experiment/components/.DS_Store +0 -0
- psychopy/experiment/components/_base.py +13 -4
- psychopy/experiment/components/_base.py.orig +823 -0
- psychopy/experiment/components/form/.DS_Store +0 -0
- psychopy/experiment/components/microphone/__init__.py +10 -1
- psychopy/experiment/components/microphone/__init__.py.orig +490 -0
- psychopy/experiment/components/polygon/__init__.py +21 -22
- psychopy/experiment/components/settings/__init__.py +13 -14
- psychopy/experiment/components/settings/__init__.py.orig +1337 -0
- psychopy/experiment/components/textbox/__init__.py.orig +310 -0
- psychopy/experiment/components/webcam/.DS_Store +0 -0
- psychopy/experiment/components/webcam/light/.DS_Store +0 -0
- psychopy/experiment/flow.py +10 -8
- psychopy/experiment/loops.py.orig +829 -0
- psychopy/experiment/params.py +8 -3
- psychopy/experiment/params.py.orig +408 -0
- psychopy/experiment/routine.py.orig +503 -0
- psychopy/experiment/routines/_base.py +15 -6
- psychopy/experiment/routines/counterbalance/__init__.py +1 -0
- psychopy/gui/qtgui.py +14 -7
- psychopy/gui/util.py +10 -14
- psychopy/gui/wxgui.py +10 -4
- psychopy/hardware/.DS_Store +0 -0
- psychopy/hardware/brainproducts.py.orig +680 -0
- psychopy/hardware/iolab.py.orig +238 -0
- psychopy/hardware/manager.py +1 -1
- psychopy/hardware/photodiode.py +59 -27
- psychopy/hardware/serialport.py +51 -0
- psychopy/hardware/speaker.py +4 -4
- psychopy/iohub/datastore/__init__.py.orig +443 -0
- psychopy/iohub/datastore/util.py.orig +692 -0
- psychopy/iohub/devices/mouse/darwin.py.orig +427 -0
- psychopy/iohub/devices/mouse/linux2.py.orig +198 -0
- psychopy/preferences/.DS_Store +0 -0
- psychopy/projects/pavlovia.py +10 -3
- psychopy/projects/pavlovia.py.orig +1295 -0
- psychopy/sound/backend_ptb.py +22 -5
- psychopy/sound/transcribe.py +24 -4
- psychopy/tests/.DS_Store +0 -0
- psychopy/tests/data/.DS_Store +0 -0
- psychopy/tests/data/TestCircle_fill_local.png +0 -0
- psychopy/tests/data/__test.png +0 -0
- psychopy/tests/data/aperture1_normHexbackground_local.png +0 -0
- psychopy/tests/data/aperture1_norm_local.png +0 -0
- psychopy/tests/data/aperture2_normHexbackground_local.png +0 -0
- psychopy/tests/data/beatandrcos_height_local.png +0 -0
- psychopy/tests/data/beatandrcos_normAddBlend_local.png +0 -0
- psychopy/tests/data/beatandrcos_normHexbackground_local.png +0 -0
- psychopy/tests/data/beatandrcos_norm_local.png +0 -0
- psychopy/tests/data/beatandrcos_stencil_local.png +0 -0
- psychopy/tests/data/blend_add_height_local.png +0 -0
- psychopy/tests/data/blend_add_normAddBlend_local.png +0 -0
- psychopy/tests/data/blend_add_normHexbackground_local.png +0 -0
- psychopy/tests/data/blend_add_normNoShade_local.png +0 -0
- psychopy/tests/data/blend_add_norm_local.png +0 -0
- psychopy/tests/data/blend_add_stencil_local.png +0 -0
- psychopy/tests/data/bufferimg_gabor_height_local.png +0 -0
- psychopy/tests/data/bufferimg_gabor_normAddBlend_local.png +0 -0
- psychopy/tests/data/bufferimg_gabor_normHexbackground_local.png +0 -0
- psychopy/tests/data/bufferimg_gabor_normNoShade_local.png +0 -0
- psychopy/tests/data/bufferimg_gabor_norm_local.png +0 -0
- psychopy/tests/data/bufferimg_gabor_stencil_local.png +0 -0
- psychopy/tests/data/circleHex_height_local.png +0 -0
- psychopy/tests/data/circleHex_normAddBlend_local.png +0 -0
- psychopy/tests/data/circleHex_normHexbackground_local.png +0 -0
- psychopy/tests/data/circleHex_normNoShade_local.png +0 -0
- psychopy/tests/data/circleHex_norm_local.png +0 -0
- psychopy/tests/data/circleHex_stencil_local.png +0 -0
- psychopy/tests/data/color_comparison_local.png +0 -0
- psychopy/tests/data/corrFullRandom_local.csv +16 -0
- psychopy/tests/data/corrFullRandom_local.tsv +6 -0
- psychopy/tests/data/correctScript/.DS_Store +0 -0
- psychopy/tests/data/dots_height_local.png +0 -0
- psychopy/tests/data/dots_normAddBlend_local.png +0 -0
- psychopy/tests/data/dots_normHexbackground_local.png +0 -0
- psychopy/tests/data/dots_normNoShade_local.png +0 -0
- psychopy/tests/data/dots_norm_local.png +0 -0
- psychopy/tests/data/dots_stencil_local.png +0 -0
- psychopy/tests/data/elarray1_height_local.png +0 -0
- psychopy/tests/data/elarray1_normAddBlend_local.png +0 -0
- psychopy/tests/data/elarray1_normHexbackground_local.png +0 -0
- psychopy/tests/data/elarray1_norm_local.png +0 -0
- psychopy/tests/data/elarray1_stencil_local.png +0 -0
- psychopy/tests/data/envelopeandrcos_height_local.png +0 -0
- psychopy/tests/data/envelopeandrcos_normAddBlend_local.png +0 -0
- psychopy/tests/data/envelopeandrcos_normHexbackground_local.png +0 -0
- psychopy/tests/data/envelopeandrcos_norm_local.png +0 -0
- psychopy/tests/data/envelopeandrcos_stencil_local.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_height_local.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_normAddBlend_local.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_normHexbackground_local.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_norm_local.png +0 -0
- psychopy/tests/data/envelopepowerandrcos_stencil_local.png +0 -0
- psychopy/tests/data/gabor1_height_local.png +0 -0
- psychopy/tests/data/gabor1_normAddBlend_local.png +0 -0
- psychopy/tests/data/gabor1_normHexbackground_local.png +0 -0
- psychopy/tests/data/gabor1_normNoShade_local.png +0 -0
- psychopy/tests/data/gabor1_norm_local.png +0 -0
- psychopy/tests/data/gabor1_stencil_local.png +0 -0
- psychopy/tests/data/greyscale_normHexbackground_local.png +0 -0
- psychopy/tests/data/imageAndGauss_height_local.png +0 -0
- psychopy/tests/data/imageAndGauss_normAddBlend_local.png +0 -0
- psychopy/tests/data/imageAndGauss_normHexbackground_local.png +0 -0
- psychopy/tests/data/imageAndGauss_normNoShade_local.png +0 -0
- psychopy/tests/data/imageAndGauss_norm_local.png +0 -0
- psychopy/tests/data/imageAndGauss_stencil_local.png +0 -0
- psychopy/tests/data/movFrame1_stencil_local.png +0 -0
- psychopy/tests/data/noiseAndRcos_height_local.png +0 -0
- psychopy/tests/data/noiseAndRcos_normAddBlend_local.png +0 -0
- psychopy/tests/data/noiseAndRcos_normHexbackground_local.png +0 -0
- psychopy/tests/data/noiseAndRcos_normNoShade_local.png +0 -0
- psychopy/tests/data/noiseAndRcos_norm_local.png +0 -0
- psychopy/tests/data/noiseAndRcos_stencil_local.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_height_local.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_normAddBlend_local.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_normHexbackground_local.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_normNoShade_local.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_norm_local.png +0 -0
- psychopy/tests/data/noiseFiltersAndRcos_stencil_local.png +0 -0
- psychopy/tests/data/numpyImage_height_local.png +0 -0
- psychopy/tests/data/numpyImage_normAddBlend_local.png +0 -0
- psychopy/tests/data/numpyImage_normHexbackground_local.png +0 -0
- psychopy/tests/data/numpyImage_normNoShade_local.png +0 -0
- psychopy/tests/data/numpyImage_norm_local.png +0 -0
- psychopy/tests/data/numpyImage_stencil_local.png +0 -0
- psychopy/tests/data/shape2_1_normAddBlend_local.png +0 -0
- psychopy/tests/data/shape2_1_normHexbackground_local.png +0 -0
- psychopy/tests/data/shape2_1_normNoShade_local.png +0 -0
- psychopy/tests/data/shape2_1_norm_local.png +0 -0
- psychopy/tests/data/shape2_1_stencil_local.png +0 -0
- psychopy/tests/data/testLoopsBlocks.psyexp_local.py +328 -0
- psychopy/tests/data/text1_height_local.png +0 -0
- psychopy/tests/data/text1_normAddBlend_local.png +0 -0
- psychopy/tests/data/text1_normHexbackground_local.png +0 -0
- psychopy/tests/data/text1_norm_local.png +0 -0
- psychopy/tests/data/text1_stencil_local.png +0 -0
- psychopy/tests/data/text2_height.png +0 -0
- psychopy/tests/data/text2_normAddBlend.png +0 -0
- psychopy/tests/data/text2_normHexbackground.png +0 -0
- psychopy/tests/data/text2_stencil.png +0 -0
- psychopy/tests/data/wedge1_height_local.png +0 -0
- psychopy/tests/data/wedge1_normAddBlend_local.png +0 -0
- psychopy/tests/data/wedge1_normHexbackground_local.png +0 -0
- psychopy/tests/data/wedge1_normNoShade_local.png +0 -0
- psychopy/tests/data/wedge1_norm_local.png +0 -0
- psychopy/tests/data/wedge1_stencil_local.png +0 -0
- psychopy/tests/test_app/.DS_Store +0 -0
- psychopy/tests/test_app/test_builder/.DS_Store +0 -0
- psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1206.csv +9 -0
- psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1206.log +177 -0
- psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1206.psydat +0 -0
- psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1206.xlsx +0 -0
- psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1324.csv +9 -0
- psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1324.log +168 -0
- psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1324.psydat +0 -0
- psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1324.xlsx +0 -0
- psychopy/tests/test_data/.DS_Store +0 -0
- psychopy/tests/test_hardware/test_CRS_BitsSharp.py.orig +68 -0
- psychopy/tests/test_tools/test_arraytools.py +112 -0
- psychopy/tests/test_visual/test_image.py.orig +219 -0
- psychopy/tools/arraytools.py +47 -0
- psychopy/tools/versionchooser.py +1 -1
- psychopy/visual/backends/pygletbackend.py +26 -8
- psychopy/visual/basevisual.py.orig +1723 -0
- psychopy/visual/form.py.orig +1181 -0
- psychopy/visual/text.py.orig +752 -0
- psychopy/visual/textbox2/textbox2.py.orig +1315 -0
- psychopy/visual/window.py +13 -5
- psychopy/visual/windowwarp.py.orig +463 -0
- {psychopy-2024.2.1.dist-info → psychopy-2024.2.4.dist-info}/METADATA +9 -9
- {psychopy-2024.2.1.dist-info → psychopy-2024.2.4.dist-info}/RECORD +244 -78
- {psychopy-2024.2.1.dist-info → psychopy-2024.2.4.dist-info}/WHEEL +1 -1
- {psychopy-2024.2.1.dist-info → psychopy-2024.2.4.dist-info}/entry_points.txt +2 -0
- psychopy/app/locale/ar_001/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/cs_CZ/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/da_DK/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/de_DE/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/el_GR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/en_NZ/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/en_US/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/es_CO/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/es_ES/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/es_US/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/et_EE/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/fa_IR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/fi_FI/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/fr_FR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/he_IL/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/hi_IN/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/hu_HU/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/it_IT/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ja_JP/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ko_KR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ms_MY/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/nl_NL/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/nn_NO/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/pl_PL/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/pt_PT/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ro_RO/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/ru_RU/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/sv_SE/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/tr_TR/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/zh_CN/LC_MESSAGE/messages.mo +0 -0
- psychopy/app/locale/zh_TW/LC_MESSAGE/messages.mo +0 -0
- psychopy-2024.2.1.dist-info/licenses/AUTHORS.md +0 -138
- /psychopy/{app/locale/ar_001/LC_MESSAGE → demos/builder}/.DS_Store +0 -0
- /psychopy/{app/locale/es_ES/LC_MESSAGE → demos/builder/Experiments}/.DS_Store +0 -0
- /psychopy/{visual → demos/builder/Tools/gammaCalibration/data}/.DS_Store +0 -0
- {psychopy-2024.2.1.dist-info → psychopy-2024.2.4.dist-info}/licenses/LICENSE +0 -0
psychopy/visual/window.py
CHANGED
|
@@ -497,7 +497,7 @@ class Window():
|
|
|
497
497
|
|
|
498
498
|
# parameters for transforming the overall view
|
|
499
499
|
self.viewScale = val2array(viewScale)
|
|
500
|
-
if
|
|
500
|
+
if viewPos is not None and self.units is None:
|
|
501
501
|
raise ValueError('You must define the window units to use viewPos')
|
|
502
502
|
self.viewPos = val2array(viewPos, withScalar=False)
|
|
503
503
|
self.viewOri = float(viewOri)
|
|
@@ -750,13 +750,17 @@ class Window():
|
|
|
750
750
|
def setViewPos(self, value, log=True):
|
|
751
751
|
setAttribute(self, 'viewPos', value, log=log)
|
|
752
752
|
|
|
753
|
-
@
|
|
753
|
+
@property
|
|
754
|
+
def fullscr(self):
|
|
755
|
+
"""Return whether the window is in fullscreen mode."""
|
|
756
|
+
return self._isFullScr
|
|
757
|
+
|
|
758
|
+
@fullscr.setter
|
|
754
759
|
def fullscr(self, value):
|
|
755
760
|
"""Set whether fullscreen mode is `True` or `False` (not all backends
|
|
756
761
|
can toggle an open window).
|
|
757
762
|
"""
|
|
758
763
|
self.backend.setFullScr(value)
|
|
759
|
-
self.__dict__['fullscr'] = value
|
|
760
764
|
self._isFullScr = value
|
|
761
765
|
|
|
762
766
|
@attributeSetter
|
|
@@ -3331,7 +3335,12 @@ class Window():
|
|
|
3331
3335
|
GL.glClear(GL.GL_DEPTH_BUFFER_BIT)
|
|
3332
3336
|
return True
|
|
3333
3337
|
|
|
3334
|
-
@
|
|
3338
|
+
@property
|
|
3339
|
+
def mouseVisible(self):
|
|
3340
|
+
"""Returns the visibility of the mouse cursor."""
|
|
3341
|
+
return self.backend.mouseVisible
|
|
3342
|
+
|
|
3343
|
+
@mouseVisible.setter
|
|
3335
3344
|
def mouseVisible(self, visibility):
|
|
3336
3345
|
"""Sets the visibility of the mouse cursor.
|
|
3337
3346
|
|
|
@@ -3345,7 +3354,6 @@ class Window():
|
|
|
3345
3354
|
|
|
3346
3355
|
"""
|
|
3347
3356
|
self.backend.setMouseVisibility(visibility)
|
|
3348
|
-
self.__dict__['mouseVisible'] = visibility
|
|
3349
3357
|
|
|
3350
3358
|
def setMouseVisible(self, visibility, log=None):
|
|
3351
3359
|
"""Usually you can use 'stim.attribute = value' syntax instead,
|
|
@@ -0,0 +1,463 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
|
|
4
|
+
"""
|
|
5
|
+
Copyright (C) 2014 Allen Institute for Brain Science
|
|
6
|
+
|
|
7
|
+
This program is free software: you can redistribute it and/or modify it
|
|
8
|
+
under the terms of the GNU General Public License Version 3
|
|
9
|
+
as published by the Free Software Foundation on 29 June 2007.
|
|
10
|
+
This program is distributed WITHOUT WARRANTY OF MERCHANTABILITY OR FITNESS
|
|
11
|
+
FOR A PARTICULAR PURPOSE OR ANY OTHER WARRANTY, EXPRESSED OR IMPLIED.
|
|
12
|
+
See the GNU General Public License Version 3 for more details.
|
|
13
|
+
You should have received a copy of the GNU General Public License along
|
|
14
|
+
with this program. If not, see http://www.gnu.org/licenses/
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
<<<<<<< HEAD
|
|
18
|
+
=======
|
|
19
|
+
from builtins import map
|
|
20
|
+
from builtins import range
|
|
21
|
+
from builtins import object
|
|
22
|
+
>>>>>>> d3a60c42c61fce88b73af6272cc4b58f92cd005a
|
|
23
|
+
import ctypes
|
|
24
|
+
import numpy as np
|
|
25
|
+
from psychopy import logging
|
|
26
|
+
import pyglet
|
|
27
|
+
GL = pyglet.gl
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class Warper:
|
|
31
|
+
"""Class to perform warps.
|
|
32
|
+
|
|
33
|
+
Supports spherical, cylindrical, warpfile, or None (disabled) warps
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
def __init__(self,
|
|
37
|
+
win,
|
|
38
|
+
warp=None,
|
|
39
|
+
warpfile=None,
|
|
40
|
+
warpGridsize=300,
|
|
41
|
+
eyepoint=(0.5, 0.5),
|
|
42
|
+
flipHorizontal=False,
|
|
43
|
+
flipVertical=False):
|
|
44
|
+
"""Warping is a final operation which can be optionally performed on
|
|
45
|
+
each frame just before transmission to the display. It is useful
|
|
46
|
+
for perspective correction when the eye to monitor distance is
|
|
47
|
+
small (say, under 50 cm), or when projecting to domes or other
|
|
48
|
+
non-planar surfaces.
|
|
49
|
+
|
|
50
|
+
These attributes define the projection and can be altered
|
|
51
|
+
dynamically using the changeProjection() method.
|
|
52
|
+
|
|
53
|
+
:Parameters:
|
|
54
|
+
win : Handle to the window.
|
|
55
|
+
|
|
56
|
+
warp : 'spherical', 'cylindrical, 'warpfile' or *None*
|
|
57
|
+
This table gives the main properties of each projection
|
|
58
|
+
|
|
59
|
+
+-----------+---------------+-----------+------------+--------------------+
|
|
60
|
+
| Warp | eyepoint | verticals | horizontals| perspective correct|
|
|
61
|
+
| | modifies warp | parallel | parallel | |
|
|
62
|
+
+===========+===============+===========+============+====================+
|
|
63
|
+
|spherical | y | n | n | y |
|
|
64
|
+
+-----------+---------------+-----------+------------+--------------------+
|
|
65
|
+
|cylindrical| y | y | n | n |
|
|
66
|
+
+-----------+---------------+-----------+------------+--------------------+
|
|
67
|
+
| warpfile | n | ? | ? | ? |
|
|
68
|
+
+-----------+---------------+-----------+------------+--------------------+
|
|
69
|
+
| None | n | y | y | n |
|
|
70
|
+
+-----------+---------------+-----------+------------+--------------------+
|
|
71
|
+
|
|
72
|
+
warpfile : *None* or filename containing Blender and Paul Bourke
|
|
73
|
+
compatible warp definition.
|
|
74
|
+
(see http://paulbourke.net/dome/warpingfisheye/)
|
|
75
|
+
warpGridsize : 300
|
|
76
|
+
Defines the resolution of the warp in both X and Y when
|
|
77
|
+
not using a warpfile. Typical values would be 64-300
|
|
78
|
+
trading off tolerance for jaggies for speed.
|
|
79
|
+
eyepoint : [0.5, 0.5] center of the screen
|
|
80
|
+
Position of the eye in X and Y as a fraction of the
|
|
81
|
+
normalized screen width and height.
|
|
82
|
+
[0,0] is the bottom left of the screen.
|
|
83
|
+
[1,1] is the top right of the screen.
|
|
84
|
+
flipHorizontal: True or *False*
|
|
85
|
+
Flip the entire output horizontally. Useful for back
|
|
86
|
+
projection scenarious.
|
|
87
|
+
flipVertical: True or *False*
|
|
88
|
+
Flip the entire output vertically. useful if projector is
|
|
89
|
+
flipped upside down.
|
|
90
|
+
|
|
91
|
+
:notes:
|
|
92
|
+
1) The eye distance from the screen is initialized from the
|
|
93
|
+
monitor definition.
|
|
94
|
+
2) The eye distance can be altered dynamically by changing
|
|
95
|
+
'warper.dist_cm' and then calling changeProjection().
|
|
96
|
+
|
|
97
|
+
Example usage to create a spherical projection::
|
|
98
|
+
|
|
99
|
+
from psychopy.visual.windowwarp import Warper
|
|
100
|
+
win = Window(monitor='testMonitor', screen=1,
|
|
101
|
+
fullscr=True, useFBO = True)
|
|
102
|
+
warper = Warper(win,
|
|
103
|
+
warp='spherical',
|
|
104
|
+
warpfile = "",
|
|
105
|
+
warpGridsize = 128,
|
|
106
|
+
eyepoint = [0.5, 0.5],
|
|
107
|
+
flipHorizontal = False,
|
|
108
|
+
flipVertical = False)
|
|
109
|
+
|
|
110
|
+
"""
|
|
111
|
+
super(Warper, self).__init__()
|
|
112
|
+
self.win = win
|
|
113
|
+
# monkey patch the warp method
|
|
114
|
+
win._renderFBO = self.drawWarp
|
|
115
|
+
self.warp = warp
|
|
116
|
+
self.warpfile = warpfile
|
|
117
|
+
self.warpGridsize = warpGridsize
|
|
118
|
+
self.eyepoint = eyepoint
|
|
119
|
+
self.flipHorizontal = flipHorizontal
|
|
120
|
+
self.flipVertical = flipVertical
|
|
121
|
+
self.initDefaultWarpSize()
|
|
122
|
+
|
|
123
|
+
# get the eye distance from the monitor object,
|
|
124
|
+
# but the pixel dimensions from the actual window object
|
|
125
|
+
w, h = win.size
|
|
126
|
+
self.aspect = w/h
|
|
127
|
+
self.dist_cm = win.monitor.getDistance()
|
|
128
|
+
if self.dist_cm is None:
|
|
129
|
+
# create a fake monitor if one isn't defined
|
|
130
|
+
self.dist_cm = 30.0
|
|
131
|
+
self.mon_width_cm = 50.0
|
|
132
|
+
logging.warning('Monitor is not calibrated')
|
|
133
|
+
else:
|
|
134
|
+
self.mon_width_cm = win.monitor.getWidth()
|
|
135
|
+
self.mon_height_cm = self.mon_width_cm / self.aspect
|
|
136
|
+
self.mon_width_pix = w
|
|
137
|
+
self.mon_height_pix = h
|
|
138
|
+
self.changeProjection(self.warp, self.warpfile, self.eyepoint)
|
|
139
|
+
|
|
140
|
+
def drawWarp(self):
|
|
141
|
+
"""Warp the output, using the vertex, texture, and optionally an
|
|
142
|
+
opacity array.
|
|
143
|
+
"""
|
|
144
|
+
GL.glUseProgram(0)
|
|
145
|
+
GL.glColorMask(True, True, True, True)
|
|
146
|
+
|
|
147
|
+
# point to color (opacity)
|
|
148
|
+
if self.gl_color is not None:
|
|
149
|
+
GL.glEnableClientState(GL.GL_COLOR_ARRAY)
|
|
150
|
+
GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.gl_color)
|
|
151
|
+
GL.glColorPointer(4, GL.GL_FLOAT, 0, None)
|
|
152
|
+
GL.glEnable(GL.GL_BLEND)
|
|
153
|
+
GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ZERO)
|
|
154
|
+
|
|
155
|
+
# point to vertex data
|
|
156
|
+
GL.glEnableClientState(GL.GL_VERTEX_ARRAY)
|
|
157
|
+
GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.gl_vb)
|
|
158
|
+
GL.glVertexPointer(2, GL.GL_FLOAT, 0, None)
|
|
159
|
+
|
|
160
|
+
# point to texture
|
|
161
|
+
GL.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY)
|
|
162
|
+
GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.gl_tb)
|
|
163
|
+
GL.glTexCoordPointer(2, GL.GL_FLOAT, 0, None)
|
|
164
|
+
|
|
165
|
+
# draw quads
|
|
166
|
+
GL.glDrawArrays(GL.GL_QUADS, 0, self.nverts)
|
|
167
|
+
|
|
168
|
+
# cleanup
|
|
169
|
+
GL.glBindBuffer(GL.GL_ARRAY_BUFFER, 0)
|
|
170
|
+
GL.glDisableClientState(GL.GL_VERTEX_ARRAY)
|
|
171
|
+
GL.glDisableClientState(GL.GL_TEXTURE_COORD_ARRAY)
|
|
172
|
+
|
|
173
|
+
if self.gl_color is not None:
|
|
174
|
+
GL.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA)
|
|
175
|
+
GL.glDisableClientState(GL.GL_COLOR_ARRAY)
|
|
176
|
+
|
|
177
|
+
def initDefaultWarpSize(self):
|
|
178
|
+
self.xgrid = self.warpGridsize
|
|
179
|
+
self.ygrid = self.warpGridsize
|
|
180
|
+
|
|
181
|
+
def changeProjection(self, warp, warpfile=None, eyepoint=(0.5, 0.5),
|
|
182
|
+
flipHorizontal=False, flipVertical=False):
|
|
183
|
+
"""Allows changing the warp method on the fly. Uses the same
|
|
184
|
+
parameter definitions as constructor.
|
|
185
|
+
"""
|
|
186
|
+
self.warp = warp
|
|
187
|
+
self.warpfile = warpfile
|
|
188
|
+
self.eyepoint = list(eyepoint)
|
|
189
|
+
self.flipHorizontal = flipHorizontal
|
|
190
|
+
self.flipVertical = flipVertical
|
|
191
|
+
|
|
192
|
+
# warpfile might have changed the size...
|
|
193
|
+
self.initDefaultWarpSize()
|
|
194
|
+
|
|
195
|
+
if self.warp is None:
|
|
196
|
+
self.projectionNone()
|
|
197
|
+
elif self.warp == 'spherical':
|
|
198
|
+
self.projectionSphericalOrCylindrical(False)
|
|
199
|
+
elif self.warp == 'cylindrical':
|
|
200
|
+
self.projectionSphericalOrCylindrical(True)
|
|
201
|
+
elif self.warp == 'warpfile':
|
|
202
|
+
self.projectionWarpfile()
|
|
203
|
+
else:
|
|
204
|
+
raise ValueError('Unknown warp specification: %s' % self.warp)
|
|
205
|
+
|
|
206
|
+
def projectionNone(self):
|
|
207
|
+
"""No warp, same projection as original PsychoPy
|
|
208
|
+
"""
|
|
209
|
+
# Vertex data
|
|
210
|
+
v0 = (-1.0, -1.0)
|
|
211
|
+
v1 = (-1.0, 1.0)
|
|
212
|
+
v2 = (1.0, 1.0)
|
|
213
|
+
v3 = (1.0, -1.0)
|
|
214
|
+
|
|
215
|
+
# Texture coordinates
|
|
216
|
+
t0 = (0.0, 0.0)
|
|
217
|
+
t1 = (0.0, 1.0)
|
|
218
|
+
t2 = (1.0, 1.0)
|
|
219
|
+
t3 = (1.0, 0.0)
|
|
220
|
+
|
|
221
|
+
vertices = np.array([v0, v1, v2, v3], 'float32')
|
|
222
|
+
tcoords = np.array([t0, t1, t2, t3], 'float32')
|
|
223
|
+
|
|
224
|
+
# draw four quads during rendering loop
|
|
225
|
+
self.nverts = 4
|
|
226
|
+
self.createVertexAndTextureBuffers(vertices, tcoords)
|
|
227
|
+
|
|
228
|
+
def projectionSphericalOrCylindrical(self, isCylindrical=False):
|
|
229
|
+
"""Correct perspective on flat screen using either a spherical or
|
|
230
|
+
cylindrical projection.
|
|
231
|
+
"""
|
|
232
|
+
self.nverts = (self.xgrid - 1) * (self.ygrid - 1) * 4
|
|
233
|
+
|
|
234
|
+
# eye position in cm
|
|
235
|
+
xEye = self.eyepoint[0] * self.mon_width_cm
|
|
236
|
+
yEye = self.eyepoint[1] * self.mon_height_cm
|
|
237
|
+
|
|
238
|
+
# create vertex grid array, and texture coords
|
|
239
|
+
# times 4 for quads
|
|
240
|
+
vertices = np.zeros(
|
|
241
|
+
((self.xgrid - 1) * (self.ygrid - 1) * 4, 2), dtype='float32')
|
|
242
|
+
tcoords = np.zeros(
|
|
243
|
+
((self.xgrid - 1) * (self.ygrid - 1) * 4, 2), dtype='float32')
|
|
244
|
+
|
|
245
|
+
equalDistanceX = np.linspace(0, self.mon_width_cm, self.xgrid)
|
|
246
|
+
equalDistanceY = np.linspace(0, self.mon_height_cm, self.ygrid)
|
|
247
|
+
|
|
248
|
+
# vertex coordinates
|
|
249
|
+
x_c = np.linspace(-1.0, 1.0, self.xgrid)
|
|
250
|
+
y_c = np.linspace(-1.0, 1.0, self.ygrid)
|
|
251
|
+
x_coords, y_coords = np.meshgrid(x_c, y_c)
|
|
252
|
+
|
|
253
|
+
x = np.zeros(((self.xgrid), (self.ygrid)), dtype='float32')
|
|
254
|
+
y = np.zeros(((self.xgrid), (self.ygrid)), dtype='float32')
|
|
255
|
+
|
|
256
|
+
x[:, :] = equalDistanceX - xEye
|
|
257
|
+
y[:, :] = equalDistanceY - yEye
|
|
258
|
+
y = np.transpose(y)
|
|
259
|
+
|
|
260
|
+
r = np.sqrt(np.square(x) + np.square(y) + np.square(self.dist_cm))
|
|
261
|
+
|
|
262
|
+
azimuth = np.arctan(x / self.dist_cm)
|
|
263
|
+
altitude = np.arcsin(y / r)
|
|
264
|
+
|
|
265
|
+
# calculate the texture coordinates
|
|
266
|
+
if isCylindrical:
|
|
267
|
+
tx = self.dist_cm * np.sin(azimuth)
|
|
268
|
+
ty = self.dist_cm * np.sin(altitude)
|
|
269
|
+
else:
|
|
270
|
+
tx = self.dist_cm * (1 + x/r) - self.dist_cm
|
|
271
|
+
ty = self.dist_cm * (1 + y/r) - self.dist_cm
|
|
272
|
+
|
|
273
|
+
# prevent div0
|
|
274
|
+
azimuth[azimuth == 0] = np.finfo(np.float32).eps
|
|
275
|
+
altitude[altitude == 0] = np.finfo(np.float32).eps
|
|
276
|
+
|
|
277
|
+
# the texture coordinates (which are now lying on the sphere)
|
|
278
|
+
# need to be remapped back onto the plane of the display.
|
|
279
|
+
# This effectively stretches the coordinates away from the eyepoint.
|
|
280
|
+
|
|
281
|
+
if isCylindrical:
|
|
282
|
+
tx = tx * azimuth / np.sin(azimuth)
|
|
283
|
+
ty = ty * altitude / np.sin(altitude)
|
|
284
|
+
else:
|
|
285
|
+
centralAngle = np.arccos(
|
|
286
|
+
np.cos(altitude) * np.cos(np.abs(azimuth)))
|
|
287
|
+
# distance from eyepoint to texture vertex
|
|
288
|
+
arcLength = centralAngle * self.dist_cm
|
|
289
|
+
# remap the texture coordinate
|
|
290
|
+
theta = np.arctan2(ty, tx)
|
|
291
|
+
tx = arcLength * np.cos(theta)
|
|
292
|
+
ty = arcLength * np.sin(theta)
|
|
293
|
+
|
|
294
|
+
u_coords = tx / self.mon_width_cm + 0.5
|
|
295
|
+
v_coords = ty / self.mon_height_cm + 0.5
|
|
296
|
+
|
|
297
|
+
# loop to create quads
|
|
298
|
+
vdex = 0
|
|
299
|
+
for y in range(0, self.ygrid - 1):
|
|
300
|
+
for x in range(0, self.xgrid - 1):
|
|
301
|
+
index = y * (self.xgrid) + x
|
|
302
|
+
|
|
303
|
+
vertices[vdex + 0, 0] = x_coords[y, x]
|
|
304
|
+
vertices[vdex + 0, 1] = y_coords[y, x]
|
|
305
|
+
vertices[vdex + 1, 0] = x_coords[y, x + 1]
|
|
306
|
+
vertices[vdex + 1, 1] = y_coords[y, x + 1]
|
|
307
|
+
vertices[vdex + 2, 0] = x_coords[y + 1, x + 1]
|
|
308
|
+
vertices[vdex + 2, 1] = y_coords[y + 1, x + 1]
|
|
309
|
+
vertices[vdex + 3, 0] = x_coords[y + 1, x]
|
|
310
|
+
vertices[vdex + 3, 1] = y_coords[y + 1, x]
|
|
311
|
+
|
|
312
|
+
tcoords[vdex + 0, 0] = u_coords[y, x]
|
|
313
|
+
tcoords[vdex + 0, 1] = v_coords[y, x]
|
|
314
|
+
tcoords[vdex + 1, 0] = u_coords[y, x + 1]
|
|
315
|
+
tcoords[vdex + 1, 1] = v_coords[y, x + 1]
|
|
316
|
+
tcoords[vdex + 2, 0] = u_coords[y + 1, x + 1]
|
|
317
|
+
tcoords[vdex + 2, 1] = v_coords[y + 1, x + 1]
|
|
318
|
+
tcoords[vdex + 3, 0] = u_coords[y + 1, x]
|
|
319
|
+
tcoords[vdex + 3, 1] = v_coords[y + 1, x]
|
|
320
|
+
|
|
321
|
+
vdex += 4
|
|
322
|
+
self.createVertexAndTextureBuffers(vertices, tcoords)
|
|
323
|
+
|
|
324
|
+
def projectionWarpfile(self):
|
|
325
|
+
"""Use a warp definition file to create the projection.
|
|
326
|
+
See: http://paulbourke.net/dome/warpingfisheye/
|
|
327
|
+
"""
|
|
328
|
+
try:
|
|
329
|
+
fh = open(self.warpfile)
|
|
330
|
+
lines = fh.readlines()
|
|
331
|
+
fh.close()
|
|
332
|
+
filetype = int(lines[0])
|
|
333
|
+
rc = list(map(int, lines[1].split()))
|
|
334
|
+
cols, rows = rc[0], rc[1]
|
|
335
|
+
warpdata = np.loadtxt(self.warpfile, skiprows=2)
|
|
336
|
+
except Exception:
|
|
337
|
+
error = 'Unable to read warpfile: ' + self.warpfile
|
|
338
|
+
logging.warning(error)
|
|
339
|
+
print(error)
|
|
340
|
+
return
|
|
341
|
+
|
|
342
|
+
if (cols * rows != warpdata.shape[0] or
|
|
343
|
+
warpdata.shape[1] != 5 or
|
|
344
|
+
filetype != 2):
|
|
345
|
+
error = 'warpfile data incorrect: ' + self.warpfile
|
|
346
|
+
logging.warning(error)
|
|
347
|
+
print(error)
|
|
348
|
+
return
|
|
349
|
+
|
|
350
|
+
self.xgrid = cols
|
|
351
|
+
self.ygrid = rows
|
|
352
|
+
|
|
353
|
+
self.nverts = (self.xgrid - 1) * (self.ygrid - 1) * 4
|
|
354
|
+
|
|
355
|
+
# create vertex grid array, and texture coords times 4 for quads
|
|
356
|
+
vertices = np.zeros(
|
|
357
|
+
((self.xgrid - 1) * (self.ygrid - 1) * 4, 2), dtype='float32')
|
|
358
|
+
tcoords = np.zeros(
|
|
359
|
+
((self.xgrid - 1) * (self.ygrid - 1) * 4, 2), dtype='float32')
|
|
360
|
+
# opacity is RGBA
|
|
361
|
+
opacity = np.ones(
|
|
362
|
+
((self.xgrid - 1) * (self.ygrid - 1) * 4, 4), dtype='float32')
|
|
363
|
+
|
|
364
|
+
# loop to create quads
|
|
365
|
+
vdex = 0
|
|
366
|
+
for y in range(0, self.ygrid - 1):
|
|
367
|
+
for x in range(0, self.xgrid - 1):
|
|
368
|
+
index = y * (self.xgrid) + x
|
|
369
|
+
|
|
370
|
+
vertices[vdex + 0, 0] = warpdata[index, 0] # x_coords[y,x]
|
|
371
|
+
vertices[vdex + 0, 1] = warpdata[index, 1] # y_coords[y,x]
|
|
372
|
+
# x_coords[y,x+1]
|
|
373
|
+
vertices[vdex + 1, 0] = warpdata[index + 1, 0]
|
|
374
|
+
# y_coords[y,x+1]
|
|
375
|
+
vertices[vdex + 1, 1] = warpdata[index + 1, 1]
|
|
376
|
+
# x_coords[y+1,x+1]
|
|
377
|
+
vertices[vdex + 2, 0] = warpdata[index + cols + 1, 0]
|
|
378
|
+
# y_coords[y+1,x+1]
|
|
379
|
+
vertices[vdex + 2, 1] = warpdata[index + cols + 1, 1]
|
|
380
|
+
# x_coords[y+1,x]
|
|
381
|
+
vertices[vdex + 3, 0] = warpdata[index + cols, 0]
|
|
382
|
+
# y_coords[y+1,x]
|
|
383
|
+
vertices[vdex + 3, 1] = warpdata[index + cols, 1]
|
|
384
|
+
|
|
385
|
+
# u_coords[y,x]
|
|
386
|
+
tcoords[vdex + 0, 0] = warpdata[index, 2]
|
|
387
|
+
# v_coords[y,x]
|
|
388
|
+
tcoords[vdex + 0, 1] = warpdata[index, 3]
|
|
389
|
+
# u_coords[y,x+1]:
|
|
390
|
+
tcoords[vdex + 1, 0] = warpdata[index + 1, 2]
|
|
391
|
+
# v_coords[y,x+1]:
|
|
392
|
+
tcoords[vdex + 1, 1] = warpdata[index + 1, 3]
|
|
393
|
+
# u_coords[y+1,x+1]:
|
|
394
|
+
tcoords[vdex + 2, 0] = warpdata[index + cols + 1, 2]
|
|
395
|
+
# v_coords[y+1,x+1]:
|
|
396
|
+
tcoords[vdex + 2, 1] = warpdata[index + cols + 1, 3]
|
|
397
|
+
# u_coords[y+1,x]
|
|
398
|
+
tcoords[vdex + 3, 0] = warpdata[index + cols, 2]
|
|
399
|
+
# v_coords[y+1,x]:
|
|
400
|
+
tcoords[vdex + 3, 1] = warpdata[index + cols, 3]
|
|
401
|
+
|
|
402
|
+
opacity[vdex, 3] = warpdata[index, 4]
|
|
403
|
+
opacity[vdex + 1, 3] = warpdata[index + 1, 4]
|
|
404
|
+
opacity[vdex + 2, 3] = warpdata[index + cols + 1, 4]
|
|
405
|
+
opacity[vdex + 3, 3] = warpdata[index + cols, 4]
|
|
406
|
+
|
|
407
|
+
vdex += 4
|
|
408
|
+
self.createVertexAndTextureBuffers(vertices, tcoords, opacity)
|
|
409
|
+
|
|
410
|
+
def createVertexAndTextureBuffers(self, vertices, tcoords, opacity=None):
|
|
411
|
+
"""Allocate hardware buffers for vertices, texture coordinates,
|
|
412
|
+
and optionally opacity.
|
|
413
|
+
"""
|
|
414
|
+
if self.flipHorizontal:
|
|
415
|
+
vertices[:, 0] = -vertices[:, 0]
|
|
416
|
+
if self.flipVertical:
|
|
417
|
+
vertices[:, 1] = -vertices[:, 1]
|
|
418
|
+
|
|
419
|
+
GL.glEnableClientState(GL.GL_VERTEX_ARRAY)
|
|
420
|
+
|
|
421
|
+
# type and size for arrays
|
|
422
|
+
arrType = ctypes.c_float
|
|
423
|
+
ptrType = ctypes.POINTER(arrType)
|
|
424
|
+
nbytes = ctypes.sizeof(arrType)
|
|
425
|
+
|
|
426
|
+
# vertex buffer in hardware
|
|
427
|
+
self.gl_vb = GL.GLuint()
|
|
428
|
+
GL.glGenBuffers(1, self.gl_vb)
|
|
429
|
+
GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.gl_vb)
|
|
430
|
+
GL.glBufferData(
|
|
431
|
+
GL.GL_ARRAY_BUFFER,
|
|
432
|
+
vertices.size * nbytes,
|
|
433
|
+
vertices.ctypes.data_as(ptrType),
|
|
434
|
+
GL.GL_STATIC_DRAW)
|
|
435
|
+
|
|
436
|
+
# vertex buffer texture data in hardware
|
|
437
|
+
self.gl_tb = GL.GLuint()
|
|
438
|
+
GL.glGenBuffers(1, self.gl_tb)
|
|
439
|
+
GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.gl_tb)
|
|
440
|
+
GL.glBufferData(
|
|
441
|
+
GL.GL_ARRAY_BUFFER,
|
|
442
|
+
tcoords.size * nbytes,
|
|
443
|
+
tcoords.ctypes.data_as(ptrType),
|
|
444
|
+
GL.GL_STATIC_DRAW)
|
|
445
|
+
|
|
446
|
+
# opacity buffer in hardware (only for warp files)
|
|
447
|
+
if opacity is not None:
|
|
448
|
+
self.gl_color = GL.GLuint()
|
|
449
|
+
GL.glGenBuffers(1, self.gl_color)
|
|
450
|
+
GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.gl_color)
|
|
451
|
+
|
|
452
|
+
# convert opacity to RGBA, one point for each corner of the quad
|
|
453
|
+
GL.glBufferData(
|
|
454
|
+
GL.GL_ARRAY_BUFFER,
|
|
455
|
+
opacity.size * nbytes,
|
|
456
|
+
opacity.ctypes.data_as(ptrType),
|
|
457
|
+
GL.GL_STATIC_DRAW)
|
|
458
|
+
|
|
459
|
+
else:
|
|
460
|
+
self.gl_color = None
|
|
461
|
+
|
|
462
|
+
GL.glBindBuffer(GL.GL_ARRAY_BUFFER, 0)
|
|
463
|
+
GL.glDisableClientState(GL.GL_VERTEX_ARRAY)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: psychopy
|
|
3
|
-
Version: 2024.2.
|
|
3
|
+
Version: 2024.2.4
|
|
4
4
|
Summary: PsychoPy provides easy, precise, flexible experiments in behavioural sciences
|
|
5
5
|
Author-Email: Open Science Tools Ltd <support@opensciencetools.org>
|
|
6
6
|
Maintainer-Email: Open Science Tools Ltd <support@opensciencetools.org>
|
|
@@ -50,7 +50,7 @@ Requires-Dist: markdown-it-py
|
|
|
50
50
|
Requires-Dist: requests
|
|
51
51
|
Requires-Dist: future
|
|
52
52
|
Requires-Dist: pypi-search>=1.2.1
|
|
53
|
-
Requires-Dist: setuptools
|
|
53
|
+
Requires-Dist: setuptools==70.3.0
|
|
54
54
|
Requires-Dist: python-gitlab
|
|
55
55
|
Requires-Dist: gitpython
|
|
56
56
|
Requires-Dist: cryptography
|
|
@@ -72,33 +72,33 @@ Requires-Dist: zeroconf; platform_system == "Darwin"
|
|
|
72
72
|
Requires-Dist: python-xlib; platform_system == "Linux"
|
|
73
73
|
Requires-Dist: distro; platform_system == "Linux"
|
|
74
74
|
Requires-Dist: tables!=3.9.2
|
|
75
|
-
Requires-Dist: packaging>=24.
|
|
75
|
+
Requires-Dist: packaging>=24.0
|
|
76
|
+
Requires-Dist: moviepy
|
|
77
|
+
Provides-Extra: tests
|
|
76
78
|
Requires-Dist: pytest>=6.2.5; extra == "tests"
|
|
77
79
|
Requires-Dist: pytest-codecov; extra == "tests"
|
|
78
80
|
Requires-Dist: pytest-cov; extra == "tests"
|
|
79
81
|
Requires-Dist: pytest-asyncio; extra == "tests"
|
|
80
82
|
Requires-Dist: flake8; extra == "tests"
|
|
81
83
|
Requires-Dist: xmlschema; extra == "tests"
|
|
84
|
+
Provides-Extra: building
|
|
82
85
|
Requires-Dist: bdist-mpkg>=0.5.0; platform_system == "Darwin" and extra == "building"
|
|
83
86
|
Requires-Dist: py2app; platform_system == "Darwin" and extra == "building"
|
|
84
87
|
Requires-Dist: dmgbuild; platform_system == "Darwin" and extra == "building"
|
|
88
|
+
Provides-Extra: suggested
|
|
85
89
|
Requires-Dist: sounddevice; extra == "suggested"
|
|
86
90
|
Requires-Dist: pylsl>=1.16.1; extra == "suggested"
|
|
87
91
|
Requires-Dist: xlwt; extra == "suggested"
|
|
88
92
|
Requires-Dist: h5py; extra == "suggested"
|
|
89
93
|
Requires-Dist: tobii_research; extra == "suggested"
|
|
90
94
|
Requires-Dist: badapted>=0.0.3; extra == "suggested"
|
|
91
|
-
Requires-Dist: egi-pynetstation>=0.0
|
|
95
|
+
Requires-Dist: egi-pynetstation>=1.0.0; extra == "suggested"
|
|
92
96
|
Requires-Dist: pyxid2>=1.0.5; extra == "suggested"
|
|
93
97
|
Requires-Dist: Phidget22; extra == "suggested"
|
|
98
|
+
Provides-Extra: legacy
|
|
94
99
|
Requires-Dist: pyo>=1.0.3; extra == "legacy"
|
|
95
100
|
Requires-Dist: pyglfw; extra == "legacy"
|
|
96
|
-
Requires-Dist: moviepy; extra == "legacy"
|
|
97
101
|
Requires-Dist: pygame; extra == "legacy"
|
|
98
|
-
Provides-Extra: tests
|
|
99
|
-
Provides-Extra: building
|
|
100
|
-
Provides-Extra: suggested
|
|
101
|
-
Provides-Extra: legacy
|
|
102
102
|
Description-Content-Type: text/markdown
|
|
103
103
|
|
|
104
104
|
# PsychoPy
|