mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 02:42:49 -04:00
Merge branch 'release/1.9.x'
Conflicts: direct/src/p3d/DeploymentTools.py
This commit is contained in:
commit
3c2f820ad8
@ -31,8 +31,8 @@ are included as part of the Windows 7.1 SDK.
|
|||||||
You will also need to have the third-party dependency libraries available for
|
You will also need to have the third-party dependency libraries available for
|
||||||
the build scripts to use. These are available from one of these two URLs,
|
the build scripts to use. These are available from one of these two URLs,
|
||||||
depending on whether you are on a 32-bit or 64-bit system:
|
depending on whether you are on a 32-bit or 64-bit system:
|
||||||
https://www.panda3d.org/download/panda3d-1.9.0/panda3d-1.9.0-tools-win32.zip
|
https://www.panda3d.org/download/panda3d-1.9.1/panda3d-1.9.1-tools-win32.zip
|
||||||
https://www.panda3d.org/download/panda3d-1.9.0/panda3d-1.9.0-tools-win64.zip
|
https://www.panda3d.org/download/panda3d-1.9.1/panda3d-1.9.1-tools-win64.zip
|
||||||
|
|
||||||
After acquiring these dependencies, you may simply build Panda3D from the
|
After acquiring these dependencies, you may simply build Panda3D from the
|
||||||
command prompt using the following command:
|
command prompt using the following command:
|
||||||
@ -97,7 +97,7 @@ Mac OS X
|
|||||||
--------
|
--------
|
||||||
|
|
||||||
On Mac OS X, you will need to download a set of precompiled thirdparty packages in order to
|
On Mac OS X, you will need to download a set of precompiled thirdparty packages in order to
|
||||||
compile Panda3D, which can be acquired from [here](https://www.panda3d.org/download/panda3d-1.9.0/panda3d-1.9.0-tools-mac.tar.gz).
|
compile Panda3D, which can be acquired from [here](https://www.panda3d.org/download/panda3d-1.9.1/panda3d-1.9.1-tools-mac.tar.gz).
|
||||||
|
|
||||||
After placing the thirdparty directory inside the panda3d source directory,
|
After placing the thirdparty directory inside the panda3d source directory,
|
||||||
you may build Panda3D using a command like the following:
|
you may build Panda3D using a command like the following:
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# ClockDelta provides the ability to use clock synchronization for
|
# ClockDelta provides the ability to use clock synchronization for
|
||||||
# distributed objects
|
# distributed objects
|
||||||
|
|
||||||
from pandac.PandaModules import *
|
from panda3d.core import ClockObject
|
||||||
from direct.directnotify import DirectNotifyGlobal
|
from direct.directnotify import DirectNotifyGlobal
|
||||||
from direct.showbase import DirectObject
|
from direct.showbase import DirectObject
|
||||||
import math
|
import math
|
||||||
|
@ -94,8 +94,8 @@ class DirectDialog(DirectFrame):
|
|||||||
('text', '', None),
|
('text', '', None),
|
||||||
('text_align', TextNode.ALeft, None),
|
('text_align', TextNode.ALeft, None),
|
||||||
('text_scale', 0.06, None),
|
('text_scale', 0.06, None),
|
||||||
('image', None, None),
|
('image', DGG.getDefaultDialogGeom(), None),
|
||||||
('relief', DGG.RAISED, None),
|
('relief', DGG.getDefaultDialogRelief(), None),
|
||||||
('borderWidth', (0.01, 0.01), None),
|
('borderWidth', (0.01, 0.01), None),
|
||||||
('buttonTextList', [], DGG.INITOPT),
|
('buttonTextList', [], DGG.INITOPT),
|
||||||
('buttonGeomList', [], DGG.INITOPT),
|
('buttonGeomList', [], DGG.INITOPT),
|
||||||
@ -316,6 +316,7 @@ class DirectDialog(DirectFrame):
|
|||||||
# reduce bottom by pad, button height and 2*button pad
|
# reduce bottom by pad, button height and 2*button pad
|
||||||
b = min(b - self['midPad'] - bpad[1] - bHeight - bpad[1], b) - pad[1]
|
b = min(b - self['midPad'] - bpad[1] - bHeight - bpad[1], b) - pad[1]
|
||||||
t = t + self['topPad'] + pad[1]
|
t = t + self['topPad'] + pad[1]
|
||||||
|
if self['frameSize'] is None:
|
||||||
self['frameSize'] = (l, r, b, t)
|
self['frameSize'] = (l, r, b, t)
|
||||||
self['image_scale'] = (r - l, 1, t - b)
|
self['image_scale'] = (r - l, 1, t - b)
|
||||||
# Center frame about text and buttons
|
# Center frame about text and buttons
|
||||||
|
@ -14,6 +14,7 @@ defaultFontFunc = TextNode.getDefaultFont
|
|||||||
defaultClickSound = None
|
defaultClickSound = None
|
||||||
defaultRolloverSound = None
|
defaultRolloverSound = None
|
||||||
defaultDialogGeom = None
|
defaultDialogGeom = None
|
||||||
|
defaultDialogRelief = PGFrameStyle.TBevelOut
|
||||||
drawOrder = 100
|
drawOrder = 100
|
||||||
panel = None
|
panel = None
|
||||||
|
|
||||||
@ -132,13 +133,16 @@ def setDefaultFontFunc(newFontFunc):
|
|||||||
|
|
||||||
def getDefaultDialogGeom():
|
def getDefaultDialogGeom():
|
||||||
global defaultDialogGeom
|
global defaultDialogGeom
|
||||||
if defaultDialogGeom == None:
|
|
||||||
defaultDialogGeom = loader.loadModel('models/gui/dialog_box_gui', okMissing = True)
|
|
||||||
return defaultDialogGeom
|
return defaultDialogGeom
|
||||||
|
|
||||||
def setDefaultDialogGeom(newDialogGeom):
|
def getDefaultDialogRelief():
|
||||||
global defaultDialogGeom
|
global defaultDialogRelief
|
||||||
|
return defaultDialogRelief
|
||||||
|
|
||||||
|
def setDefaultDialogGeom(newDialogGeom, relief=None):
|
||||||
|
global defaultDialogGeom, defaultDialogRelief
|
||||||
defaultDialogGeom = newDialogGeom
|
defaultDialogGeom = newDialogGeom
|
||||||
|
defaultDialogRelief = relief
|
||||||
|
|
||||||
def getDefaultDrawOrder():
|
def getDefaultDrawOrder():
|
||||||
return drawOrder
|
return drawOrder
|
||||||
|
@ -5,6 +5,7 @@ to build for as many platforms as possible. """
|
|||||||
__all__ = ["Standalone", "Installer"]
|
__all__ = ["Standalone", "Installer"]
|
||||||
|
|
||||||
import os, sys, subprocess, tarfile, shutil, time, zipfile, socket, getpass, struct
|
import os, sys, subprocess, tarfile, shutil, time, zipfile, socket, getpass, struct
|
||||||
|
import gzip
|
||||||
from io import BytesIO, TextIOWrapper
|
from io import BytesIO, TextIOWrapper
|
||||||
from direct.directnotify.DirectNotifyGlobal import *
|
from direct.directnotify.DirectNotifyGlobal import *
|
||||||
from direct.showbase.AppRunnerGlobal import appRunner
|
from direct.showbase.AppRunnerGlobal import appRunner
|
||||||
@ -994,7 +995,7 @@ class Installer:
|
|||||||
if self.licensefile:
|
if self.licensefile:
|
||||||
shutil.copyfile(self.licensefile.toOsSpecific(), Filename(output, "Contents/Resources/License.txt").toOsSpecific())
|
shutil.copyfile(self.licensefile.toOsSpecific(), Filename(output, "Contents/Resources/License.txt").toOsSpecific())
|
||||||
pkginfo = open(Filename(output, "Contents/PkgInfo").toOsSpecific(), "w")
|
pkginfo = open(Filename(output, "Contents/PkgInfo").toOsSpecific(), "w")
|
||||||
pkginfo.write("pkmkrpkg1")
|
pkginfo.write("pmkrpkg1")
|
||||||
pkginfo.close()
|
pkginfo.close()
|
||||||
pkginfo = open(Filename(output, "Contents/Resources/package_version").toOsSpecific(), "w")
|
pkginfo = open(Filename(output, "Contents/Resources/package_version").toOsSpecific(), "w")
|
||||||
pkginfo.write("major: 1\nminor: 9")
|
pkginfo.write("major: 1\nminor: 9")
|
||||||
@ -1079,18 +1080,18 @@ class Installer:
|
|||||||
plist.write('</plist>\n')
|
plist.write('</plist>\n')
|
||||||
plist.close()
|
plist.close()
|
||||||
|
|
||||||
if hasattr(tarfile, "PAX_FORMAT"):
|
# OS X El Capitan no longer accepts .pax archives - it must be a CPIO archive named .pax.
|
||||||
archive = tarfile.open(Filename(output, "Contents/Archive.pax.gz").toOsSpecific(), "w:gz", format = tarfile.PAX_FORMAT, tarinfo = TarInfoRootOSX)
|
archive = gzip.open(Filename(output, "Contents/Archive.pax.gz").toOsSpecific(), 'wb')
|
||||||
else:
|
self.__ino = 0
|
||||||
archive = tarfile.open(Filename(output, "Contents/Archive.pax.gz").toOsSpecific(), "w:gz", tarinfo = TarInfoRootOSX)
|
self.__writeCPIO(archive, appfn, appname)
|
||||||
archive.add(appfn.toOsSpecific(), appname)
|
archive.write(b"0707070000000000000000000000000000000000010000000000000000000001300000000000TRAILER!!!\0")
|
||||||
archive.close()
|
archive.close()
|
||||||
|
|
||||||
# Put the .pkg into a zipfile
|
# Put the .pkg into a zipfile
|
||||||
archive = Filename(output.getDirname(), "%s %s.zip" % (self.fullname, self.version))
|
zip_fn = Filename(output.getDirname(), "%s %s.pkg.zip" % (self.fullname, self.version))
|
||||||
dir = Filename(output.getDirname())
|
dir = Filename(output.getDirname())
|
||||||
dir.makeAbsolute()
|
dir.makeAbsolute()
|
||||||
zip = zipfile.ZipFile(archive.toOsSpecific(), 'w')
|
zip = zipfile.ZipFile(zip_fn.toOsSpecific(), 'w')
|
||||||
for root, dirs, files in self.os_walk(output.toOsSpecific()):
|
for root, dirs, files in self.os_walk(output.toOsSpecific()):
|
||||||
for name in files:
|
for name in files:
|
||||||
file = Filename.fromOsSpecific(os.path.join(root, name))
|
file = Filename.fromOsSpecific(os.path.join(root, name))
|
||||||
@ -1101,6 +1102,61 @@ class Installer:
|
|||||||
|
|
||||||
return output
|
return output
|
||||||
|
|
||||||
|
def __writeCPIO(self, archive, fn, name):
|
||||||
|
""" Adds the given fn under the given name to the CPIO archive. """
|
||||||
|
|
||||||
|
st = os.lstat(fn.toOsSpecific())
|
||||||
|
|
||||||
|
archive.write(b"070707") # magic
|
||||||
|
archive.write(b"000000") # dev
|
||||||
|
|
||||||
|
# Synthesize an inode number, different for each entry.
|
||||||
|
self.__ino += 1
|
||||||
|
archive.write("%06o" % (self.__ino))
|
||||||
|
|
||||||
|
# Determine based on the type which mode to write.
|
||||||
|
if os.path.islink(fn.toOsSpecific()):
|
||||||
|
archive.write("%06o" % (st.st_mode))
|
||||||
|
target = os.path.readlink(fn.toOsSpecific()).encode('utf-8')
|
||||||
|
size = len(target)
|
||||||
|
elif os.path.isdir(fn.toOsSpecific()):
|
||||||
|
archive.write(b"040755")
|
||||||
|
size = 0
|
||||||
|
elif not fn.getExtension(): # Binary file?
|
||||||
|
archive.write(b"100755")
|
||||||
|
size = st.st_size
|
||||||
|
else:
|
||||||
|
archive.write(b"100644")
|
||||||
|
size = st.st_size
|
||||||
|
|
||||||
|
archive.write("000000") # uid (root)
|
||||||
|
archive.write("000000") # gid (wheel)
|
||||||
|
archive.write("%06o" % (st.st_nlink))
|
||||||
|
archive.write("000000") # rdev
|
||||||
|
archive.write("%011o" % (st.st_mtime))
|
||||||
|
archive.write("%06o" % (len(name) + 1))
|
||||||
|
archive.write("%011o" % (size))
|
||||||
|
|
||||||
|
# Write the filename, plus terminating NUL byte.
|
||||||
|
archive.write(name.encode('utf-8'))
|
||||||
|
archive.write(b"\0")
|
||||||
|
|
||||||
|
# Copy the file data to the archive.
|
||||||
|
if os.path.islink(fn.toOsSpecific()):
|
||||||
|
archive.write(target)
|
||||||
|
elif size:
|
||||||
|
handle = open(fn.toOsSpecific(), 'rb')
|
||||||
|
data = handle.read(1024 * 1024)
|
||||||
|
while data:
|
||||||
|
archive.write(data)
|
||||||
|
data = handle.read(1024 * 1024)
|
||||||
|
handle.close()
|
||||||
|
|
||||||
|
# If this is a directory, recurse.
|
||||||
|
if os.path.isdir(fn.toOsSpecific()):
|
||||||
|
for child in os.listdir(fn.toOsSpecific()):
|
||||||
|
self.__writeCPIO(archive, Filename(fn, child), name + "/" + child)
|
||||||
|
|
||||||
def buildNSIS(self, output, platform):
|
def buildNSIS(self, output, platform):
|
||||||
# Check if we have makensis first
|
# Check if we have makensis first
|
||||||
makensis = None
|
makensis = None
|
||||||
|
@ -2427,7 +2427,7 @@ class Packager:
|
|||||||
|
|
||||||
# Binary files that are considered uncompressible, and are
|
# Binary files that are considered uncompressible, and are
|
||||||
# copied without compression.
|
# copied without compression.
|
||||||
self.uncompressibleExtensions = [ 'mp3', 'ogg', 'wav', 'rml', 'rcss', 'otf' ]
|
self.uncompressibleExtensions = [ 'mp3', 'ogg', 'ogv', 'wav', 'rml', 'rcss', 'otf' ]
|
||||||
# wav files are compressible, but p3openal_audio won't load
|
# wav files are compressible, but p3openal_audio won't load
|
||||||
# them compressed.
|
# them compressed.
|
||||||
# rml, rcss and otf files must be added here because
|
# rml, rcss and otf files must be added here because
|
||||||
@ -3744,8 +3744,7 @@ class Packager:
|
|||||||
self.__recurseDir(dirname, newDir, unprocessed = unprocessed)
|
self.__recurseDir(dirname, newDir, unprocessed = unprocessed)
|
||||||
|
|
||||||
def __recurseDir(self, filename, newName, unprocessed = None, packageTree = None):
|
def __recurseDir(self, filename, newName, unprocessed = None, packageTree = None):
|
||||||
dirList = vfs.scanDirectory(filename)
|
if filename.isDirectory():
|
||||||
if dirList:
|
|
||||||
# It's a directory name. Recurse.
|
# It's a directory name. Recurse.
|
||||||
prefix = newName
|
prefix = newName
|
||||||
if prefix and prefix[-1] != '/':
|
if prefix and prefix[-1] != '/':
|
||||||
@ -3753,6 +3752,7 @@ class Packager:
|
|||||||
|
|
||||||
# First check if this is a Python package tree. If so, add it
|
# First check if this is a Python package tree. If so, add it
|
||||||
# implicitly as a module.
|
# implicitly as a module.
|
||||||
|
dirList = vfs.scanDirectory(filename)
|
||||||
for subfile in dirList:
|
for subfile in dirList:
|
||||||
filename = subfile.getFilename()
|
filename = subfile.getFilename()
|
||||||
if filename.getBasename() == '__init__.py':
|
if filename.getBasename() == '__init__.py':
|
||||||
@ -3764,6 +3764,9 @@ class Packager:
|
|||||||
self.__recurseDir(filename, prefix + filename.getBasename(),
|
self.__recurseDir(filename, prefix + filename.getBasename(),
|
||||||
unprocessed = unprocessed)
|
unprocessed = unprocessed)
|
||||||
return
|
return
|
||||||
|
elif not filename.exists():
|
||||||
|
# It doesn't exist. Perhaps it's a virtual file. Ignore it.
|
||||||
|
return
|
||||||
|
|
||||||
# It's a file name. Add it.
|
# It's a file name. Add it.
|
||||||
ext = filename.getExtension()
|
ext = filename.getExtension()
|
||||||
|
@ -103,8 +103,6 @@ class panda3d(package):
|
|||||||
|
|
||||||
excludeModule('MySQLdb', '_mysql')
|
excludeModule('MySQLdb', '_mysql')
|
||||||
|
|
||||||
excludeModule('xml', 'xml.parsers.expat', 'xml.sax')
|
|
||||||
|
|
||||||
# Most of the core Panda3D DLL's will be included implicitly due to
|
# Most of the core Panda3D DLL's will be included implicitly due to
|
||||||
# being referenced by the above Python code. Here we name a few more
|
# being referenced by the above Python code. Here we name a few more
|
||||||
# that are also needed, but aren't referenced by any code. Again,
|
# that are also needed, but aren't referenced by any code. Again,
|
||||||
|
110
doc/ReleaseNotes
110
doc/ReleaseNotes
@ -3,31 +3,107 @@
|
|||||||
This minor release fixes some important regressions and bugs found
|
This minor release fixes some important regressions and bugs found
|
||||||
in 1.9.0, but also introduces a few minor features.
|
in 1.9.0, but also introduces a few minor features.
|
||||||
|
|
||||||
It also reintroduces the deployment pipeline that was absent from
|
It also reintroduces the deployment tools that were absent from
|
||||||
the previous release.
|
the previous release.
|
||||||
|
|
||||||
* Textures were not being scaled to power-of-2 in some cases
|
The following issues were fixed:
|
||||||
* Fix various issues with shader inputs
|
* SDK now properly installs in Mac OS X 10.11 "El Capitan"
|
||||||
* Bullet step function accidentally defaulted to step size of 0
|
* Windows 8.1+ no longer applies DPI virtualization to Panda window
|
||||||
* Use model-path for finding libRocket assets
|
* Fix ffmpeg library load issue on Mac OS X
|
||||||
* Fix inconsistent behavior with non-power-of-2 textures in rocket
|
|
||||||
* Fix regression with memoryviews
|
|
||||||
* Fix symbol error when loading libp3ffmpeg on Mac OS X
|
|
||||||
* Fix issues running maya2egg on Mac OS X
|
* Fix issues running maya2egg on Mac OS X
|
||||||
* PStats now tracks memory residency of graphics buffers
|
* Fix compiler errors on different platforms
|
||||||
* Support wireframe and point rendering modes in OpenGL ES
|
* Fix various rare crashes
|
||||||
* Add missing keys to libRocket keymap
|
* Fix crashes on shutdown in threaded pipeline
|
||||||
|
* Fix low-level threading crash on ARM machines
|
||||||
|
* More reliably and robustly handle failures opening OpenAL device
|
||||||
|
* Textures were not being scaled to power-of-2 in some cases
|
||||||
|
* Correct scaling of normal vectors with flatten operation
|
||||||
|
* Correct positioning of viewing axis when showing lens frustum
|
||||||
|
* Add dpi-window-resize option to auto-resize window on DPI change
|
||||||
|
* Fix assertions when alpha-file-channel references unknown channel
|
||||||
|
* Use OpenGL-style vertex colors by default on non-Windows systems
|
||||||
|
* Default vertex column alignment is now 4 bytes
|
||||||
|
* Add PNMImage premultiply/unpremultiply methods.
|
||||||
* Fix incorrect parsing of numbers with exponents in Config.prc
|
* Fix incorrect parsing of numbers with exponents in Config.prc
|
||||||
* Various performance optimizations
|
|
||||||
* Fix for reading URLs mounted via the virtual file system
|
* Fix for reading URLs mounted via the virtual file system
|
||||||
* Improve GLSL error reporting
|
|
||||||
* Fix issue with model disappearing in rare cases with GLSL
|
|
||||||
* Fix shader generator memory leaks and runtime performance
|
* Fix shader generator memory leaks and runtime performance
|
||||||
* Add M_confined mouse mode that keeps cursor in window
|
* Fix shader generator scaling of binormals and tangents
|
||||||
* Expose _NET_WM_PID to window managers in X11
|
* Expose _NET_WM_PID to window managers in X11
|
||||||
* bam2egg supports collision sphere and plane solids
|
* Fix a range of bugs in tinydisplay renderer.
|
||||||
* Add sample program demonstrating mouse modes
|
* Don't error when setting lens far distance to infinity
|
||||||
|
* Allow passing custom lens to saveCubeMap/saveSphereMap
|
||||||
|
* Fix errors in saveCubeMap/saveSphereMap in threaded pipeline
|
||||||
|
* Fix DynamicTextFont.makeCopy()
|
||||||
|
* Make Texture memory size estimation more accurate
|
||||||
|
* Fix various window resizing issues
|
||||||
|
* Fix PandaSystem.getCompiler() value for clang (it reported gcc)
|
||||||
|
* x2egg no longer replaces face normals with vertex normals
|
||||||
|
* Include Eigen headers in Mac and Windows SDK
|
||||||
|
* Added geomipterrain-incorrect-normals setting, default=true
|
||||||
|
* DisplayInformation resolution list was missing on Windows
|
||||||
|
* Upgrade FMOD and Bullet versions on Windows and Mac OS X
|
||||||
|
* Various performance optimizations
|
||||||
|
* Fixed various other bugs not listed here.
|
||||||
|
|
||||||
|
Fixes and improvements for the runtime:
|
||||||
|
* Fix splash screen freezing in the X11 web plug-in
|
||||||
|
* pdeploy will now handle extracted files (eg. .ico and .cur)
|
||||||
|
* Added more options for customizing splash screen
|
||||||
|
* Fix missing xml and ast modules from morepy package
|
||||||
|
* Certificate dialog is now localized to various languages
|
||||||
|
* Fix packp3d error when Python file is not in a package
|
||||||
|
* Pass on failing exit status from packaged application
|
||||||
|
* Remove annoying ":Packager(warning): No such file" warning
|
||||||
|
* Fix issue installing pdeploy-generated .pkg on OS X 10.11
|
||||||
|
|
||||||
|
Fixes for the Python API:
|
||||||
|
* Fix mysterious and rare crash in tp_traverse
|
||||||
|
* Bullet step function accidentally defaulted to step size of 0
|
||||||
|
* Fix overflow of file offsets (eg. when seeking in huge files)
|
||||||
|
* Fix regression with memoryviews
|
||||||
|
* Fix hasattr/getattr of vector classes for invalid attributes
|
||||||
|
* Allow passing a long to methods accepting an int
|
||||||
|
* Fix crash when passing None to Filename constructor
|
||||||
|
* MouseWatcherGroup was erroneously not exposed in 1.9.0
|
||||||
|
* ShowBase no longer unmounts VFS when shutting down
|
||||||
|
* No longer requires setting PATH to import panda3d.*
|
||||||
|
* DirectDialog default geom is once again respected
|
||||||
|
* DirectDialog no longer overrides custom frameSize
|
||||||
|
* Fix WebcamVideo/MicrophoneAudio.getOptions() methods
|
||||||
|
|
||||||
|
Changes relating to the OpenGL renderer:
|
||||||
|
* Various performance improvements
|
||||||
|
* Fix point/line thickness setting
|
||||||
|
* Improve GLSL error reporting
|
||||||
|
* Fix Intel driver issues, particularly with geometry shaders
|
||||||
|
* Add more error checking for parameter types
|
||||||
|
* Integer shader inputs were not being converted to float properly
|
||||||
|
* Fix crash passing an undersized array to a GLSL shader input
|
||||||
|
* p3d_ColorScale et al may now be declared as vec3
|
||||||
|
* Fix flickering when using trans_model_to_apiview in Cg
|
||||||
|
* Support wireframe and point rendering modes in OpenGL ES
|
||||||
|
* Fix issue with model disappearing in rare cases with GLSL
|
||||||
|
* Fix ColorWriteAttrib not working as it should
|
||||||
|
* Allow deactivating PStats collectors for GPU timers
|
||||||
|
* Memory residency of graphics buffers now tracked by PStats
|
||||||
|
* Allow changing OpenGL coordinate system with gl-coordinate-system
|
||||||
|
|
||||||
|
Fixes for libRocket integration:
|
||||||
|
* libRocket did not work on Mac OS X in 1.9.0
|
||||||
|
* Fix inconsistent behavior with non-power-of-2 textures in rocket
|
||||||
|
* Use model-path for finding libRocket assets
|
||||||
|
* Add missing keys to libRocket keymap
|
||||||
|
* libRocket elements showed up white in tinydisplay
|
||||||
|
|
||||||
|
New features:
|
||||||
* Add -L (lighting) and -P (graphics pipe) pview options
|
* Add -L (lighting) and -P (graphics pipe) pview options
|
||||||
|
* Add M_confined mouse mode that keeps cursor in window
|
||||||
|
* Add sample program demonstrating mouse modes
|
||||||
|
* bam2egg supports collision sphere and plane solids
|
||||||
|
* p3d_TransformTable GLSL input backported from 1.10 branch
|
||||||
|
* Add openal-device setting for selecting OpenAL audio output
|
||||||
|
* Add limited modification timestamp tracking for Ramdisk mounts
|
||||||
|
* Support for Autodesk Maya 2016
|
||||||
|
|
||||||
------------------------ RELEASE 1.9.0 ------------------------
|
------------------------ RELEASE 1.9.0 ------------------------
|
||||||
|
|
||||||
|
@ -327,7 +327,7 @@ def parseopts(args):
|
|||||||
else:
|
else:
|
||||||
PkgDisable("TOUCHINPUT")
|
PkgDisable("TOUCHINPUT")
|
||||||
|
|
||||||
if clean_build:
|
if clean_build and os.path.isdir(GetOutputDir()):
|
||||||
print("Deleting %s" % (GetOutputDir()))
|
print("Deleting %s" % (GetOutputDir()))
|
||||||
shutil.rmtree(GetOutputDir())
|
shutil.rmtree(GetOutputDir())
|
||||||
|
|
||||||
@ -783,8 +783,6 @@ if (COMPILER=="GCC"):
|
|||||||
rocket_libs = ("RocketCore", "RocketControls")
|
rocket_libs = ("RocketCore", "RocketControls")
|
||||||
if (GetOptimize() <= 3):
|
if (GetOptimize() <= 3):
|
||||||
rocket_libs += ("RocketDebugger",)
|
rocket_libs += ("RocketDebugger",)
|
||||||
if (GetHost() != "darwin"):
|
|
||||||
# We use a statically linked libboost_python on OSX
|
|
||||||
rocket_libs += ("boost_python",)
|
rocket_libs += ("boost_python",)
|
||||||
SmartPkgEnable("ROCKET", "", rocket_libs, "Rocket/Core.h")
|
SmartPkgEnable("ROCKET", "", rocket_libs, "Rocket/Core.h")
|
||||||
|
|
||||||
@ -2762,9 +2760,15 @@ if tp_dir is not None:
|
|||||||
dylibs = set()
|
dylibs = set()
|
||||||
|
|
||||||
if GetTarget() == 'darwin':
|
if GetTarget() == 'darwin':
|
||||||
|
# Make a list of all the dylibs we ship, to figure out whether we should use
|
||||||
|
# install_name_tool to correct the library reference to point to our copy.
|
||||||
for lib in glob.glob(tp_dir + "/*/lib/*.dylib"):
|
for lib in glob.glob(tp_dir + "/*/lib/*.dylib"):
|
||||||
dylibs.add(os.path.basename(lib))
|
dylibs.add(os.path.basename(lib))
|
||||||
|
|
||||||
|
if not PkgSkip("PYTHON"):
|
||||||
|
for lib in glob.glob(tp_dir + "/*/lib/" + SDK["PYTHONVERSION"] + "/*.dylib"):
|
||||||
|
dylibs.add(os.path.basename(lib))
|
||||||
|
|
||||||
for pkg in PkgListGet():
|
for pkg in PkgListGet():
|
||||||
if PkgSkip(pkg):
|
if PkgSkip(pkg):
|
||||||
continue
|
continue
|
||||||
@ -2775,49 +2779,69 @@ if tp_dir is not None:
|
|||||||
CopyAllFiles(GetOutputDir() + "/bin/", tp_pkg + "/bin/")
|
CopyAllFiles(GetOutputDir() + "/bin/", tp_pkg + "/bin/")
|
||||||
if (PkgSkip("PYTHON")==0 and os.path.exists(tp_pkg + "/bin/" + SDK["PYTHONVERSION"])):
|
if (PkgSkip("PYTHON")==0 and os.path.exists(tp_pkg + "/bin/" + SDK["PYTHONVERSION"])):
|
||||||
CopyAllFiles(GetOutputDir() + "/bin/", tp_pkg + "/bin/" + SDK["PYTHONVERSION"] + "/")
|
CopyAllFiles(GetOutputDir() + "/bin/", tp_pkg + "/bin/" + SDK["PYTHONVERSION"] + "/")
|
||||||
else:
|
|
||||||
for tp_lib in glob.glob(tp_pkg + "/lib/*.so*"):
|
|
||||||
CopyFile(GetOutputDir() + "/lib/" + os.path.basename(tp_lib), tp_lib)
|
|
||||||
|
|
||||||
if not PkgSkip("PYTHON"):
|
elif GetTarget() == 'darwin':
|
||||||
for tp_lib in glob.glob(os.path.join(tp_pkg, "lib", SDK["PYTHONVERSION"], "*.so*")):
|
|
||||||
CopyFile(GetOutputDir() + "/lib/" + os.path.basename(tp_lib), tp_lib)
|
|
||||||
|
|
||||||
if GetTarget() == 'darwin':
|
|
||||||
tp_libs = glob.glob(tp_pkg + "/lib/*.dylib")
|
tp_libs = glob.glob(tp_pkg + "/lib/*.dylib")
|
||||||
|
|
||||||
if not PkgSkip("PYTHON"):
|
if not PkgSkip("PYTHON"):
|
||||||
tp_libs += glob.glob(os.path.join(tp_pkg, "lib", SDK["PYTHONVERSION"], "*.dylib"))
|
tp_libs += glob.glob(os.path.join(tp_pkg, "lib", SDK["PYTHONVERSION"], "*.dylib"))
|
||||||
|
tp_libs += glob.glob(os.path.join(tp_pkg, "lib", SDK["PYTHONVERSION"], "*.so"))
|
||||||
|
if pkg != 'PYTHON':
|
||||||
|
tp_libs += glob.glob(os.path.join(tp_pkg, "lib", SDK["PYTHONVERSION"], "*.py"))
|
||||||
|
|
||||||
for tp_lib in tp_libs:
|
for tp_lib in tp_libs:
|
||||||
basename = os.path.basename(tp_lib)
|
basename = os.path.basename(tp_lib)
|
||||||
|
if basename.endswith('.dylib'):
|
||||||
|
# It's a dynamic link library. Put it in the lib directory.
|
||||||
target = GetOutputDir() + "/lib/" + basename
|
target = GetOutputDir() + "/lib/" + basename
|
||||||
|
dep_prefix = "@loader_path/../lib/"
|
||||||
|
lib_id = dep_prefix + basename
|
||||||
|
else:
|
||||||
|
# It's a Python module, like _rocketcore.so. Copy it to the root, because
|
||||||
|
# nowadays the 'lib' directory may no longer be on the PYTHONPATH.
|
||||||
|
target = GetOutputDir() + "/" + basename
|
||||||
|
dep_prefix = "@loader_path/lib/"
|
||||||
|
lib_id = basename
|
||||||
|
|
||||||
if not NeedsBuild([target], [tp_lib]):
|
if not NeedsBuild([target], [tp_lib]):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
CopyFile(target, tp_lib)
|
CopyFile(target, tp_lib)
|
||||||
if os.path.islink(target):
|
if os.path.islink(target) or target.endswith('.py'):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Correct the inter-library dependencies so that the build is relocatable.
|
# Correct the inter-library dependencies so that the build is relocatable.
|
||||||
oscmd('install_name_tool -id @loader_path/../lib/%s %s' % (basename, target))
|
oscmd('install_name_tool -id %s %s' % (lib_id, target))
|
||||||
oscmd("otool -L %s | grep .dylib > %s/tmp/otool-libs.txt" % (target, GetOutputDir()), True)
|
oscmd("otool -L %s | grep .dylib > %s/tmp/otool-libs.txt" % (target, GetOutputDir()), True)
|
||||||
|
|
||||||
for line in open(GetOutputDir() + "/tmp/otool-libs.txt", "r"):
|
for line in open(GetOutputDir() + "/tmp/otool-libs.txt", "r"):
|
||||||
line = line.strip()
|
line = line.strip()
|
||||||
if not line or line.startswith('@loader_path/../lib/') or line.endswith(":"):
|
if not line or line.startswith(dep_prefix) or line.endswith(":"):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
libdep = line.split(" ", 1)[0]
|
libdep = line.split(" ", 1)[0]
|
||||||
dep_basename = os.path.basename(libdep)
|
dep_basename = os.path.basename(libdep)
|
||||||
if dep_basename in dylibs:
|
if dep_basename in dylibs:
|
||||||
oscmd("install_name_tool -change %s @loader_path/../lib/%s %s" % (libdep, dep_basename, target), True)
|
oscmd("install_name_tool -change %s %s%s %s" % (libdep, dep_prefix, dep_basename, target), True)
|
||||||
|
|
||||||
JustBuilt([target], [tp_lib])
|
JustBuilt([target], [tp_lib])
|
||||||
|
|
||||||
for fwx in glob.glob(tp_pkg + "/*.framework"):
|
for fwx in glob.glob(tp_pkg + "/*.framework"):
|
||||||
CopyTree(GetOutputDir() + "/Frameworks/" + os.path.basename(fwx), fwx)
|
CopyTree(GetOutputDir() + "/Frameworks/" + os.path.basename(fwx), fwx)
|
||||||
|
|
||||||
|
else: # Linux / FreeBSD case.
|
||||||
|
for tp_lib in glob.glob(tp_pkg + "/lib/*.so*"):
|
||||||
|
CopyFile(GetOutputDir() + "/lib/" + os.path.basename(tp_lib), tp_lib)
|
||||||
|
|
||||||
|
if not PkgSkip("PYTHON"):
|
||||||
|
for tp_lib in glob.glob(os.path.join(tp_pkg, "lib", SDK["PYTHONVERSION"], "*.so*")):
|
||||||
|
base = os.path.basename(tp_lib)
|
||||||
|
if base.startswith('lib'):
|
||||||
|
CopyFile(GetOutputDir() + "/lib/" + base, tp_lib)
|
||||||
|
else:
|
||||||
|
# It's a Python module, like _rocketcore.so.
|
||||||
|
CopyFile(GetOutputDir() + "/" + base, tp_lib)
|
||||||
|
|
||||||
if GetTarget() == 'windows':
|
if GetTarget() == 'windows':
|
||||||
CopyAllFiles(GetOutputDir() + "/bin/", tp_dir + "extras/bin/")
|
CopyAllFiles(GetOutputDir() + "/bin/", tp_dir + "extras/bin/")
|
||||||
if not PkgSkip("PYTHON"):
|
if not PkgSkip("PYTHON"):
|
||||||
@ -2853,8 +2877,8 @@ if (PkgSkip("PYTHON")==0 and os.path.isdir(GetThirdpartyBase()+"/Pmw")):
|
|||||||
ConditionalWriteFile(GetOutputDir()+'/include/ctl3d.h', '/* dummy file to make MAX happy */')
|
ConditionalWriteFile(GetOutputDir()+'/include/ctl3d.h', '/* dummy file to make MAX happy */')
|
||||||
|
|
||||||
# Since Eigen is included by all sorts of core headers, as a convenience
|
# Since Eigen is included by all sorts of core headers, as a convenience
|
||||||
# to C++ users on Windows, we include it in the Panda include directory.
|
# to C++ users on Win and Mac, we include it in the Panda include directory.
|
||||||
if not PkgSkip("EIGEN") and GetTarget() == "windows" and GetThirdpartyDir():
|
if not PkgSkip("EIGEN") and GetTarget() in ("windows", "darwin") and GetThirdpartyDir():
|
||||||
CopyTree(GetOutputDir()+'/include/Eigen', GetThirdpartyDir()+'eigen/include/Eigen')
|
CopyTree(GetOutputDir()+'/include/Eigen', GetThirdpartyDir()+'eigen/include/Eigen')
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
@ -6799,7 +6823,6 @@ def MakeInstallerOSX():
|
|||||||
if (os.path.exists("Panda3D-rw.dmg")): oscmd('rm -f Panda3D-rw.dmg')
|
if (os.path.exists("Panda3D-rw.dmg")): oscmd('rm -f Panda3D-rw.dmg')
|
||||||
|
|
||||||
oscmd("mkdir -p dstroot/base/Developer/Panda3D/lib")
|
oscmd("mkdir -p dstroot/base/Developer/Panda3D/lib")
|
||||||
oscmd("mkdir -p dstroot/base/Developer/Panda3D/panda3d")
|
|
||||||
oscmd("mkdir -p dstroot/base/Developer/Panda3D/etc")
|
oscmd("mkdir -p dstroot/base/Developer/Panda3D/etc")
|
||||||
oscmd("cp %s/etc/Config.prc dstroot/base/Developer/Panda3D/etc/Config.prc" % GetOutputDir())
|
oscmd("cp %s/etc/Config.prc dstroot/base/Developer/Panda3D/etc/Config.prc" % GetOutputDir())
|
||||||
oscmd("cp %s/etc/Confauto.prc dstroot/base/Developer/Panda3D/etc/Confauto.prc" % GetOutputDir())
|
oscmd("cp %s/etc/Confauto.prc dstroot/base/Developer/Panda3D/etc/Confauto.prc" % GetOutputDir())
|
||||||
@ -6810,43 +6833,42 @@ def MakeInstallerOSX():
|
|||||||
if os.path.isdir(GetOutputDir()+"/plugins"):
|
if os.path.isdir(GetOutputDir()+"/plugins"):
|
||||||
oscmd("cp -R %s/plugins dstroot/base/Developer/Panda3D/plugins" % GetOutputDir())
|
oscmd("cp -R %s/plugins dstroot/base/Developer/Panda3D/plugins" % GetOutputDir())
|
||||||
|
|
||||||
install_libs = []
|
# Libraries that shouldn't be in base, but are instead in other modules.
|
||||||
for base in os.listdir(GetOutputDir()+"/lib"):
|
no_base_libs = ['libp3ffmpeg', 'libp3fmod_audio', 'libfmodex', 'libfmodexL']
|
||||||
if (not base.endswith(".a")):
|
|
||||||
install_libs.append("lib/"+base)
|
|
||||||
for base in os.listdir(GetOutputDir()+"/panda3d"):
|
|
||||||
if (not base.endswith(".a")):
|
|
||||||
install_libs.append("panda3d/"+base)
|
|
||||||
|
|
||||||
for base in install_libs:
|
for base in os.listdir(GetOutputDir()+"/lib"):
|
||||||
libname = "dstroot/base/Developer/Panda3D/" + base
|
if not base.endswith(".a") and base.split('.')[0] not in no_base_libs:
|
||||||
|
libname = "dstroot/base/Developer/Panda3D/lib/" + base
|
||||||
# We really need to specify -R in order not to follow symlinks
|
# We really need to specify -R in order not to follow symlinks
|
||||||
# On OSX, just specifying -P is not enough to do that.
|
# On OSX, just specifying -P is not enough to do that.
|
||||||
oscmd("cp -R -P " + GetOutputDir() + "/" + base + " " + libname)
|
oscmd("cp -R -P " + GetOutputDir() + "/lib/" + base + " " + libname)
|
||||||
|
|
||||||
oscmd("mkdir -p dstroot/tools/Developer/Tools/Panda3D")
|
oscmd("mkdir -p dstroot/tools/Developer/Panda3D/bin")
|
||||||
oscmd("mkdir -p dstroot/tools/Developer/Panda3D")
|
oscmd("mkdir -p dstroot/tools/Developer/Tools")
|
||||||
|
oscmd("ln -s ../Panda3D/bin dstroot/tools/Developer/Tools/Panda3D")
|
||||||
oscmd("mkdir -p dstroot/tools/etc/paths.d")
|
oscmd("mkdir -p dstroot/tools/etc/paths.d")
|
||||||
# Trailing newline is important, works around a bug in OSX
|
# Trailing newline is important, works around a bug in OSX
|
||||||
WriteFile("dstroot/tools/etc/paths.d/Panda3D", "/Developer/Tools/Panda3D\n")
|
WriteFile("dstroot/tools/etc/paths.d/Panda3D", "/Developer/Panda3D/bin\n")
|
||||||
|
|
||||||
oscmd("mkdir -p dstroot/tools/usr/local/share/man/man1")
|
oscmd("mkdir -p dstroot/tools/usr/local/share/man/man1")
|
||||||
oscmd("cp doc/man/*.1 dstroot/tools/usr/local/share/man/man1/")
|
oscmd("cp doc/man/*.1 dstroot/tools/usr/local/share/man/man1/")
|
||||||
|
|
||||||
for base in os.listdir(GetOutputDir()+"/bin"):
|
for base in os.listdir(GetOutputDir()+"/bin"):
|
||||||
binname = "dstroot/tools/Developer/Tools/Panda3D/" + base
|
binname = "dstroot/tools/Developer/Panda3D/bin/" + base
|
||||||
# OSX needs the -R argument to copy symbolic links correctly, it doesn't have -d. How weird.
|
# OSX needs the -R argument to copy symbolic links correctly, it doesn't have -d. How weird.
|
||||||
oscmd("cp -R " + GetOutputDir() + "/bin/" + base + " " + binname)
|
oscmd("cp -R " + GetOutputDir() + "/bin/" + base + " " + binname)
|
||||||
|
|
||||||
if PkgSkip("PYTHON")==0:
|
if PkgSkip("PYTHON")==0:
|
||||||
PV = SDK["PYTHONVERSION"].replace("python", "")
|
PV = SDK["PYTHONVERSION"].replace("python", "")
|
||||||
oscmd("mkdir -p dstroot/pythoncode/usr/local/bin")
|
oscmd("mkdir -p dstroot/pythoncode/usr/local/bin")
|
||||||
oscmd("mkdir -p dstroot/pythoncode/Developer/Panda3D")
|
oscmd("mkdir -p dstroot/pythoncode/Developer/Panda3D/panda3d")
|
||||||
oscmd("mkdir -p dstroot/pythoncode/Library/Python/%s/site-packages" % PV)
|
oscmd("mkdir -p dstroot/pythoncode/Library/Python/%s/site-packages" % PV)
|
||||||
WriteFile("dstroot/pythoncode/Library/Python/%s/site-packages/Panda3D.pth" % PV, "/Developer/Panda3D")
|
WriteFile("dstroot/pythoncode/Library/Python/%s/site-packages/Panda3D.pth" % PV, "/Developer/Panda3D")
|
||||||
oscmd("cp -R %s/pandac dstroot/pythoncode/Developer/Panda3D/pandac" % GetOutputDir())
|
oscmd("cp -R %s/pandac dstroot/pythoncode/Developer/Panda3D/pandac" % GetOutputDir())
|
||||||
oscmd("cp -R %s/direct dstroot/pythoncode/Developer/Panda3D/direct" % GetOutputDir())
|
oscmd("cp -R %s/direct dstroot/pythoncode/Developer/Panda3D/direct" % GetOutputDir())
|
||||||
oscmd("ln -s %s dstroot/pythoncode/usr/local/bin/ppython" % SDK["PYTHONEXEC"])
|
oscmd("ln -s %s dstroot/pythoncode/usr/local/bin/ppython" % SDK["PYTHONEXEC"])
|
||||||
|
oscmd("cp -R %s/*.so dstroot/pythoncode/Developer/Panda3D/" % GetOutputDir())
|
||||||
|
oscmd("cp -R %s/*.py dstroot/pythoncode/Developer/Panda3D/" % GetOutputDir())
|
||||||
if os.path.isdir(GetOutputDir()+"/Pmw"):
|
if os.path.isdir(GetOutputDir()+"/Pmw"):
|
||||||
oscmd("cp -R %s/Pmw dstroot/pythoncode/Developer/Panda3D/Pmw" % GetOutputDir())
|
oscmd("cp -R %s/Pmw dstroot/pythoncode/Developer/Panda3D/Pmw" % GetOutputDir())
|
||||||
compileall.compile_dir("dstroot/pythoncode/Developer/Panda3D/Pmw")
|
compileall.compile_dir("dstroot/pythoncode/Developer/Panda3D/Pmw")
|
||||||
@ -6855,6 +6877,26 @@ def MakeInstallerOSX():
|
|||||||
if ((base != "extensions") and (base != "extensions_native")):
|
if ((base != "extensions") and (base != "extensions_native")):
|
||||||
compileall.compile_dir("dstroot/pythoncode/Developer/Panda3D/direct/"+base)
|
compileall.compile_dir("dstroot/pythoncode/Developer/Panda3D/direct/"+base)
|
||||||
|
|
||||||
|
for base in os.listdir(GetOutputDir()+"/panda3d"):
|
||||||
|
if base.endswith('.py') or base.endswith('.so'):
|
||||||
|
libname = "dstroot/pythoncode/Developer/Panda3D/panda3d/" + base
|
||||||
|
# We really need to specify -R in order not to follow symlinks
|
||||||
|
# On OSX, just specifying -P is not enough to do that.
|
||||||
|
oscmd("cp -R -P " + GetOutputDir() + "/panda3d/" + base + " " + libname)
|
||||||
|
|
||||||
|
if not PkgSkip("FFMPEG"):
|
||||||
|
oscmd("mkdir -p dstroot/ffmpeg/Developer/Panda3D/lib")
|
||||||
|
oscmd("cp -R %s/lib/libp3ffmpeg.* dstroot/ffmpeg/Developer/Panda3D/lib/" % GetOutputDir())
|
||||||
|
|
||||||
|
#if not PkgSkip("OPENAL"):
|
||||||
|
# oscmd("mkdir -p dstroot/openal/Developer/Panda3D/lib")
|
||||||
|
# oscmd("cp -R %s/lib/libp3openal_audio.* dstroot/openal/Developer/Panda3D/lib/" % GetOutputDir())
|
||||||
|
|
||||||
|
if not PkgSkip("FMODEX"):
|
||||||
|
oscmd("mkdir -p dstroot/fmodex/Developer/Panda3D/lib")
|
||||||
|
oscmd("cp -R %s/lib/libp3fmod_audio.* dstroot/fmodex/Developer/Panda3D/lib/" % GetOutputDir())
|
||||||
|
oscmd("cp -R %s/lib/libfmodex* dstroot/fmodex/Developer/Panda3D/lib/" % GetOutputDir())
|
||||||
|
|
||||||
oscmd("mkdir -p dstroot/headers/Developer/Panda3D")
|
oscmd("mkdir -p dstroot/headers/Developer/Panda3D")
|
||||||
oscmd("cp -R %s/include dstroot/headers/Developer/Panda3D/include" % GetOutputDir())
|
oscmd("cp -R %s/include dstroot/headers/Developer/Panda3D/include" % GetOutputDir())
|
||||||
|
|
||||||
@ -6873,7 +6915,10 @@ def MakeInstallerOSX():
|
|||||||
oscmd("mkdir -p dstroot/Panda3D/Panda3D.mpkg/Contents/Resources/en.lproj/")
|
oscmd("mkdir -p dstroot/Panda3D/Panda3D.mpkg/Contents/Resources/en.lproj/")
|
||||||
|
|
||||||
pkgs = ["base", "tools", "headers"]
|
pkgs = ["base", "tools", "headers"]
|
||||||
if PkgSkip("PYTHON")==0: pkgs.append("pythoncode")
|
if not PkgSkip("PYTHON"): pkgs.append("pythoncode")
|
||||||
|
if not PkgSkip("FFMPEG"): pkgs.append("ffmpeg")
|
||||||
|
#if not PkgSkip("OPENAL"): pkgs.append("openal")
|
||||||
|
if not PkgSkip("FMODEX"): pkgs.append("fmodex")
|
||||||
if os.path.isdir("samples"): pkgs.append("samples")
|
if os.path.isdir("samples"): pkgs.append("samples")
|
||||||
for pkg in pkgs:
|
for pkg in pkgs:
|
||||||
identifier = "org.panda3d.panda3d.%s.pkg" % pkg
|
identifier = "org.panda3d.panda3d.%s.pkg" % pkg
|
||||||
@ -6918,38 +6963,51 @@ def MakeInstallerOSX():
|
|||||||
dist.write(' <options customize="always" allow-external-scripts="no" rootVolumeOnly="false"/>\n')
|
dist.write(' <options customize="always" allow-external-scripts="no" rootVolumeOnly="false"/>\n')
|
||||||
dist.write(' <license language="en" mime-type="text/plain">%s</license>\n' % ReadFile("doc/LICENSE"))
|
dist.write(' <license language="en" mime-type="text/plain">%s</license>\n' % ReadFile("doc/LICENSE"))
|
||||||
dist.write(' <choices-outline>\n')
|
dist.write(' <choices-outline>\n')
|
||||||
dist.write(' <line choice="base"/>\n')
|
for pkg in pkgs:
|
||||||
dist.write(' <line choice="tools"/>\n')
|
dist.write(' <line choice="%s"/>\n' % (pkg))
|
||||||
if PkgSkip("PYTHON")==0:
|
|
||||||
dist.write(' <line choice="pythoncode"/>\n')
|
|
||||||
if os.path.isdir("samples"):
|
|
||||||
dist.write(' <line choice="samples"/>\n')
|
|
||||||
dist.write(' <line choice="headers"/>\n')
|
|
||||||
dist.write(' </choices-outline>\n')
|
dist.write(' </choices-outline>\n')
|
||||||
dist.write(' <choice id="base" title="Panda3D Base Installation" description="This package contains the Panda3D libraries, configuration files and models/textures that are needed to use Panda3D. Location: /Developer/Panda3D/" start_enabled="false">\n')
|
dist.write(' <choice id="base" title="Panda3D Base Installation" description="This package contains the Panda3D libraries, configuration files and models/textures that are needed to use Panda3D. Location: /Developer/Panda3D/" start_enabled="false">\n')
|
||||||
dist.write(' <pkg-ref id="org.panda3d.panda3d.base.pkg"/>\n')
|
dist.write(' <pkg-ref id="org.panda3d.panda3d.base.pkg"/>\n')
|
||||||
dist.write(' </choice>\n')
|
dist.write(' </choice>\n')
|
||||||
dist.write(' <choice id="tools" title="Tools" tooltip="Useful tools and model converters to help with Panda3D development" description="This package contains the various utilities that ship with Panda3D, including packaging tools, model converters, and many more. Location: /Developer/Tools/Panda3D/">\n')
|
dist.write(' <choice id="tools" title="Tools" tooltip="Useful tools and model converters to help with Panda3D development" description="This package contains the various utilities that ship with Panda3D, including packaging tools, model converters, and many more. Location: /Developer/Panda3D/bin/">\n')
|
||||||
dist.write(' <pkg-ref id="org.panda3d.panda3d.tools.pkg"/>\n')
|
dist.write(' <pkg-ref id="org.panda3d.panda3d.tools.pkg"/>\n')
|
||||||
dist.write(' </choice>\n')
|
dist.write(' </choice>\n')
|
||||||
if PkgSkip("PYTHON")==0:
|
|
||||||
dist.write(' <choice id="pythoncode" title="Python Code" tooltip="Code you\'ll need for Python development" description="This package contains the \'direct\', \'pandac\' and \'panda3d\' python packages that are needed to do Python development with Panda3D. Location: /Developer/Panda3D/">\n')
|
if not PkgSkip("PYTHON"):
|
||||||
|
dist.write(' <choice id="pythoncode" title="Python Support" tooltip="Python bindings for the Panda3D libraries" description="This package contains the \'direct\', \'pandac\' and \'panda3d\' python packages that are needed to do Python development with Panda3D. Location: /Developer/Panda3D/">\n')
|
||||||
dist.write(' <pkg-ref id="org.panda3d.panda3d.pythoncode.pkg"/>\n')
|
dist.write(' <pkg-ref id="org.panda3d.panda3d.pythoncode.pkg"/>\n')
|
||||||
dist.write(' </choice>\n')
|
dist.write(' </choice>\n')
|
||||||
|
|
||||||
|
if not PkgSkip("FFMPEG"):
|
||||||
|
dist.write(' <choice id="ffmpeg" title="FFMpeg Plug-In" tooltip="FFMpeg video and audio decoding plug-in" description="This package contains the FFMpeg plug-in, which is used for decoding video and audio files with OpenAL.')
|
||||||
|
if PkgSkip("VORBIS"):
|
||||||
|
dist.write(' It is not required for loading .wav files, which Panda3D can read out of the box.">\n')
|
||||||
|
else:
|
||||||
|
dist.write(' It is not required for loading .wav or .ogg files, which Panda3D can read out of the box.">\n')
|
||||||
|
dist.write(' <pkg-ref id="org.panda3d.panda3d.ffmpeg.pkg"/>\n')
|
||||||
|
dist.write(' </choice>\n')
|
||||||
|
|
||||||
|
#if not PkgSkip("OPENAL"):
|
||||||
|
# dist.write(' <choice id="openal" title="OpenAL Audio Plug-In" tooltip="OpenAL audio output plug-in" description="This package contains the OpenAL audio plug-in, which is an open-source library for playing sounds.">\n')
|
||||||
|
# dist.write(' <pkg-ref id="org.panda3d.panda3d.openal.pkg"/>\n')
|
||||||
|
# dist.write(' </choice>\n')
|
||||||
|
|
||||||
|
if not PkgSkip("FMODEX"):
|
||||||
|
dist.write(' <choice id="fmodex" title="FMOD Ex Plug-In" tooltip="FMOD Ex audio output plug-in" description="This package contains the FMOD Ex audio plug-in, which is a commercial library for playing sounds. It is an optional component as Panda3D can use the open-source alternative OpenAL instead.">\n')
|
||||||
|
dist.write(' <pkg-ref id="org.panda3d.panda3d.fmodex.pkg"/>\n')
|
||||||
|
dist.write(' </choice>\n')
|
||||||
|
|
||||||
if os.path.isdir("samples"):
|
if os.path.isdir("samples"):
|
||||||
dist.write(' <choice id="samples" title="Sample Programs" tooltip="Python sample programs that use Panda3D" description="This package contains the Python sample programs that can help you with learning how to use Panda3D. Location: /Developer/Examples/Panda3D/">\n')
|
dist.write(' <choice id="samples" title="Sample Programs" tooltip="Python sample programs that use Panda3D" description="This package contains the Python sample programs that can help you with learning how to use Panda3D. Location: /Developer/Examples/Panda3D/">\n')
|
||||||
dist.write(' <pkg-ref id="org.panda3d.panda3d.samples.pkg"/>\n')
|
dist.write(' <pkg-ref id="org.panda3d.panda3d.samples.pkg"/>\n')
|
||||||
dist.write(' </choice>\n')
|
dist.write(' </choice>\n')
|
||||||
|
|
||||||
dist.write(' <choice id="headers" title="C++ Header Files" tooltip="Header files for C++ development with Panda3D" description="This package contains the C++ header files that are needed in order to do C++ development with Panda3D. You don\'t need this if you want to develop in Python. Location: /Developer/Panda3D/include/" start_selected="false">\n')
|
dist.write(' <choice id="headers" title="C++ Header Files" tooltip="Header files for C++ development with Panda3D" description="This package contains the C++ header files that are needed in order to do C++ development with Panda3D. You don\'t need this if you want to develop in Python. Location: /Developer/Panda3D/include/" start_selected="false">\n')
|
||||||
dist.write(' <pkg-ref id="org.panda3d.panda3d.headers.pkg"/>\n')
|
dist.write(' <pkg-ref id="org.panda3d.panda3d.headers.pkg"/>\n')
|
||||||
dist.write(' </choice>\n')
|
dist.write(' </choice>\n')
|
||||||
dist.write(' <pkg-ref id="org.panda3d.panda3d.base.pkg" installKBytes="%d" version="1" auth="Root">file:./Contents/Packages/base.pkg</pkg-ref>\n' % (GetDirectorySize("dstroot/base") // 1024))
|
for pkg in pkgs:
|
||||||
dist.write(' <pkg-ref id="org.panda3d.panda3d.tools.pkg" installKBytes="%d" version="1" auth="Root">file:./Contents/Packages/tools.pkg</pkg-ref>\n' % (GetDirectorySize("dstroot/tools") // 1024))
|
size = GetDirectorySize("dstroot/" + pkg) // 1024
|
||||||
if PkgSkip("PYTHON")==0:
|
dist.write(' <pkg-ref id="org.panda3d.panda3d.%s.pkg" installKBytes="%d" version="1" auth="Root">file:./Contents/Packages/%s.pkg</pkg-ref>\n' % (pkg, size, pkg))
|
||||||
dist.write(' <pkg-ref id="org.panda3d.panda3d.pythoncode.pkg" installKBytes="%d" version="1" auth="Root">file:./Contents/Packages/pythoncode.pkg</pkg-ref>\n' % (GetDirectorySize("dstroot/pythoncode") // 1024))
|
|
||||||
if os.path.isdir("samples"):
|
|
||||||
dist.write(' <pkg-ref id="org.panda3d.panda3d.samples.pkg" installKBytes="%d" version="1" auth="Root">file:./Contents/Packages/samples.pkg</pkg-ref>\n' % (GetDirectorySize("dstroot/samples") // 1024))
|
|
||||||
dist.write(' <pkg-ref id="org.panda3d.panda3d.headers.pkg" installKBytes="%d" version="1" auth="Root">file:./Contents/Packages/headers.pkg</pkg-ref>\n' % (GetDirectorySize("dstroot/headers") // 1024))
|
|
||||||
dist.write('</installer-script>\n')
|
dist.write('</installer-script>\n')
|
||||||
dist.close()
|
dist.close()
|
||||||
|
|
||||||
|
@ -2546,6 +2546,10 @@ def SetupBuildEnvironment(compiler):
|
|||||||
dyldpath.insert(0, os.path.join(builtdir, 'lib'))
|
dyldpath.insert(0, os.path.join(builtdir, 'lib'))
|
||||||
os.environ["DYLD_LIBRARY_PATH"] = os.pathsep.join(dyldpath)
|
os.environ["DYLD_LIBRARY_PATH"] = os.pathsep.join(dyldpath)
|
||||||
|
|
||||||
|
# OS X 10.11 removed DYLD_LIBRARY_PATH, but we still need to pass
|
||||||
|
# on our lib directory to ppackage, so add it to PATH instead.
|
||||||
|
os.environ["PATH"] = os.path.join(builtdir, 'lib') + ':' + os.environ.get("PATH", "")
|
||||||
|
|
||||||
# Workaround around compile issue on PCBSD
|
# Workaround around compile issue on PCBSD
|
||||||
if (os.path.exists("/usr/PCBSD")):
|
if (os.path.exists("/usr/PCBSD")):
|
||||||
os.environ["LD_LIBRARY_PATH"] += os.pathsep + "/usr/PCBSD/local/lib"
|
os.environ["LD_LIBRARY_PATH"] += os.pathsep + "/usr/PCBSD/local/lib"
|
||||||
@ -2563,8 +2567,12 @@ def CopyFile(dstfile, srcfile):
|
|||||||
if NeedsBuild([dstfile], [srcfile]):
|
if NeedsBuild([dstfile], [srcfile]):
|
||||||
if os.path.islink(srcfile):
|
if os.path.islink(srcfile):
|
||||||
# Preserve symlinks
|
# Preserve symlinks
|
||||||
if os.path.exists(dstfile):
|
if os.path.isfile(dstfile) or os.path.islink(dstfile):
|
||||||
|
print("Removing file %s" % (dstfile))
|
||||||
os.unlink(dstfile)
|
os.unlink(dstfile)
|
||||||
|
elif os.path.isdir(dstfile):
|
||||||
|
print("Removing directory %s" % (dstfile))
|
||||||
|
shutil.rmtree(dstfile)
|
||||||
os.symlink(os.readlink(srcfile), dstfile)
|
os.symlink(os.readlink(srcfile), dstfile)
|
||||||
else:
|
else:
|
||||||
WriteBinaryFile(dstfile, ReadBinaryFile(srcfile))
|
WriteBinaryFile(dstfile, ReadBinaryFile(srcfile))
|
||||||
@ -2595,24 +2603,37 @@ def CopyAllJavaSources(dir, skip=[]):
|
|||||||
JustBuilt([dstfile], [srcfile])
|
JustBuilt([dstfile], [srcfile])
|
||||||
|
|
||||||
def CopyTree(dstdir, srcdir, omitVCS=True):
|
def CopyTree(dstdir, srcdir, omitVCS=True):
|
||||||
if (os.path.isdir(dstdir)):
|
if os.path.isdir(dstdir):
|
||||||
for entry in os.listdir(srcdir):
|
source_entries = os.listdir(srcdir)
|
||||||
|
for entry in source_entries:
|
||||||
srcpth = os.path.join(srcdir, entry)
|
srcpth = os.path.join(srcdir, entry)
|
||||||
dstpth = os.path.join(dstdir, entry)
|
dstpth = os.path.join(dstdir, entry)
|
||||||
if (os.path.isfile(srcpth)):
|
|
||||||
|
if os.path.islink(srcpth) or os.path.isfile(srcpth):
|
||||||
if not omitVCS or entry not in VCS_FILES:
|
if not omitVCS or entry not in VCS_FILES:
|
||||||
CopyFile(dstpth, srcpth)
|
CopyFile(dstpth, srcpth)
|
||||||
else:
|
else:
|
||||||
if not omitVCS or entry not in VCS_DIRS:
|
if not omitVCS or entry not in VCS_DIRS:
|
||||||
CopyTree(dstpth, srcpth)
|
CopyTree(dstpth, srcpth)
|
||||||
|
|
||||||
|
# Delete files in dstdir that are not in srcdir.
|
||||||
|
for entry in os.listdir(dstdir):
|
||||||
|
if entry not in source_entries:
|
||||||
|
path = os.path.join(dstdir, entry)
|
||||||
|
if os.path.islink(path) or os.path.isfile(path):
|
||||||
|
os.remove(path)
|
||||||
|
elif os.path.isdir(path):
|
||||||
|
shutil.rmtree(path)
|
||||||
else:
|
else:
|
||||||
if GetHost() == 'windows':
|
if GetHost() == 'windows':
|
||||||
srcdir = srcdir.replace('/', '\\')
|
srcdir = srcdir.replace('/', '\\')
|
||||||
dstdir = dstdir.replace('/', '\\')
|
dstdir = dstdir.replace('/', '\\')
|
||||||
cmd = 'xcopy /I/Y/E/Q "' + srcdir + '" "' + dstdir + '"'
|
cmd = 'xcopy /I/Y/E/Q "' + srcdir + '" "' + dstdir + '"'
|
||||||
else:
|
|
||||||
cmd = 'cp -R -f ' + srcdir + ' ' + dstdir
|
|
||||||
oscmd(cmd)
|
oscmd(cmd)
|
||||||
|
else:
|
||||||
|
if subprocess.call(['cp', '-R', '-f', srcdir, dstdir]) != 0:
|
||||||
|
exit("Copy failed.")
|
||||||
|
|
||||||
if omitVCS:
|
if omitVCS:
|
||||||
DeleteVCS(dstdir)
|
DeleteVCS(dstdir)
|
||||||
|
|
||||||
|
@ -27,6 +27,12 @@ ConfigureFn(config_openalAudio) {
|
|||||||
init_libOpenALAudio();
|
init_libOpenALAudio();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ConfigVariableString openal_device
|
||||||
|
("openal-device", "",
|
||||||
|
PRC_DESC("Specify the OpenAL device string for audio playback (no quotes). If this "
|
||||||
|
"is not specified, the OpenAL default device is used."));
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: init_libOpenALAudio
|
// Function: init_libOpenALAudio
|
||||||
// Description: Initializes the library. This must be called at
|
// Description: Initializes the library. This must be called at
|
||||||
|
@ -27,4 +27,6 @@ NotifyCategoryDecl(openalAudio, EXPCL_OPENAL_AUDIO, EXPTP_OPENAL_AUDIO);
|
|||||||
extern EXPCL_OPENAL_AUDIO void init_libOpenALAudio();
|
extern EXPCL_OPENAL_AUDIO void init_libOpenALAudio();
|
||||||
extern "C" EXPCL_OPENAL_AUDIO Create_AudioManager_proc *get_audio_manager_func_openal_audio();
|
extern "C" EXPCL_OPENAL_AUDIO Create_AudioManager_proc *get_audio_manager_func_openal_audio();
|
||||||
|
|
||||||
|
extern ConfigVariableString openal_device;
|
||||||
|
|
||||||
#endif // CONFIG_OPENALAUDIO_H
|
#endif // CONFIG_OPENALAUDIO_H
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "config_audio.h"
|
#include "config_audio.h"
|
||||||
#include "config_util.h"
|
#include "config_util.h"
|
||||||
#include "config_express.h"
|
#include "config_express.h"
|
||||||
|
#include "config_openalAudio.h"
|
||||||
#include "openalAudioManager.h"
|
#include "openalAudioManager.h"
|
||||||
#include "openalAudioSound.h"
|
#include "openalAudioSound.h"
|
||||||
#include "virtualFileSystem.h"
|
#include "virtualFileSystem.h"
|
||||||
@ -27,6 +28,14 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
#ifndef ALC_DEFAULT_ALL_DEVICES_SPECIFIER
|
||||||
|
#define ALC_DEFAULT_ALL_DEVICES_SPECIFIER 0x1012
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ALC_ALL_DEVICES_SPECIFIER
|
||||||
|
#define ALC_ALL_DEVICES_SPECIFIER 0x1013
|
||||||
|
#endif
|
||||||
|
|
||||||
TypeHandle OpenALAudioManager::_type_handle;
|
TypeHandle OpenALAudioManager::_type_handle;
|
||||||
|
|
||||||
ReMutex OpenALAudioManager::_lock;
|
ReMutex OpenALAudioManager::_lock;
|
||||||
@ -116,12 +125,41 @@ OpenALAudioManager() {
|
|||||||
_forward_up[5] = 0;
|
_forward_up[5] = 0;
|
||||||
|
|
||||||
// Initialization
|
// Initialization
|
||||||
|
audio_cat.init();
|
||||||
if (_active_managers == 0 || !_openal_active) {
|
if (_active_managers == 0 || !_openal_active) {
|
||||||
_device = alcOpenDevice(NULL); // select the "preferred device"
|
_device = NULL;
|
||||||
if (!_device) {
|
string dev_name = select_audio_device();
|
||||||
// this is a unique kind of error
|
|
||||||
audio_error("OpenALAudioManager: alcOpenDevice(NULL): ALC couldn't open device");
|
if (!dev_name.empty()) {
|
||||||
|
// Open a specific device by name.
|
||||||
|
audio_cat.info() << "Using OpenAL device " << dev_name << "\n";
|
||||||
|
_device = alcOpenDevice(dev_name.c_str());
|
||||||
|
|
||||||
|
if (_device == NULL) {
|
||||||
|
audio_cat.error()
|
||||||
|
<< "Couldn't open OpenAL device \"" << dev_name << "\", falling back to default device\n";
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
audio_cat.info() << "Using default OpenAL device\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_device == NULL) {
|
||||||
|
// Open the default device.
|
||||||
|
_device = alcOpenDevice(NULL);
|
||||||
|
|
||||||
|
if (_device == NULL && dev_name != "OpenAL Soft") {
|
||||||
|
// Try the OpenAL Soft driver instead, which is fairly reliable.
|
||||||
|
_device = alcOpenDevice("OpenAL Soft");
|
||||||
|
|
||||||
|
if (_device == NULL) {
|
||||||
|
audio_cat.error()
|
||||||
|
<< "Couldn't open default OpenAL device\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_device != NULL) {
|
||||||
|
// We managed to get a device open.
|
||||||
alcGetError(_device); // clear errors
|
alcGetError(_device); // clear errors
|
||||||
_context = alcCreateContext(_device, NULL);
|
_context = alcCreateContext(_device, NULL);
|
||||||
alc_audio_errcheck("alcCreateContext(_device, NULL)", _device);
|
alc_audio_errcheck("alcCreateContext(_device, NULL)", _device);
|
||||||
@ -130,6 +168,7 @@ OpenALAudioManager() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We increment _active_managers regardless of possible errors above.
|
// We increment _active_managers regardless of possible errors above.
|
||||||
// The shutdown call will do the right thing when it's called,
|
// The shutdown call will do the right thing when it's called,
|
||||||
// either way.
|
// either way.
|
||||||
@ -150,15 +189,15 @@ OpenALAudioManager() {
|
|||||||
audio_3d_set_drop_off_factor(audio_drop_off_factor);
|
audio_3d_set_drop_off_factor(audio_drop_off_factor);
|
||||||
|
|
||||||
if (audio_cat.is_debug()) {
|
if (audio_cat.is_debug()) {
|
||||||
audio_cat->debug()
|
audio_cat.debug()
|
||||||
<< "ALC_DEVICE_SPECIFIER:" << alcGetString(_device, ALC_DEVICE_SPECIFIER) << endl;
|
<< "ALC_DEVICE_SPECIFIER:" << alcGetString(_device, ALC_DEVICE_SPECIFIER) << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (audio_cat.is_debug()) {
|
if (audio_cat.is_debug()) {
|
||||||
audio_cat->debug() << "AL_RENDERER:" << alGetString(AL_RENDERER) << endl;
|
audio_cat.debug() << "AL_RENDERER:" << alGetString(AL_RENDERER) << endl;
|
||||||
audio_cat->debug() << "AL_VENDOR:" << alGetString(AL_VENDOR) << endl;
|
audio_cat.debug() << "AL_VENDOR:" << alGetString(AL_VENDOR) << endl;
|
||||||
audio_cat->debug() << "AL_VERSION:" << alGetString(AL_VERSION) << endl;
|
audio_cat.debug() << "AL_VERSION:" << alGetString(AL_VERSION) << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,6 +251,82 @@ is_valid() {
|
|||||||
return _is_valid;
|
return _is_valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: OpenALAudioManager::select_audio_device
|
||||||
|
// Access: Private
|
||||||
|
// Description: Enumerate the audio devices, selecting the one that
|
||||||
|
// is most appropriate or has been selected by the user.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
string OpenALAudioManager::
|
||||||
|
select_audio_device() {
|
||||||
|
string selected_device = openal_device;
|
||||||
|
|
||||||
|
const char *devices = NULL;
|
||||||
|
|
||||||
|
// This extension gives us all audio paths on all drivers.
|
||||||
|
if (alcIsExtensionPresent(NULL, "ALC_ENUMERATE_ALL_EXT") == AL_TRUE) {
|
||||||
|
string default_device = alcGetString(NULL, ALC_DEFAULT_ALL_DEVICES_SPECIFIER);
|
||||||
|
devices = (const char *)alcGetString(NULL, ALC_ALL_DEVICES_SPECIFIER);
|
||||||
|
|
||||||
|
if (devices) {
|
||||||
|
audio_cat.debug() << "All OpenAL devices:\n";
|
||||||
|
|
||||||
|
while (*devices) {
|
||||||
|
string device(devices);
|
||||||
|
devices += device.size() + 1;
|
||||||
|
|
||||||
|
if (audio_cat.is_debug()) {
|
||||||
|
if (device == selected_device) {
|
||||||
|
audio_cat.debug() << " " << device << " [selected]\n";
|
||||||
|
} else if (device == default_device) {
|
||||||
|
audio_cat.debug() << " " << device << " [default]\n";
|
||||||
|
} else {
|
||||||
|
audio_cat.debug() << " " << device << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
audio_cat.debug() << "ALC_ENUMERATE_ALL_EXT not supported\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
// This extension just gives us generic driver names, like "OpenAL Soft"
|
||||||
|
// and "Generic Software", rather than individual outputs.
|
||||||
|
if (alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT") == AL_TRUE) {
|
||||||
|
string default_device = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
|
||||||
|
devices = (const char *)alcGetString(NULL, ALC_DEVICE_SPECIFIER);
|
||||||
|
|
||||||
|
if (devices) {
|
||||||
|
audio_cat.debug() << "OpenAL drivers:\n";
|
||||||
|
|
||||||
|
while (*devices) {
|
||||||
|
string device(devices);
|
||||||
|
devices += device.size() + 1;
|
||||||
|
|
||||||
|
if (selected_device.empty() && device == "OpenAL Soft" &&
|
||||||
|
default_device == "Generic Software") {
|
||||||
|
// Prefer OpenAL Soft over the buggy Generic Software driver.
|
||||||
|
selected_device = "OpenAL Soft";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (audio_cat.is_debug()) {
|
||||||
|
if (device == selected_device) {
|
||||||
|
audio_cat.debug() << " " << device << " [selected]\n";
|
||||||
|
} else if (device == default_device) {
|
||||||
|
audio_cat.debug() << " " << device << " [default]\n";
|
||||||
|
} else {
|
||||||
|
audio_cat.debug() << " " << device << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
audio_cat.debug() << "ALC_ENUMERATION_EXT not supported\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
return selected_device;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: OpenALAudioManager::make_current
|
// Function: OpenALAudioManager::make_current
|
||||||
// Access: Private
|
// Access: Private
|
||||||
|
@ -116,6 +116,8 @@ class EXPCL_OPENAL_AUDIO OpenALAudioManager : public AudioManager {
|
|||||||
virtual void update();
|
virtual void update();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
string select_audio_device();
|
||||||
|
|
||||||
void make_current() const;
|
void make_current() const;
|
||||||
|
|
||||||
bool can_use_audio(MovieAudioCursor *source);
|
bool can_use_audio(MovieAudioCursor *source);
|
||||||
|
@ -177,7 +177,7 @@ set_stop_erp(const LVecBase3 &erp) {
|
|||||||
INLINE int BulletTranslationalLimitMotor::
|
INLINE int BulletTranslationalLimitMotor::
|
||||||
get_current_limit(int axis) const {
|
get_current_limit(int axis) const {
|
||||||
|
|
||||||
nassertr((0 <- axis) && (axis <=2), false);
|
nassertr((0 <= axis) && (axis <= 2), false);
|
||||||
return _motor.m_currentLimit[axis];
|
return _motor.m_currentLimit[axis];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -798,16 +798,20 @@ set_properties_now(WindowProperties &properties) {
|
|||||||
int height = properties.get_y_size();
|
int height = properties.get_y_size();
|
||||||
|
|
||||||
if (!_properties.get_fullscreen()) {
|
if (!_properties.get_fullscreen()) {
|
||||||
_properties.set_size(width, height);
|
|
||||||
if (_window != nil) {
|
if (_window != nil) {
|
||||||
[_window setContentSize:NSMakeSize(width, height)];
|
[_window setContentSize:NSMakeSize(width, height)];
|
||||||
}
|
}
|
||||||
[_view setFrameSize:NSMakeSize(width, height)];
|
[_view setFrameSize:NSMakeSize(width, height)];
|
||||||
|
|
||||||
|
if (cocoadisplay_cat.is_debug()) {
|
||||||
cocoadisplay_cat.debug()
|
cocoadisplay_cat.debug()
|
||||||
<< "Setting size to " << width << ", " << height << "\n";
|
<< "Setting size to " << width << ", " << height << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
_context_needs_update = true;
|
// Cocoa doesn't send an event, and the other
|
||||||
|
// resize-window handlers will do nothing once the properties
|
||||||
|
// have been changed, so do this now
|
||||||
|
handle_resize_event();
|
||||||
properties.clear_size();
|
properties.clear_size();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -1022,6 +1026,23 @@ set_properties_now(WindowProperties &properties) {
|
|||||||
}
|
}
|
||||||
properties.clear_z_order();
|
properties.clear_z_order();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (properties.has_mouse_mode()) {
|
||||||
|
switch (properties.get_mouse_mode()) {
|
||||||
|
case WindowProperties::M_absolute:
|
||||||
|
case WindowProperties::M_confined: // confined is maintained in mouse move event
|
||||||
|
CGAssociateMouseAndMouseCursorPosition(true);
|
||||||
|
_properties.set_mouse_mode(properties.get_mouse_mode());
|
||||||
|
properties.clear_mouse_mode();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WindowProperties::M_relative:
|
||||||
|
CGAssociateMouseAndMouseCursorPosition(false);
|
||||||
|
_properties.set_mouse_mode(properties.get_mouse_mode());
|
||||||
|
properties.clear_mouse_mode();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -1670,6 +1691,8 @@ handle_mouse_button_event(int button, bool down) {
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void CocoaGraphicsWindow::
|
void CocoaGraphicsWindow::
|
||||||
handle_mouse_moved_event(bool in_window, double x, double y, bool absolute) {
|
handle_mouse_moved_event(bool in_window, double x, double y, bool absolute) {
|
||||||
|
double nx, ny;
|
||||||
|
|
||||||
if (absolute) {
|
if (absolute) {
|
||||||
if (cocoadisplay_cat.is_spam()) {
|
if (cocoadisplay_cat.is_spam()) {
|
||||||
if (in_window != _input_devices[0].get_pointer().get_in_window()) {
|
if (in_window != _input_devices[0].get_pointer().get_in_window()) {
|
||||||
@ -1682,15 +1705,40 @@ handle_mouse_moved_event(bool in_window, double x, double y, bool absolute) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Strangely enough, in Cocoa, mouse Y coordinates are 1-based.
|
// Strangely enough, in Cocoa, mouse Y coordinates are 1-based.
|
||||||
_input_devices[0].set_pointer(in_window, x, y - 1,
|
nx = x;
|
||||||
ClockObject::get_global_clock()->get_frame_time());
|
ny = y - 1;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// We received deltas, so add it to the current mouse position.
|
// We received deltas, so add it to the current mouse position.
|
||||||
MouseData md = _input_devices[0].get_pointer();
|
MouseData md = _input_devices[0].get_pointer();
|
||||||
_input_devices[0].set_pointer_in_window(md.get_x() + x, md.get_y() + y);
|
nx = md.get_x() + x;
|
||||||
|
ny = md.get_y() + y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_properties.get_mouse_mode() == WindowProperties::M_confined
|
||||||
|
&& !in_window) {
|
||||||
|
CGPoint point;
|
||||||
|
|
||||||
|
nx = std::max(0., std::min((double) get_x_size() - 1, nx));
|
||||||
|
ny = std::max(0., std::min((double) get_y_size() - 1, ny));
|
||||||
|
|
||||||
|
if (_properties.get_fullscreen()) {
|
||||||
|
point = CGPointMake(nx, ny + 1);
|
||||||
|
} else {
|
||||||
|
point = CGPointMake(nx + _properties.get_x_origin(),
|
||||||
|
ny + _properties.get_y_origin() + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CGWarpMouseCursorPosition(point) == kCGErrorSuccess) {
|
||||||
|
in_window = true;
|
||||||
|
} else {
|
||||||
|
cocoadisplay_cat.warning() << "Failed to return mouse pointer to window\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_input_devices[0].set_pointer(in_window, nx, ny,
|
||||||
|
ClockObject::get_global_clock()->get_frame_time());
|
||||||
|
|
||||||
if (in_window != _mouse_hidden && _properties.get_cursor_hidden()) {
|
if (in_window != _mouse_hidden && _properties.get_cursor_hidden()) {
|
||||||
// Hide the cursor if the mouse enters the window,
|
// Hide the cursor if the mouse enters the window,
|
||||||
// and unhide it when the mouse leaves the window.
|
// and unhide it when the mouse leaves the window.
|
||||||
|
@ -45,9 +45,11 @@
|
|||||||
- (void) drawRect:(NSRect)dirtyRect {
|
- (void) drawRect:(NSRect)dirtyRect {
|
||||||
// Do nothing. We draw from another thread.
|
// Do nothing. We draw from another thread.
|
||||||
|
|
||||||
|
if (cocoadisplay_cat.is_spam()) {
|
||||||
cocoadisplay_cat.spam()
|
cocoadisplay_cat.spam()
|
||||||
<< "drawRect was called.\n";
|
<< "drawRect was called.\n";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (void) finalize {
|
- (void) finalize {
|
||||||
_graphicsWindow->handle_close_event();
|
_graphicsWindow->handle_close_event();
|
||||||
@ -116,7 +118,10 @@
|
|||||||
NSPoint loc = [self convertPoint:[event locationInWindow] fromView:nil];
|
NSPoint loc = [self convertPoint:[event locationInWindow] fromView:nil];
|
||||||
BOOL inside = [self mouse:loc inRect:[self bounds]];
|
BOOL inside = [self mouse:loc inRect:[self bounds]];
|
||||||
|
|
||||||
if (_graphicsWindow->get_properties().get_mouse_mode() == WindowProperties::M_relative) {
|
// the correlation between mouse deltas and location
|
||||||
|
// are "debounced" apparently, so send deltas for both
|
||||||
|
// relative and confined modes
|
||||||
|
if (_graphicsWindow->get_properties().get_mouse_mode() != WindowProperties::M_absolute) {
|
||||||
_graphicsWindow->handle_mouse_moved_event(inside, [event deltaX], [event deltaY], false);
|
_graphicsWindow->handle_mouse_moved_event(inside, [event deltaX], [event deltaY], false);
|
||||||
} else {
|
} else {
|
||||||
_graphicsWindow->handle_mouse_moved_event(inside, loc.x, loc.y, true);
|
_graphicsWindow->handle_mouse_moved_event(inside, loc.x, loc.y, true);
|
||||||
|
@ -2064,6 +2064,25 @@ set_properties_now(WindowProperties &properties) {
|
|||||||
properties.clear_minimized();
|
properties.clear_minimized();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (properties.has_mouse_mode()) {
|
||||||
|
switch (properties.get_mouse_mode()) {
|
||||||
|
case WindowProperties::M_absolute:
|
||||||
|
CGAssociateMouseAndMouseCursorPosition(true);
|
||||||
|
_properties.set_mouse_mode(WindowProperties::M_absolute);
|
||||||
|
properties.clear_mouse_mode();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WindowProperties::M_relative:
|
||||||
|
CGAssociateMouseAndMouseCursorPosition(false);
|
||||||
|
_properties.set_mouse_mode(WindowProperties::M_relative);
|
||||||
|
properties.clear_mouse_mode();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WindowProperties::M_confined:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (osxdisplay_cat.is_debug()) {
|
if (osxdisplay_cat.is_debug()) {
|
||||||
osxdisplay_cat.debug()
|
osxdisplay_cat.debug()
|
||||||
<< "set_properties_now Out....." << _properties << "\n";
|
<< "set_properties_now Out....." << _properties << "\n";
|
||||||
|
@ -53,6 +53,10 @@ init_librocket() {
|
|||||||
RocketInputHandler::init_type();
|
RocketInputHandler::init_type();
|
||||||
RocketRegion::init_type();
|
RocketRegion::init_type();
|
||||||
|
|
||||||
|
if (rocket_cat->is_debug()) {
|
||||||
|
rocket_cat->debug() << "Initializing libRocket library.\n";
|
||||||
|
}
|
||||||
|
|
||||||
RocketFileInterface* fi = new RocketFileInterface;
|
RocketFileInterface* fi = new RocketFileInterface;
|
||||||
Rocket::Core::SetFileInterface(fi);
|
Rocket::Core::SetFileInterface(fi);
|
||||||
|
|
||||||
@ -61,6 +65,10 @@ init_librocket() {
|
|||||||
|
|
||||||
Rocket::Core::Initialise();
|
Rocket::Core::Initialise();
|
||||||
|
|
||||||
|
// Register that we have the libRocket system.
|
||||||
|
PandaSystem *ps = PandaSystem::get_global_ptr();
|
||||||
|
ps->add_system("libRocket");
|
||||||
|
|
||||||
#ifdef COMPILE_IN_DEFAULT_FONT
|
#ifdef COMPILE_IN_DEFAULT_FONT
|
||||||
#ifdef HAVE_FREETYPE
|
#ifdef HAVE_FREETYPE
|
||||||
// Load Panda's default compiled-in freetype font (Perspective Sans).
|
// Load Panda's default compiled-in freetype font (Perspective Sans).
|
||||||
|
18
samples/mouse-modes/main.py
Normal file → Executable file
18
samples/mouse-modes/main.py
Normal file → Executable file
@ -34,7 +34,8 @@ class App(ShowBase):
|
|||||||
# Disable the camera trackball controls.
|
# Disable the camera trackball controls.
|
||||||
self.disableMouse()
|
self.disableMouse()
|
||||||
|
|
||||||
self.mouseMagnitude = 144
|
# control mapping of mouse movement to box movement
|
||||||
|
self.mouseMagnitude = 1
|
||||||
|
|
||||||
self.rotateX, self.rotateY = 0, 0
|
self.rotateX, self.rotateY = 0, 0
|
||||||
|
|
||||||
@ -66,7 +67,7 @@ class App(ShowBase):
|
|||||||
self.manualRecenterMouse = True
|
self.manualRecenterMouse = True
|
||||||
|
|
||||||
# make a box to move with the mouse
|
# make a box to move with the mouse
|
||||||
self.model = self.loader.loadModel("box.egg")
|
self.model = self.loader.loadModel("box")
|
||||||
self.model.reparentTo(self.render)
|
self.model.reparentTo(self.render)
|
||||||
|
|
||||||
self.cam.setPos(0, -5, 0)
|
self.cam.setPos(0, -5, 0)
|
||||||
@ -75,7 +76,7 @@ class App(ShowBase):
|
|||||||
self.mouseTask = taskMgr.add(self.mouseTask, "Mouse Task")
|
self.mouseTask = taskMgr.add(self.mouseTask, "Mouse Task")
|
||||||
|
|
||||||
def setMouseMode(self, mode):
|
def setMouseMode(self, mode):
|
||||||
print "Changing mode to",mode
|
print("Changing mode to %s" % mode)
|
||||||
|
|
||||||
self.mouseMode = mode
|
self.mouseMode = mode
|
||||||
|
|
||||||
@ -91,7 +92,7 @@ class App(ShowBase):
|
|||||||
|
|
||||||
actualMode = wp.getMouseMode()
|
actualMode = wp.getMouseMode()
|
||||||
if self.mouseMode != actualMode:
|
if self.mouseMode != actualMode:
|
||||||
print "ACTUAL MOUSE MODE:", actualMode
|
print("ACTUAL MOUSE MODE: %s" % actualMode)
|
||||||
|
|
||||||
self.mouseMode = actualMode
|
self.mouseMode = actualMode
|
||||||
|
|
||||||
@ -106,11 +107,11 @@ class App(ShowBase):
|
|||||||
|
|
||||||
|
|
||||||
def toggleRecenter(self):
|
def toggleRecenter(self):
|
||||||
print "Toggling re-center behavior"
|
print("Toggling re-center behavior")
|
||||||
self.manualRecenterMouse = not self.manualRecenterMouse
|
self.manualRecenterMouse = not self.manualRecenterMouse
|
||||||
|
|
||||||
def toggleMouse(self):
|
def toggleMouse(self):
|
||||||
print "Toggling mouse visibility"
|
print("Toggling mouse visibility")
|
||||||
|
|
||||||
self.hideMouse = not self.hideMouse
|
self.hideMouse = not self.hideMouse
|
||||||
|
|
||||||
@ -146,6 +147,7 @@ class App(ShowBase):
|
|||||||
if self.manualRecenterMouse:
|
if self.manualRecenterMouse:
|
||||||
# move mouse back to center
|
# move mouse back to center
|
||||||
self.recenterMouse()
|
self.recenterMouse()
|
||||||
|
self.lastMouseX, self.lastMouseY = 0, 0
|
||||||
|
|
||||||
# scale position and delta to pixels for user
|
# scale position and delta to pixels for user
|
||||||
w, h = self.win.getSize()
|
w, h = self.win.getSize()
|
||||||
@ -158,8 +160,8 @@ class App(ShowBase):
|
|||||||
int(dx*w), int(dy*h)))
|
int(dx*w), int(dy*h)))
|
||||||
|
|
||||||
# rotate box by delta
|
# rotate box by delta
|
||||||
self.rotateX += dx * 10
|
self.rotateX += dx * 10 * self.mouseMagnitude
|
||||||
self.rotateY += dy * 10
|
self.rotateY += dy * 10 * self.mouseMagnitude
|
||||||
|
|
||||||
self.positionText.setText("Model rotation: {0}, {1}".format(
|
self.positionText.setText("Model rotation: {0}, {1}".format(
|
||||||
int(self.rotateX*1000)/1000., int(self.rotateY*1000)/1000.))
|
int(self.rotateX*1000)/1000., int(self.rotateY*1000)/1000.))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user