diff --git a/README.md b/README.md index 43feb9b19c..a9de69e51b 100644 --- a/README.md +++ b/README.md @@ -55,8 +55,8 @@ depending on whether you are on a 32-bit or 64-bit system, or you can [click here](https://github.com/rdb/panda3d-thirdparty) for instructions on building them from source. -http://rdb.name/thirdparty-vc14-x64.7z -http://rdb.name/thirdparty-vc14.7z +https://www.panda3d.org/download/panda3d-1.10.0/panda3d-1.10.0-tools-win64.zip +https://www.panda3d.org/download/panda3d-1.10.0/panda3d-1.10.0-tools-win32.zip After acquiring these dependencies, you may simply build Panda3D from the command prompt using the following command. (Change `14.1` to `14` if you are diff --git a/contrib/src/panda3dtoolsgui/pandaIcon.ico b/contrib/src/panda3dtoolsgui/pandaIcon.ico index cd6f45759f..3a2c1c33d4 100644 Binary files a/contrib/src/panda3dtoolsgui/pandaIcon.ico and b/contrib/src/panda3dtoolsgui/pandaIcon.ico differ diff --git a/direct/src/directbase/ThreeUpStart.py b/direct/src/directbase/ThreeUpStart.py index b0a78fcef9..87158c937a 100644 --- a/direct/src/directbase/ThreeUpStart.py +++ b/direct/src/directbase/ThreeUpStart.py @@ -1,7 +1,7 @@ print('ThreeUpStart: Starting up environment.') -from pandac.PandaModules import * +from panda3d.core import * from direct.showbase.PythonUtil import * from direct.showbase import ThreeUpShow diff --git a/direct/src/directscripts/Doxyfile.cxx b/direct/src/directscripts/Doxyfile.cxx index 7aec9a9d3d..6c81025960 100644 --- a/direct/src/directscripts/Doxyfile.cxx +++ b/direct/src/directscripts/Doxyfile.cxx @@ -1124,7 +1124,7 @@ HTML_EXTRA_FILES = # Minimum value: 0, maximum value: 359, default value: 220. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_COLORSTYLE_HUE = 228 +HTML_COLORSTYLE_HUE = 251 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors # in the HTML output. For a value of 0 the output will use grayscales only. A @@ -1132,7 +1132,7 @@ HTML_COLORSTYLE_HUE = 228 # Minimum value: 0, maximum value: 255, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_COLORSTYLE_SAT = 99 +HTML_COLORSTYLE_SAT = 150 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the # luminance component of the colors in the HTML output. Values below 100 @@ -1143,7 +1143,7 @@ HTML_COLORSTYLE_SAT = 99 # Minimum value: 40, maximum value: 240, default value: 80. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_COLORSTYLE_GAMMA = 56 +HTML_COLORSTYLE_GAMMA = 39 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting this diff --git a/direct/src/directscripts/Doxyfile.python b/direct/src/directscripts/Doxyfile.python index 5b2e73ff77..2119f7b321 100644 --- a/direct/src/directscripts/Doxyfile.python +++ b/direct/src/directscripts/Doxyfile.python @@ -864,13 +864,13 @@ HTML_STYLESHEET = $(DOXYGEN_HTML_STYLESHEET) # 180 is cyan, 240 is blue, 300 purple, and 360 is red again. # The allowed range is 0 to 359. -HTML_COLORSTYLE_HUE = 228 +HTML_COLORSTYLE_HUE = 251 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of # the colors in the HTML output. For a value of 0 the output will use # grayscales only. A value of 255 will produce the most vivid colors. -HTML_COLORSTYLE_SAT = 99 +HTML_COLORSTYLE_SAT = 150 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to # the luminance component of the colors in the HTML output. Values below @@ -879,7 +879,7 @@ HTML_COLORSTYLE_SAT = 99 # so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, # and 100 does not change the gamma. -HTML_COLORSTYLE_GAMMA = 56 +HTML_COLORSTYLE_GAMMA = 39 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting diff --git a/direct/src/dist/commands.py b/direct/src/dist/commands.py index a134aad64f..abf0e9f777 100644 --- a/direct/src/dist/commands.py +++ b/direct/src/dist/commands.py @@ -540,6 +540,7 @@ class build_apps(setuptools.Command): 'pandaegg', 'p3ffmpeg', 'p3ptloader', + 'p3assimp', ] def parse_prc(prcstr, warn_on_missing_plugin): out = [] @@ -1345,7 +1346,7 @@ class bdist_apps(setuptools.Command): self.run_command('build_apps') platforms = build_cmd.platforms - build_base = build_cmd.build_base + build_base = os.path.abspath(build_cmd.build_base) os.makedirs(self.dist_dir, exist_ok=True) os.chdir(self.dist_dir) diff --git a/direct/src/plugin_standalone/panda3d.ico b/direct/src/plugin_standalone/panda3d.ico index 381a41388b..3a2c1c33d4 100644 Binary files a/direct/src/plugin_standalone/panda3d.ico and b/direct/src/plugin_standalone/panda3d.ico differ diff --git a/direct/src/showbase/Audio3DManager.py b/direct/src/showbase/Audio3DManager.py index 4a67c9bc27..e0f38c1d2a 100644 --- a/direct/src/showbase/Audio3DManager.py +++ b/direct/src/showbase/Audio3DManager.py @@ -2,7 +2,7 @@ __all__ = ['Audio3DManager'] -from panda3d.core import Vec3, VBase3, WeakNodePath +from panda3d.core import Vec3, VBase3, WeakNodePath, ClockObject from direct.task.TaskManagerGlobal import Task, taskMgr # class Audio3DManager: @@ -122,9 +122,11 @@ class Audio3DManager: This is relative to the sound root (probably render). Default: VBase3(0, 0, 0) """ + if isinstance(velocity, tuple) and len(velocity) == 3: + velocity = VBase3(*velocity) if not isinstance(velocity, VBase3): raise TypeError("Invalid argument 1, expected ") - self.vel_dict[sound]=velocity + self.vel_dict[sound] = velocity def setSoundVelocityAuto(self, sound): """ @@ -139,14 +141,22 @@ class Audio3DManager: """ Get the velocity of the sound. """ - if (sound in self.vel_dict): + if sound in self.vel_dict: vel = self.vel_dict[sound] - if (vel!=None): + if vel is not None: return vel - else: - for known_object in list(self.sound_dict.keys()): - if self.sound_dict[known_object].count(sound): - return known_object.getPosDelta(self.root)/globalClock.getDt() + + for known_object in list(self.sound_dict.keys()): + if self.sound_dict[known_object].count(sound): + node_path = known_object.getNodePath() + if not node_path: + # The node has been deleted. + del self.sound_dict[known_object] + continue + + clock = ClockObject.getGlobalClock() + return node_path.getPosDelta(self.root) / clock.getDt() + return VBase3(0, 0, 0) def setListenerVelocity(self, velocity): @@ -155,9 +165,11 @@ class Audio3DManager: This is relative to the sound root (probably render). Default: VBase3(0, 0, 0) """ + if isinstance(velocity, tuple) and len(velocity) == 3: + velocity = VBase3(*velocity) if not isinstance(velocity, VBase3): raise TypeError("Invalid argument 0, expected ") - self.listener_vel=velocity + self.listener_vel = velocity def setListenerVelocityAuto(self): """ @@ -172,10 +184,11 @@ class Audio3DManager: """ Get the velocity of the listener. """ - if (self.listener_vel!=None): + if self.listener_vel is not None: return self.listener_vel - elif (self.listener_target!=None): - return self.listener_target.getPosDelta(self.root)/globalClock.getDt() + elif self.listener_target is not None: + clock = ClockObject.getGlobalClock() + return self.listener_target.getPosDelta(self.root) / clock.getDt() else: return VBase3(0, 0, 0) diff --git a/doc/ReleaseNotes b/doc/ReleaseNotes index 062f129ebd..07139af55b 100644 --- a/doc/ReleaseNotes +++ b/doc/ReleaseNotes @@ -1,3 +1,8 @@ +------------------------ RELEASE 1.10.1 ----------------------- + +* Fix regression with Audio3DManager.setSoundVelocityAuto() +* Audio3DManager accepts tuple in setSoundVelocity/setListenerVelocity + ------------------------ RELEASE 1.10.0 ----------------------- This is a major release with significant changes. Please review the diff --git a/dtool/PandaVersion.pp b/dtool/PandaVersion.pp index ba362a70ac..f504aab0cd 100644 --- a/dtool/PandaVersion.pp +++ b/dtool/PandaVersion.pp @@ -7,7 +7,7 @@ // place to put this. // Use spaces to separate the major, minor, and sequence numbers here. -#define PANDA_VERSION 1 10 0 +#define PANDA_VERSION 1 10 1 // This variable will be defined to false in the CVS repository, but // scripts that generate source tarballs and/or binary releases for diff --git a/dtool/src/interrogate/interfaceMakerPythonNative.cxx b/dtool/src/interrogate/interfaceMakerPythonNative.cxx index 3964cad919..ca2ed7eb8d 100644 --- a/dtool/src/interrogate/interfaceMakerPythonNative.cxx +++ b/dtool/src/interrogate/interfaceMakerPythonNative.cxx @@ -1532,13 +1532,7 @@ write_module(ostream &out, ostream *out_h, InterrogateModuleDef *def) { << " nullptr, nullptr, nullptr, nullptr\n" << "};\n" << "\n" - << "#ifdef _WIN32\n" - << "extern \"C\" __declspec(dllexport) PyObject *PyInit_" << def->module_name << "();\n" - << "#elif __GNUC__ >= 4\n" - << "extern \"C\" __attribute__((visibility(\"default\"))) PyObject *PyInit_" << def->module_name << "();\n" - << "#else\n" - << "extern \"C\" PyObject *PyInit_" << def->module_name << "();\n" - << "#endif\n" + << "extern \"C\" EXPORT_CLASS PyObject *PyInit_" << def->module_name << "();\n" << "\n" << "PyObject *PyInit_" << def->module_name << "() {\n" << " LibraryDef *refs[] = {&" << def->library_name << "_moddef, nullptr};\n" @@ -1549,13 +1543,7 @@ write_module(ostream &out, ostream *out_h, InterrogateModuleDef *def) { << "\n" << "#else // Python 2 case\n" << "\n" - << "#ifdef _WIN32\n" - << "extern \"C\" __declspec(dllexport) void init" << def->module_name << "();\n" - << "#elif __GNUC__ >= 4\n" - << "extern \"C\" __attribute__((visibility(\"default\"))) void init" << def->module_name << "();\n" - << "#else\n" - << "extern \"C\" void init" << def->module_name << "();\n" - << "#endif\n" + << "extern \"C\" EXPORT_CLASS void init" << def->module_name << "();\n" << "\n" << "void init" << def->module_name << "() {\n" << " LibraryDef *refs[] = {&" << def->library_name << "_moddef, nullptr};\n" diff --git a/dtool/src/interrogate/interrogate_module.cxx b/dtool/src/interrogate/interrogate_module.cxx index 6f7bc4bfeb..663e57762f 100644 --- a/dtool/src/interrogate/interrogate_module.cxx +++ b/dtool/src/interrogate/interrogate_module.cxx @@ -295,24 +295,10 @@ int write_python_table_native(std::ostream &out) { out.put('\n'); - out << "#if PY_MAJOR_VERSION >= 3 || !defined(NDEBUG)\n" - << "#ifdef _WIN32\n" - << "extern \"C\" __declspec(dllexport) PyObject *PyInit_" << library_name << "();\n" - << "#elif __GNUC__ >= 4\n" - << "extern \"C\" __attribute__((visibility(\"default\"))) PyObject *PyInit_" << library_name << "();\n" + out << "#if PY_MAJOR_VERSION >= 3\n" + << "extern \"C\" EXPORT_CLASS PyObject *PyInit_" << library_name << "();\n" << "#else\n" - << "extern \"C\" PyObject *PyInit_" << library_name << "();\n" - << "#endif\n" - << "#endif\n"; - - out << "#if PY_MAJOR_VERSION < 3 || !defined(NDEBUG)\n" - << "#ifdef _WIN32\n" - << "extern \"C\" __declspec(dllexport) void init" << library_name << "();\n" - << "#elif __GNUC__ >= 4\n" - << "extern \"C\" __attribute__((visibility(\"default\"))) void init" << library_name << "();\n" - << "#else\n" - << "extern \"C\" void init" << library_name << "();\n" - << "#endif\n" + << "extern \"C\" EXPORT_CLASS void init" << library_name << "();\n" << "#endif\n"; out << "\n" @@ -361,14 +347,6 @@ int write_python_table_native(std::ostream &out) { << "}\n" << "\n" - << "#ifndef NDEBUG\n" - << "void init" << library_name << "() {\n" - << " PyErr_SetString(PyExc_ImportError, \"" << module_name << " was " - << "compiled for Python \" PY_VERSION \", which is incompatible " - << "with Python 2\");\n" - << "}\n" - << "#endif\n" - << "#else // Python 2 case\n" << "\n" << "void init" << library_name << "() {\n"; @@ -402,15 +380,6 @@ int write_python_table_native(std::ostream &out) { out << " }\n" << "}\n" - << "\n" - << "#ifndef NDEBUG\n" - << "PyObject *PyInit_" << library_name << "() {\n" - << " PyErr_SetString(PyExc_ImportError, \"" << module_name << " was " - << "compiled for Python \" PY_VERSION \", which is incompatible " - << "with Python 3\");\n" - << " return nullptr;\n" - << "}\n" - << "#endif\n" << "#endif\n" << "\n"; diff --git a/dtool/src/interrogatedb/py_panda.cxx b/dtool/src/interrogatedb/py_panda.cxx index 6ebfff5b4b..5d17d8851f 100644 --- a/dtool/src/interrogatedb/py_panda.cxx +++ b/dtool/src/interrogatedb/py_panda.cxx @@ -289,7 +289,7 @@ PyObject *_Dtool_Return(PyObject *value) { /** * This function converts an int value to the appropriate enum instance. */ -PyObject *Dtool_EnumType_New(PyTypeObject *subtype, PyObject *args, PyObject *kwds) { +static PyObject *Dtool_EnumType_New(PyTypeObject *subtype, PyObject *args, PyObject *kwds) { PyObject *arg; if (!Dtool_ExtractArg(&arg, args, kwds, "value")) { return PyErr_Format(PyExc_TypeError, diff --git a/makepanda/makepackage.py b/makepanda/makepackage.py index 0747169df5..daf0877544 100755 --- a/makepanda/makepackage.py +++ b/makepanda/makepackage.py @@ -531,6 +531,10 @@ def MakeInstallerOSX(version, runtime=False, python_versions=[], **kwargs): if os.path.isdir(outputdir+"/Pmw"): oscmd("cp -R %s/Pmw dstroot/pythoncode/Developer/Panda3D/Pmw" % outputdir) + # Copy over panda3d.dist-info directory. + if os.path.isdir(outputdir + "/panda3d.dist-info"): + oscmd("cp -R %s/panda3d.dist-info dstroot/pythoncode/Developer/Panda3D/panda3d.dist-info" % (outputdir)) + for base in os.listdir(outputdir+"/panda3d"): if base.endswith('.py'): libname = "dstroot/pythoncode/Developer/Panda3D/panda3d/" + base @@ -554,9 +558,12 @@ def MakeInstallerOSX(version, runtime=False, python_versions=[], **kwargs): oscmd("mkdir -p dstroot/pybindings%s/Library/Python/%s/site-packages" % (pyver, pyver)) WriteFile("dstroot/pybindings%s/Library/Python/%s/site-packages/Panda3D.pth" % (pyver, pyver), "/Developer/Panda3D") - # Copy over panda3d.dist-info directory. - if os.path.isdir(outputdir + "/panda3d.dist-info"): - oscmd("cp -R %s/panda3d.dist-info dstroot/pybindings%s/Library/Python/%s/site-packages/" % (outputdir, pyver, pyver)) + # Evidently not all Python 3.7 installations read the above path, so do this for now + # See GitHub #502 + if pyver == "3.7": + dir = "dstroot/pybindings%s/Library/Frameworks/Python.framework/Versions/%s/lib/python%s/site-packages" % (pyver, pyver, pyver) + oscmd("mkdir -p %s" % (dir)) + WriteFile("%s/Panda3D.pth" % (dir), "/Developer/Panda3D") if not PkgSkip("FFMPEG"): oscmd("mkdir -p dstroot/ffmpeg/Developer/Panda3D/lib") diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index 40febe3cd0..dc0bded1f8 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -473,7 +473,7 @@ else: target_arch = GetTargetArch() if target_arch == 'amd64': target_arch = 'x86_64' - PLATFORM = '{0}-{1}' % (target, target_arch) + PLATFORM = '{0}-{1}'.format(target, target_arch) print("Platform: %s" % PLATFORM) diff --git a/makepanda/panda-install.bmp b/makepanda/panda-install.bmp index bfe7063586..2e6b5860f5 100644 Binary files a/makepanda/panda-install.bmp and b/makepanda/panda-install.bmp differ diff --git a/models/plugin_images/installer.bmp b/models/plugin_images/installer.bmp index bfe7063586..2e6b5860f5 100644 Binary files a/models/plugin_images/installer.bmp and b/models/plugin_images/installer.bmp differ diff --git a/panda/src/configfiles/pandaIcon.ico b/panda/src/configfiles/pandaIcon.ico index cd6f45759f..3a2c1c33d4 100644 Binary files a/panda/src/configfiles/pandaIcon.ico and b/panda/src/configfiles/pandaIcon.ico differ diff --git a/panda/src/device/inputDeviceManager.h b/panda/src/device/inputDeviceManager.h index 9cfadf2845..7fd69b804e 100644 --- a/panda/src/device/inputDeviceManager.h +++ b/panda/src/device/inputDeviceManager.h @@ -20,7 +20,7 @@ #include "inputDeviceSet.h" #ifdef _WIN32 -#include "xinputDevice.h" +#include "xInputDevice.h" class WinRawInputDevice; #endif diff --git a/panda/src/device/winInputDeviceManager.cxx b/panda/src/device/winInputDeviceManager.cxx index 033a174f6b..95f73549dd 100644 --- a/panda/src/device/winInputDeviceManager.cxx +++ b/panda/src/device/winInputDeviceManager.cxx @@ -315,7 +315,8 @@ on_input_device_arrival(HANDLE handle) { // Is this an XInput device? If so, handle it via XInput, which allows us // to handle independent left/right triggers as well as vibration output. - if (info.dwType == RIM_TYPEHID && strstr(path, "&IG_") != nullptr) { + if (info.dwType == RIM_TYPEHID && strstr(path, "&IG_") != nullptr && + XInputDevice::init_xinput()) { // This is a device we should handle via the XInput API. Check which of // the four players was the lucky one. if (_xinput_device0.check_arrival(info, inst, name, manufacturer)) { diff --git a/panda/src/device/winRawInputDevice.cxx b/panda/src/device/winRawInputDevice.cxx index eeb98f112d..9c49d83122 100644 --- a/panda/src/device/winRawInputDevice.cxx +++ b/panda/src/device/winRawInputDevice.cxx @@ -334,6 +334,14 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) { return false; } + if (device_cat.is_debug()) { + device_cat.debug() + << "Found " << _device_class << " device \"" << _name << "\" with " + << caps.NumberInputDataIndices << " data indices, " + << caps.NumberInputButtonCaps << " button caps, " + << caps.NumberInputValueCaps << " value caps\n"; + } + // Do we have a button mapping? static const ButtonHandle gamepad_buttons_common[] = { ButtonHandle::none(), @@ -374,8 +382,11 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) { _axes.clear(); USHORT num_button_caps = caps.NumberInputButtonCaps; - PHIDP_BUTTON_CAPS button_caps = (PHIDP_BUTTON_CAPS)alloca(num_button_caps * sizeof(HIDP_BUTTON_CAPS)); - _HidP_GetButtonCaps(HidP_Input, button_caps, &num_button_caps, buffer); + PHIDP_BUTTON_CAPS button_caps; + if (num_button_caps > 0u) { + button_caps = (PHIDP_BUTTON_CAPS)alloca(num_button_caps * sizeof(HIDP_BUTTON_CAPS)); + _HidP_GetButtonCaps(HidP_Input, button_caps, &num_button_caps, buffer); + } for (USHORT i = 0; i < num_button_caps; ++i) { HIDP_BUTTON_CAPS &cap = button_caps[i]; @@ -396,13 +407,15 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) { if (device_cat.is_debug()) { device_cat.debug() << "Found button: DataIndex=" << dec << cap.NotRange.DataIndex - << ", ReportID=" << dec << (int)cap.ReportID - << ", UsagePage=0x" << cap.UsagePage + << ", ReportID=" << (int)cap.ReportID + << ", UsagePage=0x" << hex << cap.UsagePage << ", Usage=0x" << cap.NotRange.Usage << dec << "\n"; } } + nassertd(cap.Range.DataIndexMin + upper < _indices.size()) continue; + // Windows will only tell us which buttons in a report are "on", so we // need to keep track of which buttons exist in which report so that we // can figure out which ones are off. @@ -429,6 +442,9 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) { handle = MouseButton::button(button); } break; + + default: + continue; } int button_index = _buttons.size(); @@ -439,8 +455,11 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) { } USHORT num_value_caps = caps.NumberInputValueCaps; - PHIDP_VALUE_CAPS value_caps = (PHIDP_VALUE_CAPS)alloca(num_value_caps * sizeof(HIDP_VALUE_CAPS)); - _HidP_GetValueCaps(HidP_Input, value_caps, &num_value_caps, buffer); + PHIDP_VALUE_CAPS value_caps; + if (num_value_caps > 0u) { + value_caps = (PHIDP_VALUE_CAPS)alloca(num_value_caps * sizeof(HIDP_VALUE_CAPS)); + _HidP_GetValueCaps(HidP_Input, value_caps, &num_value_caps, buffer); + } _hat_data_index = -1; @@ -464,7 +483,7 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) { if (device_cat.is_debug()) { device_cat.debug() << "Found value: DataIndex=" << dec << cap.NotRange.DataIndex - << ", ReportID=" << dec << (int)cap.ReportID + << ", ReportID=" << (int)cap.ReportID << ", UsagePage=0x" << hex << cap.UsagePage << ", Usage=0x" << cap.NotRange.Usage << dec << ", LogicalMin=" << cap.LogicalMin @@ -472,6 +491,8 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) { } } + nassertd(cap.Range.DataIndexMin + upper < _indices.size()) continue; + for (int j = 0; j <= upper; ++j) { USAGE usage = j + cap.Range.UsageMin; USHORT data_index = j + cap.Range.DataIndexMin; @@ -590,6 +611,8 @@ on_arrival(HANDLE handle, const RID_DEVICE_INFO &info, std::string name) { _max_data_count = _HidP_MaxDataListLength(HidP_Input, buffer); + nassertr_always(_max_data_count >= 0, false); + _handle = handle; _is_connected = true; return true; @@ -619,6 +642,10 @@ on_input(PRAWINPUT input) { nassertv(input != nullptr); nassertv(_preparsed != nullptr); + if (_max_data_count == 0) { + return; + } + BYTE *ptr = input->data.hid.bRawData; if (input->data.hid.dwSizeHid == 0) { return; @@ -626,6 +653,12 @@ on_input(PRAWINPUT input) { LightMutexHolder holder(_lock); + if (device_cat.is_spam()) { + device_cat.spam() + << _name << " received " << input->data.hid.dwCount << " reports of size " + << input->data.hid.dwSizeHid << "\n"; + } + for (DWORD i = 0; i < input->data.hid.dwCount; ++i) { process_report((PCHAR)ptr, input->data.hid.dwSizeHid); ptr += input->data.hid.dwSizeHid; @@ -654,6 +687,7 @@ process_report(PCHAR ptr, size_t size) { if (status == HIDP_STATUS_SUCCESS) { for (ULONG di = 0; di < count; ++di) { if (data[di].DataIndex != _hat_data_index) { + nassertd(data[di].DataIndex < _indices.size()) continue; const Index &idx = _indices[data[di].DataIndex]; if (idx._axis >= 0) { if (idx._signed) { diff --git a/panda/src/device/winRawInputDevice.h b/panda/src/device/winRawInputDevice.h index 8c880604be..ce4fe9a19c 100644 --- a/panda/src/device/winRawInputDevice.h +++ b/panda/src/device/winRawInputDevice.h @@ -42,10 +42,8 @@ private: private: const std::string _path; HANDLE _handle; - DWORD _size; void *_preparsed; ULONG _max_data_count; - ULONG _max_usage_count; // Indexed by report ID pvector _report_buttons; diff --git a/panda/src/device/xInputDevice.cxx b/panda/src/device/xInputDevice.cxx index 4621d467b9..9e8035fb0e 100644 --- a/panda/src/device/xInputDevice.cxx +++ b/panda/src/device/xInputDevice.cxx @@ -249,6 +249,10 @@ detect(InputDeviceManager *mgr) { */ bool XInputDevice:: init_xinput() { + if (_initialized) { + return true; + } + if (device_cat.is_debug()) { device_cat.debug() << "Initializing XInput library.\n"; } diff --git a/panda/src/vision/openCVTexture.cxx b/panda/src/vision/openCVTexture.cxx index 58c233232a..be85aa6866 100644 --- a/panda/src/vision/openCVTexture.cxx +++ b/panda/src/vision/openCVTexture.cxx @@ -22,20 +22,26 @@ #include "bamCacheRecord.h" // This symbol is predefined by the Panda3D build system to select whether we -// are using the OpenCV 2.3 or later interface, or if it is not defined, we -// are using the original interface. -#ifdef OPENCV_VER_23 +// are using the OpenCV 3.x or later interface. +#if defined(OPENCV_VER_3) + +#include +#include + +// This checks for 2.3 or later. +#elif defined(OPENCV_VER_23) #include -// #include #include +// If neither of those are predefined, assume 1.x. #else + #include #include #include -#endif // OPENCV_VER_23 +#endif // OPENCV_VER_3 TypeHandle OpenCVTexture::_type_handle; diff --git a/samples/asteroids/requirements.txt b/samples/asteroids/requirements.txt index a8e341eee1..0f30cd2bf9 100644 --- a/samples/asteroids/requirements.txt +++ b/samples/asteroids/requirements.txt @@ -1,2 +1 @@ ---pre --extra-index-url https://archive.panda3d.org/branches/deploy-ng panda3d diff --git a/setup.cfg b/setup.cfg index a2b7a81fa5..8a1a50afe0 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = Panda3D -version = 1.10.0 +version = 1.10.1 url = https://www.panda3d.org/ description = Panda3D is a framework for 3D rendering and game development for Python and C++ programs. license = Modified BSD License diff --git a/tests/build_samples.py b/tests/build_samples.py index 222a7df354..4622fd87bc 100644 --- a/tests/build_samples.py +++ b/tests/build_samples.py @@ -1,6 +1,7 @@ import os import subprocess import sys +import tempfile SAMPLES_TO_BUILD = [ 'asteroids', @@ -8,13 +9,24 @@ SAMPLES_TO_BUILD = [ SAMPLES_DIR = os.path.join(os.path.dirname(__file__), '..', 'samples') def main(): + build_base = tempfile.TemporaryDirectory() + dist_dir = tempfile.TemporaryDirectory() + for sample in SAMPLES_TO_BUILD: sampledir = os.path.join(SAMPLES_DIR, sample) os.chdir(sampledir) + args = [ + sys.executable, + 'setup.py', + 'bdist_apps', + '--build-base', build_base.name, + '--dist-dir', dist_dir.name, + ] + # This will raise a CalledProcessError if the build fails, which will cause # this script to fail - subprocess.check_call([sys.executable, 'setup.py', 'bdist_apps']) + subprocess.check_call(args) if __name__ == '__main__': main() diff --git a/tests/requirements.txt b/tests/requirements.txt index 6bb511ebbf..3bc9b3f390 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -1,3 +1,2 @@ pytest==3.2.0 ---pre --extra-index-url https://archive.panda3d.org/branches/deploy-ng panda3d diff --git a/tests/showbase/test_Audio3DManager.py b/tests/showbase/test_Audio3DManager.py new file mode 100644 index 0000000000..39b179bc91 --- /dev/null +++ b/tests/showbase/test_Audio3DManager.py @@ -0,0 +1,55 @@ +from direct.showbase.Audio3DManager import Audio3DManager +from panda3d import core +import pytest + + +@pytest.fixture(scope='session') +def manager3d(): + root = core.NodePath("root") + manager = core.AudioManager.create_AudioManager() + manager3d = Audio3DManager(manager, root=root) + yield manager3d + del manager3d + manager.shutdown() + + +def test_audio3dmanager_velocity(manager3d): + sound = manager3d.load_sfx("nonexistent") + + # Generate an object with movement + object = core.NodePath("object") + object.set_pos(0, 0, 0) + object.set_fluid_pos(1, 2, 3) + assert object.get_pos_delta() == (1, 2, 3) + + res = manager3d.attach_sound_to_object(sound, object) + assert res + + clock = core.ClockObject.get_global_clock() + clock.mode = core.ClockObject.M_slave + clock.dt = 0.5 + + # Test auto velocity calculation + manager3d.set_sound_velocity_auto(sound) + assert manager3d.get_sound_velocity(sound) == (2, 4, 6) + + # Test setting to fixed value + manager3d.set_sound_velocity(sound, (5, 5, 5)) + assert manager3d.get_sound_velocity(sound) == (5, 5, 5) + + +def test_audio3dmanager_weak(manager3d): + sound = manager3d.load_sfx("nonexistent") + object = core.NodePath("object") + + res = manager3d.attach_sound_to_object(sound, object) + assert res + assert object in manager3d.sound_dict + + manager3d.update() + assert object in manager3d.sound_dict + + object.remove_node() + manager3d.update() + + assert object not in manager3d.sound_dict