diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 5e47c93130..3316aa91bb 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,6 +1,351 @@
name: Continuous Integration
on: [push, pull_request]
+
jobs:
+ cmake:
+ name: CMake Buildsystem
+
+ strategy:
+ fail-fast: false
+
+ matrix:
+ profile:
+ - ubuntu-xenial-standard-unity-makefile
+ - ubuntu-bionic-coverage-ninja
+ - macos-eigen-coverage-unity-xcode
+ - macos-nometa-standard-makefile
+# - windows-standard-unity-msvc # FIXME when GH Actions runners upgrade CMake to >=3.16.1
+ - windows-nopython-nometa-standard-msvc
+
+ include:
+ - profile: ubuntu-xenial-standard-unity-makefile
+ os: ubuntu-16.04
+ config: Standard
+ unity: YES
+ generator: Unix Makefiles
+ compiler: Default
+ metalibs: YES
+ python: YES
+ eigen: NO
+
+ - profile: ubuntu-bionic-coverage-ninja
+ os: ubuntu-18.04
+ config: Coverage
+ unity: NO
+ generator: Ninja
+ compiler: Clang
+ metalibs: YES
+ python: YES
+ eigen: NO
+
+ - profile: macos-eigen-coverage-unity-xcode
+ os: macOS-latest
+ config: Coverage
+ unity: YES
+ generator: Xcode
+ compiler: Default
+ metalibs: YES
+ python: YES
+ eigen: YES
+
+ - profile: macos-nometa-standard-makefile
+ os: macOS-latest
+ config: Standard
+ unity: NO
+ generator: Unix Makefiles
+ compiler: Default
+ metalibs: NO
+ python: YES
+ eigen: NO
+
+ - profile: windows-standard-unity-msvc
+ os: windows-2019
+ config: Standard
+ unity: YES
+ generator: Visual Studio 16 2019
+ compiler: Default
+ metalibs: YES
+ python: YES
+ eigen: NO
+
+ - profile: windows-nopython-nometa-standard-msvc
+ os: windows-2019
+ config: Standard
+ unity: NO
+ generator: Visual Studio 16 2019
+ compiler: Default
+ metalibs: NO
+ python: NO
+ eigen: NO
+
+ runs-on: ${{ matrix.os }}
+
+ steps:
+ - uses: actions/checkout@v1
+ with:
+ fetch-depth: 10
+
+ - name: Self-destruct makepanda
+ run: python makepanda/selfdestruct.py --yes
+
+ - name: Install dependencies (macOS)
+ if: runner.os == 'macOS'
+ run: |
+ curl -O https://www.panda3d.org/download/panda3d-1.10.5/panda3d-1.10.5-tools-mac.tar.gz
+ tar -xf panda3d-1.10.5-tools-mac.tar.gz
+
+ brew install ccache
+
+ echo "##[set-env name=thirdpartyOption;]-D THIRDPARTY_DIRECTORY=../panda3d-1.10.5/thirdparty" -DHAVE_CG=OFF
+
+ - name: Install dependencies (Ubuntu)
+ if: startsWith(matrix.os, 'ubuntu')
+ run: >
+ sudo apt-get update
+
+ sudo apt-get install
+ build-essential ninja-build clang llvm ccache
+ bison flex
+ libeigen3-dev libfreetype6-dev libgl1-mesa-dev libjpeg-dev libode-dev
+ libopenal-dev libpng-dev libssl-dev libvorbis-dev libx11-dev
+ libxcursor-dev libxrandr-dev nvidia-cg-toolkit zlib1g-dev
+
+ # Workaround for CMake 3.12 finding this first:
+
+ sudo rm /usr/bin/x86_64-linux-gnu-python2.7-config
+
+ - name: Cache dependencies (Windows)
+ if: runner.os == 'Windows'
+ uses: actions/cache@v1
+ with:
+ path: thirdparty-tools
+ key: ci-cmake-${{ runner.OS }}-thirdparty-v1.10.5-r1
+ - name: Install dependencies (Windows)
+ if: runner.os == 'Windows'
+ shell: powershell
+ run: |
+ if (!(Test-Path thirdparty-tools/panda3d-1.10.5)) {
+ $wc = New-Object System.Net.WebClient
+ $wc.DownloadFile("https://www.panda3d.org/download/panda3d-1.10.5/panda3d-1.10.5-tools-win64.zip", "thirdparty-tools.zip")
+ Expand-Archive -Path thirdparty-tools.zip
+ }
+
+ echo "##[set-env name=thirdpartyOption;]-D THIRDPARTY_DIRECTORY=../thirdparty-tools/panda3d-1.10.5/thirdparty"
+
+ - name: ccache (non-Windows)
+ if: runner.os != 'Windows'
+ uses: actions/cache@v1
+ with:
+ path: ccache
+ key: ci-cmake-ccache-${{ matrix.profile }}
+
+ - name: Configure
+ shell: bash
+ env:
+ CMAKE_GENERATOR: "${{ matrix.generator }}"
+ run: >
+ mkdir build
+
+ cd build
+
+ if ${{ matrix.compiler == 'Clang' }}; then
+ if [[ "$CMAKE_GENERATOR" == *Studio*2019* ]]; then
+ export CMAKE_GENERATOR_TOOLSET=ClangCL thirdpartyOption="$thirdpartyOption -DHAVE_HARFBUZZ=NO"
+ elif [[ "$CMAKE_GENERATOR" == *Studio* ]]; then
+ export CMAKE_GENERATOR_TOOLSET=LLVM thirdpartyOption="$thirdpartyOption -DHAVE_HARFBUZZ=NO"
+ else
+ export CC=clang CXX=clang++
+ fi
+ fi
+
+ if ${{ runner.os != 'Windows' }}; then
+ compilerLauncher=$(echo -DCMAKE_C{,XX}_COMPILER_LAUNCHER=ccache)
+ echo "##[set-env name=CCACHE_DIR;]$(dirname $PWD)/ccache"
+ fi
+
+ cmake
+ ${compilerLauncher:-}
+ -D CMAKE_UNITY_BUILD=${{ matrix.unity }}
+ -D CMAKE_BUILD_TYPE="${{ matrix.config }}"
+ -D BUILD_METALIBS=${{ matrix.metalibs }}
+ -D HAVE_PYTHON=${{ matrix.python }}
+ -D HAVE_EIGEN=${{ matrix.eigen }}
+ ${thirdpartyOption:-}
+ ..
+
+ - name: Build (no Python)
+ if: contains(matrix.python, 'NO')
+ # BEGIN A
+ working-directory: build
+ run: cmake --build . --config ${{ matrix.config }} --parallel 4
+ # END A
+
+ - name: Setup Python (Python 2.7)
+ if: contains(matrix.python, 'YES')
+ uses: actions/setup-python@v1
+ with:
+ python-version: 2.7
+ - name: Configure (Python 2.7)
+ if: contains(matrix.python, 'YES')
+ working-directory: build
+ shell: bash
+ run: >
+ cmake -DWANT_PYTHON_VERSION=2.7
+ -DPython_FIND_REGISTRY=NEVER -DPython_ROOT=$pythonLocation .
+ - name: Build (Python 2.7)
+ if: contains(matrix.python, 'YES')
+ # BEGIN A
+ working-directory: build
+ run: cmake --build . --config ${{ matrix.config }} --parallel 4
+ # END A
+ - name: Test (Python 2.7)
+ # BEGIN B
+ if: contains(matrix.python, 'YES')
+ working-directory: build
+ shell: bash
+ run: |
+ PYTHON_EXECUTABLE=$(grep 'Python_EXECUTABLE:FILEPATH' CMakeCache.txt | sed 's/.*=//')
+ $PYTHON_EXECUTABLE -m pip install pytest pytest-cov
+ export COVERAGE_FILE=.coverage.$RANDOM LLVM_PROFILE_FILE=$PWD/pid-%p.profraw
+ ctest -V -C ${{ matrix.config }}
+ # END B
+
+ - name: Setup Python (Python 3.5)
+ if: contains(matrix.python, 'YES')
+ uses: actions/setup-python@v1
+ with:
+ python-version: 3.5
+ - name: Configure (Python 3.5)
+ if: contains(matrix.python, 'YES')
+ working-directory: build
+ shell: bash
+ run: >
+ cmake -DWANT_PYTHON_VERSION=3.5
+ -DPython_FIND_REGISTRY=NEVER -DPython_ROOT=$pythonLocation .
+ - name: Build (Python 3.5)
+ if: contains(matrix.python, 'YES')
+ # BEGIN A
+ working-directory: build
+ run: cmake --build . --config ${{ matrix.config }} --parallel 4
+ # END A
+ - name: Test (Python 3.5)
+ # BEGIN B
+ if: contains(matrix.python, 'YES')
+ working-directory: build
+ shell: bash
+ run: |
+ PYTHON_EXECUTABLE=$(grep 'Python_EXECUTABLE:FILEPATH' CMakeCache.txt | sed 's/.*=//')
+ $PYTHON_EXECUTABLE -m pip install pytest pytest-cov
+ export COVERAGE_FILE=.coverage.$RANDOM LLVM_PROFILE_FILE=$PWD/pid-%p.profraw
+ ctest -V -C ${{ matrix.config }}
+ # END B
+
+ - name: Setup Python (Python 3.6)
+ if: contains(matrix.python, 'YES')
+ uses: actions/setup-python@v1
+ with:
+ python-version: 3.6
+ - name: Configure (Python 3.6)
+ if: contains(matrix.python, 'YES')
+ working-directory: build
+ shell: bash
+ run: >
+ cmake -DWANT_PYTHON_VERSION=3.6
+ -DPython_FIND_REGISTRY=NEVER -DPython_ROOT=$pythonLocation .
+ - name: Build (Python 3.6)
+ if: contains(matrix.python, 'YES')
+ # BEGIN A
+ working-directory: build
+ run: cmake --build . --config ${{ matrix.config }} --parallel 4
+ # END A
+ - name: Test (Python 3.6)
+ # BEGIN B
+ if: contains(matrix.python, 'YES')
+ working-directory: build
+ shell: bash
+ run: |
+ PYTHON_EXECUTABLE=$(grep 'Python_EXECUTABLE:FILEPATH' CMakeCache.txt | sed 's/.*=//')
+ $PYTHON_EXECUTABLE -m pip install pytest pytest-cov
+ export COVERAGE_FILE=.coverage.$RANDOM LLVM_PROFILE_FILE=$PWD/pid-%p.profraw
+ ctest -V -C ${{ matrix.config }}
+ # END B
+
+ - name: Setup Python (Python 3.7)
+ if: contains(matrix.python, 'YES')
+ uses: actions/setup-python@v1
+ with:
+ python-version: 3.7
+ - name: Configure (Python 3.7)
+ if: contains(matrix.python, 'YES')
+ working-directory: build
+ shell: bash
+ run: >
+ cmake -DWANT_PYTHON_VERSION=3.7
+ -DPython_FIND_REGISTRY=NEVER -DPython_ROOT=$pythonLocation .
+ - name: Build (Python 3.7)
+ if: contains(matrix.python, 'YES')
+ # BEGIN A
+ working-directory: build
+ run: cmake --build . --config ${{ matrix.config }} --parallel 4
+ # END A
+ - name: Test (Python 3.7)
+ # BEGIN B
+ if: contains(matrix.python, 'YES')
+ working-directory: build
+ shell: bash
+ run: |
+ PYTHON_EXECUTABLE=$(grep 'Python_EXECUTABLE:FILEPATH' CMakeCache.txt | sed 's/.*=//')
+ $PYTHON_EXECUTABLE -m pip install pytest pytest-cov
+ export COVERAGE_FILE=.coverage.$RANDOM LLVM_PROFILE_FILE=$PWD/pid-%p.profraw
+ ctest -V -C ${{ matrix.config }}
+ # END B
+
+ - name: Setup Python (Python 3.8)
+ if: contains(matrix.python, 'YES')
+ uses: actions/setup-python@v1
+ with:
+ python-version: 3.8
+ - name: Configure (Python 3.8)
+ if: contains(matrix.python, 'YES')
+ working-directory: build
+ shell: bash
+ run: >
+ cmake -DWANT_PYTHON_VERSION=3.8
+ -DPython_FIND_REGISTRY=NEVER -DPython_ROOT=$pythonLocation .
+ - name: Build (Python 3.8)
+ if: contains(matrix.python, 'YES')
+ # BEGIN A
+ working-directory: build
+ run: cmake --build . --config ${{ matrix.config }} --parallel 4
+ # END A
+ - name: Test (Python 3.8)
+ # BEGIN B
+ if: contains(matrix.python, 'YES')
+ working-directory: build
+ shell: bash
+ run: |
+ PYTHON_EXECUTABLE=$(grep 'Python_EXECUTABLE:FILEPATH' CMakeCache.txt | sed 's/.*=//')
+ $PYTHON_EXECUTABLE -m pip install pytest pytest-cov
+ export COVERAGE_FILE=.coverage.$RANDOM LLVM_PROFILE_FILE=$PWD/pid-%p.profraw
+ ctest -V -C ${{ matrix.config }}
+ # END B
+
+ - name: Upload coverage reports
+ if: always() && matrix.config == 'Coverage'
+ working-directory: build
+ shell: bash
+ env:
+ CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
+ run: |
+ shopt -s expand_aliases
+ if ${{ runner.os == 'macOS' }}; then alias llvm-profdata='xcrun llvm-profdata' llvm-cov='xcrun llvm-cov'; fi
+
+ python -m coverage combine $(find . -name '.coverage.*')
+
+ llvm-profdata merge pid-*.profraw -o coverage.profdata
+ llvm-cov show $(grep -Rl LLVM_PROFILE_FILE . | sed 's/^/-object /') -instr-profile=coverage.profdata > coverage.txt
+ bash <(curl -s https://codecov.io/bash)
+
makepanda:
strategy:
matrix:
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000000..3c6daf90b0
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,152 @@
+cmake_minimum_required(VERSION 3.0.2)
+set(CMAKE_DISABLE_SOURCE_CHANGES ON) # Must go before project() below
+set(CMAKE_DISABLE_IN_SOURCE_BUILD ON) # Must go before project() below
+
+if(CMAKE_VERSION VERSION_GREATER "3.11" OR POLICY CMP0072)
+ # Prefer GLVND over libGL when available; this will be enabled by default
+ # once the minimum CMake version is at least 3.11.
+ cmake_policy(SET CMP0072 NEW)
+endif()
+
+if(CMAKE_VERSION VERSION_GREATER "3.12" OR POLICY CMP0074)
+ # Needed for THIRDPARTY_DIRECTORY support; this will be enabled by default
+ # once the minimum CMake version is at least 3.12.
+ cmake_policy(SET CMP0074 NEW)
+endif()
+
+# Figure out the version
+set(_s "[\\t ]*") # CMake doesn't support \s*
+file(STRINGS "setup.cfg" _version REGEX "^version${_s}=${_s}")
+string(REGEX REPLACE "^.*=${_s}" "" _version "${_version}")
+project(Panda3D VERSION ${_version})
+unset(_version)
+unset(_s)
+
+enable_testing()
+
+string(REPLACE "$(EFFECTIVE_PLATFORM_NAME)" "" PANDA_CFG_INTDIR "${CMAKE_CFG_INTDIR}")
+
+# Add generic modules to cmake module path,
+# and add Panda3D specific modules to cmake module path
+set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/modules/")
+set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/macros/")
+
+if(CMAKE_VERSION VERSION_GREATER "3.8")
+ # When using the Xcode generator, don't append the platform name to the
+ # intermediate configuration directory.
+ set_property(GLOBAL PROPERTY XCODE_EMIT_EFFECTIVE_PLATFORM_NAME OFF)
+endif()
+
+# Include modules builtin to CMake
+include(GNUInstallDirs) # Defines CMAKE_INSTALL_
variables
+
+# Include global modules needed for configure scripts
+include(PackageConfig) # Defines package_option
+
+# Configure Panda3D
+include(dtool/CompilerFlags.cmake)
+include(dtool/PandaVersion.cmake)
+include(dtool/Package.cmake)
+include(dtool/Config.cmake)
+
+# Include global modules
+include(AddBisonTarget) # Defines add_bison_target function
+include(AddFlexTarget) # Defines add_flex_target function
+include(BuildMetalib) # Defines add_component_library AND add_metalib
+include(CompositeSources) # Defines composite_sources function
+include(Python) # Defines add_python_target AND install_python_package
+include(Interrogate) # Defines target_interrogate AND add_python_module
+include(RunPzip) # Defines run_pzip function
+include(Versioning) # Hooks 'add_library' to apply VERSION/SOVERSION
+
+# Determine which trees to build.
+option(BUILD_DTOOL "Build the dtool source tree." ON)
+option(BUILD_PANDA "Build the panda source tree." ON)
+option(BUILD_DIRECT "Build the direct source tree." ON)
+option(BUILD_PANDATOOL "Build the pandatool source tree." ON)
+option(BUILD_CONTRIB "Build the contrib source tree." ON)
+option(BUILD_MODELS "Build/install the built-in models." ON)
+
+# Include Panda3D packages
+if(BUILD_DTOOL)
+ add_subdirectory(dtool "${CMAKE_BINARY_DIR}/dtool")
+endif()
+
+if(BUILD_PANDA)
+ add_subdirectory(panda "${CMAKE_BINARY_DIR}/panda")
+endif()
+
+if(BUILD_DIRECT)
+ add_subdirectory(direct "${CMAKE_BINARY_DIR}/direct")
+endif()
+
+if(BUILD_PANDATOOL)
+ add_subdirectory(pandatool "${CMAKE_BINARY_DIR}/pandatool")
+endif()
+
+if(BUILD_CONTRIB)
+ add_subdirectory(contrib "${CMAKE_BINARY_DIR}/contrib")
+endif()
+
+if(BUILD_MODELS)
+ run_pzip(models
+ "${CMAKE_CURRENT_SOURCE_DIR}/models/"
+ "${PROJECT_BINARY_DIR}/${PANDA_CFG_INTDIR}/models"
+ *.egg)
+ run_pzip(dmodels
+ "${CMAKE_CURRENT_SOURCE_DIR}/dmodels/src/"
+ "${PROJECT_BINARY_DIR}/${PANDA_CFG_INTDIR}/models"
+ *.egg)
+
+ add_custom_command(TARGET models
+ POST_BUILD
+ COMMAND ${CMAKE_COMMAND}
+ -DSOURCE="${CMAKE_CURRENT_SOURCE_DIR}/models/maps/"
+ -DDESTINATION="${PANDA_OUTPUT_DIR}/models/maps"
+ -P ${PROJECT_SOURCE_DIR}/cmake/scripts/CopyPattern.cmake
+ COMMENT "Copying models/maps")
+ add_custom_command(TARGET dmodels
+ POST_BUILD
+ COMMAND ${CMAKE_COMMAND}
+ -DSOURCE="${CMAKE_CURRENT_SOURCE_DIR}/dmodels/src/"
+ -DDESTINATION="${PANDA_OUTPUT_DIR}/models"
+ -DFILES_MATCHING="PATTERN;*.rgb;PATTERN;*.png;PATTERN;*.jpg;PATTERN;*.wav"
+ -P ${PROJECT_SOURCE_DIR}/cmake/scripts/CopyPattern.cmake
+ COMMENT "Copying dmodels' assets")
+
+ install(DIRECTORY "${PANDA_OUTPUT_DIR}/models"
+ COMPONENT Models DESTINATION ${CMAKE_INSTALL_DATADIR}/panda3d)
+endif()
+
+if(INTERROGATE_PYTHON_INTERFACE)
+ # If we built the Python interface, run the test suite. Note, we do NOT test
+ # for pytest before adding this test. If the user doesn't have pytest, we'd
+ # like for the tests to fail.
+
+ # In the Coverage configuration, we also require pytest-cov
+
+ add_test(NAME pytest
+ COMMAND "${PYTHON_EXECUTABLE}" -m pytest "${PROJECT_SOURCE_DIR}/tests"
+ $<$:--cov=.>
+ WORKING_DIRECTORY "${PANDA_OUTPUT_DIR}")
+endif()
+
+# Generate the Panda3DConfig.cmake file so find_package(Panda3D) works, and
+# also register the build directory with CMake's package registry.
+
+file(COPY "${PROJECT_SOURCE_DIR}/cmake/install/Panda3DConfig.cmake"
+ DESTINATION "${PROJECT_BINARY_DIR}")
+install(FILES "${PROJECT_SOURCE_DIR}/cmake/install/Panda3DConfig.cmake"
+ DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/Panda3D")
+
+include(CMakePackageConfigHelpers)
+write_basic_package_version_file(
+ "${PROJECT_BINARY_DIR}/Panda3DConfigVersion.cmake"
+ VERSION "${PROJECT_VERSION}"
+ COMPATIBILITY AnyNewerVersion)
+install(FILES "${PROJECT_BINARY_DIR}/Panda3DConfigVersion.cmake"
+ DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/Panda3D")
+
+if(NOT CMAKE_CROSSCOMPILING)
+ export(PACKAGE Panda3D)
+endif()
diff --git a/cmake/README.md b/cmake/README.md
new file mode 100644
index 0000000000..e90246ccdb
--- /dev/null
+++ b/cmake/README.md
@@ -0,0 +1,78 @@
+Building with CMake
+-------------------
+
+On Windows and macOS, please ensure that you have the very latest version of
+CMake installed; older versions may work, but if not, please upgrade to the
+latest available version of CMake before requesting help.
+
+On systems that package CMake themselves (e.g. Linux distributions), we most
+likely support the provided version of CMake as long as the system itself is
+supported.
+
+CMake will also require that you already have your system's developer tools
+installed.
+
+The quickest way to build and install Panda with CMake is to install any
+third-party dependencies and then run:
+```sh
+mkdir build && cd build
+cmake ..
+cmake --build . --config Standard --parallel 4
+[sudo] cmake --build . --config Standard --target install
+```
+
+Note that, if you are targeting 64-bit on Windows, it is necessary to supply
+the `-A x64` option when first invoking `cmake` (as `cmake -A x64 ..`).
+
+CMake itself does not build Panda; rather, it generates project files for an
+existing IDE or build tool. To select a build tool, pass the `-G` option when
+first invoking CMake, (`cmake -G Ninja ..` is highly recommended on Linux).
+Some of these (Xcode, Visual Studio) support targeting multiple configurations
+(the `--config Standard`, above, selects the `Standard` configuration in those
+cases). Other build tools (Ninja, Makefiles, ...) do not support multiple
+configurations, and the `--config` option is ignored. To change the
+configuration in these cases (from `Standard`, the default), it is necessary to
+change the `CMAKE_BUILD_TYPE` variable as explained below.
+
+The configurations are:
+
+| Configuration | Explanation |
+| -------------- | ------------------------------------------------------ |
+| Standard | Default; build provided to users of SDK |
+| Release | Distribution for end-users |
+| MinSizeRel | Like Release, but optimized for size |
+| RelWithDebInfo | Like Release, but include debug symbols |
+| Debug | Do not optimize, enable optional debugging features |
+| Coverage | Like Debug, but profile code coverage; developers only |
+
+To configure CMake, it is recommended to use cmake-gui (`cmake-gui .`),
+or ccmake (`ccmake .`), however it is also possible to configure it entirely
+through CMake's command-line interface; see `man cmake` for more details.
+
+In general, the config variable for a particular third party library is:
+```
+ HAVE_=YES/NO # Example: USE_JPEG
+```
+Panda subpackage building is handled by:
+```
+ BUILD_=YES/NO # Example: BUILD_DTOOL, BUILD_PANDA
+```
+Other configuration settings use their historical names (same names as in-source):
+```
+ # Examples
+ PANDA_DISTRIBUTOR="MyDistributor"
+ LINMATH_ALIGN=YES
+
+ # ... etc ...
+
+```
+
+For example, `makepanda.py --distributor X` becomes `cmake -DPANDA_DISTRIBUTOR=X`
+
+All found third-party libraries are enabled by default, and makepanda-style
+tools packages are searched in the same path as makepanda (however this may be
+overridden with the `THIRDPARTY_DIRECTORY` option).
+
+Most config settings are set to a sensible default for a typical PC/desktop
+Panda3D distribution. Third-party libraries and other settings can be enabled
+or disabled through configuration with the cmake GUI or CLI.
diff --git a/cmake/install/Panda3DConfig.cmake b/cmake/install/Panda3DConfig.cmake
new file mode 100644
index 0000000000..b062bcb175
--- /dev/null
+++ b/cmake/install/Panda3DConfig.cmake
@@ -0,0 +1,157 @@
+# PANDA 3D SOFTWARE
+# Copyright (c) Carnegie Mellon University. All rights reserved.
+#
+# All use of this software is subject to the terms of the revised BSD
+# license. You should have received a copy of this license along
+# with this source code in a file named "LICENSE."
+#
+# Author: CFSworks (Dec. 11, 2018)
+
+# This file is installed to CMake's package search path, and is invoked for
+# find_package(Panda3D [COMPONENTS ...])
+#
+# The following components are available for importing:
+#
+# Core - The core Panda3D libraries; this component is always included.
+#
+# Panda3D::Core::panda
+# Panda3D::Core::pandaexpress
+# etc.
+#
+#
+# Python - Python targets, which can be used for linking against the Python
+# extension modules directly. Note that this also imports the
+# Python bindings for other requested components that have them.
+#
+# Panda3D::Python::panda3d.core
+# Panda3D::Python::panda3d.physics
+# etc.
+#
+#
+# Tools - Various tools used in asset manipulation and debugging.
+#
+# Panda3D::Tools::egg2bam
+# Panda3D::Tools::egg-optchar
+# Panda3D::Tools::pview
+# etc.
+#
+#
+# Direct - Panda's "direct" Python framework; C++ support library.
+#
+# Panda3D::Direct::p3direct
+#
+#
+# Contrib - Extensions not part of the Panda3D core, but contributed by the
+# community.
+#
+# Panda3D::Contrib::p3ai
+# Panda3D::Contrib::p3rplight
+#
+#
+# Framework - Panda's "p3framework" C++ framework.
+#
+# Panda3D::Framework::p3framework
+#
+#
+# Egg - Support for the Egg file format.
+#
+# Panda3D::Egg::pandaegg
+#
+#
+# Bullet - Support for Bullet physics.
+#
+# Panda3D::Bullet::p3bullet
+#
+#
+# ODE - Support for the ODE physics engine.
+#
+# Panda3D::ODE::p3ode
+#
+#
+# FFmpeg - Support for FFmpeg media format loading.
+#
+# Panda3D::FFmpeg::p3ffmpeg
+#
+#
+# OpenAL - Support for OpenAL audio output.
+#
+# Panda3D::OpenAL::p3openal_audio
+#
+#
+# FMOD - Support for FMOD audio output.
+#
+# Panda3D::FMOD::p3fmod_audio
+#
+#
+# OpenGL - Support for OpenGL rendering.
+#
+# Panda3D::OpenGL::pandagl
+#
+#
+# DX9 - Support for Direct3D 9 rendering.
+#
+# Panda3D::DX9::pandadx9
+#
+#
+# OpenGLES1 - Support for OpenGL ES 1.x rendering.
+#
+# Panda3D::OpenGLES1::pandagles
+#
+#
+# OpenGLES2 - Support for OpenGL ES 2.x+ rendering.
+#
+# Panda3D::OpenGLES2::pandagles2
+#
+#
+# Vision - Support for vision processing.
+#
+# Panda3D::Vision::p3vision
+#
+#
+# VRPN - Support for connecting to a VRPN virtual reality server.
+#
+# Panda3D::VRPN::p3vrpn
+
+if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 3.0)
+ message(FATAL_ERROR "CMake >= 3.0.2 required")
+endif()
+
+get_filename_component(_panda_config_prefix "${CMAKE_CURRENT_LIST_FILE}" PATH)
+
+include("${_panda_config_prefix}/Panda3DPackages.cmake")
+
+set(_panda_components
+ Core Python Tools
+ Direct Contrib Framework Egg
+ Bullet ODE
+ FFmpeg
+ OpenAL FMOD
+ OpenGL DX9 OpenGLES1 OpenGLES2
+ Vision VRPN
+)
+
+set(Panda3D_FIND_REQUIRED_Core ON)
+
+foreach(_comp Core ${Panda3D_FIND_COMPONENTS})
+ if(";${_panda_components};" MATCHES ";${_comp};" AND
+ EXISTS "${_panda_config_prefix}/Panda3D${_comp}Targets.cmake")
+
+ include("${_panda_config_prefix}/Panda3D${_comp}Targets.cmake")
+
+ if(";${Panda3D_FIND_COMPONENTS};" MATCHES ";Python;" AND
+ EXISTS "${_panda_config_prefix}/Panda3D${_comp}PythonTargets.cmake")
+
+ include("${_panda_config_prefix}/Panda3D${_comp}PythonTargets.cmake")
+
+ endif()
+
+ elseif(Panda3D_FIND_REQUIRED_${_comp})
+
+ message(FATAL_ERROR "Panda3D REQUIRED component ${_comp} not found")
+
+ endif()
+
+endforeach(_comp)
+unset(_comp)
+
+unset(_panda_components)
diff --git a/cmake/macros/AddBisonTarget.cmake b/cmake/macros/AddBisonTarget.cmake
new file mode 100644
index 0000000000..0feb2616ee
--- /dev/null
+++ b/cmake/macros/AddBisonTarget.cmake
@@ -0,0 +1,75 @@
+# Filename: AddBisonTarget.cmake
+# Description: This file defines the function add_bison_target which instructs
+# cmake to use bison on an input .yxx file. If bison is not available on
+# the system, add_bison_target tries to use .prebuilt .cxx files instead.
+#
+# Usage:
+# add_bison_target(output_cxx input_yxx [DEFINES output_h] [PREFIX prefix])
+#
+
+# Define add_bison_target()
+function(add_bison_target output_cxx input_yxx)
+ set(arguments "")
+ set(outputs "${output_cxx}")
+ set(keyword "")
+
+ # Parse the extra arguments to the function.
+ foreach(arg ${ARGN})
+ if(arg STREQUAL "DEFINES")
+ set(keyword "DEFINES")
+
+ elseif(arg STREQUAL "PREFIX")
+ set(keyword "PREFIX")
+
+ elseif(keyword STREQUAL "PREFIX")
+ list(APPEND arguments -p "${arg}")
+
+ elseif(keyword STREQUAL "DEFINES")
+ list(APPEND arguments --defines="${arg}")
+ list(APPEND outputs "${arg}")
+
+ else()
+ message(SEND_ERROR "Unexpected argument ${arg} to add_bison_target")
+
+ endif()
+ endforeach()
+
+ if(keyword STREQUAL arg AND NOT keyword STREQUAL "")
+ message(SEND_ERROR "Expected argument after ${keyword}")
+ endif()
+
+ if(HAVE_BISON)
+ get_source_file_property(input_yxx "${input_yxx}" LOCATION)
+
+ # If we have bison, we can of course just run it.
+ add_custom_command(
+ OUTPUT ${outputs}
+ COMMAND ${BISON_EXECUTABLE}
+ -o "${output_cxx}" ${arguments}
+ "${input_yxx}"
+ MAIN_DEPENDENCY "${input_yxx}"
+ )
+
+ else()
+ # Look for prebuilt versions of the outputs.
+ set(commands "")
+ set(depends "")
+
+ foreach(output ${outputs})
+ set(prebuilt_file "${output}.prebuilt")
+ get_filename_component(prebuilt_file "${prebuilt_file}" ABSOLUTE)
+
+ if(NOT EXISTS "${prebuilt_file}")
+ message(SEND_ERROR "Bison was not found and ${prebuilt_file} does not exist!")
+ endif()
+
+ list(APPEND depends "${prebuilt_file}")
+ list(APPEND commands COMMAND ${CMAKE_COMMAND} -E copy ${prebuilt_file} ${output})
+ endforeach()
+
+ add_custom_command(
+ OUTPUT ${outputs}
+ ${commands}
+ DEPENDS ${depends})
+ endif()
+endfunction(add_bison_target)
diff --git a/cmake/macros/AddFlexTarget.cmake b/cmake/macros/AddFlexTarget.cmake
new file mode 100644
index 0000000000..b24aeb95fc
--- /dev/null
+++ b/cmake/macros/AddFlexTarget.cmake
@@ -0,0 +1,77 @@
+# Filename: AddFlexTarget.cmake
+# Description: This file defines the function add_flex_target which instructs
+# cmake to use flex on an input .lxx file. If flex is not available on
+# the system, add_flex_target tries to use .prebuilt .cxx files instead.
+#
+# Usage:
+# add_flex_target(output_cxx input_lxx [DEFINES output_h] [PREFIX prefix])
+#
+
+# Define add_flex_target()
+function(add_flex_target output_cxx input_lxx)
+ set(arguments "")
+ set(outputs "${output_cxx}")
+ set(keyword "")
+
+ # Parse the extra arguments to the function.
+ foreach(arg ${ARGN})
+ if(arg STREQUAL "DEFINES")
+ set(keyword "DEFINES")
+
+ elseif(arg STREQUAL "PREFIX")
+ set(keyword "PREFIX")
+
+ elseif(arg STREQUAL "CASE_INSENSITIVE")
+ list(APPEND arguments "-i")
+
+ elseif(keyword STREQUAL "PREFIX")
+ list(APPEND arguments "-P${arg}")
+
+ elseif(keyword STREQUAL "DEFINES")
+ list(APPEND arguments "--header-file=${arg}")
+ list(APPEND outputs "${arg}")
+
+ else()
+ message(SEND_ERROR "Unexpected argument ${arg} to add_flex_target")
+
+ endif()
+ endforeach()
+
+ if(keyword STREQUAL arg AND NOT keyword STREQUAL "")
+ message(SEND_ERROR "Expected argument after ${keyword}")
+ endif()
+
+ if(HAVE_FLEX)
+ get_source_file_property(input_lxx "${input_lxx}" LOCATION)
+
+ # If we have flex, we can of course just run it.
+ add_custom_command(
+ OUTPUT ${outputs}
+ COMMAND ${FLEX_EXECUTABLE}
+ "-o${output_cxx}" ${arguments}
+ "${input_lxx}"
+ MAIN_DEPENDENCY "${input_lxx}")
+
+ else()
+ # Look for prebuilt versions of the outputs.
+ set(commands "")
+ set(depends "")
+
+ foreach(output ${outputs})
+ set(prebuilt_file "${output}.prebuilt")
+ get_filename_component(prebuilt_file "${prebuilt_file}" ABSOLUTE)
+
+ if(NOT EXISTS "${prebuilt_file}")
+ message(SEND_ERROR "Flex was not found and ${prebuilt_file} does not exist!")
+ endif()
+
+ list(APPEND depends "${prebuilt_file}")
+ list(APPEND commands COMMAND ${CMAKE_COMMAND} -E copy ${prebuilt_file} ${output})
+ endforeach()
+
+ add_custom_command(
+ OUTPUT ${outputs}
+ ${commands}
+ DEPENDS ${depends})
+ endif()
+endfunction(add_flex_target)
diff --git a/cmake/macros/BuildMetalib.cmake b/cmake/macros/BuildMetalib.cmake
new file mode 100644
index 0000000000..079b794b85
--- /dev/null
+++ b/cmake/macros/BuildMetalib.cmake
@@ -0,0 +1,426 @@
+# Filename: BuildMetalib.cmake
+#
+# Description: This file contains macros to build Panda3D's "metalibs" - these
+# are special libraries that contain no unique code themselves and are
+# instead just an agglomeration of the various component libraries that get
+# linked into them. A library of libraries - a "metalibrary."
+
+#
+# Function: target_link_libraries(...)
+#
+# Overrides CMake's target_link_libraries() to support "linking" object
+# libraries. This is a partial reimplementation of CMake commit dc38970f83,
+# which is only available in CMake 3.12+
+#
+if(CMAKE_VERSION VERSION_LESS "3.12")
+ function(target_link_libraries target)
+ get_target_property(target_type "${target}" TYPE)
+ if(NOT target_type STREQUAL "OBJECT_LIBRARY")
+ _target_link_libraries("${target}" ${ARGN})
+ return()
+ endif()
+
+ foreach(library ${ARGN})
+ # This is a quick and dirty regex to tell targets apart from other stuff.
+ # It just checks if it's alphanumeric and starts with p3/panda.
+ if(library MATCHES "^(PKG::|p3|panda)[A-Za-z0-9]*$")
+ # We need to add "library"'s include directories to "target"
+ # (and transitively to INTERFACE_INCLUDE_DIRECTORIES so further
+ # dependencies will work)
+ set(include_directories "$")
+ set_property(TARGET "${target}" APPEND PROPERTY INCLUDE_DIRECTORIES "${include_directories}")
+ set_property(TARGET "${target}" APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${include_directories}")
+
+ # SYSTEM include directories should still be reported as SYSTEM, so
+ # that warnings from those includes are suppressed
+ set(sys_include_directories
+ "$")
+ target_include_directories("${target}" SYSTEM PUBLIC "${sys_include_directories}")
+
+ # And for INTERFACE_COMPILE_DEFINITIONS as well
+ set(compile_definitions "$")
+ set_property(TARGET "${target}" APPEND PROPERTY COMPILE_DEFINITIONS "${compile_definitions}")
+ set_property(TARGET "${target}" APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS "${compile_definitions}")
+
+ # Build up some generator expressions for determining whether `library`
+ # is a component library or not.
+ if(library MATCHES ".*::.*")
+ # "::" messes up CMake's genex parser; fortunately, a library whose
+ # name contains that is either an interface library or alias, and
+ # definitely not a component
+ set(is_component 0)
+ set(name_of_component "")
+ set(name_of_non_component "${library}")
+
+ else()
+ set(is_component "$")
+
+ # CMake complains if we lookup IS_COMPONENT on an INTERFACE library :(
+ set(is_object "$,OBJECT_LIBRARY>")
+ set(is_component "$>")
+
+ set(name_of_component "$<${is_component}:$>")
+ set(name_of_non_component "$<$:$>")
+
+ endif()
+
+ # Libraries are only linked transitively if they aren't components.
+ set_property(TARGET "${target}" APPEND PROPERTY
+ INTERFACE_LINK_LIBRARIES "${name_of_non_component}")
+
+ else()
+ # This is a file path to an out-of-tree library - this needs to be
+ # recorded so that the metalib can link them. (They aren't needed at
+ # all for the object libraries themselves, so they don't have to work
+ # transitively.)
+ set_property(TARGET "${target}" APPEND PROPERTY INTERFACE_LINK_LIBRARIES "${library}")
+
+ endif()
+
+ endforeach(library)
+
+ endfunction(target_link_libraries)
+endif()
+
+#
+# Function: add_component_library(target [SYMBOL building_symbol]
+# [SOURCES] [[NOINIT]/[INIT func [header]]])
+#
+# Used very similarly to add_library. You can specify a symbol with SYMBOL,
+# which works like CMake's own DEFINE_SYMBOL property: it's defined when
+# building the library, but not when building something that links against the
+# library.
+#
+# INIT specifies the init function that should be called from a metalib's init
+# function when this is added to a metalib. The header parameter can further
+# clarify what header declares this function. By default, this is
+# init_libTARGET and config_TARGET.h, respectively, where TARGET is the
+# target name (with 'p3' stripped off, if applicable). The NOINIT keyword
+# suppresses this default.
+#
+# Note that this function gets to decide whether the component library is
+# OBJECT or SHARED, and whether the library is installed or not. Also, as
+# a rule, component libraries may only be linked by other component libraries
+# in the same metalib - outside of the metalib, you must link the metalib
+# itself.
+#
+function(add_component_library target_name)
+ set(sources)
+ unset(symbol)
+
+ if(target_name MATCHES "^p3.*")
+ string(SUBSTRING "${target_name}" 2 -1 name_without_prefix)
+
+ else()
+ set(name_without_prefix "${target_name}")
+
+ endif()
+
+ set(init_func "init_lib${name_without_prefix}")
+ set(init_header "config_${name_without_prefix}.h")
+
+ set(symbol_keyword OFF)
+ set(init_keyword 0)
+ foreach(source ${ARGN})
+ if(source STREQUAL "SYMBOL")
+ set(symbol_keyword ON)
+ set(init_keyword 0)
+
+ elseif(source STREQUAL "INIT")
+ set(symbol_keyword OFF)
+ set(init_keyword 2)
+
+ elseif(source STREQUAL "NOINIT")
+ set(init_func)
+ set(init_header)
+
+ elseif(symbol_keyword)
+ set(symbol_keyword OFF)
+ set(symbol "${source}")
+
+ elseif(init_keyword EQUAL 2)
+ set(init_func "${source}")
+ set(init_keyword 1)
+
+ elseif(init_keyword EQUAL 1)
+ set(init_header "${source}")
+ set(init_keyword 0)
+
+ else()
+ list(APPEND sources "${source}")
+
+ endif()
+ endforeach()
+
+ if(BUILD_METALIBS)
+ # CMake 3.0.2 doesn't like .I/.N/.T files! We let it know that they're only
+ # headers.
+ foreach(source ${sources})
+ if(source MATCHES "\\.[INT]$")
+ set_source_files_properties(${source} PROPERTIES HEADER_FILE_ONLY ON)
+ endif()
+ endforeach(source)
+
+ add_library("${target_name}" OBJECT ${sources})
+
+ else()
+ add_library("${target_name}" ${sources})
+
+ endif()
+
+ set_target_properties("${target_name}" PROPERTIES
+ IS_COMPONENT ON
+ INIT_FUNCTION "${init_func}"
+ INIT_HEADER "${init_header}")
+
+ if(symbol)
+ set_property(TARGET "${target_name}" PROPERTY DEFINE_SYMBOL "${symbol}")
+
+ if(BUILD_METALIBS)
+ # ... DEFINE_SYMBOL is apparently not respected for object libraries?
+ set_property(TARGET "${target_name}" APPEND PROPERTY COMPILE_DEFINITIONS "${symbol}")
+
+ # Make sure other component libraries relying on this one inherit the
+ # symbol
+ set_property(TARGET "${target_name}" APPEND PROPERTY
+ INTERFACE_COMPILE_DEFINITIONS "$<$>:${symbol}>")
+ endif()
+ endif()
+
+ if(BUILD_METALIBS)
+ # Apparently neither is CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE?
+ set_property(TARGET "${target_name}" PROPERTY
+ INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}")
+
+ # If we're building dynamic libraries, the object library needs to be -fPIC
+ if(BUILD_SHARED_LIBS)
+ set_property(TARGET "${target_name}" PROPERTY
+ POSITION_INDEPENDENT_CODE ON)
+ endif()
+ endif()
+
+endfunction(add_component_library)
+
+#
+# Function: add_metalib(target [source1 source2]
+# [INCLUDE header1.h ...]
+# [INIT initfunc [initheader.h] [EXPORT type name expr]]
+# [COMPONENTS component1 ...])
+#
+# This is add_library, but for metalibs.
+#
+# The INIT keyword can specify an initialization function/header (which will be
+# autogenerated by this function) that calls the underlying component libs'
+# init functions.
+#
+# The EXPORT keyword exports the expression `expr`, which yields a value of
+# type `type`, as the undecorated (extern "C") symbol `name`
+#
+# The INCLUDE keyword allows the init file to pull in additional headers, which
+# may be useful for EXPORT.
+#
+function(add_metalib target_name)
+ set(components_keyword OFF)
+ set(init_keyword 0)
+ set(init_func)
+ set(init_header "${target_name}.h")
+ set(export_keyword 0)
+ set(export_declarations)
+ set(export_definitions)
+ set(component_init_headers)
+ set(components)
+ set(sources)
+
+ foreach(arg ${ARGN})
+ if(arg STREQUAL "COMPONENTS")
+ set(components_keyword ON)
+ set(include_keyword OFF)
+ set(init_keyword 0)
+ set(export_keyword 0)
+
+ elseif(arg STREQUAL "INCLUDE")
+ set(include_keyword ON)
+ set(components_keyword OFF)
+ set(init_keyword 0)
+ set(export_keyword 0)
+
+ elseif(arg STREQUAL "INIT")
+ set(init_keyword 2)
+ set(components_keyword OFF)
+ set(include_keyword OFF)
+ set(export_keyword 0)
+
+ elseif(arg STREQUAL "EXPORT")
+ if(NOT init_func)
+ message(FATAL_ERROR "EXPORT cannot be used before INIT")
+ endif()
+
+ set(export_keyword 3)
+ set(components_keyword OFF)
+ set(include_keyword OFF)
+ set(init_keyword 0)
+
+ elseif(components_keyword)
+ list(APPEND components "${arg}")
+
+ elseif(include_keyword)
+ set(component_init_headers
+ "${component_init_headers}#include \"${arg}\"\n")
+
+ elseif(init_keyword EQUAL 2)
+ set(init_func "${arg}")
+ set(init_keyword 1)
+
+ elseif(init_keyword EQUAL 1)
+ set(init_header "${arg}")
+ set(init_keyword 0)
+
+ elseif(export_keyword EQUAL 3)
+ set(_export_type "${arg}")
+ set(export_keyword 2)
+
+ elseif(export_keyword EQUAL 2)
+ set(_export_name "${arg}")
+ set(export_keyword 1)
+
+ elseif(export_keyword EQUAL 1)
+ set(export_declarations
+ "${export_declarations}\nextern \"C\" IMPORT_CLASS ${_export_type} ${_export_name}();")
+ set(export_definitions
+ "${export_definitions}\nextern \"C\" EXPORT_CLASS ${_export_type} ${_export_name}() { return ${arg}; }")
+ unset(_export_type)
+ unset(_export_name)
+ set(export_keyword 0)
+
+ else()
+ list(APPEND sources "${arg}")
+
+ endif()
+ endforeach()
+
+ string(REPLACE ";" "|" piped_components "${components}")
+ set(component_genex_regex ".*TARGET_PROPERTY:(${piped_components}),.*")
+
+ set(private_defines)
+ set(interface_defines)
+ set(includes)
+ set(libs)
+ set(component_init_funcs "")
+ foreach(component ${components})
+ if(NOT TARGET "${component}")
+ message(FATAL_ERROR
+ "Missing component library ${component} referenced by metalib ${target_name}!
+ (Component library targets must be created BEFORE add_metalib.)")
+ endif()
+
+ get_target_property(is_component "${component}" IS_COMPONENT)
+ if(NOT is_component)
+ message(FATAL_ERROR
+ "Attempted to metalink non-component ${component} into ${target_name}!")
+ endif()
+
+ get_target_property(component_init_header "${component}" INIT_HEADER)
+ get_target_property(component_init_func "${component}" INIT_FUNCTION)
+
+ if(component_init_header)
+ set(component_init_headers
+ "${component_init_headers}#include \"${component_init_header}\"\n")
+ endif()
+
+ if(component_init_func)
+ set(component_init_funcs
+ "${component_init_funcs} ${component_init_func}();\n")
+ endif()
+
+ if(BUILD_METALIBS)
+ # This will be an object library we're pulling in; rather than link,
+ # let's try to "flatten" all of its properties into ours.
+
+ # Private defines: Just reference using a generator expression
+ list(APPEND private_defines "$")
+
+ # Interface defines: Copy those, but filter out generator expressions
+ # referencing a component library
+ get_target_property(component_defines "${component}" INTERFACE_COMPILE_DEFINITIONS)
+ if(component_defines)
+ foreach(component_define ${component_defines})
+ if(component_define MATCHES "${component_genex_regex}")
+ # Filter, it's a genex referencing one of our components
+ elseif(component_define MATCHES ".*IS_COMPONENT.*")
+ # Filter, it's testing to see if the consumer is a component
+ else()
+ list(APPEND interface_defines ${component_define})
+ endif()
+ endforeach(component_define)
+ endif()
+
+ # Include directories: Filter out anything that references a component
+ # library or anything in the project path
+ get_target_property(component_includes "${component}" INTERFACE_INCLUDE_DIRECTORIES)
+ foreach(component_include ${component_includes})
+ if(component_include MATCHES "${component_genex_regex}")
+ # Ignore component references
+
+ elseif(component_include MATCHES "^${PROJECT_SOURCE_DIR}")
+ # Include path within project; should only be included when building
+ list(APPEND includes "$")
+
+ else()
+ # Anything else gets included
+ list(APPEND includes "${component_include}")
+
+ endif()
+ endforeach(component_include)
+
+ # Link libraries: Filter out component libraries; we aren't linking
+ # against them, we're using their objects
+ get_target_property(component_libraries "${component}" INTERFACE_LINK_LIBRARIES)
+ foreach(component_library ${component_libraries})
+ if(NOT component_library)
+ # NOTFOUND - guess there are no INTERFACE_LINK_LIBRARIES
+
+ elseif(component_library MATCHES "${component_genex_regex}")
+ # Ignore component references
+
+ elseif(component_library MATCHES ".*(${piped_components}).*")
+ # Component library, ignore
+
+ else()
+ # Anything else gets included
+ list(APPEND libs "${component_library}")
+
+ endif()
+ endforeach(component_library)
+
+ # Consume this component's objects
+ list(APPEND sources "$")
+
+ else() # NOT BUILD_METALIBS
+ list(APPEND libs "${component}")
+
+ endif()
+ endforeach()
+
+ if(init_func)
+ set(init_source_path "${CMAKE_CURRENT_BINARY_DIR}/init_${target_name}.cxx")
+ set(init_header_path "${CMAKE_CURRENT_BINARY_DIR}/${init_header}")
+
+ configure_file("${PROJECT_SOURCE_DIR}/cmake/templates/metalib_init.cxx.in"
+ "${init_source_path}")
+ list(APPEND sources "${init_source_path}")
+
+ configure_file("${PROJECT_SOURCE_DIR}/cmake/templates/metalib_init.h.in"
+ "${init_header_path}")
+ install(FILES "${init_header_path}" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
+ endif()
+
+ add_library("${target_name}" ${sources})
+ target_compile_definitions("${target_name}"
+ PRIVATE ${private_defines}
+ INTERFACE ${interface_defines})
+ target_link_libraries("${target_name}" ${libs})
+ target_include_directories("${target_name}"
+ PUBLIC ${includes}
+ INTERFACE "$/${CMAKE_INSTALL_INCLUDEDIR}/panda3d>")
+
+endfunction(add_metalib)
diff --git a/cmake/macros/CompositeSources.cmake b/cmake/macros/CompositeSources.cmake
new file mode 100644
index 0000000000..82decc5400
--- /dev/null
+++ b/cmake/macros/CompositeSources.cmake
@@ -0,0 +1,167 @@
+# Filename: CompositeSources.cmake
+# Description: This file defines the function composite_sources which looks at
+# a provided list of sources, generates _compositeN.cxx, and appends the
+# composites to the list. The original files in the list are marked as headers
+# so that they will be available in an IDE, but not compiled at build time.
+#
+# Usage:
+# composite_sources(target source_var)
+#
+# Example:
+# set(MY_SOURCES a.cxx b.cxx c.cxx)
+# composite_sources(my_lib MY_SOURCES)
+# add_library(my_lib ${MY_SOURCES})
+#
+
+
+# Settings for composite builds. Should be moved to Config.cmake?
+set(CMAKE_UNITY_BUILD "ON" CACHE BOOL
+ "Enable unity builds; Panda defaults this to on.")
+
+set(CMAKE_UNITY_BUILD_BATCH_SIZE "30" CACHE STRING
+ "How many source files to build at a time through the unity build mechanism.
+ A high value will speed up the build dramatically but will be more memory
+ intensive than a low value.")
+
+set(COMPOSITE_SOURCE_EXTENSIONS ".cxx;.mm;.c" CACHE STRING
+ "Only files of these extensions will be composited.")
+
+set(COMPOSITE_SOURCE_EXCLUSIONS "" CACHE STRING
+ "A list of targets to skip when compositing sources. This is mainly
+desirable for CI builds.")
+
+set(COMPOSITE_GENERATOR "${CMAKE_SOURCE_DIR}/cmake/scripts/MakeComposite.cmake")
+
+
+# Define composite_sources()
+function(composite_sources target sources_var)
+ if(NOT CMAKE_VERSION VERSION_LESS "3.16")
+ # CMake 3.16+ implements CMAKE_UNITY_BUILD* natively; no need to continue!
+
+ # Actually - <=3.16.2 has difficulty with multi-language support, so only
+ # allow .cxx in. Hopefully this can be removed soon.
+ foreach(_source ${${sources_var}})
+ get_filename_component(_source_ext "${_source}" EXT)
+ if(NOT _source_ext STREQUAL ".cxx")
+ set_source_files_properties(${_source} PROPERTIES
+ SKIP_UNITY_BUILD_INCLUSION YES)
+ endif()
+ endforeach(_source)
+
+ return()
+ endif()
+
+ if(NOT CMAKE_UNITY_BUILD)
+ # We've been turned off
+ return()
+ endif()
+
+ # How many sources were specified?
+ set(orig_sources ${${sources_var}})
+ set(sources ${orig_sources})
+ list(LENGTH sources num_sources)
+
+ # Don't composite if in the list of exclusions, and don't bother compositing
+ # with too few sources
+ list (FIND COMPOSITE_SOURCE_EXCLUSIONS ${target} _index)
+ if(num_sources LESS 2 OR ${CMAKE_UNITY_BUILD_BATCH_SIZE} LESS 2 OR ${_index} GREATER -1)
+ return()
+ endif()
+
+ # Sort each source file into a list.
+ foreach(source ${sources})
+ get_filename_component(extension "${source}" EXT)
+ get_source_file_property(generated "${source}" GENERATED)
+ get_source_file_property(is_header "${source}" HEADER_FILE_ONLY)
+ get_source_file_property(skip_compositing "${source}" SKIP_UNITY_BUILD_INCLUSION)
+
+ # Check if we can safely add this to a composite file.
+ if(NOT generated AND NOT is_header AND NOT skip_compositing AND
+ ";${COMPOSITE_SOURCE_EXTENSIONS};" MATCHES ";${extension};")
+
+ if(NOT DEFINED sources_${extension})
+ set(sources_${extension})
+ endif()
+
+ # Append it to one of the lists.
+ list(APPEND sources_${extension} "${source}")
+ endif()
+ endforeach(source)
+
+ # Now, put it all into one big list!
+ set(sorted_sources)
+ foreach(extension ${COMPOSITE_SOURCE_EXTENSIONS})
+ if(DEFINED sources_${extension})
+ list(APPEND sorted_sources ${sources_${extension}})
+ endif()
+ endforeach(extension)
+
+ set(composite_files)
+ set(composite_sources)
+
+ # Fill in composite_ext so we can kick off the loop.
+ list(GET sorted_sources 0 first_source)
+ get_filename_component(first_source_ext "${first_source}" EXT)
+ set(composite_ext ${first_source_ext})
+
+ while(num_sources GREATER 0)
+ # Pop the first element and adjust the sorted_sources length accordingly.
+ list(GET sorted_sources 0 source)
+ list(REMOVE_AT sorted_sources 0)
+ list(LENGTH sorted_sources num_sources)
+
+ # Add this file to our composite_sources buffer.
+ list(APPEND composite_sources ${source})
+ list(LENGTH composite_sources num_composite_sources)
+
+ # Get the next source file's extension, so we can see if we're done with
+ # this set of source files.
+ if(num_sources GREATER 0)
+ list(GET sorted_sources 0 next_source)
+ get_filename_component(next_extension "${next_source}" EXT)
+ else()
+ set(next_extension "")
+ endif()
+
+ # Check if this is the point where we should cut the file.
+ if(num_sources EQUAL 0 OR NOT num_composite_sources LESS ${CMAKE_UNITY_BUILD_BATCH_SIZE}
+ OR NOT composite_ext STREQUAL next_extension)
+ # It's pointless to make a composite source from just one file.
+ if(num_composite_sources GREATER 1)
+
+ # Figure out the name of our composite file.
+ list(LENGTH composite_files index)
+ math(EXPR index "1+${index}")
+ set(composite_file "${CMAKE_CURRENT_BINARY_DIR}/${target}_composite${index}${composite_ext}")
+ list(APPEND composite_files "${composite_file}")
+
+ # Set HEADER_FILE_ONLY to prevent it from showing up in the
+ # compiler command, but still show up in the IDE environment.
+ set_source_files_properties(${composite_sources} PROPERTIES HEADER_FILE_ONLY ON)
+
+ # We'll interrogate the composite files, so exclude the original sources.
+ set_source_files_properties(${composite_sources} PROPERTIES WRAP_EXCLUDE YES)
+
+ # Finally, add the target that generates the composite file.
+ add_custom_command(
+ OUTPUT "${composite_file}"
+ COMMAND ${CMAKE_COMMAND}
+ -DCOMPOSITE_FILE="${composite_file}"
+ -DCOMPOSITE_SOURCES="${composite_sources}"
+ -P "${COMPOSITE_GENERATOR}"
+ DEPENDS ${composite_sources})
+ endif()
+
+ # Reset for the next composite file.
+ set(composite_sources "")
+ set(composite_ext ${next_extension})
+ endif()
+ endwhile()
+
+ set_source_files_properties(${composite_files} PROPERTIES GENERATED YES)
+
+ # The new files are added to the existing files, which means the old files
+ # are still there, but they won't be compiled due to the HEADER_FILE_ONLY setting.
+ set(${sources_var} ${orig_sources} ${composite_files} PARENT_SCOPE)
+
+endfunction(composite_sources)
diff --git a/cmake/macros/Interrogate.cmake b/cmake/macros/Interrogate.cmake
new file mode 100644
index 0000000000..eb441e4b13
--- /dev/null
+++ b/cmake/macros/Interrogate.cmake
@@ -0,0 +1,400 @@
+# Filename: Interrogate.cmake
+#
+# Description: This file contains macros and functions that are used to invoke
+# interrogate, to generate wrappers for Python and/or other languages.
+#
+# Functions:
+# target_interrogate(target [ALL] [source1 [source2 ...]])
+# add_python_module(module [lib1 [lib2 ...]])
+# add_python_target(target [source1 [source2 ...]])
+#
+
+set(IGATE_FLAGS -DCPPPARSER -D__cplusplus -Dvolatile -Dmutable)
+
+# In addition, Interrogate needs to know if this is a 64-bit build:
+include(CheckTypeSize)
+check_type_size(long CMAKE_SIZEOF_LONG)
+if(CMAKE_SIZEOF_LONG EQUAL 8)
+ list(APPEND IGATE_FLAGS "-D_LP64")
+endif()
+
+
+# This is a list of regexes that are applied to every filename. If one of the
+# regexes matches, that file will not be passed to Interrogate.
+set(INTERROGATE_EXCLUDE_REGEXES
+ ".*\\.I$"
+ ".*\\.N$"
+ ".*\\.c$"
+ ".*\\.lxx$"
+ ".*\\.yxx$"
+ ".*_src\\..*"
+)
+
+if(WIN32)
+ list(APPEND IGATE_FLAGS -D_X86_ -D__STDC__=1 -D "_declspec(param)=" -D "__declspec(param)=" -D_near -D_far -D__near -D__far -D_WIN32 -D__stdcall)
+endif()
+if(MSVC_VERSION)
+ list(APPEND IGATE_FLAGS "-D_MSC_VER=${MSVC_VERSION}")
+endif()
+if(INTERROGATE_VERBOSE)
+ list(APPEND IGATE_FLAGS "-v")
+endif()
+
+set(IMOD_FLAGS -python-native)
+
+# This stores the names of every module added to the Interrogate system:
+set(ALL_INTERROGATE_MODULES CACHE INTERNAL "Internal variable")
+
+#
+# Function: target_interrogate(target [ALL] [source1 [source2 ...]])
+# NB. This doesn't actually invoke interrogate, but merely adds the
+# sources to the list of scan sources associated with the target.
+# Interrogate will be invoked when add_python_module is called.
+# If ALL is specified, all of the sources from the associated
+# target are added.
+#
+function(target_interrogate target)
+ set(sources)
+ set(extensions)
+ set(want_all OFF)
+ set(extensions_keyword OFF)
+ foreach(arg ${ARGN})
+ if(arg STREQUAL "ALL")
+ set(want_all ON)
+
+ elseif(arg STREQUAL "EXTENSIONS")
+ set(extensions_keyword ON)
+
+ elseif(extensions_keyword)
+ list(APPEND extensions "${arg}")
+
+ else()
+ list(APPEND sources "${arg}")
+
+ endif()
+ endforeach()
+
+ # If ALL was specified, pull in all sources from the target.
+ if(want_all)
+ get_target_property(target_sources "${target}" SOURCES)
+ list(APPEND sources ${target_sources})
+ endif()
+
+ list(REMOVE_DUPLICATES sources)
+
+ # Now let's get everything's absolute path, so that it can be passed
+ # through a property while still preserving the reference.
+ set(absolute_sources)
+ foreach(source ${sources})
+ get_source_file_property(exclude "${source}" WRAP_EXCLUDE)
+ if(NOT exclude)
+ get_source_file_property(location "${source}" LOCATION)
+ list(APPEND absolute_sources ${location})
+ endif()
+ endforeach(source)
+
+ set(absolute_extensions)
+ foreach(extension ${extensions})
+ get_source_file_property(location "${extension}" LOCATION)
+ list(APPEND absolute_extensions ${location})
+ endforeach(extension)
+
+ set_target_properties("${target}" PROPERTIES
+ IGATE_SOURCES "${absolute_sources}")
+ set_target_properties("${target}" PROPERTIES
+ IGATE_EXTENSIONS "${absolute_extensions}")
+
+ # CMake has no property for determining the source directory where the
+ # target was originally added. interrogate_sources makes use of this
+ # property (if it is set) in order to make all paths on the command-line
+ # relative to it, thereby shortening the command-line even more.
+ # Since this is not an Interrogate-specific property, it is not named with
+ # an IGATE_ prefix.
+ set_target_properties("${target}" PROPERTIES
+ TARGET_SRCDIR "${CMAKE_CURRENT_SOURCE_DIR}")
+
+ # Also store where the build files are kept, so the Interrogate output can go
+ # there as well.
+ set_target_properties("${target}" PROPERTIES
+ TARGET_BINDIR "${CMAKE_CURRENT_BINARY_DIR}/${PANDA_CFG_INTDIR}")
+
+endfunction(target_interrogate)
+
+#
+# Function: interrogate_sources(target output database language_flags module)
+#
+# This function actually runs a component-level interrogation against 'target'.
+# It generates the outfile.cxx (output) and dbfile.in (database) files, which
+# can then be used during the interrogate_module step to produce language
+# bindings.
+#
+# The target must first have had sources selected with target_interrogate.
+# Failure to do so will result in an error.
+#
+function(interrogate_sources target output database language_flags)
+ get_target_property(sources "${target}" IGATE_SOURCES)
+ get_target_property(extensions "${target}" IGATE_EXTENSIONS)
+
+ if(NOT sources)
+ message(FATAL_ERROR
+ "Cannot interrogate ${target} unless it's run through target_interrogate first!")
+ endif()
+
+ get_target_property(srcdir "${target}" TARGET_SRCDIR)
+ if(NOT srcdir)
+ # No TARGET_SRCDIR was set, so we'll do everything relative to our
+ # current binary dir instead:
+ set(srcdir "${CMAKE_CURRENT_BINARY_DIR}")
+ endif()
+
+ set(scan_sources)
+ set(nfiles)
+ foreach(source ${sources})
+ get_filename_component(source_basename "${source}" NAME)
+
+ # Only certain sources should actually be scanned by Interrogate. The
+ # rest are merely dependencies. This uses the exclusion regex above in
+ # order to determine what files are okay:
+ set(exclude OFF)
+ foreach(regex ${INTERROGATE_EXCLUDE_REGEXES})
+ if("${source_basename}" MATCHES "${regex}")
+ set(exclude ON)
+ endif()
+ endforeach(regex)
+
+ if(NOT exclude)
+ # This file is to be scanned by Interrogate. In order to avoid
+ # cluttering up the command line, we should first make it relative:
+ file(RELATIVE_PATH rel_source "${srcdir}" "${source}")
+ list(APPEND scan_sources "${rel_source}")
+
+ # Also see if this file has a .N counterpart, which has directives
+ # specific for Interrogate. If there is a .N file, we add it as a dep,
+ # so that CMake will rerun Interrogate if the .N files are modified:
+ get_filename_component(source_path "${source}" PATH)
+ get_filename_component(source_name_we "${source}" NAME_WE)
+ set(nfile "${source_path}/${source_name_we}.N")
+ if(EXISTS "${nfile}")
+ list(APPEND nfiles "${nfile}")
+ endif()
+ endif()
+ endforeach(source)
+
+ # Also add extensions, in relative-path form
+ foreach(extension ${extensions})
+ file(RELATIVE_PATH rel_extension "${srcdir}" "${extension}")
+ list(APPEND scan_sources "${rel_extension}")
+ endforeach(extension)
+
+ # Interrogate also needs the include paths, so we'll extract them from the
+ # target. These are available via a generator expression.
+
+ # When we read the INTERFACE_INCLUDE_DIRECTORIES property, we need to read it
+ # from a target that has the IS_INTERROGATE=1 property.
+ # (See PackageConfig.cmake for an explanation why.)
+ # The problem is, custom commands are not targets, so we can't put target
+ # properties on them. And if you try to use the $
+ # generator expression from the context of a custom command, it'll instead
+ # read the property from the most recent actual target. As a workaround for
+ # this, we create a fake target with the IS_INTERROGATE property set and pull
+ # the INTERFACE_INCLUDE_DIRECTORIES property out through that.
+ # I hate it, but such is CMake.
+ add_custom_target(${target}_igate_internal)
+ set_target_properties(${target}_igate_internal PROPERTIES
+ IS_INTERROGATE 1
+ INTERFACE_INCLUDE_DIRECTORIES "$")
+
+ # Note, the \t is a workaround for a CMake bug where using a plain space in
+ # a JOIN will cause it to be escaped. Tabs are not escaped and will
+ # separate correctly.
+ set(include_flags "-I$,\t-I>")
+
+ # Get the compiler definition flags. These must be passed to Interrogate
+ # in the same way that they are passed to the compiler so that Interrogate
+ # will preprocess each file in the same way.
+ set(_compile_defs "$")
+ if(NOT CMAKE_HOST_WIN32)
+ # Win32's command-line parser doesn't understand "'"
+ # that's fine, it also ignores '"'
+ set(_q "'")
+ endif()
+ set(_compile_defs_flags "-D${_q}$${_q}")
+ # We may have just ended up with -D'' if there are no flags; filter that
+ set(define_flags
+ "$<$>:${_compile_defs_flags}>")
+
+ # Some of the definitions may be specified using -D flags in the global
+ # CXX_FLAGS variables; parse those out (this also picks up NDEBUG)
+ set(_configs ${CMAKE_CONFIGURATION_TYPES} ${CMAKE_BUILD_TYPE} "")
+ list(REMOVE_DUPLICATES _configs)
+ foreach(_config ${_configs})
+ if(_config STREQUAL "")
+ set(flags "${CMAKE_CXX_FLAGS}")
+ else()
+ string(TOUPPER "${_config}" _CONFIG)
+ set(flags "${CMAKE_CXX_FLAGS_${_CONFIG}}")
+ endif()
+
+ # Convert "/D define1" and "-Ddefine2" flags, interspersed with other
+ # compiler nonsense, into a basic "-Ddefine1 -Ddefine2" string
+ string(REGEX MATCHALL "[/-]D[ \t]*[A-Za-z0-9_]+" igate_flags "${flags}")
+ string(REPLACE ";" " " igate_flags "${igate_flags}")
+ string(REPLACE "/D" "-D" igate_flags "${igate_flags}")
+
+ if(_config STREQUAL "")
+ list(APPEND define_flags "${igate_flags}")
+ else()
+ list(APPEND define_flags "$<$:${igate_flags}>")
+ endif()
+ endforeach(_config)
+
+ get_filename_component(output_directory "${output}" DIRECTORY)
+ get_filename_component(database_directory "${database}" DIRECTORY)
+
+ add_custom_command(
+ OUTPUT "${output}" "${database}"
+ COMMAND ${CMAKE_COMMAND} -E
+ make_directory "${output_directory}"
+ COMMAND ${CMAKE_COMMAND} -E
+ make_directory "${database_directory}"
+ COMMAND host_interrogate
+ -oc "${output}"
+ -od "${database}"
+ -srcdir "${srcdir}"
+ -library ${target}
+ ${INTERROGATE_OPTIONS}
+ ${IGATE_FLAGS}
+ ${language_flags}
+ ${define_flags}
+ -S "${PROJECT_SOURCE_DIR}/dtool/src/interrogatedb"
+ -S "${PROJECT_SOURCE_DIR}/dtool/src/parser-inc"
+ -S "${PYTHON_INCLUDE_DIRS}"
+ ${include_flags}
+ ${scan_sources}
+
+ DEPENDS host_interrogate ${sources} ${extensions} ${nfiles}
+ COMMENT "Interrogating ${target}")
+
+ # Propagate the target's compile definitions to the output file
+ set_source_files_properties("${output}" PROPERTIES
+ COMPILE_DEFINITIONS "$")
+
+endfunction(interrogate_sources)
+
+#
+# Function: add_python_module(module [lib1 [lib2 ...]] [LINK lib1 ...]
+# [IMPORT mod1 ...])
+# Uses interrogate to create a Python module. If the LINK keyword is specified,
+# the Python module is linked against the specified libraries instead of those
+# listed before. The IMPORT keyword makes the output module import another
+# Python module when it's initialized.
+#
+function(add_python_module module)
+ if(NOT INTERROGATE_PYTHON_INTERFACE)
+ return()
+ endif()
+
+ set(targets)
+ set(component "Python")
+ set(link_targets)
+ set(import_flags)
+ set(infiles_rel)
+ set(infiles_abs)
+ set(sources_abs)
+ set(extensions)
+
+ set(keyword)
+ foreach(arg ${ARGN})
+ if(arg STREQUAL "LINK" OR arg STREQUAL "IMPORT" OR arg STREQUAL "COMPONENT")
+ set(keyword "${arg}")
+
+ elseif(keyword STREQUAL "LINK")
+ list(APPEND link_targets "${arg}")
+ set(keyword)
+
+ elseif(keyword STREQUAL "IMPORT")
+ list(APPEND import_flags "-import" "${arg}")
+ set(keyword)
+
+ elseif(keyword STREQUAL "COMPONENT")
+ set(component "${arg}")
+ set(keyword)
+
+ else()
+ list(APPEND targets "${arg}")
+
+ endif()
+ endforeach(arg)
+
+ if(NOT link_targets)
+ set(link_targets ${targets})
+ endif()
+
+ string(REGEX REPLACE "^.*\\." "" modname "${module}")
+
+ foreach(target ${targets})
+ get_target_property(workdir_abs "${target}" TARGET_BINDIR)
+ if(NOT workdir_abs)
+ # No TARGET_BINDIR was set, so we'll just use our current directory:
+ set(workdir_abs "${CMAKE_CURRENT_BINARY_DIR}/${PANDA_CFG_INTDIR}")
+ endif()
+ # Keep command lines short
+ file(RELATIVE_PATH workdir_rel "${CMAKE_CURRENT_BINARY_DIR}" "${workdir_abs}")
+
+ interrogate_sources(${target}
+ "${workdir_abs}/${target}_igate.cxx"
+ "${workdir_abs}/${target}.in"
+ "-python-native;-module;${module}")
+
+ get_target_property(target_extensions "${target}" IGATE_EXTENSIONS)
+ list(APPEND infiles_rel "${workdir_rel}/${target}.in")
+ list(APPEND infiles_abs "${workdir_abs}/${target}.in")
+ list(APPEND sources_abs "${workdir_abs}/${target}_igate.cxx")
+ list(APPEND extensions ${target_extensions})
+ endforeach(target)
+
+ add_custom_command(
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${PANDA_CFG_INTDIR}/${module}_module.cxx"
+ COMMAND ${CMAKE_COMMAND} -E
+ make_directory "${CMAKE_CURRENT_BINARY_DIR}/${PANDA_CFG_INTDIR}"
+ COMMAND host_interrogate_module
+ -oc "${CMAKE_CURRENT_BINARY_DIR}/${PANDA_CFG_INTDIR}/${module}_module.cxx"
+ -module ${modname} -library ${modname}
+ ${import_flags}
+ ${INTERROGATE_MODULE_OPTIONS}
+ ${IMOD_FLAGS} ${infiles_rel}
+ DEPENDS host_interrogate_module ${infiles_abs}
+ COMMENT "Generating module ${module}")
+
+ # CMake chokes on ${CMAKE_CFG_INTDIR} in source paths when unity builds are
+ # enabled. The easiest way out of this is to skip unity for those paths.
+ # Since generated Interrogate .cxx files are pretty big already, this doesn't
+ # really inconvenience us at all.
+ set_source_files_properties(
+ "${CMAKE_CURRENT_BINARY_DIR}/${PANDA_CFG_INTDIR}/${module}_module.cxx"
+ ${sources_abs} PROPERTIES
+ SKIP_UNITY_BUILD_INCLUSION YES)
+
+ add_python_target(${module} COMPONENT "${component}" EXPORT "${component}"
+ "${CMAKE_CURRENT_BINARY_DIR}/${PANDA_CFG_INTDIR}/${module}_module.cxx"
+ ${sources_abs} ${extensions})
+ target_link_libraries(${module} ${link_targets})
+
+ if(CMAKE_VERSION VERSION_LESS "3.11")
+ # CMake <3.11 doesn't allow generator expressions on source files, so we
+ # need to copy them to our target, which does allow them.
+
+ foreach(source ${sources_abs})
+ get_source_file_property(compile_definitions "${source}" COMPILE_DEFINITIONS)
+ if(compile_definitions)
+ set_property(TARGET ${module} APPEND PROPERTY
+ COMPILE_DEFINITIONS ${compile_definitions})
+
+ set_source_files_properties("${source}" PROPERTIES COMPILE_DEFINITIONS "")
+ endif()
+ endforeach(source)
+ endif()
+
+ list(APPEND ALL_INTERROGATE_MODULES "${module}")
+ set(ALL_INTERROGATE_MODULES "${ALL_INTERROGATE_MODULES}" CACHE INTERNAL "Internal variable")
+endfunction(add_python_module)
diff --git a/cmake/macros/PackageConfig.cmake b/cmake/macros/PackageConfig.cmake
new file mode 100644
index 0000000000..b3160e49fe
--- /dev/null
+++ b/cmake/macros/PackageConfig.cmake
@@ -0,0 +1,506 @@
+# Filename: PackageConfig.cmake
+#
+# This module defines functions which find and configure libraries
+# and packages for Panda3D.
+#
+# Assumes an attempt to find the package has already been made with
+# find_package(). (i.e. relies on packagename_FOUND variable)
+#
+# The packages are added as imported/interface libraries in the PKG::
+# namespace. If the package is not found (or disabled by the user),
+# a dummy package will be created instead. Therefore, it is safe
+# to link against the PKG::PACKAGENAME target unconditionally.
+#
+# Function: package_option
+# Usage:
+# package_option(package_name package_doc_string
+# [DEFAULT ON | OFF]
+# [IMPORTED_AS CMake::Imported::Target [...]]
+# [FOUND_AS find_name]
+# [LICENSE license])
+#
+# Examples:
+# package_option(LIBNAME "Enables LIBNAME support." DEFAULT OFF)
+#
+# If no default is given, the default in normal
+# builds is to enable all found third-party packages.
+# In builds for redistribution, there is the additional requirement that
+# the package be suitably-licensed.
+#
+# FOUND_AS indicates the name of the CMake find_package() module, which
+# may differ from Panda3D's internal name for that package.
+#
+# IMPORTED_AS is used to indicate that the find_package() may have
+# provided one or more IMPORTED targets, and that if at least one is
+# found, the IMPORTED target(s) should be used instead of the
+# variables provided by find_package()
+#
+#
+# Function: package_status
+# Usage:
+# package_status(package_name "Package description" ["Config summary"])
+#
+# Examples:
+# package_status(OpenAL "OpenAL Audio Output")
+# package_status(ROCKET "Rocket" "without Python bindings")
+#
+#
+# Function: show_packages
+# Usage:
+# show_packages()
+#
+# This prints the package usage report using the information provided in
+# calls to package_status above.
+#
+
+set(_ALL_PACKAGE_OPTIONS CACHE INTERNAL "Internal variable")
+
+#
+# package_option
+#
+# In order to make sure no third-party licenses are inadvertently violated,
+# this imposes a few rules regarding license:
+# 1) If there is no license, no special restrictions.
+# 2) If there is a license, but the build is not flagged for redistribution,
+# no special restrictions.
+# 3) If there is a license, and this is for redistribution, the package is
+# forcibly defaulted off and must be explicitly enabled, unless the license
+# matches a list of licenses suitable for redistribution.
+#
+function(package_option name)
+ # Parse the arguments.
+ set(command)
+ set(default)
+ set(found_as "${name}")
+ set(imported_as)
+ set(license "")
+ set(cache_string)
+
+ string(TOUPPER "${name}" name)
+
+ foreach(arg ${ARGN})
+ if(command STREQUAL "DEFAULT")
+ set(default "${arg}")
+ set(command)
+
+ elseif(command STREQUAL "FOUND_AS")
+ set(found_as "${arg}")
+ set(command)
+
+ elseif(command STREQUAL "LICENSE")
+ set(license "${arg}")
+ set(command)
+
+ elseif(arg STREQUAL "DEFAULT")
+ set(command "DEFAULT")
+
+ elseif(arg STREQUAL "FOUND_AS")
+ set(command "FOUND_AS")
+
+ elseif(arg STREQUAL "LICENSE")
+ set(command "LICENSE")
+
+ elseif(arg STREQUAL "IMPORTED_AS")
+ set(command "IMPORTED_AS")
+
+ elseif(command STREQUAL "IMPORTED_AS")
+ list(APPEND imported_as "${arg}")
+
+ else()
+ # Yes, a list, because semicolons can be in there, and
+ # that gets split up into multiple args, so we have to
+ # join it back together here.
+ list(APPEND cache_string "${arg}")
+
+ endif()
+ endforeach()
+
+ if(command AND NOT command STREQUAL "IMPORTED_AS")
+ message(SEND_ERROR "${command} in package_option takes an argument")
+ endif()
+
+ # If the default is not set, we set it.
+ if(NOT DEFINED default)
+ if(IS_DIST_BUILD)
+ # Accept things that don't have a configured license
+ if(license STREQUAL "")
+ set(default "${${found_as}_FOUND}")
+
+ else()
+ list(FIND PANDA_DIST_USE_LICENSES ${license} license_index)
+ # If the license isn't in the accept listed, don't use the package
+ if(${license_index} EQUAL "-1")
+ set(default OFF)
+
+ else()
+ set(default "${${found_as}_FOUND}")
+
+ endif()
+
+ endif()
+
+ else()
+ set(default "${${found_as}_FOUND}")
+
+ endif()
+ endif()
+
+ # If it was set by the user but not found, display an error.
+ string(TOUPPER "${found_as}" FOUND_AS)
+ if(HAVE_${name} AND NOT ${found_as}_FOUND AND NOT ${FOUND_AS}_FOUND)
+ message(SEND_ERROR "NOT FOUND: ${name}. Disable HAVE_${name} to continue.")
+ endif()
+
+ # Prevent the function from being called twice.
+ # This would indicate a cmake error.
+ if(";${_ALL_PACKAGE_OPTIONS};" MATCHES ";${name};")
+ message(SEND_ERROR "package_option(${name}) was called twice.
+ This is a bug in the cmake build scripts.")
+
+ else()
+ list(APPEND _ALL_PACKAGE_OPTIONS "${name}")
+ set(_ALL_PACKAGE_OPTIONS "${_ALL_PACKAGE_OPTIONS}" CACHE INTERNAL "Internal variable")
+
+ endif()
+
+ set(PANDA_PACKAGE_DEFAULT_${name} "${default}" PARENT_SCOPE)
+
+ # Create the INTERFACE library used to depend on this package.
+ add_library(PKG::${name} INTERFACE IMPORTED GLOBAL)
+
+ # Explicitly record the package's include directories as system include
+ # directories. CMake does do this automatically for INTERFACE libraries, but
+ # it does it by discovering all transitive links first, then reading
+ # INTERFACE_INCLUDE_DIRECTORIES for those which are INTERFACE libraries. So,
+ # this would be broken for the metalib system (pre CMake 3.12) which doesn't
+ # "link" the object libraries.
+ if(CMAKE_VERSION VERSION_LESS "3.12")
+ set_target_properties(PKG::${name} PROPERTIES
+ INTERFACE_SYSTEM_INCLUDE_DIRECTORIES
+ "$")
+ endif()
+
+ # Create the option, and if it actually is enabled, populate the INTERFACE
+ # library created above
+ option("HAVE_${name}" "${cache_string}" "${default}")
+ if(HAVE_${name})
+ set(use_variables ON)
+
+ # This is gross, but we actually want to hide package include directories
+ # from Interrogate to make sure it relies on parser-inc instead, so we'll
+ # use some generator expressions to do that.
+ set(_is_not_interface_lib
+ "$,INTERFACE_LIBRARY>>")
+ set(_is_not_interrogate
+ "$>>>")
+
+ foreach(implib ${imported_as})
+ if(TARGET ${implib})
+ # We found one of the implibs, so we don't need to use variables
+ # (below) anymore
+ set(use_variables OFF)
+
+ # Hide it from Interrogate
+ target_link_libraries(PKG::${name} INTERFACE
+ "$<${_is_not_interrogate}:$>")
+ endif()
+ endforeach(implib)
+
+ if(use_variables)
+ if(DEFINED ${found_as}_INCLUDE_DIRS)
+ set(includes ${${found_as}_INCLUDE_DIRS})
+ elseif(DEFINED ${found_as}_INCLUDE_DIR)
+ set(includes "${${found_as}_INCLUDE_DIR}")
+ elseif(DEFINED ${FOUND_AS}_INCLUDE_DIRS)
+ set(includes ${${FOUND_AS}_INCLUDE_DIRS})
+ else()
+ set(includes "${${FOUND_AS}_INCLUDE_DIR}")
+ endif()
+
+ if(DEFINED ${found_as}_LIBRARIES)
+ set(libs ${${found_as}_LIBRARIES})
+ elseif(DEFINED ${found_as}_LIBRARY)
+ set(libs "${${found_as}_LIBRARY}")
+ elseif(DEFINED ${FOUND_AS}_LIBRARIES)
+ set(libs ${${FOUND_AS}_LIBRARIES})
+ else()
+ set(libs "${${FOUND_AS}_LIBRARY}")
+ endif()
+
+ target_link_libraries(PKG::${name} INTERFACE ${libs})
+
+ # Hide it from Interrogate
+ set_target_properties(PKG::${name} PROPERTIES
+ INTERFACE_INCLUDE_DIRECTORIES "$<${_is_not_interrogate}:${includes}>")
+ endif()
+ endif()
+endfunction(package_option)
+
+set(_ALL_CONFIG_PACKAGES CACHE INTERNAL "Internal variable")
+
+#
+# package_status
+#
+function(package_status name desc)
+ set(note "")
+ foreach(arg ${ARGN})
+ set(note "${arg}")
+ endforeach()
+
+ string(TOUPPER "${name}" name)
+
+ if(NOT ";${_ALL_PACKAGE_OPTIONS};" MATCHES ";${name};")
+ message(SEND_ERROR "package_status(${name}) was called before package_option(${name}).
+ This is a bug in the cmake build scripts.")
+ return()
+ endif()
+
+ if(";${_ALL_CONFIG_PACKAGES};" MATCHES ";${name};")
+ message(SEND_ERROR "package_status(${name}) was called twice.
+ This is a bug in the cmake build scripts.")
+
+ else()
+ list(APPEND _ALL_CONFIG_PACKAGES "${name}")
+ set(_ALL_CONFIG_PACKAGES "${_ALL_CONFIG_PACKAGES}" CACHE INTERNAL "Internal variable")
+
+ endif()
+
+ set(PANDA_PACKAGE_DESC_${name} "${desc}" PARENT_SCOPE)
+ set(PANDA_PACKAGE_NOTE_${name} "${note}" PARENT_SCOPE)
+endfunction()
+
+#
+# show_packages
+#
+function(show_packages)
+ message("")
+ message("Configuring support for the following optional third-party packages:")
+
+ foreach(package ${_ALL_CONFIG_PACKAGES})
+ set(desc "${PANDA_PACKAGE_DESC_${package}}")
+ set(note "${PANDA_PACKAGE_NOTE_${package}}")
+ if(HAVE_${package})
+ if(NOT note STREQUAL "")
+ message("+ ${desc} (${note})")
+ else()
+ message("+ ${desc}")
+ endif()
+
+ else()
+ if(NOT ${package}_FOUND)
+ set(reason "not found")
+ elseif(NOT PANDA_PACKAGE_DEFAULT_${package})
+ set(reason "not requested")
+ else()
+ set(reason "disabled")
+ endif()
+
+ message("- ${desc} (${reason})")
+
+ endif()
+ endforeach()
+endfunction()
+
+#
+# export_packages(filename)
+#
+# Generates an includable CMake file that contains definitions for every PKG::
+# package defined.
+#
+function(export_packages filename)
+ set(exports "# Exports for Panda3D PKG:: packages\n")
+
+ foreach(pkg ${_ALL_PACKAGE_OPTIONS})
+ set(exports "${exports}\n# Create imported target PKG::${pkg}\n")
+ set(exports "${exports}add_library(PKG::${pkg} INTERFACE IMPORTED)\n\n")
+
+ set(exports "${exports}set_target_properties(PKG::${pkg} PROPERTIES\n")
+ foreach(prop
+ INTERFACE_COMPILE_DEFINITIONS
+ INTERFACE_COMPILE_FEATURES
+ INTERFACE_COMPILE_OPTIONS
+ INTERFACE_INCLUDE_DIRECTORIES
+ INTERFACE_LINK_DEPENDS
+ INTERFACE_LINK_DIRECTORIES
+ INTERFACE_LINK_OPTIONS
+ INTERFACE_POSITION_INDEPENDENT_CODE
+ #INTERFACE_SYSTEM_INCLUDE_DIRECTORIES # Let the consumer dictate this
+ INTERFACE_SOURCES)
+
+ set(prop_ex "$")
+ set(exports "${exports}$<$: ${prop} \"${prop_ex}\"\n>")
+
+ endforeach(prop)
+
+ # Ugh, INTERFACE_LINK_LIBRARIES isn't transitive. Fine. Take care of it
+ # by hand:
+ set(libraries)
+ set(stack "PKG::${pkg}")
+ set(history)
+ while(stack)
+ # Remove head item from stack
+ unset(head)
+ while(NOT DEFINED head)
+ if(NOT stack)
+ break()
+ endif()
+
+ list(GET stack 0 head)
+ list(REMOVE_AT stack 0)
+
+ # Don't visit anything twice
+ list(FIND history "${head}" _index)
+ if(_index GREATER -1)
+ unset(head)
+ endif()
+ endwhile()
+
+ if(head)
+ list(APPEND history "${head}")
+ else()
+ break()
+ endif()
+
+ # If head isn't a target, add it to `libraries`, else recurse
+ if(TARGET "${head}")
+ get_target_property(link_libs "${head}" INTERFACE_LINK_LIBRARIES)
+ if(link_libs)
+ list(APPEND stack ${link_libs})
+ endif()
+
+ get_target_property(type "${head}" TYPE)
+ if(NOT type STREQUAL "INTERFACE_LIBRARY")
+ get_target_property(imported_location "${head}" IMPORTED_LOCATION)
+ get_target_property(imported_implib "${head}" IMPORTED_IMPLIB)
+ if(imported_implib)
+ list(APPEND libraries ${imported_implib})
+ elseif(imported_location)
+ list(APPEND libraries ${imported_location})
+ endif()
+
+ get_target_property(configs "${head}" IMPORTED_CONFIGURATIONS)
+ if(configs AND NOT imported_location)
+ foreach(config ${configs})
+ get_target_property(imported_location "${head}" IMPORTED_LOCATION_${config})
+
+ # Prefer IMPORTED_IMPLIB where present
+ get_target_property(imported_implib "${head}" IMPORTED_IMPLIB_${config})
+ if(imported_implib)
+ set(imported_location "${imported_implib}")
+ endif()
+
+ if(imported_location)
+ if(configs MATCHES ".*;.*")
+ set(_bling "$<1:$>") # genex-escaped $
+ list(APPEND libraries "${_bling}<${_bling}:${imported_location}>")
+
+ else()
+ list(APPEND libraries ${imported_location})
+
+ endif()
+ endif()
+ endforeach(config)
+ endif()
+
+ elseif(CMAKE_VERSION VERSION_GREATER "3.8")
+ # This is an INTERFACE_LIBRARY, and CMake is new enough to support
+ # IMPORTED_IMPLIB
+ get_target_property(imported_libname "${head}" IMPORTED_LIBNAME)
+ if(imported_libname)
+ list(APPEND libraries ${imported_libname})
+ endif()
+
+ endif()
+
+ elseif("${head}" MATCHES "\\$]+\)>")
+ string(REGEX REPLACE ".*\\$]+\)>.*" "\\1" match "${head}")
+ list(APPEND stack "${match}")
+
+ else()
+ list(APPEND libraries "${head}")
+
+ endif()
+ endwhile(stack)
+
+ set(exports "${exports} INTERFACE_LINK_LIBRARIES \"${libraries}\"\n")
+
+ set(exports "${exports})\n")
+ endforeach(pkg)
+
+ # file(GENERATE) does not like $ (and it's meant to be
+ # consumed by our importer) so we escape it
+ set(_bling "$<1:$>") # genex-escaped $
+ string(REPLACE "$ "${destination}/${dstfile}" < "${source}/${filename}"
+ DEPENDS host_pzip
+ COMMENT "")
+
+ else()
+ # If pzip isn't built, we just copy instead.
+ list(APPEND dstfiles "${destination}/${filename}")
+
+ add_custom_command(OUTPUT "${destination}/${filename}"
+ COMMAND ${CMAKE_COMMAND} -E
+ copy_if_different "${source}/${filename}" "${destination}/${filename}"
+ COMMENT "")
+
+ endif()
+
+ endforeach(filename)
+
+ add_custom_target(${target_name} ALL
+ DEPENDS ${dstfiles}
+ WORKING_DIRECTORY "${destination}")
+
+endfunction(run_pzip)
diff --git a/cmake/macros/Versioning.cmake b/cmake/macros/Versioning.cmake
new file mode 100644
index 0000000000..33dbeb87d2
--- /dev/null
+++ b/cmake/macros/Versioning.cmake
@@ -0,0 +1,21 @@
+# Filename: Versioning.cmake
+#
+# Description: Contains an override for add_library to set the
+# VERSION and SOVERSION properties on all shared libraries, automatically, to
+# the project version.
+#
+# Functions:
+# add_library(...)
+#
+
+function(add_library target_name)
+ _add_library("${target_name}" ${ARGN})
+
+ get_target_property(type "${target_name}" TYPE)
+ if(type STREQUAL "SHARED_LIBRARY")
+ set_target_properties("${target_name}" PROPERTIES
+ VERSION "${PROJECT_VERSION}"
+ SOVERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}")
+ endif()
+
+endfunction(add_library)
diff --git a/cmake/modules/FindARToolKit.cmake b/cmake/modules/FindARToolKit.cmake
new file mode 100644
index 0000000000..fa383768e6
--- /dev/null
+++ b/cmake/modules/FindARToolKit.cmake
@@ -0,0 +1,33 @@
+# Filename: FindARToolKit.cmake
+# Authors: CFSworks (3 Nov, 2018)
+#
+# Usage:
+# find_package(ARToolKit [REQUIRED] [QUIET])
+#
+# Once done this will define:
+# ARTOOLKIT_FOUND - system has ARToolKit
+# ARTOOLKIT_INCLUDE_DIR - the include directory containing ARToolKit header files
+# ARTOOLKIT_LIBRARIES - the paths to the ARToolKit client libraries
+#
+
+find_path(ARTOOLKIT_INCLUDE_DIR "AR/ar.h")
+
+find_library(ARTOOLKIT_AR_LIBRARY
+ NAMES "AR" "libAR")
+
+find_library(ARTOOLKIT_ARMulti_LIBRARY
+ NAMES "ARMulti" "libARMulti")
+
+mark_as_advanced(ARTOOLKIT_INCLUDE_DIR ARTOOLKIT_AR_LIBRARY ARTOOLKIT_ARMulti_LIBRARY)
+
+set(ARTOOLKIT_LIBRARIES)
+if(ARTOOLKIT_AR_LIBRARY)
+ list(APPEND ARTOOLKIT_LIBRARIES "${ARTOOLKIT_AR_LIBRARY}")
+endif()
+if(ARTOOLKIT_ARMulti_LIBRARY)
+ list(APPEND ARTOOLKIT_LIBRARIES "${ARTOOLKIT_ARMulti_LIBRARY}")
+endif()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(ARToolKit DEFAULT_MSG
+ ARTOOLKIT_INCLUDE_DIR ARTOOLKIT_LIBRARIES)
diff --git a/cmake/modules/FindAssimp.cmake b/cmake/modules/FindAssimp.cmake
new file mode 100644
index 0000000000..2a73babc9b
--- /dev/null
+++ b/cmake/modules/FindAssimp.cmake
@@ -0,0 +1,33 @@
+# Filename: FindAssimp.cmake
+# Authors: CFSworks (9 Nov, 2018)
+#
+# Usage:
+# find_package(Assimp [REQUIRED] [QUIET])
+#
+# Once done this will define:
+# ASSIMP_FOUND - system has Assimp
+# ASSIMP_INCLUDE_DIR - the path to the location of the assimp/ directory
+# ASSIMP_LIBRARIES - the libraries to link against for Assimp
+#
+
+find_path(ASSIMP_INCLUDE_DIR
+ NAMES "assimp/Importer.hpp")
+
+find_library(ASSIMP_ASSIMP_LIBRARY
+ NAMES "assimp")
+
+find_library(ASSIMP_IRRXML_LIBRARY
+ NAMES "IrrXML")
+
+if(ASSIMP_ASSIMP_LIBRARY)
+ set(ASSIMP_LIBRARIES "${ASSIMP_ASSIMP_LIBRARY}")
+
+ if(ASSIMP_IRRXML_LIBRARY)
+ list(APPEND ASSIMP_LIBRARIES "${ASSIMP_IRRXML_LIBRARY}")
+ endif()
+endif()
+
+mark_as_advanced(ASSIMP_INCLUDE_DIR ASSIMP_LIBRARIES)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Assimp DEFAULT_MSG ASSIMP_INCLUDE_DIR ASSIMP_LIBRARIES)
diff --git a/cmake/modules/FindCg.cmake b/cmake/modules/FindCg.cmake
new file mode 100644
index 0000000000..ed6805c4be
--- /dev/null
+++ b/cmake/modules/FindCg.cmake
@@ -0,0 +1,175 @@
+# Filename: FindCg.cmake
+# Author: kestred (8 Dec, 2013)
+#
+# Usage:
+# find_package(Cg [REQUIRED] [QUIET])
+#
+# Once done this will define:
+# CG_FOUND - system has NvidiaCg
+# CG_INCLUDE_DIR - the NvidiaCg include directory
+# CG_INCLUDE_DIRS - directories for all NvidiaCg components
+# CG_LIBRARY_DIR - the NvidiaCg library directory
+# CG_LIBRARY - the path to the library binary
+# CG_LIBRARIES - the paths to the Cg library and each library below.
+#
+# CGGL_FOUND - system has CgGL
+# CGGL_INCLUDE_DIR - the CgGL include directory
+# CGGL_LIBRARY_DIR - the CgGL library directory
+# CGGL_LIBRARY - the path to the library binary
+#
+
+
+### Define macros to find each sublibrary ###
+
+# Find Cg for OpenGL
+macro(find_cggl)
+ if(APPLE)
+ # GL support is built-in on Apple
+ set(CGGL_LIBRARY "${CG_LIBRARY}")
+ set(CGGL_LIBRARY_DIR "${CG_LIBRARY_DIR}")
+ set(CGGL_INCLUDE_DIR "${CG_INCLUDE_DIR}")
+ endif()
+
+ if(Cg_FIND_QUIETLY)
+ set(CgGL_FIND_QUIETLY TRUE)
+ endif()
+ if(NOT CGGL_LIBRARY_DIR OR NOT CGGL_INCLUDE_DIR)
+ # Find the include directory
+ find_path(CGGL_INCLUDE_DIR
+ NAMES "cgGL.h"
+ PATHS "C:/Program Files/Cg"
+ "C:/Program Files/NVIDIA Corporation/Cg/include"
+ "/usr/include"
+ "/usr/local/include"
+ "/opt/Cg"
+ "/opt/nvidia-cg-toolkit/include" # Gentoo
+ PATH_SUFFIXES "" "Cg" "cg"
+ DOC "The path to NvidiaCgGL's include directory."
+ )
+
+ # Find the library directory
+ find_library(CGGL_LIBRARY
+ NAMES "CgGL" "libCgGL"
+ PATHS "C:/Program Files/Cg"
+ "C:/Program Files/NVIDIA Corporation/Cg"
+ "/usr"
+ "/usr/lib/x86_64-linux-gnu"
+ "/usr/local"
+ "/opt/Cg"
+ "/opt/nvidia-cg-toolkit" # Gentoo
+ PATH_SUFFIXES "" "lib" "lib32" "lib64"
+ DOC "The filepath to NvidiaCgGL's libary binary."
+ )
+ get_filename_component(CGGL_LIBRARY_DIR "${CGGL_LIBRARY}" PATH)
+ set(CGGL_LIBRARY_DIR "${CGGL_LIBRARY_DIR}" CACHE PATH "The path to the CgGL library directory.") # Library path
+
+ mark_as_advanced(CGGL_INCLUDE_DIR)
+ mark_as_advanced(CGGL_LIBRARY_DIR)
+ mark_as_advanced(CGGL_LIBRARY)
+ endif()
+
+ find_package_handle_standard_args(CgGL DEFAULT_MSG CGGL_LIBRARY CGGL_INCLUDE_DIR CGGL_LIBRARY_DIR)
+
+endmacro()
+
+
+# Find Cg for Direct3D 9
+macro(find_cgd3d9)
+ if(Cg_FIND_QUIETLY)
+ set(CgD3D9_FIND_QUIETLY TRUE)
+ endif()
+ if(NOT CGD3D9_LIBRARY_DIR OR NOT CGD3D9_INCLUDE_DIR)
+ # Find the include directory
+ find_path(CGD3D9_INCLUDE_DIR
+ NAMES "cgD3D9.h"
+ PATHS "C:/Program Files/Cg"
+ "C:/Program Files/NVIDIA Corporation/Cg/include"
+ "/usr/include"
+ "/usr/local/include"
+ "/opt/Cg"
+ "/opt/nvidia-cg-toolkit/include" # Gentoo
+ PATH_SUFFIXES "" "Cg" "cg"
+ DOC "The path to NvidiaCgD3D9's include directory."
+ )
+
+ # Find the library directory
+ find_library(CGD3D9_LIBRARY
+ NAMES "CgD3D9" "libCgD3D9"
+ PATHS "C:/Program Files/Cg"
+ "C:/Program Files/NVIDIA Corporation/Cg"
+ "/usr"
+ "/usr/lib/x86_64-linux-gnu"
+ "/usr/local"
+ "/opt/Cg"
+ "/opt/nvidia-cg-toolkit" # Gentoo
+ PATH_SUFFIXES "" "lib" "lib32" "lib64"
+ DOC "The filepath to NvidiaCgD3D9's libary binary."
+ )
+ get_filename_component(CGD3D9_LIBRARY_DIR "${CGD3D9_LIBRARY}" PATH)
+ set(CGD3D9_LIBRARY_DIR "${CGD3D9_LIBRARY_DIR}" CACHE PATH "The path to the CgD3D9 library directory.") # Library path
+
+ mark_as_advanced(CGD3D9_INCLUDE_DIR)
+ mark_as_advanced(CGD3D9_LIBRARY_DIR)
+ mark_as_advanced(CGD3D9_LIBRARY)
+ endif()
+
+ find_package_handle_standard_args(CgD3D9 DEFAULT_MSG CGD3D9_LIBRARY CGD3D9_INCLUDE_DIR CGD3D9_LIBRARY_DIR)
+
+endmacro()
+
+
+
+# Find base Nvidia Cg
+if(NOT CG_LIBRARY_DIR OR NOT CG_INCLUDE_DIRS)
+ # Find the include directory
+ find_path(CG_INCLUDE_DIR
+ NAMES "Cg/cg.h"
+ PATHS "C:/Program Files/Cg"
+ "C:/Program Files/NVIDIA Corporation/Cg/include"
+ "/usr/include"
+ "/usr/local/include"
+ "/opt/Cg"
+ "/opt/nvidia-cg-toolkit/include" # Gentoo
+ PATH_SUFFIXES "" "Cg" "cg"
+ DOC "The path to NvidiaCg's include directory."
+ )
+
+ # Find the library directory
+ find_library(CG_LIBRARY
+ NAMES "Cg" "libCg"
+ PATHS "C:/Program Files/Cg"
+ "C:/Program Files/NVIDIA Corporation/Cg"
+ "/usr"
+ "/usr/lib/x86_64-linux-gnu"
+ "/usr/local"
+ "/opt/Cg"
+ "/opt/nvidia-cg-toolkit" # Gentoo
+ PATH_SUFFIXES "" "lib" "lib32" "lib64"
+ )
+ get_filename_component(CG_LIBRARY_DIR "${CG_LIBRARY}" PATH)
+ set(CG_LIBRARY_DIR "${CG_LIBRARY_DIR}" CACHE PATH "The path to NvidiaCG's library directory.") # Library path
+
+ string(REGEX REPLACE "/Cg$" "" CG_BASE_INCLUDE_DIR "${CG_INCLUDE_DIR}")
+ set(CG_INCLUDE_DIRS ${CG_BASE_INCLUDE_DIR} ${CG_INCLUDE_DIR})
+
+ mark_as_advanced(CG_INCLUDE_DIRS)
+ mark_as_advanced(CG_INCLUDE_DIR)
+ mark_as_advanced(CG_LIBRARY_DIR)
+ mark_as_advanced(CG_LIBRARY)
+endif()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Cg DEFAULT_MSG CG_LIBRARY CG_INCLUDE_DIRS CG_LIBRARY_DIR)
+
+if(CG_INCLUDE_DIR AND CG_LIBRARY_DIR)
+ find_cggl()
+ find_cgd3d9()
+
+ set(CG_LIBRARIES ${CG_LIBRARY})
+ if(CGGL_LIBRARY)
+ list(APPEND CG_LIBRARIES "${CGGL_LIBRARY}")
+ endif()
+ if(CGD3D9_LIBRARY)
+ list(APPEND CG_LIBRARIES "${CGD3D9_LIBRARY}")
+ endif()
+endif()
diff --git a/cmake/modules/FindDirect3D9.cmake b/cmake/modules/FindDirect3D9.cmake
new file mode 100644
index 0000000000..4752150b4b
--- /dev/null
+++ b/cmake/modules/FindDirect3D9.cmake
@@ -0,0 +1,104 @@
+# Filename: FindDirect3D9.cmake
+# Authors: CFSworks (26 Oct, 2018)
+#
+# Usage:
+# find_package(Direct3D9 [REQUIRED] [QUIET])
+#
+# This supports the following components:
+# d3dx9
+# dxerr
+# dxguid
+#
+# Once done this will define:
+# DIRECT3D9_FOUND - system has Direct3D 9.x
+# DIRECT3D9_INCLUDE_DIR - the include directory containing d3d9.h - note that
+# this will be empty if it's part of the Windows SDK.
+# DIRECT3D9_LIBRARY - the path to d3d9.lib
+# DIRECT3D9_LIBRARIES - the path to d3d9.lib and all extra component
+# libraries
+#
+
+include(CheckIncludeFile)
+
+if(Direct3D9_FIND_QUIETLY)
+ if(DEFINED CMAKE_REQUIRED_QUIET)
+ set(_OLD_CMAKE_REQUIRED_QUIET ${CMAKE_REQUIRED_QUIET})
+ endif()
+ # Suppress check_include_file messages
+ set(CMAKE_REQUIRED_QUIET ON)
+endif()
+
+check_include_file("d3d9.h" SYSTEM_INCLUDE_D3D9_H)
+mark_as_advanced(SYSTEM_INCLUDE_D3D9_H)
+
+if(Direct3D9_FIND_QUIETLY)
+ if(DEFINED _OLD_CMAKE_REQUIRED_QUIET)
+ set(CMAKE_REQUIRED_QUIET ${_OLD_CMAKE_REQUIRED_QUIET})
+ unset(_OLD_CMAKE_REQUIRED_QUIET)
+ else()
+ unset(CMAKE_REQUIRED_QUIET)
+ endif()
+endif()
+
+if(SYSTEM_INCLUDE_D3D9_H
+ AND NOT Direct3D9_FIND_REQUIRED_d3dx9
+ AND NOT Direct3D9_FIND_REQUIRED_dxerr)
+ # It's available as #include - easy enough. We'll use "." as a way
+ # of saying "We found it, but please erase this variable later."
+ set(DIRECT3D9_INCLUDE_DIR ".")
+
+ # Since d3d9.h is on the search path, we can pretty much assume d3d9.lib is
+ # as well.
+ set(DIRECT3D9_LIBRARY "d3d9.lib")
+
+ # And dxguid.lib, why not
+ set(DIRECT3D9_dxguid_LIBRARY "dxguid.lib")
+
+else()
+ # We could not find it easily - maybe it's installed separately as part of
+ # the DirectX SDK?
+
+ find_path(DIRECT3D9_INCLUDE_DIR
+ NAMES d3d9.h
+ PATHS "$ENV{DXSDK_DIR}/Include")
+
+ if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ set(dx_lib_path "$ENV{DXSDK_DIR}/Lib/x64/")
+ else()
+ set(dx_lib_path "$ENV{DXSDK_DIR}/Lib/x86/")
+ endif()
+
+ find_library(DIRECT3D9_LIBRARY d3d9 "${dx_lib_path}" NO_DEFAULT_PATH)
+
+ find_library(DIRECT3D9_d3dx9_LIBRARY d3dx9 "${dx_lib_path}" NO_DEFAULT_PATH)
+ find_library(DIRECT3D9_dxerr_LIBRARY dxerr "${dx_lib_path}" NO_DEFAULT_PATH)
+ find_library(DIRECT3D9_dxguid_LIBRARY dxguid "${dx_lib_path}" NO_DEFAULT_PATH)
+
+ unset(dx_lib_path)
+endif()
+
+mark_as_advanced(DIRECT3D9_INCLUDE_DIR DIRECT3D9_LIBRARY)
+set(DIRECT3D9_LIBRARIES "${DIRECT3D9_LIBRARY}")
+
+foreach(_component d3dx9 dxerr dxguid)
+ if(DIRECT3D9_${_component}_LIBRARY)
+ set(Direct3D9_${_component}_FOUND ON)
+ list(FIND Direct3D9_FIND_COMPONENTS "${_component}" _index)
+ if(${_index} GREATER -1)
+ list(APPEND DIRECT3D9_LIBRARIES "${DIRECT3D9_${_component}_LIBRARY}")
+ endif()
+ unset(_index)
+ endif()
+endforeach(_component)
+unset(_component)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Direct3D9 HANDLE_COMPONENTS
+ REQUIRED_VARS DIRECT3D9_INCLUDE_DIR DIRECT3D9_LIBRARY DIRECT3D9_LIBRARIES)
+
+# See above - if we found the include as part of the system path, we don't want
+# to actually modify the include search path, but we need a non-empty string to
+# satisfy find_package_handle_standard_args()
+if(DIRECT3D9_INCLUDE_DIR STREQUAL ".")
+ set(DIRECT3D9_INCLUDE_DIR "")
+endif()
diff --git a/cmake/modules/FindEGL.cmake b/cmake/modules/FindEGL.cmake
new file mode 100644
index 0000000000..111083db85
--- /dev/null
+++ b/cmake/modules/FindEGL.cmake
@@ -0,0 +1,21 @@
+# Filename: FindEGL.cmake
+# Authors: CFSworks (21 Oct, 2018)
+#
+# Usage:
+# find_package(EGL [REQUIRED] [QUIET])
+#
+# Once done this will define:
+# EGL_FOUND - system has EGL
+# EGL_INCLUDE_DIR - the include directory containing EGL/egl.h
+# EGL_LIBRARY - the library to link against for EGL
+#
+
+find_path(EGL_INCLUDE_DIR "EGL/egl.h")
+
+find_library(EGL_LIBRARY
+ NAMES "EGL")
+
+mark_as_advanced(EGL_INCLUDE_DIR EGL_LIBRARY)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(EGL DEFAULT_MSG EGL_INCLUDE_DIR EGL_LIBRARY)
diff --git a/cmake/modules/FindEigen3.cmake b/cmake/modules/FindEigen3.cmake
new file mode 100644
index 0000000000..6b56819383
--- /dev/null
+++ b/cmake/modules/FindEigen3.cmake
@@ -0,0 +1,25 @@
+# Filename: FindEigen3.cmake
+# Authors: kestred (13 Dec, 2013)
+#
+# Usage:
+# find_package(Eigen3 [REQUIRED] [QUIET])
+#
+# Once done this will define:
+# EIGEN_FOUND - system has any version of Eigen
+# EIGEN3_FOUND - system has Eigen3
+# EIGEN3_INCLUDE_DIR - the Eigen3 include directory
+#
+
+find_path(EIGEN3_INCLUDE_DIR
+ NAMES signature_of_eigen3_matrix_library
+ PATH_SUFFIXES eigen3 eigen)
+
+mark_as_advanced(EIGEN3_INCLUDE_DIR)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Eigen3 DEFAULT_MSG EIGEN3_INCLUDE_DIR)
+
+if(EIGEN3_FOUND)
+ set(EIGEN_FOUND TRUE)
+ set(EIGEN_INCLUDE_DIR ${EIGEN3_INCLUDE_DIR})
+endif()
diff --git a/cmake/modules/FindFCollada.cmake b/cmake/modules/FindFCollada.cmake
new file mode 100644
index 0000000000..fcf4ee492d
--- /dev/null
+++ b/cmake/modules/FindFCollada.cmake
@@ -0,0 +1,88 @@
+# Filename: FindFCollada.cmake
+# Author: CFSworks (17 Mar, 2019)
+#
+# Usage:
+# find_package(FCollada [REQUIRED] [QUIET])
+#
+# Once done this will define:
+# FCOLLADA_FOUND - system has FCollada
+# FCOLLADA_INCLUDE_DIR - the FCollada include directory
+#
+# FCOLLADA_RELEASE_LIBRARY - the filepath of the FCollada release library
+# FCOLLADA_DEBUG_LIBRARY - the filepath of the FCollada debug library
+#
+# FCollada::FCollada - The recommended FCollada library to link against
+#
+
+# Find the FCollada include files
+find_path(FCOLLADA_INCLUDE_DIR "FCollada.h" PATH_SUFFIXES "FCollada")
+
+# Find the library built for release
+find_library(FCOLLADA_RELEASE_LIBRARY
+ NAMES "FCollada" "libFCollada"
+ "FColladaS" "libFColladaS"
+ "FColladaU" "libFColladaU"
+ "FColladaSU" "libFColladaSU"
+)
+
+# Find the library built for debug
+find_library(FCOLLADA_DEBUG_LIBRARY
+ NAMES "FColladaD" "libFColladaD"
+ "FColladaSD" "libFColladaSD"
+ "FColladaUD" "libFColladaUD"
+ "FColladaSUD" "libFColladaSUD"
+)
+
+mark_as_advanced(FCOLLADA_INCLUDE_DIR)
+mark_as_advanced(FCOLLADA_RELEASE_LIBRARY)
+mark_as_advanced(FCOLLADA_DEBUG_LIBRARY)
+
+set(_defines)
+if(FCOLLADA_RELEASE_LIBRARY MATCHES "FCollada[^/]*U" OR
+ FCOLLADA_DEBUG_LIBRARY MATCHES "FCollada[^/]*U")
+ list(APPEND _defines "UNICODE")
+endif()
+if(NOT MSVC AND
+ NOT FCOLLADA_RELEASE_LIBRARY MATCHES "FCollada[^/]*S" AND
+ NOT FCOLLADA_DEBUG_LIBRARY MATCHES "FCollada[^/]*S")
+ list(APPEND _defines "FCOLLADA_DLL")
+endif()
+
+# Identify the configs which we have available
+set(_configs)
+if(FCOLLADA_INCLUDE_DIR)
+ if(FCOLLADA_RELEASE_LIBRARY)
+ list(APPEND _configs RELEASE)
+ endif()
+ if(FCOLLADA_DEBUG_LIBRARY)
+ list(APPEND _configs DEBUG)
+ endif()
+
+ if(_configs)
+ set(_HAS_FCOLLADA_LIBRARY ON)
+ add_library(FCollada::FCollada UNKNOWN IMPORTED GLOBAL)
+
+ set_target_properties(FCollada::FCollada PROPERTIES
+ INTERFACE_COMPILE_DEFINITIONS "${_defines}"
+ INTERFACE_INCLUDE_DIRECTORIES "${FCOLLADA_INCLUDE_DIR}")
+
+ endif()
+
+endif()
+
+foreach(_config ${_configs})
+ set_property(TARGET FCollada::FCollada
+ APPEND PROPERTY IMPORTED_CONFIGURATIONS "${_config}")
+
+ set_target_properties(FCollada::FCollada PROPERTIES
+ IMPORTED_LOCATION_${_config} "${FCOLLADA_${_config}_LIBRARY}")
+
+endforeach(_config)
+unset(_config)
+unset(_configs)
+unset(_defines)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(FCollada DEFAULT_MSG FCOLLADA_INCLUDE_DIR _HAS_FCOLLADA_LIBRARY)
+
+unset(_HAS_FCOLLADA_LIBRARY)
diff --git a/cmake/modules/FindFFMPEG.cmake b/cmake/modules/FindFFMPEG.cmake
new file mode 100644
index 0000000000..88a0021be6
--- /dev/null
+++ b/cmake/modules/FindFFMPEG.cmake
@@ -0,0 +1,116 @@
+# Filename: FindFFMPEG.cmake
+# Author: CFSworks (10 Apr, 2014)
+#
+# Usage:
+# find_package(FFMPEG [REQUIRED] [QUIET])
+#
+# Once done this will define:
+# FFMPEG_FOUND - system has ffmpeg
+# FFMPEG_INCLUDE_DIR - the ffmpeg include directory
+# FFMPEG_LIBRARIES - the path to the library binary
+#
+# FFMPEG_LIBAVCODEC - the path to the libavcodec library binary
+# FFMPEG_LIBAVFORMAT - the path to the libavformat library binary
+# FFMPEG_LIBAVUTIL - the path to the libavutil library binary
+#
+
+# Find the libffmpeg include files
+find_path(FFMPEG_INCLUDE_DIR
+ NAMES "libavcodec/avcodec.h"
+ PATHS "/usr/include"
+ "/usr/local/include"
+ "/sw/include"
+ "/opt/include"
+ "/opt/local/include"
+ "/opt/csw/include"
+ PATH_SUFFIXES "libav" "ffmpeg"
+)
+
+# Find the libavcodec library
+find_library(FFMPEG_LIBAVCODEC
+ NAMES "avcodec"
+ PATHS "/usr"
+ "/usr/local"
+ "/usr/freeware"
+ "/sw"
+ "/opt"
+ "/opt/csw"
+ PATH_SUFFIXES "lib" "lib32" "lib64"
+)
+
+# Find the libavformat library
+find_library(FFMPEG_LIBAVFORMAT
+ NAMES "avformat"
+ PATHS "/usr"
+ "/usr/local"
+ "/usr/freeware"
+ "/sw"
+ "/opt"
+ "/opt/csw"
+ PATH_SUFFIXES "lib" "lib32" "lib64"
+)
+
+# Find the libavutil library
+find_library(FFMPEG_LIBAVUTIL
+ NAMES "avutil"
+ PATHS "/usr"
+ "/usr/local"
+ "/usr/freeware"
+ "/sw"
+ "/opt"
+ "/opt/csw"
+ PATH_SUFFIXES "lib" "lib32" "lib64"
+)
+
+mark_as_advanced(FFMPEG_INCLUDE_DIR)
+mark_as_advanced(FFMPEG_LIBAVCODEC)
+mark_as_advanced(FFMPEG_LIBAVFORMAT)
+mark_as_advanced(FFMPEG_LIBAVUTIL)
+
+# Translate library into library directory
+if(FFMPEG_LIBAVCODEC)
+ unset(FFMPEG_LIBRARY_DIR CACHE)
+ get_filename_component(FFMPEG_LIBRARY_DIR "${FFMPEG_LIBAVCODEC}" PATH)
+ set(FFMPEG_LIBRARY_DIR "${FFMPEG_LIBRARY_DIR}" CACHE PATH "The path to libffmpeg's library directory.") # Library path
+endif()
+
+set(FFMPEG_LIBRARIES)
+if(FFMPEG_LIBAVCODEC)
+ list(APPEND FFMPEG_LIBRARIES "${FFMPEG_LIBAVCODEC}")
+endif()
+if(FFMPEG_LIBAVFORMAT)
+ list(APPEND FFMPEG_LIBRARIES "${FFMPEG_LIBAVFORMAT}")
+endif()
+if(FFMPEG_LIBAVUTIL)
+ list(APPEND FFMPEG_LIBRARIES "${FFMPEG_LIBAVUTIL}")
+endif()
+
+if(APPLE)
+ # When statically built for Apple, FFMPEG may have dependencies on these
+ # additional frameworks and libraries.
+
+ find_library(APPLE_COREVIDEO_LIBRARY CoreVideo)
+ if(APPLE_COREVIDEO_LIBRARY)
+ list(APPEND FFMPEG_LIBRARIES "${APPLE_COREVIDEO_LIBRARY}")
+ endif()
+
+ find_library(APPLE_VDA_LIBRARY VideoDecodeAcceleration)
+ if(APPLE_VDA_LIBRARY)
+ list(APPEND FFMPEG_LIBRARIES "${APPLE_VDA_LIBRARY}")
+ endif()
+
+ find_library(APPLE_ICONV_LIBRARY iconv)
+ if(APPLE_ICONV_LIBRARY)
+ list(APPEND FFMPEG_LIBRARIES "${APPLE_ICONV_LIBRARY}")
+ endif()
+
+ find_library(APPLE_BZ2_LIBRARY bz2)
+ if(APPLE_BZ2_LIBRARY)
+ list(APPEND FFMPEG_LIBRARIES "${APPLE_BZ2_LIBRARY}")
+ endif()
+endif()
+
+mark_as_advanced(FFMPEG_LIBRARY_DIR)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(FFMPEG DEFAULT_MSG FFMPEG_LIBRARIES FFMPEG_LIBAVCODEC FFMPEG_LIBAVFORMAT FFMPEG_LIBAVUTIL FFMPEG_INCLUDE_DIR FFMPEG_LIBRARY_DIR)
diff --git a/cmake/modules/FindFFTW3.cmake b/cmake/modules/FindFFTW3.cmake
new file mode 100644
index 0000000000..23f76cc5e5
--- /dev/null
+++ b/cmake/modules/FindFFTW3.cmake
@@ -0,0 +1,107 @@
+# Filename: FindFFTW.cmake
+# Author: Unknown (???), kestred (29 Nov, 2013)
+#
+# Usage:
+# find_package(FFTW [REQUIRED] [QUIET])
+#
+# Once done this will define:
+# FFTW3_FOUND - true if fftw is found on the system
+# FFTW3_INCLUDE_DIR - the fftw include directory
+# FFTW3_LIBRARY_DIR - the fftw library directory
+# FFTW3_LIBRARY - the path to the library binary
+#
+# The following variables will be checked by the function
+# FFTW3_ROOT - if set, the libraries are exclusively searched under this path
+#
+
+# Check if we can use PkgConfig
+find_package(PkgConfig QUIET)
+
+#Determine from PKG
+if(PKG_CONFIG_FOUND AND NOT FFTW3_ROOT)
+ pkg_check_modules(PKG_FFTW QUIET "fftw3")
+endif()
+
+if(FFTW3_ROOT)
+ # Try to find headers under root
+ find_path(FFTW3_INCLUDE_DIR
+ NAMES "fftw3.h"
+ PATHS ${FFTW3_ROOT}
+ PATH_SUFFIXES "include"
+ NO_DEFAULT_PATH
+ )
+
+ # Try to find library under root
+ find_library(FFTW3_LIBRARY
+ NAMES "fftw3"
+ PATHS ${FFTW3_ROOT}
+ PATH_SUFFIXES "lib" "lib64"
+ NO_DEFAULT_PATH
+ )
+
+ find_library(FFTW3_FFTWF_LIBRARY
+ NAMES "fftw3f"
+ PATHS ${FFTW3_ROOT}
+ PATH_SUFFIXES "lib" "lib64"
+ NO_DEFAULT_PATH
+ )
+
+ find_library(FFTW3_FFTWL_LIBRARY
+ NAMES "fftw3l"
+ PATHS ${FFTW3_ROOT}
+ PATH_SUFFIXES "lib" "lib64"
+ NO_DEFAULT_PATH
+ )
+else()
+ # Find headers the normal way
+ find_path(FFTW3_INCLUDE_DIR
+ NAMES "fftw3.h"
+ PATHS ${PKG_FFTW3_INCLUDE_DIRS}
+ ${INCLUDE_INSTALL_DIR}
+ "/usr/include"
+ "/usr/local/include"
+ PATH_SUFFIXES "" "fftw"
+ )
+
+ # Find library the normal way
+ find_library(FFTW3_LIBRARY
+ NAMES "fftw3"
+ PATHS ${PKG_FFTW3_LIBRARY_DIRS}
+ ${LIB_INSTALL_DIR}
+ "/usr"
+ "/usr/local"
+ PATH_SUFFIXES "" "lib" "lib32" "lib64"
+ )
+
+ find_library(FFTW3_FFTWF_LIBRARY
+ NAMES "fftw3f"
+ PATHS ${PKG_FFTW3_LIBRARY_DIRS}
+ ${LIB_INSTALL_DIR}
+ "/usr"
+ "/usr/local"
+ PATH_SUFFIXES "" "lib" "lib32" "lib64"
+ )
+
+
+ find_library(FFTW3_FFTWL_LIBRARY
+ NAMES "fftw3l"
+ PATHS ${PKG_FFTW3_LIBRARY_DIRS}
+ ${LIB_INSTALL_DIR}
+ "/usr"
+ "/usr/local"
+ PATH_SUFFIXES "" "lib" "lib32" "lib64"
+ )
+endif()
+
+# Get the directory conaining FFTW3_LIBRARY
+get_filename_component(FFTW3_LIBRARY_DIR "${FFTW3_LIBRARY}" PATH)
+set(FFTW3_LIBRARY_DIR "${FFTW3_LIBRARY_DIR}" CACHE PATH "The path to fftw's library directory.") # Library path
+
+mark_as_advanced(FFTW3_INCLUDE_DIR)
+mark_as_advanced(FFTW3_LIBRARY_DIR)
+mark_as_advanced(FFTW3_LIBRARY)
+mark_as_advanced(FFTW3_FFTWF_LIBRARY)
+mark_as_advanced(FFTW3_FFTWL_LIBRARY)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(FFTW3 DEFAULT_MSG FFTW3_LIBRARY FFTW3_INCLUDE_DIR FFTW3_LIBRARY_DIR)
diff --git a/cmake/modules/FindFMODEx.cmake b/cmake/modules/FindFMODEx.cmake
new file mode 100644
index 0000000000..63d0b2437a
--- /dev/null
+++ b/cmake/modules/FindFMODEx.cmake
@@ -0,0 +1,83 @@
+# Filename: FindFMODEx.cmake
+# Author: kestred (8 Dec, 2013)
+#
+# Usage:
+# find_pcackage(FMODEx [REQUIRED] [QUIET])
+#
+# Once done this will define:
+# FMODEX_FOUND - system has FMOD Ex
+# FMODEX_INCLUDE_DIR - the FMOD Ex include directory
+# FMODEX_LIBRARY_DIR - the FMOD Ex library directory
+# FMODEX_LIBRARY - the path to the library binary
+#
+# FMODEX_32_LIBRARY - the filepath of the FMOD Ex SDK 32-bit library
+# FMOXEX_64_LIBRARY - the filepath of the FMOD Ex SDK 64-bit library
+#
+
+# Find the include directory
+find_path(FMODEX_INCLUDE_DIR
+ NAMES "fmod.h"
+ PATHS "/usr/include"
+ "/usr/local/include"
+ "/sw/include"
+ "/opt/include"
+ "/opt/local/include"
+ "/opt/csw/include"
+ "/opt/fmodex/include"
+ "/opt/fmodex/api/inc"
+ "C:/Program Files (x86)/FMOD SoundSystem/FMOD Programmers API Win32/api/inc"
+ PATH_SUFFIXES "" "fmodex/fmod" "fmodex/fmod3" "fmod" "fmod3"
+ DOC "The path to FMOD Ex's include directory."
+)
+
+# Find the 32-bit library
+find_library(FMODEX_32_LIBRARY
+ NAMES "fmodex_vc" "fmodex_bc" "fmodex" "fmodexL" "libfmodex" "libfmodexL" "fmodex_vc" "fmodexL_vc"
+ PATHS "/usr"
+ "/usr/local"
+ "/usr/X11R6"
+ "/usr/local/X11R6"
+ "/sw"
+ "/opt"
+ "/opt/local"
+ "/opt/csw"
+ "/opt/fmodex"
+ "/opt/fmodex/api"
+ "C:/Program Files (x86)/FMOD SoundSystem/FMOD Programmers API Win32/api/lib"
+ PATH_SUFFIXES "" "lib" "lib32"
+)
+
+# Find the 64-bit library
+find_library(FMODEX_64_LIBRARY
+ NAMES "fmodex64" "libfmodex64" "fmodexL64" "libfmodexL64" "fmodex64_vc" "fmodexL64_vc"
+ PATHS "/usr"
+ "/usr/local"
+ "/usr/X11R6"
+ "/usr/local/X11R6"
+ "/sw"
+ "/opt"
+ "/opt/local"
+ "/opt/csw"
+ "/opt/fmodex"
+ "/opt/fmodex/api"
+ "/usr/freeware"
+ PATH_SUFFIXES "" "lib" "lib64"
+)
+
+if(FMODEX_32_LIBRARY)
+ set(FMODEX_LIBRARY ${FMODEX_32_LIBRARY} CACHE FILEPATH "The filepath to FMOD Ex's library binary.")
+elseif(FMODEX_64_LIBRARY)
+ set(FMODEX_LIBRARY ${FMODEX_64_LIBRARY} CACHE FILEPATH "The filepath to FMOD Ex's library binary.")
+endif()
+
+get_filename_component(FMODEX_LIBRARY_DIR "${FMODEX_LIBRARY}" PATH)
+set(FMODEX_LIBRARY_DIR "${FMODEX_LIBRARY_DIR}" CACHE PATH "The path to FMOD Ex's library directory.")
+
+mark_as_advanced(FMODEX_INCLUDE_DIR)
+mark_as_advanced(FMODEX_LIBRARY_DIR)
+mark_as_advanced(FMODEX_LIBRARY)
+mark_as_advanced(FMODEX_32_LIBRARY)
+mark_as_advanced(FMODEX_64_LIBRARY)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(FMODEx DEFAULT_MSG FMODEX_LIBRARY FMODEX_INCLUDE_DIR FMODEX_LIBRARY_DIR)
diff --git a/cmake/modules/FindHarfBuzz.cmake b/cmake/modules/FindHarfBuzz.cmake
new file mode 100644
index 0000000000..fd27ea603a
--- /dev/null
+++ b/cmake/modules/FindHarfBuzz.cmake
@@ -0,0 +1,23 @@
+# Filename: FindHarfBuzz.cmake
+# Authors: CFSworks (2 Nov, 2018)
+#
+# Usage:
+# find_package(HarfBuzz [REQUIRED] [QUIET])
+#
+# Once done this will define:
+# HARFBUZZ_FOUND - system has HarfBuzz
+# HARFBUZZ_INCLUDE_DIR - the include directory containing hb.h
+# HARFBUZZ_LIBRARY - the path to the HarfBuzz library
+#
+
+find_path(HARFBUZZ_INCLUDE_DIR
+ NAMES "hb.h"
+ PATH_SUFFIXES "harfbuzz")
+
+find_library(HARFBUZZ_LIBRARY
+ NAMES "harfbuzz")
+
+mark_as_advanced(HARFBUZZ_INCLUDE_DIR HARFBUZZ_LIBRARY)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(HarfBuzz DEFAULT_MSG HARFBUZZ_INCLUDE_DIR HARFBUZZ_LIBRARY)
diff --git a/cmake/modules/FindLibSquish.cmake b/cmake/modules/FindLibSquish.cmake
new file mode 100644
index 0000000000..3399d81ae7
--- /dev/null
+++ b/cmake/modules/FindLibSquish.cmake
@@ -0,0 +1,78 @@
+# Filename: FindLibSquish.cmake
+# Author: kestred (7 Dec, 2013)
+#
+# Usage:
+# find_package(LibSquish [REQUIRED] [QUIET])
+#
+# Once done this will define:
+# LIBSQUISH_FOUND - system has libsquish
+# LIBSQUISH_INCLUDE_DIR - the libsquish include directory
+# LIBSQUISH_LIBRARY_DIR - the libsquish library directory
+# LIBSQUISH_LIBRARY - the path to the library binary
+#
+# LIBSQUISH_RELEASE_LIBRARY - the filepath of the libsquish release library
+# LIBSQUISH_DEBUG_LIBRARY - the filepath of the libsquish debug library
+#
+
+# Find the libsquish include files
+find_path(LIBSQUISH_INCLUDE_DIR
+ NAMES "squish.h"
+ PATHS "/usr/include"
+ "/usr/local/include"
+ "/sw/include"
+ "/opt/include"
+ "/opt/local/include"
+ "/opt/csw/include"
+ PATH_SUFFIXES "" "cppunit"
+)
+
+# Find the libsquish library built for release
+find_library(LIBSQUISH_RELEASE_LIBRARY
+ NAMES "squish" "libsquish"
+ PATHS "/usr"
+ "/usr/local"
+ "/usr/freeware"
+ "/sw"
+ "/opt"
+ "/opt/csw"
+ PATH_SUFFIXES "lib" "lib32" "lib64"
+)
+
+# Find the libsquish library built for debug
+find_library(LIBSQUISH_DEBUG_LIBRARY
+ NAMES "squishd" "libsquishd"
+ PATHS "/usr"
+ "/usr/local"
+ "/usr/freeware"
+ "/sw"
+ "/opt"
+ "/opt/csw"
+ PATH_SUFFIXES "lib" "lib32" "lib64"
+)
+
+
+mark_as_advanced(LIBSQUISH_INCLUDE_DIR)
+mark_as_advanced(LIBSQUISH_RELEASE_LIBRARY)
+mark_as_advanced(LIBSQUISH_DEBUG_LIBRARY)
+
+# Choose library
+if(CMAKE_BUILD_TYPE MATCHES "Debug" AND LIBSQUISH_DEBUG_LIBRARY)
+ set(LIBSQUISH_LIBRARY ${LIBSQUISH_DEBUG_LIBRARY} CACHE FILEPATH "The filepath to libsquish's library binary.")
+elseif(LIBSQUISH_RELEASE_LIBRARY)
+ set(LIBSQUISH_LIBRARY ${LIBSQUISH_RELEASE_LIBRARY} CACHE FILEPATH "The filepath to libsquish's library binary.")
+elseif(LIBSQUISH_DEBUG_LIBRARY)
+ set(LIBSQUISH_LIBRARY ${LIBSQUISH_DEBUG_LIBRARY} CACHE FILEPATH "The filepath to libsquish's library binary.")
+endif()
+
+# Translate library into library directory
+if(LIBSQUISH_LIBRARY)
+ unset(LIBSQUISH_LIBRARY_DIR CACHE)
+ get_filename_component(LIBSQUISH_LIBRARY_DIR "${LIBSQUISH_LIBRARY}" PATH)
+ set(LIBSQUISH_LIBRARY_DIR "${LIBSQUISH_LIBRARY_DIR}" CACHE PATH "The path to libsquish's library directory.") # Library path
+endif()
+
+mark_as_advanced(LIBSQUISH_LIBRARY)
+mark_as_advanced(LIBSQUISH_LIBRARY_DIR)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(LibSquish DEFAULT_MSG LIBSQUISH_LIBRARY LIBSQUISH_INCLUDE_DIR LIBSQUISH_LIBRARY_DIR)
diff --git a/cmake/modules/FindODE.cmake b/cmake/modules/FindODE.cmake
new file mode 100644
index 0000000000..6bd51c21f3
--- /dev/null
+++ b/cmake/modules/FindODE.cmake
@@ -0,0 +1,157 @@
+# Filename: FindODE.cmake
+# Author: CFSworks (7 Feb, 2014)
+#
+# Usage:
+# find_package(ODE [REQUIRED] [QUIET])
+#
+# Once done this will define:
+# ODE_FOUND - system has ode
+# ODE_INCLUDE_DIR - the ode include directory
+#
+# ODE_RELEASE_LIBRARY - the filepath of the ode release library
+# ODE_DEBUG_LIBRARY - the filepath of the ode debug library
+#
+# ODE_SINGLE_DEBUG_LIBRARY - the filepath of the single-precision ode debug library
+# ODE_SINGLE_RELEASE_LIBRARY - the filepath of the single-precision ode release library
+# ODE_DOUBLE_DEBUG_LIBRARY - the filepath of the double-precision ode debug library
+# ODE_DOUBLE_RELEASE_LIBRARY - the filepath of the double-precision ode release library
+#
+# ODE::ODE - The recommended ODE library to link against
+# ODE::ODE_single - If available, this links against single-precision ODE
+# ODE::ODE_double - If available, this links against double-precision ODE
+#
+
+# Find the libode include files
+find_path(ODE_INCLUDE_DIR "ode/ode.h")
+
+# Find the libode library built for release
+find_library(ODE_RELEASE_LIBRARY
+ NAMES "ode" "libode")
+
+# Find the libode library built for debug
+find_library(ODE_DEBUG_LIBRARY
+ NAMES "oded" "liboded")
+
+# Find the single-precision library built for release
+find_library(ODE_SINGLE_RELEASE_LIBRARY
+ NAMES "ode_single" "libode_single")
+
+# Find the single-precision library built for debug
+find_library(ODE_SINGLE_DEBUG_LIBRARY
+ NAMES "ode_singled" "libode_singled")
+
+# Find the double-precision library built for release
+find_library(ODE_DOUBLE_RELEASE_LIBRARY
+ NAMES "ode_double" "libode_double")
+
+# Find the double-precision library built for debug
+find_library(ODE_DOUBLE_DEBUG_LIBRARY
+ NAMES "ode_doubled" "libode_doubled")
+
+# Find libccd, which ODE sometimes links against, so we want to let the linker
+# know about it if it's present.
+find_library(ODE_LIBCCD_LIBRARY
+ NAMES "ccd" "libccd")
+
+mark_as_advanced(ODE_INCLUDE_DIR)
+mark_as_advanced(ODE_RELEASE_LIBRARY)
+mark_as_advanced(ODE_DEBUG_LIBRARY)
+mark_as_advanced(ODE_SINGLE_RELEASE_LIBRARY)
+mark_as_advanced(ODE_SINGLE_DEBUG_LIBRARY)
+mark_as_advanced(ODE_DOUBLE_RELEASE_LIBRARY)
+mark_as_advanced(ODE_DOUBLE_DEBUG_LIBRARY)
+mark_as_advanced(ODE_LIBCCD_LIBRARY)
+
+# Define targets for both precisions (and unspecified)
+foreach(_precision _single _double "")
+ string(TOUPPER "${_precision}" _PRECISION)
+
+ if(EXISTS "${ODE${_PRECISION}_RELEASE_LIBRARY}" OR
+ EXISTS "${ODE${_PRECISION}_DEBUG_LIBRARY}")
+ if(NOT TARGET ODE::ODE${_precision})
+ add_library(ODE::ODE${_precision} UNKNOWN IMPORTED GLOBAL)
+
+ set_target_properties(ODE::ODE${_precision} PROPERTIES
+ INTERFACE_INCLUDE_DIRECTORIES "${ODE_INCLUDE_DIR}")
+
+ if(ODE_LIBCCD_LIBRARY)
+ set_target_properties(ODE::ODE${_precision} PROPERTIES
+ INTERFACE_LINK_LIBRARIES "${ODE_LIBCCD_LIBRARY}")
+ endif()
+
+ if(EXISTS "${ODE${_PRECISION}_RELEASE_LIBRARY}")
+ set_property(TARGET ODE::ODE${_precision} APPEND PROPERTY
+ IMPORTED_CONFIGURATIONS RELEASE)
+ set_target_properties(ODE::ODE${_precision} PROPERTIES
+ IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C"
+ IMPORTED_LOCATION_RELEASE "${ODE${_PRECISION}_RELEASE_LIBRARY}")
+ endif()
+
+ if(EXISTS "${ODE${_PRECISION}_DEBUG_LIBRARY}")
+ set_property(TARGET ODE::ODE${_precision} APPEND PROPERTY
+ IMPORTED_CONFIGURATIONS DEBUG)
+ set_target_properties(ODE::ODE${_precision} PROPERTIES
+ IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C"
+ IMPORTED_LOCATION_DEBUG "${ODE${_PRECISION}_DEBUG_LIBRARY}")
+ endif()
+
+ # If this has a precision, we should be sure to define
+ # dIDESINGLE/dIDEDOUBLE to keep it consistent
+ if(_precision)
+ string(REPLACE "_" "dIDE" _precision_symbol "${_PRECISION}")
+
+ set_target_properties(ODE::ODE${_precision} PROPERTIES
+ INTERFACE_COMPILE_DEFINITIONS "${_precision_symbol}")
+
+ unset(_precision_symbol)
+ endif()
+
+ endif()
+ endif()
+endforeach(_precision)
+unset(_precision)
+unset(_PRECISION)
+
+# OKAY. If everything went well, we have ODE::ODE_single and/or
+# ODE::ODE_double. We might even have an ODE::ODE, but if not, we need to
+# alias one of the other two to it.
+if(NOT TARGET ODE::ODE)
+ if(TARGET ODE::ODE_single)
+ set(_copy_from "ODE::ODE_single")
+ elseif(TARGET ODE::ODE_double)
+ set(_copy_from "ODE::ODE_double")
+ endif()
+
+ if(DEFINED _copy_from)
+ add_library(ODE::ODE UNKNOWN IMPORTED GLOBAL)
+
+ foreach(_prop
+ INTERFACE_INCLUDE_DIRECTORIES
+ INTERFACE_COMPILE_DEFINITIONS
+ INTERFACE_LINK_LIBRARIES
+ IMPORTED_CONFIGURATIONS
+ IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE
+ IMPORTED_LOCATION_RELEASE
+ IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG
+ IMPORTED_LOCATION_DEBUG)
+
+ get_target_property(_value "${_copy_from}" "${_prop}")
+ if(_value)
+ set_target_properties(ODE::ODE PROPERTIES "${_prop}" "${_value}")
+ endif()
+ unset(_value)
+ endforeach(_prop)
+ unset(_prop)
+ endif()
+
+ unset(_copy_from)
+endif()
+
+if(TARGET ODE::ODE)
+ set(_HAS_ODE_LIBRARY ON)
+endif()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(ODE DEFAULT_MSG ODE_INCLUDE_DIR _HAS_ODE_LIBRARY)
+
+unset(_HAS_ODE_LIBRARY)
diff --git a/cmake/modules/FindOgg.cmake b/cmake/modules/FindOgg.cmake
new file mode 100644
index 0000000000..f9de72f127
--- /dev/null
+++ b/cmake/modules/FindOgg.cmake
@@ -0,0 +1,20 @@
+# Filename: FindOgg.cmake
+# Authors: CFSworks (13 Jan, 2019)
+#
+# Usage:
+# find_package(Ogg [REQUIRED] [QUIET])
+#
+# Once done this will define:
+# OGG_FOUND - system has Ogg
+# OGG_INCLUDE_DIR - the include directory containing ogg/
+# OGG_LIBRARY - the path to the ogg library
+#
+
+find_path(OGG_INCLUDE_DIR NAMES "ogg/ogg.h")
+
+find_library(OGG_LIBRARY NAMES "ogg" "libogg_static")
+
+mark_as_advanced(OGG_INCLUDE_DIR OGG_LIBRARY)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Ogg DEFAULT_MSG OGG_INCLUDE_DIR OGG_LIBRARY)
diff --git a/cmake/modules/FindOpenCV.cmake b/cmake/modules/FindOpenCV.cmake
new file mode 100644
index 0000000000..77d49edfbe
--- /dev/null
+++ b/cmake/modules/FindOpenCV.cmake
@@ -0,0 +1,92 @@
+# Filename: FindOpenCV.cmake
+# Authors: CFSworks (3 Nov, 2018)
+#
+# Usage:
+# find_package(OpenCV [REQUIRED] [QUIET])
+#
+# This supports the following components:
+# calib3d
+# contrib
+# core
+# features2d
+# flann
+# gpu
+# highgui
+# imgproc
+# legacy
+# ml
+# nonfree
+# objdetect
+# photo
+# stitching
+# superres
+# video
+# videoio
+# videostab
+#
+# Once done this will define:
+# OPENCV_FOUND - system has OpenCV
+# OpenCV_INCLUDE_DIRS - the include dir(s) containing OpenCV header files
+# OpenCV_comp_LIBRARY - the path to the OpenCV library for the particular
+# component
+# OpenCV_LIBS - the paths to the OpenCV libraries for the requested
+# component(s)
+# OpenCV_VERSION_MAJOR- a "best guess" of the major version (X.x)
+# OpenCV_VERSION_MINOR- a "best guess" of the minor version (x.X)
+#
+
+set(OpenCV_INCLUDE_DIRS)
+
+find_path(OpenCV_V1_INCLUDE_DIR
+ NAMES "cv.h"
+ PATH_SUFFIXES "opencv")
+mark_as_advanced(OpenCV_V1_INCLUDE_DIR)
+if(OpenCV_V1_INCLUDE_DIR)
+ list(APPEND OpenCV_INCLUDE_DIRS "${OpenCV_V1_INCLUDE_DIR}")
+
+ # This is a wild guess:
+ set(OpenCV_VERSION_MAJOR 1)
+ set(OpenCV_VERSION_MINOR 0)
+endif()
+
+find_path(OpenCV_V2_INCLUDE_DIR "opencv2/core/version.hpp")
+mark_as_advanced(OpenCV_V2_INCLUDE_DIR)
+if(OpenCV_V2_INCLUDE_DIR)
+ list(APPEND OpenCV_INCLUDE_DIRS "${OpenCV_V2_INCLUDE_DIR}")
+
+ file(STRINGS "${OpenCV_V2_INCLUDE_DIR}/opencv2/core/version.hpp"
+ _version_major REGEX "#define CV_VERSION_EPOCH")
+ file(STRINGS "${OpenCV_V2_INCLUDE_DIR}/opencv2/core/version.hpp"
+ _version_minor REGEX "#define CV_VERSION_MAJOR")
+
+ string(REGEX REPLACE "[^0-9]" "" OpenCV_VERSION_MAJOR "${_version_major}")
+ string(REGEX REPLACE "[^0-9]" "" OpenCV_VERSION_MINOR "${_version_minor}")
+ unset(_version_major)
+ unset(_version_minor)
+endif()
+
+set(OpenCV_LIBS)
+foreach(_component calib3d contrib core features2d flann gpu highgui imgproc
+ legacy ml nonfree objdetect photo stitching superres video
+ videoio videostab)
+
+ list(FIND OpenCV_FIND_COMPONENTS "${_component}" _index)
+ if(_index GREATER -1 OR _component STREQUAL "core")
+ if(NOT OpenCV_${_component}_LIBRARY)
+ find_library(OpenCV_${_component}_LIBRARY
+ NAMES "opencv_${_component}")
+ endif()
+
+ if(OpenCV_${_component}_LIBRARY)
+ list(APPEND OpenCV_LIBS "${OpenCV_${_component}_LIBRARY}")
+ set(OpenCV_${_component}_FOUND ON)
+ endif()
+ endif()
+ unset(_index)
+endforeach(_component)
+unset(_component)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(OpenCV HANDLE_COMPONENTS
+ REQUIRED_VARS OpenCV_INCLUDE_DIRS OpenCV_LIBS
+ OpenCV_VERSION_MAJOR OpenCV_VERSION_MINOR)
diff --git a/cmake/modules/FindOpenEXR.cmake b/cmake/modules/FindOpenEXR.cmake
new file mode 100644
index 0000000000..365ceec733
--- /dev/null
+++ b/cmake/modules/FindOpenEXR.cmake
@@ -0,0 +1,88 @@
+# Filename: FindOpenEXR.cmake
+# Authors: CFSworks (5 Nov, 2018)
+#
+# Usage:
+# find_package(OpenEXR [REQUIRED] [QUIET])
+#
+# Once done this will define:
+# OPENEXR_FOUND - system has OpenEXR
+# OPENEXR_INCLUDE_DIR - the include directory containing OpenEXR header files
+# OPENEXR_LIBRARIES - the path to the OpenEXR libraries
+#
+
+find_path(OPENEXR_INCLUDE_DIR
+ "ImfVersion.h"
+ PATH_SUFFIXES "OpenEXR")
+
+mark_as_advanced(OPENEXR_INCLUDE_DIR)
+
+find_library(OPENEXR_imf_LIBRARY
+ NAMES "IlmImf")
+
+if(OPENEXR_imf_LIBRARY)
+ get_filename_component(_imf_dir "${OPENEXR_imf_LIBRARY}" DIRECTORY)
+ find_library(OPENEXR_imfutil_LIBRARY
+ NAMES "IlmImfUtil"
+ PATHS "${_imf_dir}"
+ NO_DEFAULT_PATH)
+
+ find_library(OPENEXR_ilmthread_LIBRARY
+ NAMES "IlmThread"
+ PATHS "${_imf_dir}"
+ NO_DEFAULT_PATH)
+
+ find_library(OPENEXR_iex_LIBRARY
+ NAMES "Iex"
+ PATHS "${_imf_dir}"
+ NO_DEFAULT_PATH)
+
+ find_library(OPENEXR_iexmath_LIBRARY
+ NAMES "IexMath"
+ PATHS "${_imf_dir}"
+ NO_DEFAULT_PATH)
+
+ find_library(OPENEXR_imath_LIBRARY
+ NAMES "Imath"
+ PATHS "${_imf_dir}"
+ NO_DEFAULT_PATH)
+
+ find_library(OPENEXR_half_LIBRARY
+ NAMES "Half"
+ PATHS "${_imf_dir}"
+ NO_DEFAULT_PATH)
+
+ unset(_imf_dir)
+endif()
+
+mark_as_advanced(
+ OPENEXR_imf_LIBRARY
+ OPENEXR_imfutil_LIBRARY
+ OPENEXR_ilmthread_LIBRARY
+ OPENEXR_iex_LIBRARY
+ OPENEXR_iexmath_LIBRARY
+ OPENEXR_imath_LIBRARY
+ OPENEXR_half_LIBRARY
+)
+
+set(OPENEXR_LIBRARIES
+ ${OPENEXR_imf_LIBRARY}
+ ${OPENEXR_imfutil_LIBRARY}
+ ${OPENEXR_ilmthread_LIBRARY}
+ ${OPENEXR_iex_LIBRARY}
+ ${OPENEXR_iexmath_LIBRARY}
+ ${OPENEXR_imath_LIBRARY}
+ ${OPENEXR_half_LIBRARY}
+)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(OpenEXR DEFAULT_MSG
+ OPENEXR_INCLUDE_DIR OPENEXR_LIBRARIES
+
+ OPENEXR_imf_LIBRARY
+ OPENEXR_imfutil_LIBRARY
+ OPENEXR_ilmthread_LIBRARY
+ OPENEXR_iex_LIBRARY
+ OPENEXR_iexmath_LIBRARY
+ OPENEXR_imath_LIBRARY
+ OPENEXR_half_LIBRARY
+)
diff --git a/cmake/modules/FindOpenGLES1.cmake b/cmake/modules/FindOpenGLES1.cmake
new file mode 100644
index 0000000000..ab4305088d
--- /dev/null
+++ b/cmake/modules/FindOpenGLES1.cmake
@@ -0,0 +1,21 @@
+# Filename: FindOpenGLES1.cmake
+# Authors: CFSworks (21 Oct, 2018)
+#
+# Usage:
+# find_package(OpenGLES1 [REQUIRED] [QUIET])
+#
+# Once done this will define:
+# OPENGLES1_FOUND - system has OpenGL ES 1.x
+# OPENGLES1_INCLUDE_DIR - the include directory containing GLES/gl.h
+# OPENGLES1_LIBRARY - the library to link against for OpenGL ES 1.x
+#
+
+find_path(OPENGLES1_INCLUDE_DIR "GLES/gl.h")
+
+find_library(OPENGLES1_LIBRARY
+ NAMES "GLESv1" "GLESv1_CM" "GLES_CM")
+
+mark_as_advanced(OPENGLES1_INCLUDE_DIR OPENGLES1_LIBRARY)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(OpenGLES1 DEFAULT_MSG OPENGLES1_INCLUDE_DIR OPENGLES1_LIBRARY)
diff --git a/cmake/modules/FindOpenGLES2.cmake b/cmake/modules/FindOpenGLES2.cmake
new file mode 100644
index 0000000000..f1e4752ad2
--- /dev/null
+++ b/cmake/modules/FindOpenGLES2.cmake
@@ -0,0 +1,21 @@
+# Filename: FindOpenGLES2.cmake
+# Authors: CFSworks (21 Oct, 2018)
+#
+# Usage:
+# find_package(OpenGLES2 [REQUIRED] [QUIET])
+#
+# Once done this will define:
+# OPENGLES2_FOUND - system has OpenGL ES 2.x
+# OPENGLES2_INCLUDE_DIR - the include directory containing GLES2/gl2.h
+# OPENGLES2_LIBRARY - the library to link against for OpenGL ES 2.x
+#
+
+find_path(OPENGLES2_INCLUDE_DIR "GLES2/gl2.h")
+
+find_library(OPENGLES2_LIBRARY
+ NAMES "GLESv2")
+
+mark_as_advanced(OPENGLES2_INCLUDE_DIR OPENGLES2_LIBRARY)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(OpenGLES2 DEFAULT_MSG OPENGLES2_INCLUDE_DIR OPENGLES2_LIBRARY)
diff --git a/cmake/modules/FindOpusFile.cmake b/cmake/modules/FindOpusFile.cmake
new file mode 100644
index 0000000000..88139de084
--- /dev/null
+++ b/cmake/modules/FindOpusFile.cmake
@@ -0,0 +1,34 @@
+# Filename: FindOpusFile.cmake
+# Authors: CFSworks (13 Jan, 2019)
+#
+# Usage:
+# find_package(OpusFile [REQUIRED] [QUIET])
+#
+# Once done this will define:
+# OPUSFILE_FOUND - system has Ogg and opusfile
+# OPUSFILE_INCLUDE_DIRS - the include directory/ies containing opus/ and ogg/
+# OPUSFILE_LIBRARIES - the paths to the opus and opusfile libraries
+#
+
+# Find Ogg
+find_package(Ogg QUIET)
+
+# Find Opus
+find_path(OPUS_INCLUDE_DIR NAMES "opus/opusfile.h")
+
+find_library(OPUS_opus_LIBRARY NAMES "opus")
+find_library(OPUS_opusfile_LIBRARY NAMES "opusfile")
+
+mark_as_advanced(OPUS_INCLUDE_DIR OPUS_opus_LIBRARY OPUS_opusfile_LIBRARY)
+
+# Define output variables
+set(OPUSFILE_INCLUDE_DIRS ${OPUS_INCLUDE_DIR} "${OPUS_INCLUDE_DIR}/opus")
+if(NOT OGG_INCLUDE_DIR STREQUAL OPUS_INCLUDE_DIR)
+ list(APPEND OPUSFILE_INCLUDE_DIRS ${OGG_INCLUDE_DIR})
+endif()
+set(OPUSFILE_LIBRARIES ${OPUS_opusfile_LIBRARY} ${OPUS_opus_LIBRARY} ${OGG_LIBRARY})
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(OpusFile DEFAULT_MSG
+ Ogg_FOUND
+ OPUS_INCLUDE_DIR OPUS_opus_LIBRARY OPUS_opusfile_LIBRARY)
diff --git a/cmake/modules/FindSWResample.cmake b/cmake/modules/FindSWResample.cmake
new file mode 100644
index 0000000000..eb3ec28f03
--- /dev/null
+++ b/cmake/modules/FindSWResample.cmake
@@ -0,0 +1,50 @@
+# Filename: FindSWResample.cmake
+# Author: CFSworks (10 Apr, 2014)
+#
+# Usage:
+# find_package(SWResample [REQUIRED] [QUIET])
+#
+# Once done this will define:
+# SWRESAMPLE_FOUND - system has ffmpeg's libswresample
+# SWRESAMPLE_INCLUDE_DIR - the libswresample include directory
+# SWRESAMPLE_LIBRARY - the path to the library binary
+#
+
+# Find the libswresample include files
+find_path(SWRESAMPLE_INCLUDE_DIR
+ NAMES "libswresample/swresample.h"
+ PATHS "/usr/include"
+ "/usr/local/include"
+ "/sw/include"
+ "/opt/include"
+ "/opt/local/include"
+ "/opt/csw/include"
+ PATH_SUFFIXES "libav" "ffmpeg"
+)
+
+# Find the libswresample library
+find_library(SWRESAMPLE_LIBRARY
+ NAMES "swresample"
+ PATHS "/usr"
+ "/usr/local"
+ "/usr/freeware"
+ "/sw"
+ "/opt"
+ "/opt/csw"
+ PATH_SUFFIXES "lib" "lib32" "lib64"
+)
+
+mark_as_advanced(SWRESAMPLE_INCLUDE_DIR)
+mark_as_advanced(SWRESAMPLE_LIBRARY)
+
+# Translate library into library directory
+if(SWRESAMPLE_LIBRARY)
+ unset(SWRESAMPLE_LIBRARY_DIR CACHE)
+ get_filename_component(SWRESAMPLE_LIBRARY_DIR "${SWRESAMPLE_LIBRARY}" PATH)
+ set(SWRESAMPLE_LIBRARY_DIR "${SWRESAMPLE_LIBRARY_DIR}" CACHE PATH "The path to libffmpeg's library directory.") # Library path
+endif()
+
+mark_as_advanced(SWRESAMPLE_LIBRARY_DIR)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(SWResample DEFAULT_MSG SWRESAMPLE_LIBRARY SWRESAMPLE_INCLUDE_DIR SWRESAMPLE_LIBRARY_DIR)
diff --git a/cmake/modules/FindSWScale.cmake b/cmake/modules/FindSWScale.cmake
new file mode 100644
index 0000000000..f337f9b988
--- /dev/null
+++ b/cmake/modules/FindSWScale.cmake
@@ -0,0 +1,50 @@
+# Filename: FindSWScale.cmake
+# Author: CFSworks (10 Apr, 2014)
+#
+# Usage:
+# find_package(SWScale [REQUIRED] [QUIET])
+#
+# Once done this will define:
+# SWSCALE_FOUND - system has ffmpeg's libswscale
+# SWSCALE_INCLUDE_DIR - the libswscale include directory
+# SWSCALE_LIBRARY - the path to the library binary
+#
+
+# Find the libswscale include files
+find_path(SWSCALE_INCLUDE_DIR
+ NAMES "libswscale/swscale.h"
+ PATHS "/usr/include"
+ "/usr/local/include"
+ "/sw/include"
+ "/opt/include"
+ "/opt/local/include"
+ "/opt/csw/include"
+ PATH_SUFFIXES "libav" "ffmpeg"
+)
+
+# Find the libswscale library
+find_library(SWSCALE_LIBRARY
+ NAMES "swscale"
+ PATHS "/usr"
+ "/usr/local"
+ "/usr/freeware"
+ "/sw"
+ "/opt"
+ "/opt/csw"
+ PATH_SUFFIXES "lib" "lib32" "lib64"
+)
+
+mark_as_advanced(SWSCALE_INCLUDE_DIR)
+mark_as_advanced(SWSCALE_LIBRARY)
+
+# Translate library into library directory
+if(SWSCALE_LIBRARY)
+ unset(SWSCALE_LIBRARY_DIR CACHE)
+ get_filename_component(SWSCALE_LIBRARY_DIR "${SWSCALE_LIBRARY}" PATH)
+ set(SWSCALE_LIBRARY_DIR "${SWSCALE_LIBRARY_DIR}" CACHE PATH "The path to libffmpeg's library directory.") # Library path
+endif()
+
+mark_as_advanced(SWSCALE_LIBRARY_DIR)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(SWScale DEFAULT_MSG SWSCALE_LIBRARY SWSCALE_INCLUDE_DIR SWSCALE_LIBRARY_DIR)
diff --git a/cmake/modules/FindVRPN.cmake b/cmake/modules/FindVRPN.cmake
new file mode 100644
index 0000000000..6a7599e205
--- /dev/null
+++ b/cmake/modules/FindVRPN.cmake
@@ -0,0 +1,40 @@
+# Filename: FindVRPN.cmake
+# Authors: CFSworks (2 Nov, 2018)
+#
+# Usage:
+# find_package(VRPN [REQUIRED] [QUIET])
+#
+# Once done this will define:
+# VRPN_FOUND - system has VRPN
+# VRPN_INCLUDE_DIR - the include directory containing VRPN header files
+# VRPN_LIBRARIES - the path to the VRPN client libraries
+#
+
+find_path(VRPN_INCLUDE_DIR "vrpn_Connection.h")
+
+find_library(VRPN_vrpn_LIBRARY
+ NAMES "vrpn")
+
+mark_as_advanced(VRPN_INCLUDE_DIR VRPN_vrpn_LIBRARY)
+
+if(VRPN_vrpn_LIBRARY)
+ get_filename_component(_vrpn_dir "${VRPN_vrpn_LIBRARY}" DIRECTORY)
+ find_library(VRPN_quat_LIBRARY
+ NAMES "quat"
+ PATHS "${_vrpn_dir}"
+ NO_DEFAULT_PATH)
+
+ unset(_vrpn_dir)
+ mark_as_advanced(VRPN_quat_LIBRARY)
+endif()
+
+set(VRPN_LIBRARIES)
+if(VRPN_vrpn_LIBRARY)
+ list(APPEND VRPN_LIBRARIES "${VRPN_vrpn_LIBRARY}")
+endif()
+if(VRPN_quat_LIBRARY)
+ list(APPEND VRPN_LIBRARIES "${VRPN_quat_LIBRARY}")
+endif()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(VRPN DEFAULT_MSG VRPN_INCLUDE_DIR VRPN_LIBRARIES)
diff --git a/cmake/modules/FindVorbisFile.cmake b/cmake/modules/FindVorbisFile.cmake
new file mode 100644
index 0000000000..f85e847d0a
--- /dev/null
+++ b/cmake/modules/FindVorbisFile.cmake
@@ -0,0 +1,34 @@
+# Filename: FindVorbisFile.cmake
+# Authors: CFSworks (13 Jan, 2019)
+#
+# Usage:
+# find_package(VorbisFile [REQUIRED] [QUIET])
+#
+# Once done this will define:
+# VORBISFILE_FOUND - system has Ogg and vorbisfile
+# VORBISFILE_INCLUDE_DIRS - the include directory/ies containing vorbis/ and ogg/
+# VORBISFILE_LIBRARIES - the paths to the vorbis and vorbisfile libraries
+#
+
+# Find Ogg
+find_package(Ogg QUIET)
+
+# Find Vorbis
+find_path(VORBIS_INCLUDE_DIR NAMES "vorbis/vorbisfile.h")
+
+find_library(VORBIS_vorbis_LIBRARY NAMES "vorbis" "libvorbis_static")
+find_library(VORBIS_vorbisfile_LIBRARY NAMES "vorbisfile" "libvorbisfile_static")
+
+mark_as_advanced(VORBIS_INCLUDE_DIR VORBIS_vorbis_LIBRARY VORBIS_vorbisfile_LIBRARY)
+
+# Define output variables
+set(VORBISFILE_INCLUDE_DIRS ${VORBIS_INCLUDE_DIR})
+if(NOT OGG_INCLUDE_DIR STREQUAL VORBIS_INCLUDE_DIR)
+ list(APPEND VORBISFILE_INCLUDE_DIRS ${OGG_INCLUDE_DIR})
+endif()
+set(VORBISFILE_LIBRARIES ${VORBIS_vorbisfile_LIBRARY} ${VORBIS_vorbis_LIBRARY} ${OGG_LIBRARY})
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(VorbisFile DEFAULT_MSG
+ Ogg_FOUND
+ VORBIS_INCLUDE_DIR VORBIS_vorbis_LIBRARY VORBIS_vorbisfile_LIBRARY)
diff --git a/cmake/modules/README.md b/cmake/modules/README.md
new file mode 100644
index 0000000000..057b9cc95d
--- /dev/null
+++ b/cmake/modules/README.md
@@ -0,0 +1,7 @@
+Directory Info
+--------------
+**Directory:** /cmake/modules
+**License:** Unlicense
+**Description:** This directory is used for standard CMake modules which are safe
+to use outside of a Panda3D project. This should be the normal location for
+most FindXYZZY packages that are written for Panda3D.
diff --git a/cmake/scripts/ConcatenateToCXX.cmake b/cmake/scripts/ConcatenateToCXX.cmake
new file mode 100644
index 0000000000..2ed19085b1
--- /dev/null
+++ b/cmake/scripts/ConcatenateToCXX.cmake
@@ -0,0 +1,70 @@
+# Filename: ConcatenateToCXX.cmake
+#
+# Description: When run, creates a single C++ file which includes a const char[]
+# containing the bytes from one or more files.
+#
+# There is a {SYMBOL_NAME}_size symbol defined as well, storing the total
+# number of bytes in the concatenated input files.
+#
+# A single null terminator byte is added for the benefit of programs that
+# simply treat the data array as a string.
+#
+# Usage:
+# This script is invoked via add_custom_target, like this:
+# cmake -D OUTPUT_FILE="out.cxx" -D SYMBOL_NAME=data -D INPUT_FILES="a.bin b.bin" -P ConcatenateToCXX.cmake
+#
+
+if(NOT CMAKE_SCRIPT_MODE_FILE)
+ message(FATAL_ERROR "ConcatenateToCXX.cmake should not be included but run in script mode.")
+ return()
+endif()
+
+if(NOT DEFINED OUTPUT_FILE)
+ message(FATAL_ERROR "OUTPUT_FILE should be defined when running ConcatenateToCXX.cmake!")
+ return()
+endif()
+
+if(NOT DEFINED SYMBOL_NAME)
+ set(SYMBOL_NAME "data")
+endif()
+
+file(WRITE "${OUTPUT_FILE}" "/* Generated by CMake. DO NOT EDIT. */
+
+extern const char ${SYMBOL_NAME}[];
+extern const int ${SYMBOL_NAME}_size;
+
+const char ${SYMBOL_NAME}[] = {\n")
+
+set(byte_count 0)
+separate_arguments(INPUT_FILES)
+foreach(infile ${INPUT_FILES})
+ file(APPEND "${OUTPUT_FILE}" " /* ${infile} */\n")
+
+ set(offset 0)
+ while(1)
+ # Read up to 1024 bytes from the input file
+ file(READ "${infile}" data LIMIT 1024 OFFSET ${offset} HEX)
+ math(EXPR offset "${offset} + 1024")
+
+ # If 'data' is empty, we're done
+ if(NOT data)
+ break()
+ endif()
+
+ # Count the bytes we're adding
+ string(LENGTH "${data}" strlen)
+ math(EXPR byte_count "${byte_count} + (${strlen} / 2)")
+
+ # Format runs of up to 32 hex chars by indenting and giving a newline
+ string(REGEX REPLACE
+ "(...?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?.?)" " \\1\n"
+ data "${data}")
+ # Format each byte (2 hex chars) in each line with 0x prefix and comma suffix
+ string(REGEX REPLACE "([0-9a-fA-F][0-9a-fA-F])" " 0x\\1," data "${data}")
+ file(APPEND "${OUTPUT_FILE}" "${data}")
+ endwhile()
+endforeach(infile)
+
+file(APPEND "${OUTPUT_FILE}" " 0\n};
+
+extern const int ${SYMBOL_NAME}_size = ${byte_count};\n")
diff --git a/cmake/scripts/CopyPattern.cmake b/cmake/scripts/CopyPattern.cmake
new file mode 100644
index 0000000000..52b66cb91c
--- /dev/null
+++ b/cmake/scripts/CopyPattern.cmake
@@ -0,0 +1,27 @@
+# Filename: CopyPattern.cmake
+#
+# Description: This is a standalone version of CMake's file(COPY) command so we
+# can use all of its features during build-time instead of
+# config-time.
+#
+# Usage:
+# This script is invoked via add_custom_target, like this:
+# cmake -D SOURCE=[source directory]
+# -D DESTINATION=[destination directory]
+# -D FILES_MATCHING="[globbing patterns passed to file(COPY)]"
+# -P CopyPattern.cmake
+if(NOT DEFINED SOURCE OR NOT DEFINED DESTINATION)
+ message(SEND_ERROR "CopyPattern.cmake requires SOURCE and DESTINATION to be
+defined.")
+endif()
+
+if(DEFINED FILES_MATCHING)
+ separate_arguments(FILES_MATCHING UNIX_COMMAND ${FILES_MATCHING})
+
+ file(COPY "${SOURCE}"
+ DESTINATION "${DESTINATION}"
+ FILES_MATCHING ${FILES_MATCHING})
+else()
+ file(COPY "${SOURCE}"
+ DESTINATION "${DESTINATION}")
+endif()
diff --git a/cmake/scripts/CopyPython.cmake b/cmake/scripts/CopyPython.cmake
new file mode 100644
index 0000000000..a611850b62
--- /dev/null
+++ b/cmake/scripts/CopyPython.cmake
@@ -0,0 +1,78 @@
+# Filename: CopyPython.cmake
+#
+# Description: When run, copies Python files from a source directory to a
+# build directory located somewhere in the project's binary path. If
+# PYTHON_EXECUTABLES is provided, it will also invoke compileall in the
+# destination dir(s) to precache .pyc/.pyo files.
+#
+# Usage:
+# This script is invoked via add_custom_target, like this:
+# cmake -D OUTPUT_DIR="/out/dir/Release"
+# -D SOURCE_DIR="/panda3d/direct/src/"
+# -D PYTHON_EXECUTABLES="/usr/bin/python3.6"
+# -P CopyPython.cmake
+#
+
+if(NOT CMAKE_SCRIPT_MODE_FILE)
+ message(FATAL_ERROR "CopyPython.cmake should not be included but run in script mode.")
+ return()
+endif()
+
+if(NOT DEFINED OUTPUT_DIR)
+ message(FATAL_ERROR "OUTPUT_DIR should be defined when running CopyPython.cmake!")
+ return()
+endif()
+
+# Ensure OUTPUT_DIR exists
+file(MAKE_DIRECTORY ${OUTPUT_DIR})
+
+# If there's a SOURCE_DIR, glob for .py files and copy
+# (this is done by hand to avoid the CMake bug where it creates empty dirs)
+if(DEFINED SOURCE_DIR)
+ file(GLOB_RECURSE py_files RELATIVE "${SOURCE_DIR}" "${SOURCE_DIR}/*.py")
+ foreach(py_file ${py_files})
+ get_filename_component(py_file_parent "${py_file}" DIRECTORY)
+ file(TIMESTAMP "${SOURCE_DIR}/${py_file}" src_stamp)
+ file(TIMESTAMP "${OUTPUT_DIR}/${py_file}" dst_stamp)
+
+ # The file is only copied if:
+ # - there's an __init__.py in its dir (or file is in the root) (i.e. file belongs to a package), and
+ # - the modification timestamp differs (i.e. file changed or never copied)
+ if((py_file_parent STREQUAL "." OR NOT py_file_parent
+ OR EXISTS "${SOURCE_DIR}/${py_file_parent}/__init__.py")
+ AND NOT src_stamp STREQUAL dst_stamp)
+
+ file(COPY "${SOURCE_DIR}/${py_file}" DESTINATION "${OUTPUT_DIR}/${py_file_parent}")
+ set(changed YES)
+ endif()
+
+ endforeach(py_file)
+
+else()
+ # No SOURCE_DIR; assume we're outdated since our caller might be populating
+ # the OUTPUT_DIR themselves
+ set(changed YES)
+
+endif()
+
+# Make sure Python recognizes OUTPUT_DIR as a package
+if(NOT EXISTS "${OUTPUT_DIR}/__init__.py")
+ file(WRITE "${OUTPUT_DIR}/__init__.py" "")
+ set(changed YES)
+endif()
+
+# Generate .pyc files for each Python version, if our caller wants
+if(changed AND DEFINED PYTHON_EXECUTABLES)
+ foreach(interp ${PYTHON_EXECUTABLES})
+ execute_process(
+ COMMAND "${interp}" -m compileall .
+ OUTPUT_QUIET
+ WORKING_DIRECTORY "${OUTPUT_DIR}")
+
+ execute_process(
+ COMMAND "${interp}" -O -m compileall .
+ OUTPUT_QUIET
+ WORKING_DIRECTORY "${OUTPUT_DIR}")
+
+ endforeach(interp)
+endif()
diff --git a/cmake/scripts/MakeComposite.cmake b/cmake/scripts/MakeComposite.cmake
new file mode 100644
index 0000000000..fb4d88f6b6
--- /dev/null
+++ b/cmake/scripts/MakeComposite.cmake
@@ -0,0 +1,28 @@
+# Filename: MakeComposite.cmake
+#
+# Description: When run, creates a single C++ file which includes multiple
+# other C++ files, to help facilitate unity builds.
+# Unity builds provide significantly increased compile speed.
+#
+# Usage:
+# This script is invoked via add_custom_target, like this:
+# cmake -P MakeComposite.cmake -D COMPOSITE_FILE="x_composite1.cxx" -D COMPOSITE_SOURCES="a.cxx b.cxx"
+#
+
+if(CMAKE_SCRIPT_MODE_FILE)
+ if(NOT DEFINED COMPOSITE_FILE)
+ message(FATAL_ERROR "COMPOSITE_FILE should be defined when running MakeComposite.cmake!")
+ return()
+ endif()
+
+ file(WRITE "${COMPOSITE_FILE}" "/* Generated by CMake. DO NOT EDIT. */\n")
+
+ separate_arguments(COMPOSITE_SOURCES)
+ foreach(source ${COMPOSITE_SOURCES})
+ file(APPEND "${COMPOSITE_FILE}" "#include \"${source}\"\n")
+ endforeach()
+
+else()
+ message(SEND_ERROR "MakeComposite.cmake should not be included but run in script mode.")
+
+endif()
diff --git a/cmake/scripts/README.md b/cmake/scripts/README.md
new file mode 100644
index 0000000000..1f97423ab8
--- /dev/null
+++ b/cmake/scripts/README.md
@@ -0,0 +1,10 @@
+Directory Info
+--------------
+**Directory:** /cmake/scripts
+**License:** Unlicense
+**Description:** This directory is used for cmake files which are not meant to
+be included using CMake's normal include() directive. Typically, files in this
+directory will be invoked as a custom command/target in the form of:
+```
+ cmake -P [... other options ...]
+```
diff --git a/cmake/templates/metalib_init.cxx.in b/cmake/templates/metalib_init.cxx.in
new file mode 100644
index 0000000000..f8975d400d
--- /dev/null
+++ b/cmake/templates/metalib_init.cxx.in
@@ -0,0 +1,9 @@
+#include "dtoolbase.h"
+
+@component_init_headers@
+
+EXPORT_CLASS void
+@init_func@() {
+@component_init_funcs@
+}
+@export_definitions@
diff --git a/cmake/templates/metalib_init.h.in b/cmake/templates/metalib_init.h.in
new file mode 100644
index 0000000000..4ae8db0d34
--- /dev/null
+++ b/cmake/templates/metalib_init.h.in
@@ -0,0 +1,9 @@
+#ifndef _METALIB_INIT_@target_name@
+#define _METALIB_INIT_@target_name@
+
+#include "dtoolbase.h"
+
+IMPORT_CLASS void @init_func@();
+@export_declarations@
+
+#endif
diff --git a/cmake/templates/win32_python/__init__.py b/cmake/templates/win32_python/__init__.py
new file mode 100644
index 0000000000..758478f46b
--- /dev/null
+++ b/cmake/templates/win32_python/__init__.py
@@ -0,0 +1,23 @@
+def _fixup_dlls():
+ try:
+ path = __path__[0]
+ except (NameError, IndexError):
+ return # Not a package, or not on filesystem
+
+ import os
+
+ relpath = os.path.relpath(path, __path__[-1])
+ dll_path = os.path.abspath(os.path.join(__path__[-1], '../bin', relpath))
+ if not os.path.isdir(dll_path):
+ return
+
+ if hasattr(os, 'add_dll_directory'):
+ os.add_dll_directory(dll_path)
+ else:
+ os_path = os.environ.get('PATH', '')
+ os_path = os_path.split(os.pathsep) if os_path else []
+ os_path.insert(0, dll_path)
+ os.environ['PATH'] = os.pathsep.join(os_path)
+
+_fixup_dlls()
+del _fixup_dlls
diff --git a/contrib/CMakeLists.txt b/contrib/CMakeLists.txt
new file mode 100644
index 0000000000..ff5145261e
--- /dev/null
+++ b/contrib/CMakeLists.txt
@@ -0,0 +1,18 @@
+if(NOT BUILD_PANDA)
+ message(FATAL_ERROR "Cannot build contrib without panda! Please enable the BUILD_PANDA option.")
+endif()
+
+# Include source directories
+add_subdirectory(src/ai)
+add_subdirectory(src/contribbase)
+add_subdirectory(src/rplight)
+
+if(HAVE_PYTHON)
+ add_python_module(panda3d.ai p3ai
+ IMPORT panda3d.core COMPONENT ContribPython)
+
+ add_python_module(panda3d._rplight p3rplight
+ IMPORT panda3d.core COMPONENT ContribPython)
+endif()
+
+export_targets(Contrib COMPONENT ContribDevel)
diff --git a/contrib/src/ai/CMakeLists.txt b/contrib/src/ai/CMakeLists.txt
new file mode 100644
index 0000000000..3e7f028444
--- /dev/null
+++ b/contrib/src/ai/CMakeLists.txt
@@ -0,0 +1,54 @@
+set(P3AI_HEADERS
+ aiBehaviors.h
+ aiCharacter.h
+ aiGlobals.h
+ aiNode.h
+ aiPathFinder.h
+ aiWorld.h
+ arrival.h
+ config_ai.h
+ evade.h
+ flee.h
+ flock.h
+ meshNode.h
+ obstacleAvoidance.h
+ pathFind.h
+ pathFollow.h
+ pursue.h
+ seek.h
+ wander.h
+)
+
+set(P3AI_SOURCES
+ aiBehaviors.cxx
+ aiCharacter.cxx
+ aiNode.cxx
+ aiPathFinder.cxx
+ aiWorld.cxx
+ arrival.cxx
+ config_ai.cxx
+ evade.cxx
+ flee.cxx
+ flock.cxx
+ meshNode.cxx
+ obstacleAvoidance.cxx
+ pathFind.cxx
+ pathFollow.cxx
+ pursue.cxx
+ seek.cxx
+ wander.cxx
+)
+
+composite_sources(p3ai P3AI_SOURCES)
+add_library(p3ai ${P3AI_HEADERS} ${P3AI_SOURCES})
+set_target_properties(p3ai PROPERTIES DEFINE_SYMBOL BUILDING_PANDAAI)
+target_link_libraries(p3ai p3contribbase)
+target_interrogate(p3ai ALL)
+
+install(TARGETS p3ai
+ EXPORT Contrib COMPONENT Contrib
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT ContribDevel)
+install(FILES ${P3AI_HEADERS} COMPONENT ContribDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/contrib/src/contribbase/CMakeLists.txt b/contrib/src/contribbase/CMakeLists.txt
new file mode 100644
index 0000000000..630bffc0a6
--- /dev/null
+++ b/contrib/src/contribbase/CMakeLists.txt
@@ -0,0 +1,14 @@
+set(P3CONTRIBBASE_SOURCES
+ contribbase.cxx
+)
+
+set(P3CONTRIBBASE_HEADERS
+ contribbase.h contribsymbols.h
+)
+
+# Yes, INTERFACE: don't build it, there's no code!
+add_library(p3contribbase INTERFACE)
+target_link_libraries(p3contribbase INTERFACE panda)
+
+install(TARGETS p3contribbase EXPORT Contrib COMPONENT Contrib)
+install(FILES ${P3CONTRIBBASE_HEADERS} COMPONENT ContribDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/contrib/src/rplight/CMakeLists.txt b/contrib/src/rplight/CMakeLists.txt
new file mode 100644
index 0000000000..9f476c30cd
--- /dev/null
+++ b/contrib/src/rplight/CMakeLists.txt
@@ -0,0 +1,52 @@
+set(P3RPLIGHT_HEADERS
+ config_rplight.h
+ gpuCommand.h gpuCommand.I
+ gpuCommandList.h
+ iesDataset.h
+ internalLightManager.h internalLightManager.I
+ pointerSlotStorage.h
+ pssmCameraRig.h pssmCameraRig.I
+ rpLight.h rpLight.I
+ rpPointLight.h rpPointLight.I
+ rpSpotLight.h rpSpotLight.I
+ shadowAtlas.h shadowAtlas.I
+ shadowManager.h shadowManager.I
+ shadowSource.h shadowSource.I
+ tagStateManager.h tagStateManager.I
+)
+
+set(P3RPLIGHT_SOURCES
+ config_rplight.cxx
+ gpuCommand.cxx
+ gpuCommandList.cxx
+ iesDataset.cxx
+ internalLightManager.cxx
+ pssmCameraRig.cxx
+ rpLight.cxx
+ rpPointLight.cxx
+ rpSpotLight.cxx
+ shadowAtlas.cxx
+ shadowManager.cxx
+ shadowSource.cxx
+ tagStateManager.cxx
+)
+
+composite_sources(p3rplight P3RPLIGHT_SOURCES)
+# STATIC, because it doesn't contain any EXPCL_ stuff
+add_library(p3rplight STATIC ${P3RPLIGHT_HEADERS} ${P3RPLIGHT_SOURCES})
+target_link_libraries(p3rplight p3contribbase)
+target_interrogate(p3rplight ALL)
+
+if(MODULE_TYPE STREQUAL "MODULE")
+ # Because it's STATIC (see above), we need to make it PIC so it can link into
+ # a Python module
+ set_target_properties(p3rplight PROPERTIES POSITION_INDEPENDENT_CODE ON)
+endif()
+
+install(TARGETS p3rplight
+ EXPORT Contrib COMPONENT Contrib
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT ContribDevel)
+install(FILES ${P3RPLIGHT_HEADERS} COMPONENT ContribDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/direct/CMakeLists.txt b/direct/CMakeLists.txt
new file mode 100644
index 0000000000..686ca23cc5
--- /dev/null
+++ b/direct/CMakeLists.txt
@@ -0,0 +1,75 @@
+if(NOT BUILD_PANDA)
+ message(FATAL_ERROR "Cannot build direct without panda! Please enable the BUILD_PANDA option.")
+endif()
+
+# Include source directories which have C++ components:
+add_subdirectory(src/dcparse)
+add_subdirectory(src/dcparser)
+add_subdirectory(src/deadrec)
+add_subdirectory(src/directbase)
+#add_subdirectory(src/directd)
+#add_subdirectory(src/directdServer)
+add_subdirectory(src/distributed)
+add_subdirectory(src/interval)
+add_subdirectory(src/motiontrail)
+add_subdirectory(src/showbase)
+
+set(P3DIRECT_COMPONENTS
+ p3dcparser p3deadrec
+ p3interval p3motiontrail p3showbase
+)
+if(HAVE_PYTHON)
+ list(APPEND P3DIRECT_COMPONENTS p3distributed)
+endif()
+
+set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME "DirectDevel")
+add_metalib(p3direct INIT init_libdirect direct.h COMPONENTS ${P3DIRECT_COMPONENTS})
+unset(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME)
+set_property(TARGET p3direct PROPERTY LINKER_LANGUAGE "CXX")
+
+# Installation:
+install(TARGETS p3direct
+ EXPORT Direct COMPONENT Direct
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ ARCHIVE COMPONENT DirectDevel)
+
+if(HAVE_PYTHON)
+ # Now for the Python side of everything
+
+ add_python_module(panda3d.direct
+ p3dcparser p3deadrec p3distributed p3interval
+ p3motiontrail p3showbase LINK p3direct IMPORT panda3d.core COMPONENT Direct)
+
+ # Copy Python source files into the build directory
+ install_python_package(direct SOURCE "${CMAKE_CURRENT_SOURCE_DIR}/src" LIB COMPONENT Direct)
+
+ # This bit is to generate the 'pandac' compatibility shim. It's deprecated now,
+ # but in older versions of Panda3D, one would use
+ # from pandac.PandaModules import *
+ # instead of
+ # from panda3d.FOO import *
+ # Generate PandaModules:
+ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/pandac/PandaModules.py"
+ "\"This module is deprecated. Import from panda3d.core and other panda3d.* modules instead.\"
+
+print(\"Warning: pandac.PandaModules is deprecated, import from panda3d.core instead\")\n")
+
+ foreach(module ${ALL_INTERROGATE_MODULES})
+ string(REGEX REPLACE "^.*\\." "" module_name "${module}")
+ file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/pandac/PandaModules.py" "
+try:
+ from ${module} import *
+except ImportError as err:
+ if not (\"No module named\" in str(err) and \"${module_name}\" in str(err)):
+ raise
+")
+ endforeach()
+
+ # Now install ourselves:
+ install_python_package(pandac SOURCE "${CMAKE_CURRENT_BINARY_DIR}/pandac" LIB COMPONENT Direct)
+endif()
+
+# "Direct" component contains both the Python stuff and the non-Python stuff,
+# because direct has a pretty solid dependency on Python.
+export_targets(Direct NAMESPACE "Panda3D::Direct::" COMPONENT DirectDevel)
diff --git a/direct/src/actor/Actor.py b/direct/src/actor/Actor.py
index 11d4990351..7aeed5d535 100644
--- a/direct/src/actor/Actor.py
+++ b/direct/src/actor/Actor.py
@@ -212,7 +212,7 @@ class Actor(DirectObject, NodePath):
self.__LODCenter = Point3(0, 0, 0)
self.switches = None
- if (other == None):
+ if other is None:
# act like a normal constructor
# create base hierarchy
@@ -352,7 +352,7 @@ class Actor(DirectObject, NodePath):
self.gotName = other.gotName
# copy the scene graph elements of other
- if (overwrite):
+ if overwrite:
otherCopy = other.copyTo(NodePath())
otherCopy.detachNode()
# assign these elements to ourselve (overwrite)
@@ -372,7 +372,7 @@ class Actor(DirectObject, NodePath):
self.switches = other.switches
self.__LODNode = self.find('**/+LODNode')
self.__hasLOD = 0
- if (not self.__LODNode.isEmpty()):
+ if not self.__LODNode.isEmpty():
self.__hasLOD = 1
@@ -418,7 +418,7 @@ class Actor(DirectObject, NodePath):
subpartDef = self.__subpartDict.get(partName, Actor.SubpartDef(partName))
partDef = partBundleDict.get(subpartDef.truePartName)
- if partDef == None:
+ if partDef is None:
Actor.notify.error("no part named: %s" % (partName))
self.__doListJoints(0, partDef.getBundle(),
@@ -491,7 +491,7 @@ class Actor(DirectObject, NodePath):
for animName, file, animControl in animInfo:
print(' Anim: %s' % animName)
print(' File: %s' % file)
- if animControl == None:
+ if animControl is None:
print(' (not loaded)')
else:
print(' NumFrames: %d PlayRate: %0.2f' %
@@ -500,7 +500,12 @@ class Actor(DirectObject, NodePath):
def cleanup(self):
"""
- Actor cleanup function
+ This method should be called when intending to destroy the Actor, and
+ cleans up any additional resources stored on the Actor class before
+ removing the underlying node using `removeNode()`.
+
+ Note that `removeNode()` itself is not sufficient to destroy actors,
+ which is why this method exists.
"""
self.stop(None)
self.clearPythonData()
@@ -512,6 +517,11 @@ class Actor(DirectObject, NodePath):
self.removeNode()
def removeNode(self):
+ """
+ You should call `cleanup()` for Actor objects instead, since
+ :meth:`~panda3d.core.NodePath.removeNode()` is not sufficient for
+ completely destroying Actor objects.
+ """
if self.__geomNode and (self.__geomNode.getNumChildren() > 0):
assert self.notify.warning("called actor.removeNode() on %s without calling cleanup()" % self.getName())
NodePath.removeNode(self)
@@ -525,7 +535,7 @@ class Actor(DirectObject, NodePath):
def flush(self):
"""
- Actor flush function
+ Actor flush function. Used by `cleanup()`.
"""
self.clearPythonData()
@@ -557,14 +567,14 @@ class Actor(DirectObject, NodePath):
bundles = []
for lodName, partBundleDict in self.__partBundleDict.items():
- if partName == None:
+ if partName is None:
for partDef in partBundleDict.values():
bundles.append(partDef.getBundle())
else:
subpartDef = self.__subpartDict.get(partName, Actor.SubpartDef(partName))
partDef = partBundleDict.get(subpartDef.truePartName)
- if partDef != None:
+ if partDef is not None:
bundles.append(partDef.getBundle())
else:
Actor.notify.warning("Couldn't find part: %s" % (partName))
@@ -635,7 +645,7 @@ class Actor(DirectObject, NodePath):
Set the node that switches actor geometry in and out.
If one is not supplied as an argument, make one
"""
- if (node == None):
+ if node is None:
node = LODNode.makeDefaultLod("lod")
if self.__LODNode:
@@ -685,7 +695,7 @@ class Actor(DirectObject, NodePath):
self.switches[lodName] = [inDist, outDist]
# add the switch distance info
self.__LODNode.node().addSwitch(inDist, outDist)
- if center != None:
+ if center is not None:
self.setCenter(center)
def setLOD(self, lodName, inDist=0, outDist=0):
@@ -724,7 +734,7 @@ class Actor(DirectObject, NodePath):
return self.__hasLOD
def setCenter(self, center):
- if center == None:
+ if center is None:
center = Point3(0, 0, 0)
self.__LODCenter = center
if self.__LODNode:
@@ -782,7 +792,7 @@ class Actor(DirectObject, NodePath):
Returns True if any joint has changed as a result of this,
False otherwise. """
- if lodName == None:
+ if lodName is None:
lodNames = self.getLODNames()
else:
lodNames = [lodName]
@@ -790,7 +800,7 @@ class Actor(DirectObject, NodePath):
anyChanged = False
if lod < len(lodNames):
lodName = lodNames[lod]
- if partName == None:
+ if partName is None:
partBundleDict = self.__partBundleDict[lodName]
partNames = list(partBundleDict.keys())
else:
@@ -906,11 +916,11 @@ class Actor(DirectObject, NodePath):
return
lodName, animControlDict = next(iter(self.__animControlDict.items()))
- if partName == None:
+ if partName is None:
partName, animDict = next(iter(animControlDict.items()))
else:
animDict = animControlDict.get(partName)
- if animDict == None:
+ if animDict is None:
# part was not present
Actor.notify.warning("couldn't find part: %s" % (partName))
return None
@@ -931,11 +941,11 @@ class Actor(DirectObject, NodePath):
in dictionary. NOTE: only returns info for an arbitrary LOD
"""
lodName, animControlDict = next(iter(self.__animControlDict.items()))
- if partName == None:
+ if partName is None:
partName, animDict = next(iter(animControlDict.items()))
else:
animDict = animControlDict.get(partName)
- if animDict == None:
+ if animDict is None:
# part was not present
Actor.notify.warning("couldn't find part: %s" % (partName))
return None
@@ -969,7 +979,7 @@ class Actor(DirectObject, NodePath):
return None
subpartDef = self.__subpartDict.get(partName, Actor.SubpartDef(partName))
partDef = partBundleDict.get(subpartDef.truePartName)
- if partDef != None:
+ if partDef is not None:
return partDef.partBundleNP
return None
@@ -984,7 +994,7 @@ class Actor(DirectObject, NodePath):
return None
subpartDef = self.__subpartDict.get(partName, Actor.SubpartDef(partName))
partDef = partBundleDict.get(subpartDef.truePartName)
- if partDef != None:
+ if partDef is not None:
return partDef.getBundle()
return None
@@ -1001,9 +1011,9 @@ class Actor(DirectObject, NodePath):
return
# remove the part
- if (partName in partBundleDict):
+ if partName in partBundleDict:
partBundleDict[partName].partBundleNP.removeNode()
- del(partBundleDict[partName])
+ del partBundleDict[partName]
# find the corresponding anim control dict
if self.mergeLODBundles:
@@ -1014,8 +1024,8 @@ class Actor(DirectObject, NodePath):
return
# remove the animations
- if (partName in partDict):
- del(partDict[partName])
+ if partName in partDict:
+ del partDict[partName]
def hidePart(self, partName, lodName="lodRoot"):
"""
@@ -1093,7 +1103,7 @@ class Actor(DirectObject, NodePath):
if node is None:
node = partDef.partBundleNP.attachNewNode(jointName)
- if (joint):
+ if joint:
if localTransform:
joint.addLocalTransform(node.node())
else:
@@ -1125,7 +1135,7 @@ class Actor(DirectObject, NodePath):
# Get a handle to the joint.
joint = bundle.findChild(jointName)
- if (joint):
+ if joint:
joint.clearNetTransforms()
joint.clearLocalTransforms()
else:
@@ -1139,11 +1149,11 @@ class Actor(DirectObject, NodePath):
joints=[]
pattern = GlobPattern(jointName)
- if lodName == None and self.mergeLODBundles:
+ if lodName is None and self.mergeLODBundles:
# Get the common bundle.
partBundleDicts = [self.__commonBundleHandles]
- elif lodName == None:
+ elif lodName is None:
# Get all LOD's.
partBundleDicts = self.__partBundleDict.values()
else:
@@ -1232,7 +1242,7 @@ class Actor(DirectObject, NodePath):
return None
joint = bundle.findChild(jointName)
- if joint == None:
+ if joint is None:
Actor.notify.warning("no joint named %s!" % (jointName))
return None
return joint.getDefaultValue()
@@ -1252,7 +1262,7 @@ class Actor(DirectObject, NodePath):
return None
joint = bundle.findChild(jointName)
- if joint == None:
+ if joint is None:
Actor.notify.warning("no joint named %s!" % (jointName))
return None
return joint.getTransformState()
@@ -1277,7 +1287,7 @@ class Actor(DirectObject, NodePath):
anyGood = False
for bundleDict in self.__partBundleDict.values():
bundle = bundleDict[trueName].getBundle()
- if node == None:
+ if node is None:
node = self.attachNewNode(ModelNode(jointName))
joint = bundle.findChild(jointName)
if joint and isinstance(joint, MovingPartMatrix):
@@ -1299,7 +1309,7 @@ class Actor(DirectObject, NodePath):
optimal than controlJoint() for cases in which the transform
is not intended to be animated during the lifetime of the
Actor. """
- if transform == None:
+ if transform is None:
transform = TransformState.makePosHprScale(pos, hpr, scale)
subpartDef = self.__subpartDict.get(partName, Actor.SubpartDef(partName))
@@ -1330,7 +1340,7 @@ class Actor(DirectObject, NodePath):
partDef = partBundleDict.get(subpartDef.truePartName)
if partDef:
joint = partDef.partBundleNP.find("**/" + jointName)
- if (joint.isEmpty()):
+ if joint.isEmpty():
Actor.notify.warning("%s not found!" % (jointName))
else:
return path.instanceTo(joint)
@@ -1350,7 +1360,7 @@ class Actor(DirectObject, NodePath):
anotherPartDef = partBundleDict.get(anotherPartName)
if anotherPartDef:
joint = anotherPartDef.partBundleNP.find("**/" + jointName)
- if (joint.isEmpty()):
+ if joint.isEmpty():
Actor.notify.warning("%s not found!" % (jointName))
else:
partDef.partBundleNP.reparentTo(joint)
@@ -1395,10 +1405,10 @@ class Actor(DirectObject, NodePath):
root under the given lod.
"""
# check to see if we are working within an lod
- if lodName != None:
+ if lodName is not None:
# find the named lod node
lodRoot = self.__LODNode.find(str(lodName))
- if root == None:
+ if root is None:
# no need to look further
root = lodRoot
else:
@@ -1406,7 +1416,7 @@ class Actor(DirectObject, NodePath):
root = lodRoot.find("**/" + root)
else:
# start search from self if no root and no lod given
- if root == None:
+ if root is None:
root = self
frontParts = root.findAllMatches("**/" + frontPartName)
@@ -1426,7 +1436,7 @@ class Actor(DirectObject, NodePath):
# Find the back part.
backPart = root.find("**/" + backPartName)
- if (backPart.isEmpty()):
+ if backPart.isEmpty():
Actor.notify.warning("no part named %s!" % (backPartName))
return
@@ -1442,7 +1452,7 @@ class Actor(DirectObject, NodePath):
def fixBounds(self, partName = None):
- if(partName == None):
+ if partName is None:
#iterate through everything
for lodData in self.__partBundleDict.values():
for partData in lodData.values():
@@ -1473,7 +1483,7 @@ class Actor(DirectObject, NodePath):
in this actor
"""
# if no part name specified fix all parts
- if (part==None):
+ if part is None:
part = self
# update all characters first
@@ -1531,12 +1541,12 @@ class Actor(DirectObject, NodePath):
Play the given animation on the given part of the actor.
If no part is specified, try to play on all parts. NOTE:
plays over ALL LODs"""
- if fromFrame == None:
+ if fromFrame is None:
for control in self.getAnimControls(animName, partName):
control.play()
else:
for control in self.getAnimControls(animName, partName):
- if toFrame == None:
+ if toFrame is None:
control.play(fromFrame, control.getNumFrames() - 1)
else:
control.play(fromFrame, toFrame)
@@ -1550,12 +1560,12 @@ class Actor(DirectObject, NodePath):
all LOD's
"""
- if fromFrame == None:
+ if fromFrame is None:
for control in self.getAnimControls(animName, partName):
control.loop(restart)
else:
for control in self.getAnimControls(animName, partName):
- if toFrame == None:
+ if toFrame is None:
control.loop(restart, fromFrame, control.getNumFrames() - 1)
else:
control.loop(restart, fromFrame, toFrame)
@@ -1567,11 +1577,11 @@ class Actor(DirectObject, NodePath):
restarting at zero frame if requested. If no part name
is given then try to loop on all parts. NOTE: loops on
all LOD's"""
- if fromFrame == None:
+ if fromFrame is None:
fromFrame = 0
for control in self.getAnimControls(animName, partName):
- if toFrame == None:
+ if toFrame is None:
control.pingpong(restart, fromFrame, control.getNumFrames() - 1)
else:
control.pingpong(restart, fromFrame, toFrame)
@@ -1623,11 +1633,11 @@ class Actor(DirectObject, NodePath):
Config.prc variable.
"""
for bundle in self.getPartBundles(partName = partName):
- if blendType != None:
+ if blendType is not None:
bundle.setBlendType(blendType)
- if animBlend != None:
+ if animBlend is not None:
bundle.setAnimBlendFlag(animBlend)
- if frameBlend != None:
+ if frameBlend is not None:
bundle.setFrameBlendFlag(frameBlend)
def enableBlend(self, blendType = PartBundle.BTNormalizedLinear, partName = None):
@@ -1706,15 +1716,15 @@ class Actor(DirectObject, NodePath):
partDict = self.__animControlDict.get(lodName)
# if this assertion fails, named lod was not present
- assert partDict != None
+ assert partDict is not None
animDict = partDict.get(partName)
- if animDict == None:
+ if animDict is None:
# part was not present
Actor.notify.warning("couldn't find part: %s" % (partName))
else:
anim = animDict.get(animName)
- if anim == None:
+ if anim is None:
# anim was not present
assert Actor.notify.debug("couldn't find anim: %s" % (animName))
pass
@@ -1750,7 +1760,7 @@ class Actor(DirectObject, NodePath):
If lodName is None or omitted, all LOD's are returned.
"""
- if partName == None and self.__subpartsComplete:
+ if partName is None and self.__subpartsComplete:
# If we have the __subpartsComplete flag, and no partName
# is specified, it really means to play the animation on
# all subparts, not on the overall Actor.
@@ -1759,12 +1769,12 @@ class Actor(DirectObject, NodePath):
controls = []
# build list of lodNames and corresponding animControlDicts
# requested.
- if lodName == None or self.mergeLODBundles:
+ if lodName is None or self.mergeLODBundles:
# Get all LOD's
animControlDictItems = self.__animControlDict.items()
else:
partDict = self.__animControlDict.get(lodName)
- if partDict == None:
+ if partDict is None:
Actor.notify.warning("couldn't find lod: %s" % (lodName))
animControlDictItems = []
else:
@@ -1773,7 +1783,7 @@ class Actor(DirectObject, NodePath):
for lodName, partDict in animControlDictItems:
# Now, build the list of partNames and the corresponding
# animDicts.
- if partName == None:
+ if partName is None:
# Get all main parts, but not sub-parts.
animDictItems = []
for thisPart, animDict in partDict.items():
@@ -1791,14 +1801,14 @@ class Actor(DirectObject, NodePath):
for pName in partNameList:
animDict = partDict.get(pName)
- if animDict == None:
+ if animDict is None:
# Maybe it's a subpart that hasn't been bound yet.
subpartDef = self.__subpartDict.get(pName)
if subpartDef:
animDict = {}
partDict[pName] = animDict
- if animDict == None:
+ if animDict is None:
# part was not present
Actor.notify.warning("couldn't find part: %s" % (pName))
else:
@@ -1824,7 +1834,7 @@ class Actor(DirectObject, NodePath):
names = animDict.keys()
for animName in names:
anim = animDict.get(animName)
- if anim == None and partName != None:
+ if anim is None and partName is not None:
for pName in partNameList:
# Maybe it's a subpart that hasn't been bound yet.
subpartDef = self.__subpartDict.get(pName)
@@ -1835,14 +1845,14 @@ class Actor(DirectObject, NodePath):
anim = anim.makeCopy()
animDict[animName] = anim
- if anim == None:
+ if anim is None:
# anim was not present
assert Actor.notify.debug("couldn't find anim: %s" % (animName))
pass
else:
# bind the animation first if we need to
animControl = anim.animControl
- if animControl == None:
+ if animControl is None:
animControl = self.__bindAnimToPart(
animName, thisPart, lodName,
allowAsyncBind = allowAsyncBind)
@@ -1869,7 +1879,7 @@ class Actor(DirectObject, NodePath):
if isinstance(modelPath, NodePath):
# If we got a NodePath instead of a string, use *that* as
# the model directly.
- if (copy):
+ if copy:
model = modelPath.copyTo(NodePath())
else:
model = modelPath
@@ -1898,15 +1908,15 @@ class Actor(DirectObject, NodePath):
if model is not None:
model = NodePath(model)
- if (model == None):
+ if model is None:
raise IOError("Could not load Actor model %s" % (modelPath))
- if (model.node().isOfType(Character.getClassType())):
+ if model.node().isOfType(Character.getClassType()):
bundleNP = model
else:
bundleNP = model.find("**/+Character")
- if (bundleNP.isEmpty()):
+ if bundleNP.isEmpty():
Actor.notify.warning("%s is not a character!" % (modelPath))
model.reparentTo(self.__geomNode)
else:
@@ -1923,7 +1933,7 @@ class Actor(DirectObject, NodePath):
# Now extract out the Character and integrate it with
# the Actor.
- if (lodName!="lodRoot"):
+ if lodName != "lodRoot":
# parent to appropriate node under LOD switch
bundleNP.reparentTo(self.__LODNode.find(str(lodName)))
else:
@@ -1965,7 +1975,7 @@ class Actor(DirectObject, NodePath):
self.gotName = 1
bundleDict = self.__partBundleDict.get(lodName, None)
- if bundleDict == None:
+ if bundleDict is None:
# make a dictionary to store these parts in
bundleDict = {}
self.__partBundleDict[lodName] = bundleDict
@@ -2254,7 +2264,7 @@ class Actor(DirectObject, NodePath):
for lodName in lodNames:
for partName in partNames:
for animDef in self.__animControlDict[lodName][partName].values():
- if animDef.animControl != None:
+ if animDef.animControl is not None:
# Try to clear any control effects before we let
# our handle on them go. This is especially
# important if the anim control was blending
@@ -2266,12 +2276,12 @@ class Actor(DirectObject, NodePath):
for partName in partNames:
for anim in anims:
animDef = self.__animControlDict[lodName][partName].get(anim)
- if animDef and animDef.animControl != None:
+ if animDef and animDef.animControl is not None:
# Try to clear any control effects before we let
# our handle on them go. This is especially
# important if the anim control was blending
# animations.
- animDef.animControl.getPart().clearControlEffects()
+ animDef.animControl.getPart().setControlEffect(animDef.animControl, 0.0)
animDef.animControl = None
@@ -2329,19 +2339,19 @@ class Actor(DirectObject, NodePath):
partDict = self.__animControlDict[lodName]
animDict = partDict.get(partName)
- if animDict == None:
+ if animDict is None:
# It must be a subpart that hasn't been bound yet.
animDict = {}
partDict[partName] = animDict
anim = animDict.get(animName)
- if anim == None:
+ if anim is None:
# It must be a subpart that hasn't been bound yet.
anim = partDict[subpartDef.truePartName].get(animName)
anim = anim.makeCopy()
animDict[animName] = anim
- if anim == None:
+ if anim is None:
Actor.notify.error("actor has no animation %s", animName)
# only bind if not already bound!
@@ -2396,7 +2406,7 @@ class Actor(DirectObject, NodePath):
# find the part in our tree
bundleNP = partLod.find("**/%s%s"%(Actor.partPrefix,partName))
- if (bundleNP != None):
+ if bundleNP is not None:
# store the part bundle
self.__prepareBundle(bundleNP, partDef.partModel,
partName, lodName)
@@ -2468,7 +2478,7 @@ class Actor(DirectObject, NodePath):
else:
lodNames = [lodName]
- if partName == None and self.__subpartsComplete:
+ if partName is None and self.__subpartsComplete:
partNames = self.__subpartDict.keys()
else:
partNames = [partName]
diff --git a/direct/src/dcparse/CMakeLists.txt b/direct/src/dcparse/CMakeLists.txt
new file mode 100644
index 0000000000..e5cdee5b18
--- /dev/null
+++ b/direct/src/dcparse/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_executable(p3dcparse dcparse.cxx)
+target_link_libraries(p3dcparse p3direct)
+install(TARGETS p3dcparse EXPORT Direct COMPONENT Direct DESTINATION ${CMAKE_INSTALL_BINDIR})
diff --git a/direct/src/dcparser/CMakeLists.txt b/direct/src/dcparser/CMakeLists.txt
new file mode 100644
index 0000000000..e90ca815d8
--- /dev/null
+++ b/direct/src/dcparser/CMakeLists.txt
@@ -0,0 +1,87 @@
+set(P3DCPARSER_HEADERS
+ dcAtomicField.h dcAtomicField.I
+ dcClass.h dcClass.I
+ dcDeclaration.h
+ dcField.h dcField.I
+ dcFile.h dcFile.I
+ dcKeyword.h dcKeywordList.h
+ dcLexer.lxx dcLexerDefs.h
+ dcMolecularField.h
+ dcParser.yxx dcParserDefs.h
+ dcSubatomicType.h
+ dcPackData.h dcPackData.I
+ dcPacker.h dcPacker.I
+ dcPackerCatalog.h dcPackerCatalog.I
+ dcPackerInterface.h dcPackerInterface.I
+ dcParameter.h
+ dcClassParameter.h
+ dcArrayParameter.h
+ dcSimpleParameter.h
+ dcSwitchParameter.h
+ dcNumericRange.h dcNumericRange.I
+ dcSwitch.h
+ dcTypedef.h
+ dcbase.h
+ dcindent.h
+ dcmsgtypes.h
+ hashGenerator.h
+ primeNumberGenerator.h
+)
+
+set(P3DCPARSER_SOURCES
+ dcAtomicField.cxx
+ dcClass.cxx
+ dcDeclaration.cxx
+ dcField.cxx
+ dcFile.cxx
+ dcKeyword.cxx
+ dcKeywordList.cxx
+ dcMolecularField.cxx
+ dcSubatomicType.cxx
+ dcPackData.cxx
+ dcPacker.cxx
+ dcPackerCatalog.cxx
+ dcPackerInterface.cxx
+ dcParameter.cxx
+ dcClassParameter.cxx
+ dcArrayParameter.cxx
+ dcSimpleParameter.cxx
+ dcSwitchParameter.cxx
+ dcSwitch.cxx
+ dcTypedef.cxx
+ dcindent.cxx
+ hashGenerator.cxx
+ primeNumberGenerator.cxx
+)
+
+set(P3DCPARSER_IGATEEXT
+ dcClass_ext.cxx dcClass_ext.h
+ dcField_ext.cxx dcField_ext.h
+ dcPacker_ext.cxx dcPacker_ext.h
+)
+
+add_bison_target(dcParser.cxx dcParser.yxx DEFINES dcParser.h PREFIX dcyy)
+add_flex_target(dcLexer.cxx dcLexer.lxx CASE_INSENSITIVE PREFIX dcyy)
+
+# These cannot be interrogated, and are excluded from the composites.
+set(P3DCPARSER_PARSER_SOURCES
+ dcParser.cxx
+ dcLexer.cxx)
+
+composite_sources(p3dcparser P3DCPARSER_SOURCES)
+add_component_library(p3dcparser NOINIT SYMBOL BUILDING_DIRECT_DCPARSER
+ ${P3DCPARSER_HEADERS} ${P3DCPARSER_SOURCES} ${P3DCPARSER_PARSER_SOURCES})
+target_compile_definitions(p3dcparser PUBLIC WITHIN_PANDA)
+target_link_libraries(p3dcparser p3directbase panda)
+target_interrogate(p3dcparser ${P3DCPARSER_HEADERS} ${P3DCPARSER_SOURCES}
+ EXTENSIONS ${P3DCPARSER_IGATEEXT})
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3dcparser
+ EXPORT Direct COMPONENT Direct
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT DirectDevel)
+endif()
+install(FILES ${P3DCPARSER_HEADERS} COMPONENT DirectDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/direct/src/dcparser/dcbase.h b/direct/src/dcparser/dcbase.h
index 3a3fbbd13e..75ddca8030 100644
--- a/direct/src/dcparser/dcbase.h
+++ b/direct/src/dcparser/dcbase.h
@@ -36,12 +36,12 @@
#else // WITHIN_PANDA
-#ifdef WIN32
+#ifdef _MSC_VER
/* C4786: 255 char debug symbols */
#pragma warning (disable : 4786)
/* C4503: decorated name length exceeded */
#pragma warning (disable : 4503)
-#endif /* WIN32_VC */
+#endif /* _MSC_VER */
#include
#include
@@ -54,7 +54,7 @@
// These header files are needed to compile dcLexer.cxx, the output from flex.
// flex doesn't create a perfectly windows-friendly source file right out of
// the box.
-#ifdef WIN32
+#ifdef _WIN32
#include
#include
#else
diff --git a/direct/src/deadrec/CMakeLists.txt b/direct/src/deadrec/CMakeLists.txt
new file mode 100644
index 0000000000..0a2bb1b96a
--- /dev/null
+++ b/direct/src/deadrec/CMakeLists.txt
@@ -0,0 +1,24 @@
+set(P3DEADREC_HEADERS
+ config_deadrec.h
+ smoothMover.h smoothMover.I
+)
+
+set(P3DEADREC_SOURCES
+ config_deadrec.cxx
+ smoothMover.cxx
+)
+
+add_component_library(p3deadrec SYMBOL BUILDING_DIRECT_DEADREC
+ ${P3DEADREC_HEADERS} ${P3DEADREC_SOURCES})
+target_link_libraries(p3deadrec p3directbase panda)
+target_interrogate(p3deadrec ALL)
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3deadrec
+ EXPORT Direct COMPONENT Direct
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT DirectDevel)
+endif()
+install(FILES ${P3DEADREC_HEADERS} COMPONENT DirectDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/direct/src/directbase/CMakeLists.txt b/direct/src/directbase/CMakeLists.txt
new file mode 100644
index 0000000000..eea5100de2
--- /dev/null
+++ b/direct/src/directbase/CMakeLists.txt
@@ -0,0 +1,14 @@
+set(P3DIRECTBASE_SOURCES
+ directbase.cxx
+)
+
+set(P3DIRECTBASE_HEADERS
+ directbase.h directsymbols.h
+)
+
+# Yes, INTERFACE: don't build it, there's no code!
+add_library(p3directbase INTERFACE)
+target_link_libraries(p3directbase INTERFACE panda)
+
+install(TARGETS p3directbase EXPORT Direct COMPONENT Direct)
+install(FILES ${P3DIRECTBASE_HEADERS} COMPONENT DirectDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/direct/src/dist/commands.py b/direct/src/dist/commands.py
index b70effdf87..644b3774c6 100644
--- a/direct/src/dist/commands.py
+++ b/direct/src/dist/commands.py
@@ -396,27 +396,22 @@ class build_apps(setuptools.Command):
self.announce('Gathering wheels for platform: {}'.format(platform), distutils.log.INFO)
- whldir = os.path.join(self.build_base, '__whl_cache__')
+ whlcache = os.path.join(self.build_base, '__whl_cache__')
- #TODO find a better way to get abi tag than from internal/private pip APIs
- if hasattr(pip, 'pep425tags'):
- pep425tags = pip.pep425tags
- wheel = pip.wheel
- else:
- from pip._internal import pep425tags, wheel
+ pip_version = int(pip.__version__.split('.')[0])
+ if pip_version < 9:
+ raise RuntimeError("pip 9.0 or greater is required, but found {}".format(pip.__version__))
- abi_tag = pep425tags.get_abi_tag()
-
- if 'u' in abi_tag and (platform.startswith('win') or platform.startswith('macosx')):
- abi_tag = abi_tag.replace('u', '')
+ abi_tag = 'cp%d%d' % (sys.version_info[:2])
+ if sys.version_info < (3, 8):
+ abi_tag += 'm'
# For these distributions, we need to append 'u' on Linux
if abi_tag in ('cp26m', 'cp27m', 'cp32m') and not platform.startswith('win') and not platform.startswith('macosx'):
abi_tag += 'u'
- pip_version = pip.__version__.split('.')
- if int(pip_version[0]) < 9:
- raise RuntimeError("pip 9.0 or greater is required, but found {}".format(pip.__version__))
+ whldir = os.path.join(whlcache, '_'.join((platform, abi_tag)))
+ os.makedirs(whldir, exist_ok=True)
# Remove any .zip files. These are built from a VCS and block for an
# interactive prompt on subsequent downloads.
@@ -444,19 +439,12 @@ class build_apps(setuptools.Command):
subprocess.check_call([sys.executable, '-m', 'pip'] + pip_args)
- # Now figure out which of the downloaded wheels are relevant to us.
- tags = pep425tags.get_supported(platform=platform, abi=abi_tag)
- wheelpaths = []
- for filename in os.listdir(whldir):
- try:
- whl = wheel.Wheel(filename)
- except wheel.InvalidWheelFilename:
- continue
-
- if whl.supported(tags):
- wheelpaths.append(os.path.join(whldir, filename))
-
- return wheelpaths
+ # Return a list of paths to the downloaded whls
+ return [
+ os.path.join(whldir, filename)
+ for filename in os.listdir(whldir)
+ if filename.endswith('.whl')
+ ]
def update_pe_resources(self, appname, runtime):
"""Update resources (e.g., icons) in windows PE file"""
diff --git a/direct/src/distributed/CMakeLists.txt b/direct/src/distributed/CMakeLists.txt
new file mode 100644
index 0000000000..898323f0d5
--- /dev/null
+++ b/direct/src/distributed/CMakeLists.txt
@@ -0,0 +1,35 @@
+if(NOT HAVE_PYTHON)
+ return()
+endif()
+
+set(P3DISTRIBUTED_HEADERS
+ config_distributed.h
+ cConnectionRepository.h
+ cConnectionRepository.I
+ cDistributedSmoothNodeBase.h
+ cDistributedSmoothNodeBase.I
+)
+
+set(P3DISTRIBUTED_SOURCES
+ config_distributed.cxx
+)
+
+set(P3DISTRIBUTED_IGATEEXT
+ cConnectionRepository.cxx
+ cDistributedSmoothNodeBase.cxx
+)
+
+add_component_library(p3distributed NOINIT SYMBOL BUILDING_DIRECT_DISTRIBUTED
+ ${P3DISTRIBUTED_HEADERS} ${P3DISTRIBUTED_SOURCES})
+target_link_libraries(p3distributed p3directbase p3dcparser panda)
+target_interrogate(p3distributed ALL EXTENSIONS ${P3DISTRIBUTED_IGATEEXT})
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3distributed
+ EXPORT Direct COMPONENT Direct
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT DirectDevel)
+endif()
+install(FILES ${P3DISTRIBUTED_HEADERS} COMPONENT DirectDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/direct/src/fsm/FSM.py b/direct/src/fsm/FSM.py
index eb67f55c0a..8236b64a75 100644
--- a/direct/src/fsm/FSM.py
+++ b/direct/src/fsm/FSM.py
@@ -153,6 +153,12 @@ class FSM(DirectObject):
# must be approved by some filter function.
defaultTransitions = None
+ # An enum class for special states like the DEFAULT or ANY state,
+ # that should be treatened by the FSM in a special way
+ class EnumStates():
+ ANY = 1
+ DEFAULT = 2
+
def __init__(self, name):
self.fsmLock = RLock()
self._name = name
@@ -382,6 +388,27 @@ class FSM(DirectObject):
# accept it.
return (request,) + args
+ elif FSM.EnumStates.ANY in self.defaultTransitions.get(self.state, []):
+ # Whenever we have a '*' as our to transition, we allow
+ # to transit to any other state
+ return (request,) + args
+
+ elif request in self.defaultTransitions.get(FSM.EnumStates.ANY, []):
+ # If the requested state is in the default transitions
+ # from any state list, we also alow to transit to the
+ # new state
+ return (request,) + args
+
+ elif FSM.EnumStates.ANY in self.defaultTransitions.get(FSM.EnumStates.ANY, []):
+ # This is like we had set the defaultTransitions to None.
+ # Any state can transit to any other state
+ return (request,) + args
+
+ elif request in self.defaultTransitions.get(FSM.EnumStates.DEFAULT, []):
+ # This is the fallback state that we use whenever no
+ # other trnasition was possible
+ return (request,) + args
+
# If self.defaultTransitions is not None, it is an error
# to request a direct state transition (capital letter
# request) not listed in defaultTransitions and not
diff --git a/direct/src/gui/DirectScrollBar.py b/direct/src/gui/DirectScrollBar.py
index a873924456..822cb5b3a6 100644
--- a/direct/src/gui/DirectScrollBar.py
+++ b/direct/src/gui/DirectScrollBar.py
@@ -88,6 +88,8 @@ class DirectScrollBar(DirectFrame):
else:
self.incButton['frameSize'] = (f[0], f[1], f[2]*0.05, f[3]*0.05)
+ self._lastOrientation = self['orientation']
+
self.guiItem.setThumbButton(self.thumb.guiItem)
self.guiItem.setLeftButton(self.decButton.guiItem)
self.guiItem.setRightButton(self.incButton.guiItem)
@@ -140,13 +142,38 @@ class DirectScrollBar(DirectFrame):
def setOrientation(self):
if self['orientation'] == DGG.HORIZONTAL:
+ if self._lastOrientation in (DGG.VERTICAL, DGG.VERTICAL_INVERTED):
+ fpre = self['frameSize']
+ # swap frameSize width and height to keep custom frameSizes
+ self['frameSize'] = (fpre[2], fpre[3], fpre[0], fpre[1])
+ f = self.decButton['frameSize']
+ self.decButton['frameSize'] = (f[2], f[3], f[0], f[1])
+ f = self.incButton['frameSize']
+ self.incButton['frameSize'] = (f[2], f[3], f[0], f[1])
self.guiItem.setAxis(Vec3(1, 0, 0))
elif self['orientation'] == DGG.VERTICAL:
+ if self._lastOrientation == DGG.HORIZONTAL:
+ fpre = self['frameSize']
+ # swap frameSize width and height to keep custom frameSizes
+ self['frameSize'] = (fpre[2], fpre[3], fpre[0], fpre[1])
+ f = self.decButton['frameSize']
+ self.decButton['frameSize'] = (f[2], f[3], f[0], f[1])
+ f = self.incButton['frameSize']
+ self.incButton['frameSize'] = (f[2], f[3], f[0], f[1])
self.guiItem.setAxis(Vec3(0, 0, -1))
elif self['orientation'] == DGG.VERTICAL_INVERTED:
+ if self._lastOrientation == DGG.HORIZONTAL:
+ fpre = self['frameSize']
+ # swap frameSize width and height to keep custom frameSizes
+ self['frameSize'] = (fpre[2], fpre[3], fpre[0], fpre[1])
+ f = self.decButton['frameSize']
+ self.decButton['frameSize'] = (f[2], f[3], f[0], f[1])
+ f = self.incButton['frameSize']
+ self.incButton['frameSize'] = (f[2], f[3], f[0], f[1])
self.guiItem.setAxis(Vec3(0, 0, 1))
else:
raise ValueError('Invalid value for orientation: %s' % (self['orientation']))
+ self._lastOrientation = self['orientation']
def setManageButtons(self):
self.guiItem.setManagePieces(self['manageButtons'])
diff --git a/direct/src/gui/DirectScrolledFrame.py b/direct/src/gui/DirectScrolledFrame.py
index 7b30ba499e..c860797b74 100644
--- a/direct/src/gui/DirectScrolledFrame.py
+++ b/direct/src/gui/DirectScrolledFrame.py
@@ -77,9 +77,11 @@ class DirectScrolledFrame(DirectFrame):
self.initialiseoptions(DirectScrolledFrame)
def setScrollBarWidth(self):
+ if self.fInit: return
+
w = self['scrollBarWidth']
- self.verticalScroll["frameSize"] = (-w / 2.0, w / 2.0, -1, 1)
- self.horizontalScroll["frameSize"] = (-1, 1, -w / 2.0, w / 2.0)
+ self.verticalScroll["frameSize"] = (-w / 2.0, w / 2.0, self.verticalScroll["frameSize"][2], self.verticalScroll["frameSize"][3])
+ self.horizontalScroll["frameSize"] = (self.horizontalScroll["frameSize"][0], self.horizontalScroll["frameSize"][1], -w / 2.0, w / 2.0)
def setCanvasSize(self):
f = self['canvasSize']
diff --git a/direct/src/gui/DirectSlider.py b/direct/src/gui/DirectSlider.py
index c5823a9efc..e113f34055 100644
--- a/direct/src/gui/DirectSlider.py
+++ b/direct/src/gui/DirectSlider.py
@@ -41,7 +41,7 @@ class DirectSlider(DirectFrame):
('extraArgs', [], None),
)
- if kw.get('orientation') == DGG.VERTICAL:
+ if kw.get('orientation') in (DGG.VERTICAL, DGG.VERTICAL_INVERTED):
# These are the default options for a vertical layout.
optiondefs += (
('frameSize', (-0.08, 0.08, -1, 1), None),
@@ -72,6 +72,8 @@ class DirectSlider(DirectFrame):
else:
self.thumb['frameSize'] = (f[0], f[1], f[2]*0.05, f[3]*0.05)
+ self._lastOrientation = self['orientation']
+
self.guiItem.setThumbButton(self.thumb.guiItem)
# Bind command function
@@ -115,11 +117,35 @@ class DirectSlider(DirectFrame):
def setOrientation(self):
if self['orientation'] == DGG.HORIZONTAL:
+ if self._lastOrientation in (DGG.VERTICAL, DGG.VERTICAL_INVERTED):
+ fpre = self['frameSize']
+ # swap frameSize width and height to keep custom frameSizes
+ self['frameSize'] = (fpre[2], fpre[3], fpre[0], fpre[1])
+ tf = self.thumb['frameSize']
+ self.thumb['frameSize'] = (tf[2], tf[3], tf[0], tf[1])
self.guiItem.setAxis(Vec3(1, 0, 0))
+ self['frameVisibleScale'] = (1, 0.25)
elif self['orientation'] == DGG.VERTICAL:
+ if self._lastOrientation == DGG.HORIZONTAL:
+ fpre = self['frameSize']
+ # swap frameSize width and height to keep custom frameSizes
+ self['frameSize'] = (fpre[2], fpre[3], fpre[0], fpre[1])
+ tf = self.thumb['frameSize']
+ self.thumb['frameSize'] = (tf[2], tf[3], tf[0], tf[1])
self.guiItem.setAxis(Vec3(0, 0, 1))
+ self['frameVisibleScale'] = (0.25, 1)
+ elif self['orientation'] == DGG.VERTICAL_INVERTED:
+ if self._lastOrientation == DGG.HORIZONTAL:
+ fpre = self['frameSize']
+ # swap frameSize width and height to keep custom frameSizes
+ self['frameSize'] = (fpre[2], fpre[3], fpre[0], fpre[1])
+ tf = self.thumb['frameSize']
+ self.thumb['frameSize'] = (tf[2], tf[3], tf[0], tf[1])
+ self.guiItem.setAxis(Vec3(0, 0, -1))
+ self['frameVisibleScale'] = (0.25, 1)
else:
raise ValueError('Invalid value for orientation: %s' % (self['orientation']))
+ self._lastOrientation = self['orientation']
def destroy(self):
if (hasattr(self, 'thumb')):
diff --git a/direct/src/interval/CMakeLists.txt b/direct/src/interval/CMakeLists.txt
new file mode 100644
index 0000000000..2eba8a917a
--- /dev/null
+++ b/direct/src/interval/CMakeLists.txt
@@ -0,0 +1,54 @@
+set(P3INTERVAL_HEADERS
+ config_interval.h
+ cInterval.I cInterval.h
+ cIntervalManager.I cIntervalManager.h
+ cConstraintInterval.I cConstraintInterval.h
+ cConstrainTransformInterval.I cConstrainTransformInterval.h
+ cConstrainPosInterval.I cConstrainPosInterval.h
+ cConstrainHprInterval.I cConstrainHprInterval.h
+ cConstrainPosHprInterval.I cConstrainPosHprInterval.h
+ cLerpInterval.I cLerpInterval.h
+ cLerpNodePathInterval.I cLerpNodePathInterval.h
+ cLerpAnimEffectInterval.I cLerpAnimEffectInterval.h
+ cMetaInterval.I cMetaInterval.h
+ hideInterval.I hideInterval.h
+ lerpblend.h
+ showInterval.I showInterval.h
+ waitInterval.I waitInterval.h
+ lerp_helpers.h
+)
+
+set(P3INTERVAL_SOURCES
+ config_interval.cxx
+ cInterval.cxx
+ cIntervalManager.cxx
+ cConstraintInterval.cxx
+ cConstrainTransformInterval.cxx
+ cConstrainPosInterval.cxx
+ cConstrainHprInterval.cxx
+ cConstrainPosHprInterval.cxx
+ cLerpInterval.cxx
+ cLerpNodePathInterval.cxx
+ cLerpAnimEffectInterval.cxx
+ cMetaInterval.cxx
+ hideInterval.cxx
+ lerpblend.cxx
+ showInterval.cxx
+ waitInterval.cxx
+)
+
+composite_sources(p3interval P3INTERVAL_SOURCES)
+add_component_library(p3interval SYMBOL BUILDING_DIRECT_INTERVAL
+ ${P3INTERVAL_HEADERS} ${P3INTERVAL_SOURCES})
+target_link_libraries(p3interval p3directbase panda)
+target_interrogate(p3interval ALL)
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3interval
+ EXPORT Direct COMPONENT Direct
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT DirectDevel)
+endif()
+install(FILES ${P3INTERVAL_HEADERS} COMPONENT DirectDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/direct/src/motiontrail/CMakeLists.txt b/direct/src/motiontrail/CMakeLists.txt
new file mode 100644
index 0000000000..2c4ba8b78b
--- /dev/null
+++ b/direct/src/motiontrail/CMakeLists.txt
@@ -0,0 +1,24 @@
+set(P3MOTIONTRAIL_HEADERS
+ config_motiontrail.h
+ cMotionTrail.h
+)
+
+set(P3MOTIONTRAIL_SOURCES
+ config_motiontrail.cxx
+ cMotionTrail.cxx
+)
+
+add_component_library(p3motiontrail SYMBOL BUILDING_DIRECT_MOTIONTRAIL
+ ${P3MOTIONTRAIL_HEADERS} ${P3MOTIONTRAIL_SOURCES})
+target_link_libraries(p3motiontrail p3directbase panda)
+target_interrogate(p3motiontrail ALL)
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3motiontrail
+ EXPORT Direct COMPONENT Direct
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT DirectDevel)
+endif()
+install(FILES ${P3MOTIONTRAIL_HEADERS} COMPONENT DirectDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/direct/src/particles/ParticleEffect.py b/direct/src/particles/ParticleEffect.py
index 41930dd46b..2705ae39fd 100644
--- a/direct/src/particles/ParticleEffect.py
+++ b/direct/src/particles/ParticleEffect.py
@@ -36,6 +36,10 @@ class ParticleEffect(NodePath):
self.addParticles(particles)
self.renderParent = None
+ def birthLitter(self):
+ for p in self.particlesDict.values():
+ p.birthLitter()
+
def cleanup(self):
self.removeNode()
self.disable()
@@ -269,3 +273,4 @@ class ParticleEffect(NodePath):
clear_to_initial = clearToInitial
soft_stop = softStop
soft_start = softStart
+ birth_litter = birthLitter
diff --git a/direct/src/showbase/CMakeLists.txt b/direct/src/showbase/CMakeLists.txt
new file mode 100644
index 0000000000..a45fa14b4b
--- /dev/null
+++ b/direct/src/showbase/CMakeLists.txt
@@ -0,0 +1,32 @@
+set(P3SHOWBASE_HEADERS
+ showBase.h
+)
+
+set(P3SHOWBASE_SOURCES
+ showBase.cxx
+)
+
+if(APPLE)
+ list(APPEND P3SHOWBASE_SOURCES showBase_assist.mm)
+
+ # Bug in CMake 3.16.2: it tries to put .mm with the .cxx
+ set_source_files_properties(showBase_assist.mm PROPERTIES
+ SKIP_UNITY_BUILD_INCLUSION YES)
+
+endif()
+
+add_component_library(p3showbase NOINIT SYMBOL BUILDING_DIRECT_SHOWBASE
+ ${P3SHOWBASE_HEADERS} ${P3SHOWBASE_SOURCES})
+
+target_link_libraries(p3showbase p3directbase panda)
+target_interrogate(p3showbase ALL)
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3showbase
+ EXPORT Direct COMPONENT Direct
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT DirectDevel)
+endif()
+install(FILES ${P3SHOWBASE_HEADERS} COMPONENT DirectDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/direct/src/showbase/showBase.cxx b/direct/src/showbase/showBase.cxx
index 588dbb6540..7f90d4c93c 100644
--- a/direct/src/showbase/showBase.cxx
+++ b/direct/src/showbase/showBase.cxx
@@ -27,7 +27,7 @@ extern "C" { void CPSEnableForegroundOperation(ProcessSerialNumber* psn); }
#include "camera.h"
#include "graphicsPipeSelection.h"
-#ifdef WIN32
+#ifdef _WIN32
#include // For SystemParametersInfo()
STICKYKEYS g_StartupStickyKeys = {sizeof(STICKYKEYS), 0};
TOGGLEKEYS g_StartupToggleKeys = {sizeof(TOGGLEKEYS), 0};
@@ -131,7 +131,7 @@ query_fullscreen_testresult(int xsize, int ysize) {
void
store_accessibility_shortcut_keys() {
-#ifdef WIN32
+#ifdef _WIN32
SystemParametersInfo(SPI_GETSTICKYKEYS, sizeof(STICKYKEYS), &g_StartupStickyKeys, 0);
SystemParametersInfo(SPI_GETTOGGLEKEYS, sizeof(TOGGLEKEYS), &g_StartupToggleKeys, 0);
SystemParametersInfo(SPI_GETFILTERKEYS, sizeof(FILTERKEYS), &g_StartupFilterKeys, 0);
@@ -140,7 +140,7 @@ store_accessibility_shortcut_keys() {
void
allow_accessibility_shortcut_keys(bool allowKeys) {
-#ifdef WIN32
+#ifdef _WIN32
if( allowKeys )
{
// Restore StickyKeysetc to original state and enable Windows key
diff --git a/dtool/CMakeLists.txt b/dtool/CMakeLists.txt
new file mode 100644
index 0000000000..62308bd980
--- /dev/null
+++ b/dtool/CMakeLists.txt
@@ -0,0 +1,14 @@
+# Generate dtool_config.h
+include(LocalSetup.cmake)
+
+# Include dtool source directories
+add_subdirectory(src/cppparser)
+add_subdirectory(src/dconfig)
+add_subdirectory(src/dtoolbase)
+add_subdirectory(src/dtoolutil)
+add_subdirectory(src/interrogate)
+add_subdirectory(src/interrogatedb)
+add_subdirectory(src/prc)
+
+# Include dtool metalib
+add_subdirectory(metalibs/dtool)
diff --git a/dtool/CompilerFlags.cmake b/dtool/CompilerFlags.cmake
new file mode 100644
index 0000000000..a947d50927
--- /dev/null
+++ b/dtool/CompilerFlags.cmake
@@ -0,0 +1,247 @@
+#
+# CompilerFlags.cmake
+#
+# This file sets up various compiler flags (warning levels, turning off options
+# we don't need, etc.) It must be included directly from the root
+# CMakeLists.txt, due to its use of set(...)
+#
+
+include(CheckCXXCompilerFlag)
+
+# These are flags for the custom configurations we add
+# Standard
+if(MSVC)
+ set(CMAKE_C_FLAGS_STANDARD "/Ox")
+ set(CMAKE_CXX_FLAGS_STANDARD "/Ox")
+else()
+ set(CMAKE_C_FLAGS_STANDARD "-O3")
+ set(CMAKE_CXX_FLAGS_STANDARD "-O3")
+endif()
+set(CMAKE_SHARED_LINKER_FLAGS_STANDARD "")
+set(CMAKE_MODULE_LINKER_FLAGS_STANDARD "")
+set(CMAKE_EXE_LINKER_FLAGS_STANDARD "")
+
+# Coverage (when we know how to support it)
+if(CMAKE_CXX_COMPILER_ID MATCHES "(AppleClang|Clang)")
+ set(CMAKE_C_FLAGS_COVERAGE
+ "${CMAKE_C_FLAGS_DEBUG} -fprofile-instr-generate -fcoverage-mapping")
+ set(CMAKE_CXX_FLAGS_COVERAGE
+ "${CMAKE_CXX_FLAGS_DEBUG} -fprofile-instr-generate -fcoverage-mapping")
+
+ set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE
+ "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} -fprofile-instr-generate")
+ set(CMAKE_MODULE_LINKER_FLAGS_COVERAGE
+ "${CMAKE_MODULE_LINKER_FLAGS_DEBUG} -fprofile-instr-generate")
+ set(CMAKE_EXE_LINKER_FLAGS_COVERAGE
+ "${CMAKE_EXE_LINKER_FLAGS_DEBUG} -fprofile-instr-generate")
+
+elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GCC")
+ set(CMAKE_C_FLAGS_COVERAGE "${CMAKE_C_FLAGS_DEBUG} --coverage")
+ set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_DEBUG} --coverage")
+
+ set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE
+ "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} --coverage")
+ set(CMAKE_MODULE_LINKER_FLAGS_COVERAGE
+ "${CMAKE_MODULE_LINKER_FLAGS_DEBUG} --coverage")
+ set(CMAKE_EXE_LINKER_FLAGS_COVERAGE
+ "${CMAKE_EXE_LINKER_FLAGS_DEBUG} --coverage")
+
+endif()
+
+# Panda3D is now a C++11 project. Newer versions of CMake support this out of
+# the box; for older versions we take a shot in the dark:
+if(CMAKE_VERSION VERSION_LESS "3.1")
+ check_cxx_compiler_flag("-std=gnu++11" COMPILER_SUPPORTS_CXX11)
+ if(COMPILER_SUPPORTS_CXX11)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
+ else()
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++0x")
+ endif()
+
+else()
+ set(CMAKE_CXX_STANDARD 11)
+ set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+endif()
+
+# Set certain CMake flags we expect
+set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON)
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ON)
+
+# Set up the output directory structure, mimicking that of makepanda
+set(CMAKE_BINARY_DIR "${CMAKE_BINARY_DIR}/cmake")
+
+if(CMAKE_CFG_INTDIR STREQUAL ".")
+ # Single-configuration generator; output goes straight in the binary dir
+ set(PANDA_OUTPUT_DIR "${PROJECT_BINARY_DIR}")
+
+else()
+ # Multi-configuration generator; add a per-configuration path prefix
+ set(PANDA_OUTPUT_DIR "${PROJECT_BINARY_DIR}/$")
+
+endif()
+
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PANDA_OUTPUT_DIR}/bin")
+set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PANDA_OUTPUT_DIR}/lib")
+set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PANDA_OUTPUT_DIR}/lib")
+
+set(MODULE_DESTINATION "${CMAKE_INSTALL_LIBDIR}")
+
+# Runtime code assumes that dynamic modules have a "lib" prefix; Windows
+# assumes that debug libraries have a _d suffix.
+set(CMAKE_SHARED_MODULE_PREFIX "lib")
+if(WIN32)
+ set(CMAKE_DEBUG_POSTFIX "_d")
+
+ # Windows uses libfoo.lib for static libraries and foo.lib/dll for dynamic.
+ set(CMAKE_STATIC_LIBRARY_PREFIX "lib")
+
+ # On Windows, modules (DLLs) are located in bin; lib is just for .lib files
+ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PANDA_OUTPUT_DIR}/bin")
+ if(BUILD_SHARED_LIBS)
+ set(MODULE_DESTINATION "bin")
+ endif()
+endif()
+
+# Though not technically correct, we'll still want MODULE type libraries
+# (used for display and audio plugins) to use a .dylib extension.
+if(APPLE)
+ set(CMAKE_SHARED_MODULE_SUFFIX ".dylib")
+endif()
+
+# We want the output structured like build/CONFIG/bin, not build/bin/CONFIG per
+# the default for multi-configuration generators. In CMake 3.4+, it switches
+# automatically if the *_OUTPUT_DIRECTORY property contains a generator
+# expresssion, but as of this writing we support as early as CMake 3.0.2.
+#
+# So, let's just do this:
+if(CMAKE_VERSION VERSION_LESS "3.4")
+ foreach(_type RUNTIME ARCHIVE LIBRARY)
+ foreach(_config ${CMAKE_CONFIGURATION_TYPES})
+ string(TOUPPER "${_config}" _config)
+ set(CMAKE_${_type}_OUTPUT_DIRECTORY_${_config} "${CMAKE_${_type}_OUTPUT_DIRECTORY}")
+ endforeach(_config)
+ endforeach(_type)
+endif()
+
+# Set warning levels
+if(MSVC)
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W3")
+ set(CMAKE_CCXX_FLAGS "${CMAKE_CXX_FLAGS} /W3")
+
+else()
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
+
+endif()
+
+if(CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang)")
+ set(global_flags
+ "-Wno-unused-function -Wno-unused-parameter -fno-strict-aliasing")
+ set(release_flags "-Wno-unused-variable")
+
+ if(NOT MSVC)
+ # These flags upset Clang when it's in MSVC mode
+ set(release_flags "${release_flags} -fno-stack-protector -ffast-math -fno-unsafe-math-optimizations")
+
+ # Allow NaN to occur in the public SDK
+ set(standard_flags "${release_flags} -fno-finite-math-only")
+
+ else()
+ set(standard_flags "${release_flags}")
+
+ endif()
+
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${global_flags}")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${global_flags} -Wno-reorder")
+ set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${release_flags}")
+ set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${release_flags}")
+ set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} ${release_flags}")
+ set(CMAKE_CXX_FLAGS_STANDARD "${CMAKE_CXX_FLAGS_STANDARD} ${standard_flags}")
+
+ if(MSVC)
+ # Clang behaving as MSVC
+ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-command-line-argument")
+ set(CMAKE_CXX_FLAGS
+ "${CMAKE_CXX_FLAGS} -Wno-microsoft-template -Wno-unused-command-line-argument")
+ endif()
+endif()
+
+if(WIN32)
+ add_definitions(-D_CRT_SECURE_NO_WARNINGS)
+endif()
+
+# CMake will often pass -rdynamic when linking executables as a convenience for
+# projects that might forget when to use ENABLE_EXPORTS. This is preposterous,
+# since it prevents the linker from removing symbols unneeded by the executable
+# and stops us from identifying cases where ENABLE_EXPORTS is needed.
+set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
+set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
+
+# As long as we're figuring out compiler flags, figure out the flags for
+# turning C++ exception support on and off
+if(MSVC)
+ set(cxx_exceptions_on "/EHsc")
+ set(cxx_exceptions_off "/D_HAS_EXCEPTIONS=0")
+
+ set(cxx_rtti_on "/GR")
+ set(cxx_rtti_off "/GR-")
+
+else()
+ check_cxx_compiler_flag("-fno-exceptions" COMPILER_SUPPORTS_FEXCEPTIONS)
+ if(COMPILER_SUPPORTS_FEXCEPTIONS)
+ set(cxx_exceptions_on "-fexceptions")
+ set(cxx_exceptions_off "-fno-exceptions")
+
+ else()
+ set(cxx_exceptions_on)
+ set(cxx_exceptions_off)
+
+ endif()
+
+ check_cxx_compiler_flag("-fno-rtti" COMPILER_SUPPORTS_FRTTI)
+ if(COMPILER_SUPPORTS_FRTTI)
+ set(cxx_rtti_on "-frtti")
+ set(cxx_rtti_off "-fno-rtti")
+
+ else()
+ set(cxx_rtti_on)
+ set(cxx_rtti_off)
+
+ endif()
+
+endif()
+
+set(cxx_exceptions_property "$>")
+add_compile_options(
+ "$<${cxx_exceptions_property}:${cxx_exceptions_on}>"
+ "$<$:${cxx_exceptions_off}>")
+
+set(cxx_rtti_property "$>")
+if(NOT ANDROID)
+ # Normally, our Debug build defaults RTTI on. This is not the case on
+ # Android, where we don't use it even on Debug, to save space.
+
+ set(cxx_rtti_property "$,${cxx_rtti_property}>")
+endif()
+add_compile_options(
+ "$<${cxx_rtti_property}:${cxx_rtti_on}>"
+ "$<$:${cxx_rtti_off}>")
+set_property(DIRECTORY "${PROJECT_SOURCE_DIR}" APPEND PROPERTY
+ COMPILE_DEFINITIONS "$<${cxx_rtti_property}:HAVE_RTTI>")
+
+if(MSVC)
+ set(msvc_bigobj_property "$>")
+ add_compile_options("$<${msvc_bigobj_property}:/bigobj>")
+endif()
+
+# We should use -fvisibility=hidden everywhere, as it makes sure we think
+# about what symbols really should be exposed externally. For more info, see:
+# https://gcc.gnu.org/wiki/Visibility
+if(NOT MSVC)
+ check_cxx_compiler_flag("-fvisibility=hidden" COMPILER_SUPPORTS_FVISIBILITY_HIDDEN)
+ if(COMPILER_SUPPORTS_FVISIBILITY_HIDDEN)
+ add_compile_options("-fvisibility=hidden")
+ endif()
+endif()
diff --git a/dtool/Config.cmake b/dtool/Config.cmake
new file mode 100644
index 0000000000..e36d63b588
--- /dev/null
+++ b/dtool/Config.cmake
@@ -0,0 +1,600 @@
+#
+# dtool/Config.cmake
+#
+# This file defines certain configuration variables that are written
+# into the various make scripts. It is processed by CMake to
+# generate build scripts appropriate to each environment.
+#
+
+include(CMakeDependentOption)
+
+# Define our target platform.
+# The values "UNIX", "WIN32", "MINGW", "MSYS", and "CYGWIN"
+# are automatically provided by CMAKE. "APPLE" is also provided by
+# CMAKE but may be True on systems that are not OS X.
+if(CMAKE_SYSTEM_NAME MATCHES "Linux" OR CMAKE_SYSTEM_NAME MATCHES "Android")
+ set(IS_LINUX 1)
+endif()
+if(CMAKE_SYSTEM_NAME MATCHES "Darwin")
+ set(IS_OSX 1)
+endif()
+if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
+ set(IS_FREEBSD 1)
+endif()
+
+if(CMAKE_VERSION VERSION_GREATER "3.8")
+ get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+else()
+ message(WARNING "Multi-configuration builds may not work properly when using
+a CMake < 3.9. Making a guess if this is a multi-config generator.")
+ if(DEFINED CMAKE_CONFIGURATION_TYPES)
+ set(IS_MULTICONFIG ON)
+ else()
+ set(IS_MULTICONFIG OFF)
+ endif()
+endif()
+
+# Define the type of build we are setting up.
+
+set(_configs Standard Release RelWithDebInfo Debug MinSizeRel)
+if(DEFINED CMAKE_CXX_FLAGS_COVERAGE)
+ list(APPEND _configs Coverage)
+endif()
+
+if(IS_MULTICONFIG)
+ set(CMAKE_CONFIGURATION_TYPES ${_configs})
+else()
+ # CMAKE_BUILD_TYPE can't just be set using the usual set(CACHE) method since
+ # it's an empty string by default.
+ if(NOT CMAKE_BUILD_TYPE)
+ set(CMAKE_BUILD_TYPE Standard)
+ endif()
+ set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS ${_configs})
+endif()
+
+set(PER_CONFIG_OPTIONS)
+
+# Are we building with static or dynamic linking?
+option(BUILD_SHARED_LIBS
+ "Causes subpackages to be built separately -- setup for dynamic linking.
+Utilities/tools/binaries/etc are then dynamically linked to the
+libraries instead of being statically linked." ON)
+
+option(BUILD_METALIBS
+ "Should we build 'metalibs' -- fewer, larger libraries that contain the bulk
+of the code instead of many smaller components. Note that turning this off
+will still result in the 'metalibs' being built, but they will instead be many
+smaller stub libraries and not 'meta' libraries." ON)
+
+# The character used to separate components of an OS-specific
+# directory name depends on the platform (it is '/' on Unix, '\' on
+# Windows). That character selection is hardcoded into Panda and
+# cannot be changed here. (Note that an internal Panda filename
+# always uses the forward slash, '/', to separate the components of a
+# directory name.)
+
+# There's a different character used to separate the complete
+# directory names in a search path specification. On Unix, the
+# normal convention is ':', on Windows, it has to be ';', because the
+# colon is already used to mark the drive letter. This character is
+# selectable here. Most users won't want to change this. If
+# multiple characters are placed in this string, any one of them may
+# be used as a separator character.
+if(WIN32)
+ set(DEFAULT_PATHSEP ";")
+else()
+ set(DEFAULT_PATHSEP ":")
+endif()
+
+
+# Panda uses prc files for runtime configuration. There are many
+# compiled-in options to customize the behavior of the prc config
+# system; most users won't need to change any of them. Feel free to
+# skip over all of the PRC_* variables defined here.
+
+# The default behavior is to search for files names *.prc in the
+# directory specified by the PRC_DIR environment variable, and then
+# to search along all of the directories named by the PRC_PATH
+# environment variable. Either of these variables might be
+# undefined; if both of them are undefined, the default is to search
+# in the directory named here by DEFAULT_PRC_DIR.
+
+# By default, we specify the /etc dir, which is a special
+# syntax that causes it to automatically search up the directory
+# tree starting at the location of libpandaexpress.dll for any
+# directories called 'etc'.
+
+if(UNIX)
+ set(_default_prc "etc/panda3d")
+else()
+ set(_default_prc "etc")
+endif()
+set(DEFAULT_PRC_DIR "${_default_prc}" CACHE STRING
+ "The compiled-in default directory to look for the Config.prc file,
+in the absence of the PRC_DIR environment variable set, and in
+the absence of anything specified via the configpath directive.")
+
+# You can specify the names of the environment variables that are
+# used to specify the search location(s) for prc files at runtime.
+# These are space-separated lists of environment variable names.
+# Specify empty string for either one of these to disable the
+# feature. For instance, redefining PRC_DIR_ENVVARS here to
+# PRC_DIR would cause the environment variable $PRC_DIR
+# to be consulted at startup instead of the default value of
+# $PANDA_PRC_DIR.
+
+set(PRC_DIR_ENVVARS "PANDA_PRC_DIR" CACHE STRING
+ "The compiled-in name of the environment variable(s) that contain
+the name of a single directory in which to search for prc files.")
+
+set(PRC_PATH_ENVVARS "PANDA_PRC_PATH" CACHE STRING
+ "The compiled-in name of the environment variable(s) that contain
+the name of multiple directories, separated by DEFAULT_PATHSEP, in
+which to search for prc files.")
+
+# You can specify the name of the file(s) to search for in the above
+# paths to be considered a config file. This should be a
+# space-separated list of filename patterns. This is *.prc by
+# default; normally there's no reason to change this.
+
+set(PRC_PATTERNS "*.prc" CACHE STRING
+ "The filename(s) to search for in the above paths. Normally this is
+*.prc.")
+
+# You can optionally encrypt your prc file(s) to help protect them
+# from curious eyes. You have to specify the encryption key, which
+# gets hard-coded into the executable. (This feature provides mere
+# obfuscation, not real security, since the encryption key can
+# potentially be extracted by a hacker.) This requires building with
+# OpenSSL.
+
+set(PRC_ENCRYPTED_PATTERNS "*.prc.pe" CACHE STRING
+ "The filename(s) for encrypted prc files.")
+
+set(PRC_ENCRYPTION_KEY "" CACHE STRING
+ "The encryption key used to decrypt any encrypted prc files
+identified by PRC_ENCRYPTED_PATTERNS.")
+
+# One unusual feature of config is the ability to execute one or more
+# of the files it discovers as if it were a program, and then treat
+# the output of this program as a prc file. If you want to use this
+# feature, define this variable to the filename pattern or patterns
+# for such executable-style config programs (e.g. *prc.exe). This
+# can be the same as the above if you like this sort of ambiguity; in
+# that case, config will execute the file if it appears to be
+# executable; otherwise, it will simply read it.
+
+set(PRC_EXECUTABLE_PATTERNS "" CACHE STRING
+ "The filename(s) to search for, and execute, in the above paths.
+Normally this is empty.")
+
+# If you do use the above feature, you'll need another environment
+# variable that specifies additional arguments to pass to the
+# executable programs. The default definition, given here, makes
+# that variable be $PANDA_PRC_XARGS. Sorry, the same arguments
+# must be supplied to all executables in a given runtime session.
+
+set(PRC_EXECUTABLE_ARGS_ENVVAR "PANDA_PRC_XARGS" CACHE STRING
+ "The environment variable that defines optional args to pass to
+executables found that match one of the above patterns.")
+
+# You can implement signed prc files, if you require this advanced
+# feature. This allows certain config variables to be set only by a
+# prc file that has been provided by a trusted source. To do this,
+# first install and compile Dtool with OpenSSL and run the program
+# make-prc-key, and then specify here the output filename generated
+# by that program, and then recompile Dtool.
+
+set(PRC_PUBLIC_KEYS_FILENAME "" CACHE STRING "")
+
+# By default, the signed-prc feature, above, is enabled only for a
+# release build. In a normal development environment, any prc file
+# can set any config variable, whether or not it is signed. Set
+# this variable true or false to explicitly enable or disable this
+# feature.
+#XXX For which build types should this be enabled?
+if(CMAKE_BUILD_TYPE STREQUAL "Release")
+ set(DEFAULT_PRC_RESPECT_TRUST_LEVEL ON)
+else()
+ set(DEFAULT_PRC_RESPECT_TRUST_LEVEL OFF)
+endif()
+
+option(PRC_RESPECT_TRUST_LEVEL
+ "Define if we want to enable the trust_level feature of prc config
+variables. This requires OpenSSL and PRC_PUBLIC_KEYS_FILENAME,
+above." ${DEFAULT_PRC_RESPECT_TRUST_LEVEL})
+
+# If trust level is in effect, this specifies the default trust level
+# for any legacy (Dconfig) config variables (that is, variables
+# created using the config.GetBool(), etc. interface, rather than the
+# newer ConfigVariableBool interface).
+
+set(PRC_DCONFIG_TRUST_LEVEL "0" CACHE STRING
+ "The trust level value for any legacy (DConfig) variables.")
+
+# If trust level is in effect, you may globally increment the
+# (mis)trust level of all variables by the specified amount.
+# Incrementing this value by 1 will cause all variables to require at
+# least a level 1 signature.
+
+set(PRC_INC_TRUST_LEVEL "0" CACHE STRING
+ "The amount by which we globally increment the trust level.")
+
+# Similarly, the descriptions are normally saved only in a
+# development build, not in a release build. Set this value true to
+# explicitly save them anyway.
+#XXX only for release-release builds
+option(PRC_SAVE_DESCRIPTIONS
+ "Define if you want to save the descriptions for ConfigVariables."
+ ON)
+
+mark_as_advanced(DEFAULT_PRC_DIR PRC_DIR_ENVVARS PRC_PATH_ENVVARS
+ PRC_PATTERNS PRC_ENCRYPTED_PATTERNS PRC_ENCRYPTION_KEY
+ PRC_EXECUTABLE_PATTERNS PRC_EXECUTABLE_ARGS_ENVVAR
+ PRC_PUBLIC_KEYS_FILENAME PRC_RESPECT_TRUST_LEVEL
+ PRC_DCONFIG_TRUST_LEVEL PRC_INC_TRUST_LEVEL PRC_SAVE_DESCRIPTIONS)
+
+#
+# This is the end of the PRC variable customization section. The
+# remaining variables are of general interest to everyone.
+#
+
+# The following options relate to interrogate, the tool that is
+# used to generate bindings for non-C++ languages.
+
+option(WANT_INTERROGATE
+ "Do you want to include Interrogate in the installation? This
+program reads C++ source files and generates bindings for another
+language. If you won't be building interfaces for other languages,
+you don't need the program." ON)
+
+cmake_dependent_option(INTERROGATE_PYTHON_INTERFACE
+ "Do you want to generate a Python-callable interrogate interface?
+This is only necessary if you plan to make calls into Panda from a
+program written in Python. This is done only if HAVE_PYTHON is also
+true." ON "HAVE_PYTHON" OFF)
+
+set(INTERROGATE_C_INTERFACE
+ "Do you want to generate a C-callable interrogate interface? This
+generates an interface similar to the Python interface above, with
+a C calling convention. It should be useful for most other kinds
+of scripting language; the VR Studio used to use this to make calls
+into Panda from Squeak." OFF)
+
+set(INTERROGATE_OPTIONS "-fnames;-string;-refcount;-assert" CACHE STRING
+ "What additional options should be passed to interrogate when
+generating either of the above two interfaces? Generally, you
+probably don't want to mess with this.")
+
+option(INTERROGATE_VERBOSE
+ "Set this if you would like interrogate to generate advanced
+debugging information." OFF)
+
+mark_as_advanced(INTERROGATE_OPTIONS)
+
+#
+# The following options have to do with the memory allocation system
+# that will be used by Panda3D.
+#
+
+option(DO_MEMORY_USAGE
+ "Do you want to compile in support for tracking memory usage? This
+enables you to define the variable 'track-memory-usage' at runtime
+to help track memory leaks, and also report total memory usage on
+PStats. There is some small overhead for having this ability
+available, even if it is unused." OFF)
+list(APPEND PER_CONFIG_OPTIONS DO_MEMORY_USAGE)
+set(DO_MEMORY_USAGE_Debug ON CACHE BOOL "")
+
+option(SIMULATE_NETWORK_DELAY
+ "This option compiles in support for simulating network delay via
+the min-lag and max-lag prc variables. It adds a tiny bit of
+overhead even when it is not activated, so it is typically enabled
+only in a development build." OFF)
+list(APPEND PER_CONFIG_OPTIONS SIMULATE_NETWORK_DELAY)
+set(SIMULATE_NETWORK_DELAY_Debug ON CACHE BOOL "")
+
+option(SUPPORT_IMMEDIATE_MODE
+ "This option compiles in support for immediate-mode OpenGL
+rendering. Since this is normally useful only for researching
+buggy drivers, and since there is a tiny bit of per-primitive
+overhead to have this option available even if it is unused, it is
+by default enabled only in a development build. This has no effect
+on DirectX rendering." OFF)
+list(APPEND PER_CONFIG_OPTIONS SUPPORT_IMMEDIATE_MODE)
+set(SUPPORT_IMMEDIATE_MODE_Debug ON CACHE BOOL "")
+
+option(NOTIFY_DEBUG
+ "Do you want to include the 'debug' and 'spam' Notify messages?
+Normally, these are stripped out when we build for release, but sometimes it's
+useful to keep them around. Turn this setting on to achieve that." OFF)
+list(APPEND PER_CONFIG_OPTIONS NOTIFY_DEBUG)
+set(NOTIFY_DEBUG_Debug ON CACHE BOOL "")
+
+option(SUPPORT_FIXED_FUNCTION
+ "This option compiles in support for the fixed-function OpenGL
+pipeline. It is only really useful to turn this off if you are targeting
+an OpenGL ES 2 system." ON)
+
+option(USE_MEMORY_DLMALLOC
+ "This is an optional alternative memory-allocation scheme
+available within Panda. You can experiment with it to see
+if it gives better performance than the system malloc(), but
+at the time of this writing, it doesn't appear that it does." OFF)
+
+option(USE_MEMORY_PTMALLOC2
+ "This is an optional alternative memory-allocation scheme
+available within Panda. You can experiment with it to see
+if it gives better performance than the system malloc(), but
+at the time of this writing, it doesn't appear that it does." OFF)
+
+option(MEMORY_HOOK_DO_ALIGN
+ "Set this true if you prefer to use the system malloc library even
+if 16-byte alignment must be performed on top of it, wasting up to
+30% of memory usage. If you do not set this, and 16-byte alignment
+is required and not provided by the system malloc library, then an
+alternative malloc system (above) will be used instead." OFF)
+
+option(USE_DELETED_CHAIN
+ "Define this true to use the DELETED_CHAIN macros, which support
+fast re-use of existing allocated blocks, minimizing the low-level
+calls to malloc() and free() for frequently-created and -deleted
+objects. There's usually no reason to set this false, unless you
+suspect a bug in Panda's memory management code." ON)
+
+mark_as_advanced(DO_MEMORY_USAGE SIMULATE_NETWORK_DELAY
+ SUPPORT_IMMEDIATE_MODE USE_MEMORY_DLMALLOC USE_MEMORY_PTMALLOC2
+ MEMORY_HOOK_DO_ALIGN USE_DELETED_CHAIN)
+
+
+#
+# This section relates to mobile-device/phone support and options
+#
+
+# iPhone support
+set(BUILD_IPHONE "" CACHE STRING
+ "Panda contains some experimental code to compile for IPhone. This
+requires the Apple IPhone SDK, which is currently only available
+for OS X platforms. Set this to either 'iPhoneSimulator' or
+'iPhoneOS'. Note that this is still *experimental* and incomplete!
+Don't enable this unless you know what you're doing!")
+set_property(CACHE BUILD_IPHONE PROPERTY STRINGS "" iPhoneSimulator iPhoneOS)
+
+
+# Android support
+option(BUILD_ANDROID
+ "Panda contains some experimental code to compile for Android.
+This requires the Google Android NDK. Besides BUILD_ANDROID, you'll
+also have to set ANDROID_NDK_HOME." OFF)
+
+set(ANDROID_NDK_HOME "" CACHE STRING
+ "The location of the Android NDK directory. ANDROID_NDK_HOME may
+not contain any spaces.")
+
+set(ANDROID_ABI "armeabi-v7a" CACHE STRING
+ "Can be be set to armeabi-v7a, arm64-v8a, x86, or x86_64,
+depending on which architecture should be targeted.")
+set_property(CACHE ANDROID_ABI PROPERTY STRINGS
+ armeabi-v7a arm64-v8a x86 x86_64)
+
+set(ANDROID_STL "c++_shared" CACHE STRING "")
+set(ANDROID_PLATFORM "android-14" CACHE STRING "")
+set(ANDROID_ARCH "arm" CACHE STRING "")
+if(ANDROID_ARCH STREQUAL "arm")
+ set(ANDROID_TOOLCHAIN "arm-linux-androideabi")
+else()
+ set(ANDROID_TOOLCHAIN "")
+endif()
+
+mark_as_advanced(ANDROID_NDK_HOME ANDROID_ABI ANDROID_STL
+ ANDROID_PLATFORM ANDROID_ARCH)
+
+
+#
+# Now let's check for the presence of various thirdparty libraries.
+#
+
+
+# By default, we'll assume the user only wants to run with Debug
+# python if he has to--that is, on Windows when building a debug build.
+set(USE_DEBUG_PYTHON OFF)
+if(WIN32)
+ set(USE_DEBUG_PYTHON_Debug ON)
+endif()
+list(APPEND PER_CONFIG_OPTIONS USE_DEBUG_PYTHON)
+
+cmake_dependent_option(HAVE_VIDEO4LINUX
+ "Set this to enable webcam support on Linux." ON
+ "IS_LINUX" OFF)
+
+
+# If you are having trouble linking in OpenGL extension functions at
+# runtime for some reason, you can set this variable. It also,
+# requires you to install the OpenGL header files and compile-time
+# libraries appropriate to the version you want to compile against.
+set(MIN_GL_VERSION "1 1" CACHE STRING
+ "The variable is the major, minor version of OpenGL, separated by a
+space (instead of a dot). Thus, \"1 1\" means OpenGL version 1.1.
+
+This defines the minimum runtime version of OpenGL that Panda will
+require. Setting it to a higher version will compile in hard
+references to the extension functions provided by that OpenGL
+version and below, which may reduce runtime portability to other
+systems, but it will avoid issues with getting extension function
+pointers.")
+
+
+# Should build tinydisplay?
+#option(HAVE_TINYDISPLAY
+# "Builds TinyDisplay, a light software renderer based on TinyGL,
+#that is built into Panda. TinyDisplay is not as full-featured as Mesa
+#but is many times faster." ON)
+#option(HAVE_TINYDISPLAY_MinSizeRel "" OFF)
+#list(APPEND PER_CONFIG_OPTIONS HAVE_TINYDISPLAY)
+
+
+# Is SDL installed, and where?
+set(Threads_FIND_QUIETLY TRUE) # Fix for builtin FindSDL
+set(Eigen3_FIND_QUIETLY TRUE) # Fix for builtin FindSDL
+set(PythonLibs_FIND_QUIETLY TRUE) # Fix for builtin FindSDL
+set(PythonInterp_FIND_QUIETLY TRUE) # Fix for builtin FindSDL
+
+find_package(SDL QUIET)
+
+package_option(SDL
+ "The SDL library is useful only for tinydisplay, and is not even
+required for that, as tinydisplay is also supported natively on
+each supported platform.")
+
+# Cleanup after builtin FindSDL
+mark_as_advanced(SDLMAIN_LIBRARY)
+mark_as_advanced(SDL_INCLUDE_DIR)
+mark_as_advanced(SDL_LIBRARY)
+mark_as_advanced(SDL_LIBRARY_TEMP)
+
+
+if(HAVE_GL AND HAVE_X11 AND NOT APPLE)
+ option(HAVE_GLX "Enables GLX. Requires OpenGL and X11." ON)
+else()
+ option(HAVE_GLX "Enables GLX. Requires OpenGL and X11." OFF)
+endif()
+
+option(LINK_IN_GLXGETPROCADDRESS
+ "Define this to compile in a reference to the glXGetProcAddress().
+This is only relevant from platforms using OpenGL under X."
+ OFF)
+
+if(WIN32 AND HAVE_GL)
+ option(HAVE_WGL "Enable WGL. Requires OpenGL on Windows." ON)
+else()
+ option(HAVE_WGL "Enable WGL. Requires OpenGL on Windows." OFF)
+endif()
+
+cmake_dependent_option(HAVE_COCOA "Enable Cocoa. Requires Mac OS X." ON
+ "APPLE" OFF)
+
+#
+# Miscellaneous settings
+#
+
+option(WANT_NATIVE_NET
+ "Define this true to build the low-level native network
+implementation. Normally this should be set true." ON)
+
+option(HAVE_NET
+ "Do you want to build the high-level network interface? This layers
+on top of the low-level native_net interface, specified above.
+Normally, if you build NATIVE_NET, you will also build NET."
+ ${WANT_NATIVE_NET})
+
+option(HAVE_EGG
+ "Do you want to build the egg loader? Usually there's no reason to
+avoid building this, unless you really want to make a low-footprint
+build (such as, for instance, for the iPhone)." ON)
+
+option(HAVE_AUDIO
+ "Do you want to build the audio interface?" ON)
+
+option(DO_PSTATS
+ "Enable the pstats client?" ON)
+
+option(USE_PANDAFILESTREAM
+ "Enable the PandaFileStream implementation of pfstream etc.?" ON)
+
+# These image formats don't require the assistance of a third-party
+# library to read and write, so there's normally no reason to disable
+# them int he build, unless you are looking to reduce the memory footprint.
+option(HAVE_SGI_RGB "Enable support for loading SGI RGB images." ON)
+option(HAVE_TGA "Enable support for loading TGA images." ON)
+option(HAVE_IMG "Enable support for loading IMG images." ON)
+option(HAVE_SOFTIMAGE_PIC "Enable support for loading SOFTIMAGE PIC images." ON)
+option(HAVE_BMP "Enable support for loading BMP images." ON)
+option(HAVE_PNM "Enable support for loading PNM images." ON)
+
+foreach(adv_image_format
+ HAVE_SGI_RGB HAVE_TGA HAVE_IMG HAVE_SOFTIMAGE_PIC HAVE_BMP HAVE_PNM)
+
+ option(${adv_image_format}_MinSizeRel "" OFF)
+ list(APPEND PER_CONFIG_OPTIONS ${adv_image_format})
+
+ mark_as_advanced(${adv_image_format} ${adv_image_format}_MinSizeRel)
+
+endforeach(adv_image_format)
+
+# How to invoke bison and flex. Panda takes advantage of some
+# bison/flex features, and therefore specifically requires bison and
+# flex, not some other versions of yacc and lex. However, you only
+# need to have these programs if you need to make changes to the
+# bison or flex sources (see the next point, below).
+
+find_package(BISON QUIET)
+find_package(FLEX QUIET)
+
+# You may not even have bison and flex installed. If you don't, no
+# sweat; Panda ships with the pre-generated output of these programs,
+# so you don't need them unless you want to make changes to the
+# grammars themselves (files named *.yxx or *.lxx).
+
+set(HAVE_BISON ${BISON_FOUND})
+set(HAVE_FLEX ${FLEX_FOUND})
+
+
+### Configure threading support ###
+set(CMAKE_THREAD_PREFER_PTHREAD ON)
+set(THREADS_PREFER_PTHREAD_FLAG ON)
+find_package(Threads QUIET)
+
+set(THREADS_LIBRARIES "${CMAKE_THREAD_LIBS_INIT}")
+set(HAVE_POSIX_THREADS ${CMAKE_USE_PTHREADS_INIT})
+
+# Add basic use flag for threading
+package_option(THREADS
+ "If on, compile Panda3D with threading support.
+Building in support for threading will enable Panda to take
+advantage of multiple CPU's if you have them (and if the OS
+supports kernel threads running on different CPU's), but it will
+slightly slow down Panda for the single CPU case."
+ IMPORTED_AS Threads::Threads)
+
+# Configure debug threads
+option(DEBUG_THREADS "If on, enables debugging of thread and sync operations (i.e. mutexes, deadlocks)" OFF)
+list(APPEND PER_CONFIG_OPTIONS DEBUG_THREADS)
+set(DEBUG_THREADS_Debug ON CACHE BOOL "")
+
+option(SIMPLE_THREADS
+ "If on, compile with simulated threads. Threads, by default, use
+OS-provided threading constructs, which usually allows for full
+multithreading support (i.e. the program can use multiple CPU's).
+On the other hand, compiling in this full OS-provided support can
+impose some substantial runtime overhead, making the application
+run slower on a single-CPU machine. This settings avoid the overhead,
+but still gain some of the basic functionality of threads." OFF)
+list(APPEND PER_CONFIG_OPTIONS SIMPLE_THREADS)
+
+option(OS_SIMPLE_THREADS
+ "If on, OS threading constructs will be used to perform context switches.
+A mutex is used to ensure that only one thread runs at a time, so the
+normal SIMPLE_THREADS optimizations still apply, and the normal
+SIMPLE_THREADS scheduler is used to switch between threads (instead
+of the OS scheduler). This may be more portable and more reliable,
+but it is a hybrid between user-space threads and os-provided threads." ON)
+list(APPEND PER_CONFIG_OPTIONS OS_SIMPLE_THREADS)
+
+### Configure pipelining ###
+option(DO_PIPELINING "If on, compile with pipelined rendering." ON)
+
+### Miscellaneous configuration
+option(COMPILE_IN_DEFAULT_FONT
+ "If on, compiles in a default font, so that every TextNode will always
+have a font available without requiring the user to specify one.
+When turned off, the generated library will save a few kilobytes." ON)
+list(APPEND PER_CONFIG_OPTIONS COMPILE_IN_DEFAULT_FONT)
+set(COMPILE_IN_DEFAULT_FONT_MinSizeRel OFF CACHE BOOL "")
+
+option(STDFLOAT_DOUBLE
+ "Define this true to compile a special version of Panda to use a
+'double' floating-precision type for most internal values, such as
+positions and transforms, instead of the standard single-precision
+'float' type. This does not affect the default numeric type of
+vertices, which is controlled by the runtime config variable
+vertices-float64." OFF)
diff --git a/dtool/LocalSetup.cmake b/dtool/LocalSetup.cmake
new file mode 100644
index 0000000000..eed31b0e84
--- /dev/null
+++ b/dtool/LocalSetup.cmake
@@ -0,0 +1,219 @@
+#
+# LocalSetup.cmake
+#
+# This file contains further instructions to set up the DTOOL package
+# when using CMake. In particular, it creates the dtool_config.h
+# file based on the user's selected configure variables.
+#
+
+include(CheckCXXSourceCompiles)
+include(CheckCSourceRuns)
+include(CheckIncludeFileCXX)
+include(CheckFunctionExists)
+include(CheckTypeSize)
+include(TestBigEndian)
+include(TestForSTDNamespace)
+
+# Check if this is a big-endian system.
+test_big_endian(WORDS_BIGENDIAN)
+
+# Define if we have lockf().
+check_cxx_source_compiles("
+#include
+int main(int argc, char *argv[]) { lockf(0, F_LOCK, 0); return 0; }
+" PHAVE_LOCKF)
+
+# Define if we can trust the compiler not to insert extra bytes in
+# structs between base structs and derived structs.
+check_c_source_runs("
+struct A { int a; };
+struct B : public A { int b; };
+int main(int argc, char *argv[]) {
+ struct B i;
+ if ((size_t) &(i.b) == ((size_t) &(i.a)) + sizeof(struct A)) {
+ return 0;
+ } else {
+ return 1;
+ }
+}" SIMPLE_STRUCT_POINTERS)
+
+# Define if we have STL hash_map etc. available.
+# We're not using this functionality at the moment, it seems.
+set(HAVE_STL_HASH OFF)
+
+# Check if we have a gettimeofday() function.
+check_function_exists(gettimeofday HAVE_GETTIMEOFDAY)
+
+# Define if gettimeofday() takes only one parameter.
+check_cxx_source_compiles("
+#include
+int main(int argc, char *argv[]) {
+ struct timeval tv;
+ int result;
+ result = gettimeofday(&tv);
+ return 0;
+}" GETTIMEOFDAY_ONE_PARAM)
+
+# Check if we have getopt.
+check_function_exists(getopt HAVE_GETOPT)
+check_function_exists(getopt_long_only HAVE_GETOPT_LONG_ONLY)
+check_include_file_cxx(getopt.h PHAVE_GETOPT_H)
+
+# Define if you have ioctl(TIOCGWINSZ) to determine terminal width.
+#XXX can we make a test case for this that isn't dependent on
+# the current terminal? It might also be useful for Cygwin users.
+if(UNIX)
+ set(IOCTL_TERMINAL_WIDTH 1)
+endif()
+
+# Do the system headers define key ios typedefs like ios::openmode
+# and ios::fmtflags?
+check_cxx_source_compiles("
+#include
+std::ios::openmode foo;
+std::ios::fmtflags bar;
+int main(int argc, char *argv[]) { return 0; }
+" HAVE_IOS_TYPEDEFS)
+
+# Define if the C++ iostream library defines ios::binary.
+check_cxx_source_compiles("
+#include
+std::ios::openmode binary = std::ios::binary;
+int main(int argc, char *argv[]) { return 0; }
+" HAVE_IOS_BINARY)
+
+# Can we safely call getenv() at static init time?
+if(WIN32 OR UNIX)
+ set(STATIC_INIT_GETENV 1)
+endif()
+
+# Can we read the file /proc/self/[*] to determine our
+# environment variables at static init time?
+if(IS_LINUX)
+ set(HAVE_PROC_SELF_EXE 1)
+ set(HAVE_PROC_SELF_MAPS 1)
+ set(HAVE_PROC_SELF_ENVIRON 1)
+ set(HAVE_PROC_SELF_CMDLINE 1)
+endif()
+
+if(IS_FREEBSD)
+ set(HAVE_PROC_CURPROC_FILE 1)
+ set(HAVE_PROC_CURPROC_MAP 1)
+ set(HAVE_PROC_CURPROC_CMDLINE 1)
+endif()
+
+# Do we have a global pair of argc/argv variables that we can read at
+# static init time? Should we prototype them? What are they called?
+if(WIN32)
+ set(HAVE_GLOBAL_ARGV ON)
+ set(PROTOTYPE_GLOBAL_ARGV OFF)
+ set(GLOBAL_ARGV __argv)
+ set(GLOBAL_ARGC __argc)
+endif()
+
+# Do we have all these header files?
+check_include_file_cxx(io.h PHAVE_IO_H)
+check_include_file_cxx(iostream PHAVE_IOSTREAM)
+check_include_file_cxx(malloc.h PHAVE_MALLOC_H)
+check_include_file_cxx(sys/malloc.h PHAVE_SYS_MALLOC_H)
+check_include_file_cxx(alloca.h PHAVE_ALLOCA_H)
+check_include_file_cxx(locale.h PHAVE_LOCALE_H)
+check_include_file_cxx(string.h PHAVE_STRING_H)
+check_include_file_cxx(stdlib.h PHAVE_STDLIB_H)
+check_include_file_cxx(limits.h PHAVE_LIMITS_H)
+check_include_file_cxx(sstream PHAVE_SSTREAM)
+check_include_file_cxx(new PHAVE_NEW)
+check_include_file_cxx(sys/types.h PHAVE_SYS_TYPES_H)
+check_include_file_cxx(sys/time.h PHAVE_SYS_TIME_H)
+check_include_file_cxx(unistd.h PHAVE_UNISTD_H)
+check_include_file_cxx(utime.h PHAVE_UTIME_H)
+check_include_file_cxx(glob.h PHAVE_GLOB_H)
+check_include_file_cxx(dirent.h PHAVE_DIRENT_H)
+check_include_file_cxx(ucontext.h PHAVE_UCONTEXT_H) #TODO doesn't work on OSX, use sys/ucontext.h
+check_include_file_cxx(linux/input.h PHAVE_LINUX_INPUT_H)
+check_include_file_cxx(stdint.h PHAVE_STDINT_H)
+
+# Do we have Posix threads?
+#set(HAVE_POSIX_THREADS ${CMAKE_USE_PTHREADS_INIT})
+
+# Do we have SSE2 support?
+include(CheckCXXCompilerFlag)
+check_cxx_compiler_flag(-msse2 HAVE_SSE2)
+
+# Set LINK_ALL_STATIC if we're building everything as static libraries.
+# Also set the library type used for "modules" appropriately.
+if(BUILD_SHARED_LIBS)
+ set(LINK_ALL_STATIC OFF)
+ set(MODULE_TYPE "MODULE"
+ CACHE INTERNAL "" FORCE)
+
+else()
+ set(LINK_ALL_STATIC ON)
+ set(MODULE_TYPE "STATIC"
+ CACHE INTERNAL "" FORCE)
+
+endif()
+
+# Now go through all the packages and report whether we have them.
+show_packages()
+
+message("")
+if(INTERROGATE_PYTHON_INTERFACE)
+ message("Compilation will generate Python interfaces for Python ${PYTHON_VERSION_STRING}.")
+else()
+ message("Configuring Panda WITHOUT Python interfaces.")
+endif()
+
+if(HAVE_THREADS)
+ if(SIMPLE_THREADS)
+ message("Compilation will include simulated threading support.")
+ elseif(DO_PIPELINING)
+ message("Compilation will include full, pipelined threading support.")
+ else()
+ message("Compilation will include nonpipelined threading support.")
+ endif()
+
+else()
+ message("Configuring Panda without threading support.")
+
+endif()
+
+message("")
+message("See dtool_config.h for more details about the specified configuration.")
+
+message("")
+
+# Generate dtool_config.h
+if(IS_MULTICONFIG)
+ foreach(config ${CMAKE_CONFIGURATION_TYPES})
+ foreach(option ${PER_CONFIG_OPTIONS})
+ # Check for the presence of a config-specific option, and override what's
+ # in the cache if there is.
+ if(DEFINED ${option}_${config})
+ set(${option} ${${option}_${config}})
+ endif()
+ endforeach(option)
+
+ # Generate a dtool_config.h for this specific config
+ configure_file(dtool_config.h.in "${PROJECT_BINARY_DIR}/${config}/include/dtool_config.h")
+
+ # unset() does not unset CACHE variables by default, just normal variables.
+ # By doing this we're reverting back to what was in the cache.
+ foreach(option ${PER_CONFIG_OPTIONS})
+ unset(${option})
+ endforeach(option)
+ endforeach(config)
+else()
+ # Just configure things like normal.
+ configure_file(dtool_config.h.in "${PROJECT_BINARY_DIR}/include/dtool_config.h")
+endif()
+
+install(FILES "${PANDA_OUTPUT_DIR}/include/dtool_config.h"
+ COMPONENT CoreDevel
+ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
+
+# Generate the package configuration file
+export_packages("${PROJECT_BINARY_DIR}/Panda3DPackages.cmake")
+install(FILES "${PROJECT_BINARY_DIR}/Panda3DPackages.cmake"
+ COMPONENT CoreDevel
+ DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/Panda3D")
diff --git a/dtool/Package.cmake b/dtool/Package.cmake
new file mode 100644
index 0000000000..fbf014390c
--- /dev/null
+++ b/dtool/Package.cmake
@@ -0,0 +1,765 @@
+set(_thirdparty_dir_default "${PROJECT_SOURCE_DIR}/thirdparty")
+if(NOT (APPLE OR WIN32) OR NOT IS_DIRECTORY "${_thirdparty_dir_default}")
+ set(_thirdparty_dir_default "")
+endif()
+
+set(THIRDPARTY_DIRECTORY "${_thirdparty_dir_default}" CACHE PATH
+ "Optional location of a makepanda-style thirdparty directory. All libraries
+ located here will be prioritized over system libraries. Useful for
+ cross-compiling.")
+
+set(THIRDPARTY_DLLS)
+
+if(THIRDPARTY_DIRECTORY)
+ # This policy is necessary for PackageName_ROOT variables to be respected
+ if(POLICY CMP0074)
+ cmake_policy(GET CMP0074 _policy_cmp0074)
+ endif()
+
+ if(NOT _policy_cmp0074 STREQUAL "NEW")
+ message(FATAL_ERROR
+ "Your version of CMake is too old; please upgrade or unset THIRDPARTY_DIRECTORY to continue.")
+ endif()
+
+ # Dig up the actual "libs" directory
+ if(APPLE)
+ set(_package_dir "${THIRDPARTY_DIRECTORY}/darwin-libs-a")
+
+ # Make sure thirdparty has the first shot, not system frameworks
+ set(CMAKE_FIND_FRAMEWORK LAST)
+
+ elseif(WIN32)
+ if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ set(_package_dir "${THIRDPARTY_DIRECTORY}/win-libs-vc14-x64")
+
+ file(GLOB _python_dirs "${THIRDPARTY_DIRECTORY}/win-python*-x64")
+ else()
+ set(_package_dir "${THIRDPARTY_DIRECTORY}/win-libs-vc14")
+
+ file(GLOB _python_dirs "${THIRDPARTY_DIRECTORY}/win-python*")
+ endif()
+
+ list(REVERSE _python_dirs) # Descending order of version
+ if(NOT DEFINED Python_ROOT)
+ set(Python_ROOT "${_python_dirs}")
+ endif()
+
+ set(BISON_ROOT "${THIRDPARTY_DIRECTORY}/win-util")
+ set(FLEX_ROOT "${THIRDPARTY_DIRECTORY}/win-util")
+
+ else()
+ message(FATAL_ERROR
+ "You can't use THIRDPARTY_DIRECTORY on this platform. Unset it to continue.")
+
+ endif()
+
+ if(NOT EXISTS "${_package_dir}")
+ message(FATAL_ERROR
+ "Either your THIRDPARTY_DIRECTORY path does not exist, or it is for the wrong platform.")
+
+ endif()
+
+ foreach(_Package
+ ARToolKit
+ Assimp
+ Bullet
+ Cg
+ Eigen3
+ FCollada
+ FFMPEG
+ FMODEx
+ Freetype
+ HarfBuzz
+ JPEG
+ LibSquish
+ ODE
+ Ogg
+ OpenAL
+ OpenEXR
+ OpenSSL
+ OpusFile
+ PNG
+ SWResample
+ SWScale
+ TIFF
+ VorbisFile
+ VRPN
+ ZLIB
+ )
+
+ string(TOLOWER "${_Package}" _package)
+ string(TOUPPER "${_Package}" _PACKAGE)
+
+ # Some packages in the thirdparty dir have different subdirectory names from
+ # the name of the CMake package
+ if(_package STREQUAL "cg")
+ set(_package "nvidiacg")
+ elseif(_package STREQUAL "eigen3")
+ set(_package "eigen")
+ elseif(_package STREQUAL "ogg")
+ set(_package "vorbis") # It's in the same install dir here
+ elseif(_package STREQUAL "opusfile")
+ set(_package "opus")
+ elseif(_package STREQUAL "libsquish")
+ set(_package "squish")
+ elseif(_package STREQUAL "swresample" OR _package STREQUAL "swscale")
+ set(_package "ffmpeg") # These are also part of FFmpeg
+ elseif(_package STREQUAL "vorbisfile")
+ set(_package "vorbis")
+ endif()
+
+ # Set search path
+ set(${_Package}_ROOT "${_package_dir}/${_package}")
+
+ # Set up copying DLLs, if necessary
+ file(GLOB _dlls "${${_Package}_ROOT}/bin/*.dll")
+ if(_dlls)
+ set(_havevar "HAVE_${_PACKAGE}")
+ set(THIRDPARTY_DLLS_${_havevar} "${_dlls}")
+ list(APPEND THIRDPARTY_DLLS "${_havevar}")
+
+ endif()
+
+ endforeach(_Package)
+
+endif()
+
+# This is used to copy the DLLs alongside the output of `package`
+function(thirdparty_copy_alongside package)
+ set(_dlls)
+
+ foreach(_havevar ${THIRDPARTY_DLLS})
+ if(${_havevar})
+ list(APPEND _dlls ${THIRDPARTY_DLLS_${_havevar}})
+ endif()
+ endforeach(_havevar)
+
+ if(NOT _dlls)
+ # Don't try to copy/install nothingness
+ return()
+ endif()
+
+ add_custom_command(TARGET ${package} POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ ${_dlls} $
+ )
+
+ # Also install the DLLs
+ install(FILES ${_dlls} DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+endfunction(thirdparty_copy_alongside)
+
+#
+# ------------ Python ------------
+#
+
+set(WANT_PYTHON_VERSION ""
+ CACHE STRING "Which Python version to seek out for building Panda3D against.")
+
+if(DEFINED _PREV_WANT_PYTHON_VERSION
+ AND NOT _PREV_WANT_PYTHON_VERSION STREQUAL WANT_PYTHON_VERSION)
+ # The user changed WANT_PYTHON_VERSION. We need to force FindPython to start
+ # anew, deleting any variable that was autodetected last time
+ foreach(_prev_var ${_PREV_PYTHON_VALUES})
+ string(REPLACE "=" ";" _prev_var "${_prev_var}")
+ list(GET _prev_var 0 _prev_var_name)
+ list(GET _prev_var 1 _prev_var_sha1)
+ string(SHA1 _current_var_sha1 "${${_prev_var_name}}")
+
+ if(_prev_var_sha1 STREQUAL _current_var_sha1)
+ unset(${_prev_var_name} CACHE)
+ endif()
+
+ endforeach(_prev_var)
+
+ unset(_PREV_PYTHON_VALUES CACHE)
+
+endif()
+
+if(WANT_PYTHON_VERSION)
+ # A specific version is requested; ensure we get that specific version
+ list(APPEND WANT_PYTHON_VERSION "EXACT")
+endif()
+
+get_directory_property(_old_cache_vars CACHE_VARIABLES)
+find_package(Python ${WANT_PYTHON_VERSION} QUIET COMPONENTS Interpreter Development)
+
+if(Python_FOUND)
+ set(PYTHON_FOUND ON)
+ set(PYTHON_EXECUTABLE ${Python_EXECUTABLE})
+ set(PYTHON_INCLUDE_DIRS ${Python_INCLUDE_DIRS})
+ set(PYTHON_LIBRARY_DIRS ${Python_LIBRARY_DIRS})
+ set(PYTHON_VERSION_STRING ${Python_VERSION})
+
+elseif(CMAKE_VERSION VERSION_LESS "3.12")
+ find_package(PythonInterp ${WANT_PYTHON_VERSION} QUIET)
+ find_package(PythonLibs ${PYTHON_VERSION_STRING} QUIET)
+
+ if(PYTHONLIBS_FOUND)
+ set(PYTHON_FOUND ON)
+
+ if(NOT PYTHON_VERSION_STRING)
+ set(PYTHON_VERSION_STRING ${PYTHONLIBS_VERSION_STRING})
+ endif()
+ endif()
+
+endif()
+
+if(CMAKE_VERSION VERSION_LESS "3.15")
+ # CMake versions this old don't provide Python::Module, so we need to hack up
+ # the variables to ensure no explicit linkage against libpython occurs
+
+ if(WIN32)
+ # Nothing needed here; explicit linkage is appropriate
+ set(PYTHON_LIBRARY "${Python_LIBRARY}")
+ set(PYTHON_LIBRARIES ${Python_LIBRARIES})
+
+ elseif(APPLE OR UNIX)
+ # Just unset and let the implicit linkage take over
+ set(PYTHON_LIBRARY "")
+ set(PYTHON_LIBRARIES "")
+
+ if(APPLE)
+ # macOS requires this explicit flag on the linker command line to allow the
+ # references to the Python symbols to resolve at dynamic link time
+ string(APPEND CMAKE_MODULE_LINKER_FLAGS " -undefined dynamic_lookup")
+
+ endif()
+
+ else()
+ # On every other platform, guessing is a bad idea - insist the user upgrade
+ # their CMake instead.
+ message(WARNING "For Python support on this platform, please use CMake >= 3.15!")
+ set(PYTHON_FOUND OFF)
+
+ endif()
+
+endif()
+
+package_option(Python
+ DEFAULT ON
+ "Enables support for Python. If INTERROGATE_PYTHON_INTERFACE
+is also enabled, Python bindings will be generated."
+ IMPORTED_AS Python::Module)
+
+# Also detect the optimal install paths:
+if(HAVE_PYTHON)
+ if(WIN32 AND NOT CYGWIN)
+ set(_LIB_DIR ".")
+ set(_ARCH_DIR ".")
+
+ elseif(PYTHON_EXECUTABLE)
+ execute_process(
+ COMMAND ${PYTHON_EXECUTABLE}
+ -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(False))"
+ OUTPUT_VARIABLE _LIB_DIR
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+ execute_process(
+ COMMAND ${PYTHON_EXECUTABLE}
+ -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(True))"
+ OUTPUT_VARIABLE _ARCH_DIR
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ else()
+ set(_LIB_DIR "")
+ set(_ARCH_DIR "")
+
+ endif()
+
+ execute_process(
+ COMMAND ${PYTHON_EXECUTABLE}
+ -c "from sysconfig import get_config_var as g; print((g('EXT_SUFFIX') or g('SO'))[:])"
+ OUTPUT_VARIABLE _EXT_SUFFIX
+ ERROR_QUIET
+ OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+ if(NOT _EXT_SUFFIX)
+ if(CYGWIN)
+ set(_EXT_SUFFIX ".dll")
+ elseif(WIN32)
+ set(_EXT_SUFFIX ".pyd")
+ else()
+ set(_EXT_SUFFIX ".so")
+ endif()
+ endif()
+
+ set(PYTHON_LIB_INSTALL_DIR "${_LIB_DIR}" CACHE STRING
+ "Path to the Python architecture-independent package directory.")
+
+ set(PYTHON_ARCH_INSTALL_DIR "${_ARCH_DIR}" CACHE STRING
+ "Path to the Python architecture-dependent package directory.")
+
+ set(PYTHON_EXTENSION_SUFFIX "${_EXT_SUFFIX}" CACHE STRING
+ "Suffix for Python binary extension modules.")
+
+endif()
+
+if(NOT DEFINED _PREV_PYTHON_VALUES)
+ # We need to make note of all auto-defined Python variables
+ set(_prev_python_values)
+
+ get_directory_property(_new_cache_vars CACHE_VARIABLES)
+ foreach(_cache_var ${_new_cache_vars})
+ if(_cache_var MATCHES "^(Python|PYTHON)_" AND NOT _old_cache_vars MATCHES ";${_cache_var};")
+ string(SHA1 _cache_var_sha1 "${${_cache_var}}")
+ list(APPEND _prev_python_values "${_cache_var}=${_cache_var_sha1}")
+ endif()
+ endforeach(_cache_var)
+
+ set(_PREV_PYTHON_VALUES "${_prev_python_values}" CACHE INTERNAL "Internal." FORCE)
+endif()
+
+set(_PREV_WANT_PYTHON_VERSION "${WANT_PYTHON_VERSION}" CACHE INTERNAL "Internal." FORCE)
+
+
+#
+# ------------ Data handling libraries ------------
+#
+
+# OpenSSL
+find_package(OpenSSL COMPONENTS SSL Crypto QUIET)
+
+package_option(OpenSSL
+ DEFAULT ON
+ "Enable OpenSSL support"
+ IMPORTED_AS OpenSSL::SSL OpenSSL::Crypto)
+
+option(REPORT_OPENSSL_ERRORS
+ "Define this true to include the OpenSSL code to report verbose
+error messages when they occur." OFF)
+option(REPORT_OPENSSL_ERRORS_Debug "" ON)
+
+package_status(OpenSSL "OpenSSL")
+
+# zlib
+find_package(ZLIB QUIET)
+
+package_option(ZLIB
+ "Enables support for compression of Panda assets."
+ IMPORTED_AS ZLIB::ZLIB)
+
+package_status(ZLIB "zlib")
+
+
+#
+# ------------ Image formats ------------
+#
+
+# JPEG
+find_package(JPEG QUIET)
+
+package_option(JPEG "Enable support for loading .jpg images.")
+
+package_status(JPEG "libjpeg")
+
+# PNG
+find_package(PNG QUIET)
+
+package_option(PNG
+ "Enable support for loading .png images."
+ IMPORTED_AS PNG::PNG)
+
+package_status(PNG "libpng")
+
+# TIFF
+find_package(TIFF QUIET)
+
+package_option(TIFF "Enable support for loading .tif images.")
+
+package_status(TIFF "libtiff")
+
+# OpenEXR
+find_package(OpenEXR QUIET)
+
+package_option(OpenEXR "Enable support for loading .exr images.")
+
+package_status(OpenEXR "OpenEXR")
+
+# libsquish
+find_package(LibSquish QUIET)
+
+package_option(SQUISH
+ "Enables support for automatic compression of DXT textures."
+ FOUND_AS LibSquish)
+
+package_status(SQUISH "libsquish")
+
+
+#
+# ------------ Asset formats ------------
+#
+
+# Assimp
+find_package(Assimp QUIET)
+
+package_option(Assimp
+ "Build pandatool with support for loading 3D assets supported by Assimp.")
+
+package_status(Assimp "Assimp")
+
+# FCollada
+find_package(FCollada QUIET)
+
+package_option(FCollada
+ "Build pandatool with support for loading Collada files using FCollada."
+ IMPORTED_AS FCollada::FCollada)
+
+package_status(FCollada "FCollada")
+
+
+#
+# ------------ Math libraries ------------
+#
+
+# Eigen
+find_package(Eigen3 QUIET)
+
+package_option(EIGEN
+ "Enables use of the Eigen linear algebra library.
+If this is provided, Panda will use this library as the fundamental
+implementation of its own linmath library; otherwise, it will use
+its own internal implementation. The primary advantage of using
+Eigen is SSE2 support, which is only activated if LINMATH_ALIGN
+is also enabled."
+ FOUND_AS Eigen3
+ LICENSE "MPL-2")
+
+option(LINMATH_ALIGN
+ "This is required for activating SSE2 support using Eigen.
+Activating this does constrain most objects in Panda to 16-byte
+alignment, which could impact memory usage on very-low-memory
+platforms. Currently experimental." ON)
+
+if(LINMATH_ALIGN)
+ package_status(EIGEN "Eigen linear algebra library" "vectorization enabled in build")
+else()
+ package_status(EIGEN "Eigen linear algebra library" "vectorization NOT enabled in build")
+endif()
+
+# FFTW
+# FFTW 3.3.7, when built with autotools, doesn't install
+# FFTW3LibraryDepends.cmake, which will crash us if we use CONFIG mode. BAH!
+# Force MODULE mode to fix that.
+find_package(FFTW3 MODULE QUIET)
+
+package_option(FFTW
+ "This enables support for compression of animations in .bam files.
+ This is only necessary for creating or reading .bam files containing
+ compressed animations."
+ FOUND_AS "FFTW3"
+ LICENSE "GPL")
+
+package_status(FFTW "FFTW")
+
+
+#
+# ------------ Multimedia formats ------------
+#
+
+# FFmpeg
+find_package(FFMPEG QUIET)
+find_package(SWScale QUIET)
+find_package(SWResample QUIET)
+
+package_option(FFMPEG
+ "Enables support for audio- and video-decoding using the FFmpeg library.")
+package_option(SWScale
+ "Enables support for FFmpeg's libswscale for video rescaling.")
+package_option(SWResample
+ "Enables support for FFmpeg's libresample for audio resampling.")
+
+if(HAVE_SWSCALE AND HAVE_SWRESAMPLE)
+ set(ffmpeg_features "with swscale and swresample")
+elseif(HAVE_SWSCALE)
+ set(ffmpeg_features "with swscale")
+elseif(HAVE_SWRESAMPLE)
+ set(ffmpeg_features "with swresample")
+else()
+ set(ffmpeg_features "without resampling/rescaling support")
+endif()
+package_status(FFMPEG "FFmpeg" "${ffmpeg_features}")
+
+# Vorbis
+find_package(VorbisFile QUIET)
+
+package_option(VORBIS
+ FOUND_AS VorbisFile
+ "Enables support for decoding Vorbis-encoded .ogg audio files via libvorbisfile.")
+
+package_status(VORBIS "Vorbis")
+
+# Opus
+find_package(OpusFile QUIET)
+
+package_option(OPUS
+ FOUND_AS OpusFile
+ "Enables support for decoding .opus audio files via libopusfile.")
+
+package_status(OPUS "Opus")
+
+#
+# ------------ Audio libraries ------------
+#
+
+# FMOD Ex
+find_package(FMODEx QUIET)
+
+package_option(FMODEx
+ "This enables support for the FMOD Ex sound library,
+ from Firelight Technologies. This audio library is free for non-commercial
+ use."
+ LICENSE "FMOD")
+
+package_status(FMODEx "FMOD Ex sound library")
+
+# OpenAL
+find_package(OpenAL QUIET)
+
+package_option(OpenAL
+ "This enables support for audio output via OpenAL. Some platforms, such as
+ macOS, provide their own OpenAL implementation, which Panda3D can use. But,
+ on most platforms this will imply OpenAL Soft, which is LGPL licensed."
+ IMPORTED_AS OpenAL::OpenAL
+ LICENSE "LGPL")
+
+package_status(OpenAL "OpenAL sound library")
+
+if(OpenAL_FOUND AND APPLE OR OPENAL_FOUND AND APPLE)
+ set(HAVE_OPENAL_FRAMEWORK YES)
+endif()
+
+
+#
+# ------------ UI libraries ------------
+#
+
+# Freetype
+
+find_package(Freetype QUIET)
+
+package_option(Freetype
+ "This enables support for the FreeType font-rendering library. If disabled,
+ Panda3D will only be able to read fonts specially made with egg-mkfont."
+ IMPORTED_AS freetype)
+
+package_status(Freetype "FreeType")
+
+# HarfBuzz
+
+# Some versions of harfbuzz-config.cmake contain an endless while loop, so we
+# force MODULE mode here.
+find_package(HarfBuzz MODULE QUIET)
+
+package_option(HarfBuzz
+ "This enables support for the HarfBuzz text shaping library."
+ IMPORTED_AS harfbuzz::harfbuzz)
+
+package_status(HarfBuzz "HarfBuzz")
+
+# GTK2
+
+set(Freetype_FIND_QUIETLY TRUE) # Fix for builtin FindGTK2
+set(GTK2_GTK_FIND_QUIETLY TRUE) # Fix for builtin FindGTK2
+find_package(GTK2 QUIET COMPONENTS gtk)
+
+package_option(GTK2)
+
+package_status(GTK2 "gtk+-2")
+
+
+#
+# ------------ Physics engines ------------
+#
+
+# Bullet
+find_package(Bullet MODULE QUIET)
+
+package_option(Bullet
+ "Enable this option to support game dynamics with the Bullet physics library.")
+
+package_status(Bullet "Bullet physics")
+
+# ODE
+find_package(ODE QUIET)
+
+package_option(ODE
+ "Enable this option to support game dynamics with the Open Dynamics Engine (ODE)."
+ LICENSE "BSD-3"
+ IMPORTED_AS ODE::ODE)
+
+package_status(ODE "Open Dynamics Engine")
+
+
+#
+# ------------ SpeedTree ------------
+#
+
+# SpeedTree
+find_package(SpeedTree QUIET)
+
+package_option(SpeedTree
+ "Enable this option to include scenegraph support for SpeedTree trees."
+ LICENSE "SpeedTree")
+
+package_status(SpeedTree "SpeedTree")
+
+
+#
+# ------------ Rendering APIs ------------
+#
+
+# OpenGL
+find_package(OpenGL QUIET)
+
+package_option(GL
+ "Enable OpenGL support."
+ FOUND_AS OPENGL
+ IMPORTED_AS OpenGL::GL)
+
+package_status(GL "OpenGL")
+
+# OpenGL ES 1
+if(NOT APPLE) # Apple X11 ships the GLES headers but they're broken
+ find_package(OpenGLES1 QUIET)
+endif()
+
+package_option(GLES1
+ "Enable support for OpenGL ES 1.x rendering APIs."
+ FOUND_AS OPENGLES1)
+
+package_status(GLES1 "OpenGL ES 1.x")
+
+# OpenGL ES 2
+if(NOT APPLE) # Apple X11 ships the GLES headers but they're broken
+ find_package(OpenGLES2 QUIET)
+endif()
+
+package_option(GLES2
+ "Enable support for OpenGL ES 2.x rendering APIs."
+ FOUND_AS OPENGLES2)
+
+package_status(GLES2 "OpenGL ES 2.x")
+
+# Direct3D 9
+find_package(Direct3D9 QUIET COMPONENTS dxguid dxerr d3dx9)
+
+package_option(DX9
+ "Enable support for DirectX 9. This is typically only viable on Windows."
+ FOUND_AS Direct3D9)
+
+package_status(DX9 "Direct3D 9.x")
+
+# Nvidia Cg
+find_package(Cg QUIET)
+
+package_option(CG
+ "Enable support for Nvidia Cg Shading Language"
+ LICENSE "Nvidia")
+package_option(CGGL
+ "Enable support for Nvidia Cg's OpenGL API."
+ LICENSE "Nvidia")
+package_option(CGD3D9
+ "Enable support for Nvidia Cg's Direct3D 9 API."
+ LICENSE "Nvidia")
+
+if(HAVE_CGGL AND HAVE_CGD3D9)
+ set(cg_apis "supporting OpenGL and Direct3D 9")
+elseif(HAVE_CGGL)
+ set(cg_apis "supporting OpenGL")
+elseif(HAVE_CGDX9)
+ set(cg_apis "supporting Direct3D 9")
+else()
+ set(cg_apis "WITHOUT rendering backend support")
+endif()
+package_status(CG "Nvidia Cg Shading Language" "${cg_apis}")
+
+
+#
+# ------------ Display APIs ------------
+#
+
+# X11 (and GLX)
+
+if(NOT APPLE)
+ find_package(X11 QUIET)
+endif()
+
+if(NOT X11_Xkb_FOUND OR NOT X11_Xutil_FOUND)
+ # Panda implicitly requires these supplementary X11 libs; if we can't find
+ # them, we just say we didn't find X11 at all.
+ set(X11_FOUND OFF)
+endif()
+
+package_option(X11
+ "Provides X-server support on Unix platforms. X11 may need to be linked
+against for tinydisplay, but probably only on a Linux platform.")
+
+set(HAVE_GLX_AVAILABLE OFF)
+if(HAVE_GL AND HAVE_X11 AND NOT APPLE)
+ set(HAVE_GLX_AVAILABLE ON)
+endif()
+
+option(HAVE_GLX "Enables GLX. Requires OpenGL and X11." ${HAVE_GLX_AVAILABLE})
+if(HAVE_GLX AND NOT HAVE_GLX_AVAILABLE)
+ message(SEND_ERROR "HAVE_GLX manually set to ON but it is not available!")
+endif()
+
+if(HAVE_GLX)
+ package_status(X11 "X11" "with GLX")
+else()
+ package_status(X11 "X11" "without GLX")
+endif()
+
+# EGL
+find_package(EGL QUIET)
+
+package_option(EGL
+ "Enable support for the Khronos EGL context management interface for
+ OpenGL ES. This is necessary to support OpenGL ES under X11.")
+
+package_status(EGL "EGL")
+
+#
+# ------------ Vision tools ------------
+#
+
+# OpenCV
+find_package(OpenCV QUIET COMPONENTS core highgui OPTIONAL_COMPONENTS videoio)
+
+package_option(OpenCV
+ "Enable support for OpenCV. This will be built into the 'vision' package."
+ FOUND_AS OpenCV)
+
+package_status(OpenCV "OpenCV")
+
+# CMake <3.7 doesn't support GREATER_EQUAL, so this uses NOT LESS instead.
+if(NOT OpenCV_VERSION_MAJOR LESS 3)
+ set(OPENCV_VER_3 ON)
+
+elseif(NOT OpenCV_VERSION_MAJOR LESS 2 AND
+ NOT OpenCV_VERSION_MINOR LESS 3)
+ set(OPENCV_VER_23 ON)
+
+endif()
+
+# ARToolKit
+find_package(ARToolKit QUIET)
+
+package_option(ARToolKit
+ "Enable support for ARToolKit. This will be built into the 'vision' package.")
+
+package_status(ARToolKit "ARToolKit")
+
+
+#
+# ------------ VR integration ------------
+#
+
+# VRPN
+find_package(VRPN QUIET)
+
+package_option(VRPN
+ "Enables support for connecting to VRPN servers. This is only needed if you
+ are building Panda3D for a fixed VRPN-based VR installation.")
+
+package_status(VRPN "VRPN")
diff --git a/dtool/PandaVersion.cmake b/dtool/PandaVersion.cmake
new file mode 100644
index 0000000000..2ca0a3e6e5
--- /dev/null
+++ b/dtool/PandaVersion.cmake
@@ -0,0 +1,103 @@
+# This file defines the current version number for Panda. It is read
+# by the top CMakeLists.txt, which puts it in the global namespace for
+# all CMake scripts for Panda.
+
+option(PANDA_OFFICIAL_VERSION
+ "This variable will be defined to false in the CVS repository, but
+scripts that generate source tarballs and/or binary releases for
+distribution, by checking out Panda from an official CVS tag,
+should explictly set this to true. When false, it indicates that
+the current version of Panda was checked out from CVS, so it may
+not be a complete representation of the indicated version."
+ OFF)
+
+set(PANDA_DISTRIBUTOR homebuilt CACHE STRING
+ "This string is reported verbatim by PandaSystem::get_distributor().
+It should be set by whoever provides a particular distribution of
+Panda. If you build your own Panda, leave this unchanged.")
+
+set(PANDA_DIST_USE_LICENSES "BSD-3;BSD-2;MIT" CACHE STRING
+ "This is a list of allowed licenses for 3rd-party packages to build
+support for when performing a Distribution build of Panda3d.
+Note: This only is checked for packages that CMake has declared with a
+particular license. Some packages don't have a listed license because
+they are almost always required/used, or because they are only used in
+plugins that can be easily removed (eg. directx, ffmpeg, fmod, ...).")
+
+set(PANDA_PACKAGE_VERSION CACHE STRING
+ "This string is used to describe the Panda3D \"package\" associated
+with this current build of Panda. It should increment with major
+and minor version changes, but not sequence (or \"bugfix\") changes.
+It should be unique for each unique distributor. The default is
+the empty string, which means this build does not precisely match
+any distributable Panda3D packages. If you are making a Panda3D
+build which you will be using to produce a distributable Panda3D
+package, you should set this string appropriately.")
+
+set(P3D_PLUGIN_VERSION "1.0.4" CACHE STRING
+ "We also define a version for the Panda3D plugin/runtime,
+i.e. nppanda3d.dll, p3dactivex.ocx, and panda3d.exe. This is an
+independent version number from PANDA_VERSION or
+PANDA_PACKAGE_VERSION, because it is anticipated that this plugin
+code, once settled, will need to be updated much less frequently
+than Panda itself.")
+
+set(P3D_COREAPI_VERSION "${P3D_PLUGIN_VERSION}.1" CACHE STRING
+ "Finally, there's a separate version number for the Core API. At
+first, we didn't believe we needed a Core API version number, but
+in this belief we were naive. This version number is a little less
+strict in its format requirements than P3D_PLUGIN_VERSION, above,
+and it doesn't necessarily consist of a specific number of
+integers, but by convention it will consist of four integers, with
+the first three matching the plugin version, and the fourth integer
+being incremented with each new Core API revision.")
+
+mark_as_advanced(PANDA_VERSION PANDA_OFFICIAL_VERSION
+ PANDA_PACKAGE_VERSION P3D_PLUGIN_VERSION P3D_COREAPI_VERSION
+ PANDA_DIST_USE_LICENSES)
+
+# The version gets a "c" at the end if it's not an official one.
+if(PANDA_OFFICIAL_VERSION)
+ set(VERSION_SUFFIX "")
+else()
+ set(VERSION_SUFFIX "c")
+endif()
+
+set(PANDA_VERSION_STR "${PROJECT_VERSION}${VERSION_SUFFIX}")
+
+# This symbol is used to enforce ABI incompatibility between
+# major versions of Panda3D.
+set(PANDA_VERSION_SYMBOL panda_version_${PROJECT_VERSION_MAJOR}_${PROJECT_VERSION_MINOR})
+
+# The Panda version as a number, with three digits reserved
+# for each component.
+math(EXPR PANDA_NUMERIC_VERSION "${PROJECT_VERSION_MAJOR}*1000000 + ${PROJECT_VERSION_MINOR}*1000 + ${PROJECT_VERSION_PATCH}")
+
+# The Panda Git SHA1 refspec, for PandaSystem::get_git_commit()
+find_package(Git QUIET)
+if(GIT_EXECUTABLE)
+ execute_process(
+ COMMAND "${GIT_EXECUTABLE}" rev-parse HEAD
+ WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
+ OUTPUT_VARIABLE PANDA_GIT_COMMIT_STR
+ ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)
+endif()
+
+# Separate the plugin version into its three components.
+string(REPLACE "." ";" P3D_PLUGIN_VERSION_LIST "${P3D_PLUGIN_VERSION}")
+list(GET P3D_PLUGIN_VERSION_LIST 0 P3D_PLUGIN_MAJOR_VERSION)
+list(GET P3D_PLUGIN_VERSION_LIST 1 P3D_PLUGIN_MINOR_VERSION)
+list(GET P3D_PLUGIN_VERSION_LIST 2 P3D_PLUGIN_SEQUENCE_VERSION)
+
+set(P3D_PLUGIN_VERSION_STR "${P3D_PLUGIN_VERSION}${VERSION_SUFFIX}")
+
+# The plugin version as dot-delimited integer quad, according to MS
+# conventions for DLL version numbers.
+if(PANDA_OFFICIAL_VERSION)
+ set(P3D_PLUGIN_DLL_DOT_VERSION "${P3D_PLUGIN_VERSION}.1000")
+else()
+ set(P3D_PLUGIN_DLL_DOT_VERSION "${P3D_PLUGIN_VERSION}.0")
+endif()
+
+# The same thing as a comma-delimited quad.
+string(REPLACE "." "," P3D_PLUGIN_DLL_COMMA_VERSION "${P3D_PLUGIN_DLL_DOT_VERSION}")
diff --git a/dtool/dtool_config.h.in b/dtool/dtool_config.h.in
new file mode 100644
index 0000000000..159488ab9d
--- /dev/null
+++ b/dtool/dtool_config.h.in
@@ -0,0 +1,251 @@
+/* dtool_config.h. Generated automatically by CMake. */
+#ifndef DTOOL_CONFIG_H
+#define DTOOL_CONFIG_H
+
+/* Define if we have Eigen available. */
+#cmakedefine HAVE_EIGEN
+#cmakedefine LINMATH_ALIGN
+
+/* Define if we have Python installed. */
+#cmakedefine HAVE_PYTHON
+#cmakedefine USE_DEBUG_PYTHON
+/* Define if we have Python as a framework (Mac OS X). */
+#cmakedefine PYTHON_FRAMEWORK
+
+/* Define if we have OpenAL installed as a framework. */
+#cmakedefine HAVE_OPENAL_FRAMEWORK
+
+/* Define if we have Freetype 2.0 or better available. */
+#cmakedefine HAVE_FREETYPE
+
+/* Define if we want to compile in a default font. */
+#cmakedefine COMPILE_IN_DEFAULT_FONT
+
+/* Define to use doubles for most numbers, intead of single-precision floats. */
+#cmakedefine STDFLOAT_DOUBLE
+
+/* Define if we have built libRocket available and built with Python support. */
+#cmakedefine HAVE_ROCKET_PYTHON
+
+/* Define if we have ARToolKit available. */
+#cmakedefine HAVE_ARTOOLKIT
+
+/* Define if we have libvorbisfile available. */
+#cmakedefine HAVE_VORBIS
+
+/* Define if we have libopus available. */
+#cmakedefine HAVE_OPUS
+
+/* Define if we have OpenSSL installed. */
+#cmakedefine HAVE_OPENSSL
+
+/* Define if we have libjpeg installed. */
+#cmakedefine HAVE_JPEG
+
+/* Define to build video-for-linux. */
+#cmakedefine HAVE_VIDEO4LINUX
+
+/* Define if we have libpng installed. */
+#cmakedefine HAVE_PNG
+
+/* Define if we have libtiff installed. */
+#cmakedefine HAVE_TIFF
+
+/* Define if we have OpenEXR installed. */
+#cmakedefine HAVE_OPENEXR
+
+/* Define if we want to build these other image file formats. */
+#cmakedefine HAVE_SGI_RGB
+#cmakedefine HAVE_TGA
+#cmakedefine HAVE_IMG
+#cmakedefine HAVE_SOFTIMAGE_PIC
+#cmakedefine HAVE_BMP
+#cmakedefine HAVE_PNM
+
+/* Define if we have CG installed. */
+#cmakedefine HAVE_CG
+
+/* Define if we have zlib installed. */
+#cmakedefine HAVE_ZLIB
+
+/* Define if we have OpenGL installed and want to build for GL. */
+#cmakedefine MIN_GL_VERSION_MAJOR
+#cmakedefine MIN_GL_VERSION_MINOR
+
+/* Define if we have OpenCV installed and want to build for OpenCV. */
+#cmakedefine HAVE_OPENCV
+
+/* The choice of generic vs. the specific dxerr library largely
+ depends on which SDK you have installed. */
+#cmakedefine USE_GENERIC_DXERR_LIBRARY
+
+/* Define if we have the SDL library. */
+#cmakedefine HAVE_SDL
+
+/* Define if we have X11. */
+#cmakedefine HAVE_X11
+
+/* Define if we want to compile the threading code. */
+#cmakedefine HAVE_THREADS
+
+/* Define if we want to use fast, user-space simulated threads. */
+#cmakedefine SIMPLE_THREADS
+
+/* Define to enable deadlock detection, mutex recursion checks, etc. */
+#cmakedefine DEBUG_THREADS
+
+/* Define to implement mutexes and condition variables via a user-space spinlock. */
+#cmakedefine MUTEX_SPINLOCK
+
+/* Define to enable the PandaFileStream implementation of pfstream etc. */
+#cmakedefine USE_PANDAFILESTREAM
+
+/* Define if we want to compile the net code. */
+#cmakedefine HAVE_NET
+
+/* Define if we want to compile the audio code. */
+#cmakedefine HAVE_AUDIO
+
+/* Define if we want to use PStats. */
+#cmakedefine DO_PSTATS
+
+/* Define if we want to type-check downcasts. */
+#cmakedefine DO_DCAST
+
+/* Define if we want to provide collision system recording and
+ visualization tools. */
+#cmakedefine DO_COLLISION_RECORDING
+
+/* Define if we want to enable track-memory-usage. */
+#cmakedefine DO_MEMORY_USAGE
+
+/* Define if we want to enable min-lag and max-lag. */
+#cmakedefine SIMULATE_NETWORK_DELAY
+
+/* Define if we want to allow immediate mode OpenGL rendering. */
+#cmakedefine SUPPORT_IMMEDIATE_MODE
+
+/* Define if we want to support fixed-function OpenGL rendering. */
+#cmakedefine SUPPORT_FIXED_FUNCTION
+
+/* Define for either of the alternative malloc schemes. */
+#cmakedefine USE_MEMORY_DLMALLOC
+#cmakedefine USE_MEMORY_PTMALLOC2
+
+/* Define if we want to compile in support for pipelining. */
+#cmakedefine DO_PIPELINING
+
+/* Define if we want to keep Notify debug messages around, or undefine
+ to compile them out. */
+#cmakedefine NOTIFY_DEBUG
+
+/* The compiled-in character(s) to expect to separate different
+ components of a path list (e.g. $PRC_PATH). */
+#define DEFAULT_PATHSEP "@DEFAULT_PATHSEP@"
+
+/* Many of the prc variables are exported by
+ dtool/src/prc/prc_parameters.h.pp, instead of here. Only those prc
+ variables that must be visible outside of the prc directory are
+ exported here. */
+
+/* Define if you want to save the descriptions for ConfigVariables. */
+#cmakedefine PRC_SAVE_DESCRIPTIONS
+
+
+/* Define if your processor stores words with the most significant
+ byte first (like Motorola and SPARC, unlike Intel and VAX). */
+#cmakedefine WORDS_BIGENDIAN
+
+/* Define if we can trust the compiler not to insert extra bytes in
+ structs between base structs and derived structs. */
+#cmakedefine SIMPLE_STRUCT_POINTERS
+
+/* Define if we have Dinkumware STL installed. */
+#cmakedefine HAVE_DINKUM
+
+/* Define if we have STL hash_map etc. available */
+#cmakedefine HAVE_STL_HASH
+
+/* Define if you have the getopt function. */
+#cmakedefine HAVE_GETOPT
+
+/* Define if you have the getopt_long_only function. */
+#cmakedefine HAVE_GETOPT_LONG_ONLY
+
+/* Define if getopt appears in getopt.h. */
+#cmakedefine PHAVE_GETOPT_H
+
+/* Do the system headers define key ios typedefs like ios::openmode
+ and ios::fmtflags? */
+#cmakedefine HAVE_IOS_TYPEDEFS
+
+/* Define if you have the header file. */
+#cmakedefine PHAVE_IO_H
+
+/* Define if you have the header file. */
+#cmakedefine PHAVE_IOSTREAM
+
+/* Define if you have the header file. */
+#cmakedefine PHAVE_MALLOC_H
+
+/* Define if you have the header file. */
+#cmakedefine PHAVE_SYS_MALLOC_H
+
+/* Define if you have the header file. */
+#cmakedefine PHAVE_ALLOCA_H
+
+/* Define if you have the header file. */
+#cmakedefine PHAVE_LOCALE_H
+
+/* Define if you have the header file. */
+#cmakedefine PHAVE_STRING_H
+
+/* Define if you have the header file. */
+#cmakedefine PHAVE_STDLIB_H
+
+/* Define if you have the header file. */
+#cmakedefine PHAVE_LIMITS_H
+
+/* Define if you have the header file. */
+#cmakedefine PHAVE_SSTREAM
+
+/* Define if you have the header file. */
+#cmakedefine PHAVE_NEW
+
+/* Define if you have the header file. */
+#cmakedefine PHAVE_SYS_TYPES_H
+
+/* Define if you have the header file. */
+#cmakedefine PHAVE_SYS_TIME_H
+
+/* Define if you have the header file. */
+#cmakedefine PHAVE_UNISTD_H
+
+/* Do we have ? This enables us to use raw mouse input. */
+#cmakedefine PHAVE_LINUX_INPUT_H
+
+/* Do we have ? */
+#cmakedefine PHAVE_STDINT_H
+
+/* Do we have Posix threads? */
+#cmakedefine HAVE_POSIX_THREADS
+
+/* Is the code being compiled with the Tau profiler's instrumentor? */
+#cmakedefine USE_TAU
+
+// To activate the DELETED_CHAIN macros.
+#cmakedefine USE_DELETED_CHAIN
+
+// If we are to build the native net interfaces.
+#cmakedefine WANT_NATIVE_NET
+
+/* Static linkage instead of the normal dynamic linkage? */
+#cmakedefine LINK_ALL_STATIC
+
+/* Platform-identifying defines. */
+#cmakedefine IS_OSX
+#cmakedefine IS_LINUX
+#cmakedefine IS_FREEBSD
+#cmakedefine BUILD_IPHONE
+
+#endif
diff --git a/dtool/metalibs/dtool/CMakeLists.txt b/dtool/metalibs/dtool/CMakeLists.txt
new file mode 100644
index 0000000000..812c457b72
--- /dev/null
+++ b/dtool/metalibs/dtool/CMakeLists.txt
@@ -0,0 +1,13 @@
+set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME "CoreDevel")
+add_metalib(p3dtool INIT init_libdtool dtool.h COMPONENTS p3dtoolutil p3dtoolbase)
+unset(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME)
+
+install(TARGETS p3dtool
+ EXPORT Core COMPONENT Core
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT CoreDevel)
+
+# Also handle thirdparty DLLs
+thirdparty_copy_alongside(p3dtool)
diff --git a/dtool/src/cppparser/CMakeLists.txt b/dtool/src/cppparser/CMakeLists.txt
new file mode 100644
index 0000000000..4408a52198
--- /dev/null
+++ b/dtool/src/cppparser/CMakeLists.txt
@@ -0,0 +1,44 @@
+set(P3CPPPARSER_HEADERS
+ cppArrayType.h cppBison.yxx cppBisonDefs.h
+ cppClassTemplateParameter.h cppCommentBlock.h
+ cppClosureType.h cppConstType.h
+ cppDeclaration.h cppEnumType.h cppExpression.h
+ cppExpressionParser.h cppExtensionType.h cppFile.h
+ cppFunctionGroup.h cppFunctionType.h cppGlobals.h
+ cppIdentifier.h cppInstance.h cppInstanceIdentifier.h
+ cppMakeProperty.h cppMakeSeq.h cppManifest.h
+ cppNameComponent.h cppNamespace.h
+ cppParameterList.h cppParser.h cppPointerType.h
+ cppPreprocessor.h cppReferenceType.h cppScope.h
+ cppSimpleType.h cppStructType.h cppTBDType.h
+ cppTemplateParameterList.h cppTemplateScope.h cppToken.h
+ cppType.h cppTypeDeclaration.h cppTypeParser.h
+ cppTypeProxy.h cppTypedefType.h cppUsing.h cppVisibility.h
+)
+
+set(P3CPPPARSER_SOURCES
+ cppArrayType.cxx ${CMAKE_CURRENT_BINARY_DIR}/cppBison.cxx
+ cppClassTemplateParameter.cxx
+ cppCommentBlock.cxx cppClosureType.cxx cppConstType.cxx cppDeclaration.cxx
+ cppEnumType.cxx cppExpression.cxx cppExpressionParser.cxx
+ cppExtensionType.cxx cppFile.cxx cppFunctionGroup.cxx
+ cppFunctionType.cxx cppGlobals.cxx cppIdentifier.cxx
+ cppInstance.cxx cppInstanceIdentifier.cxx
+ cppMakeProperty.cxx cppMakeSeq.cxx cppManifest.cxx
+ cppNameComponent.cxx cppNamespace.cxx cppParameterList.cxx
+ cppParser.cxx cppPointerType.cxx cppPreprocessor.cxx
+ cppReferenceType.cxx cppScope.cxx cppSimpleType.cxx
+ cppStructType.cxx cppTBDType.cxx
+ cppTemplateParameterList.cxx cppTemplateScope.cxx
+ cppToken.cxx cppType.cxx cppTypeDeclaration.cxx
+ cppTypeParser.cxx cppTypeProxy.cxx cppTypedefType.cxx
+ cppUsing.cxx cppVisibility.cxx
+)
+
+add_bison_target(cppBison.cxx cppBison.yxx DEFINES cppBison.h PREFIX cppyy)
+
+composite_sources(p3cppParser P3CPPPARSER_SOURCES)
+add_library(p3cppParser STATIC ${P3CPPPARSER_HEADERS} ${P3CPPPARSER_SOURCES})
+target_link_libraries(p3cppParser p3dtool)
+
+install(TARGETS p3cppParser EXPORT Core COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_LIBDIR})
diff --git a/dtool/src/dconfig/CMakeLists.txt b/dtool/src/dconfig/CMakeLists.txt
new file mode 100644
index 0000000000..ccd9e6c144
--- /dev/null
+++ b/dtool/src/dconfig/CMakeLists.txt
@@ -0,0 +1,6 @@
+# Yes, INTERFACE: don't build it, there's no code!
+# We're only doing this to put the .h file on the path.
+add_library(p3dconfig INTERFACE)
+
+install(FILES dconfig.h COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
+install(TARGETS p3dconfig EXPORT Core COMPONENT Core)
diff --git a/dtool/src/dtoolbase/CMakeLists.txt b/dtool/src/dtoolbase/CMakeLists.txt
new file mode 100644
index 0000000000..aea0a1196f
--- /dev/null
+++ b/dtool/src/dtoolbase/CMakeLists.txt
@@ -0,0 +1,106 @@
+configure_file(pandaVersion.h.in pandaVersion.h)
+configure_file(checkPandaVersion.h.in checkPandaVersion.h)
+configure_file(checkPandaVersion.cxx.in checkPandaVersion.cxx)
+
+if(CMAKE_CXX_STANDARD GREATER 16)
+ # This serves as a reminder to update checkPandaVersion.h.in when we upgrade
+ # to C++17, which supports inline variables - a cleaner way of depending on
+ # the Panda version symbol from a header than what we're currently doing.
+ message(FATAL_ERROR "Developer notice: Update checkPandaVersion.h.in for C++17!")
+endif()
+
+set(P3DTOOLBASE_HEADERS
+ ${CMAKE_CURRENT_BINARY_DIR}/checkPandaVersion.h
+ ${CMAKE_CURRENT_BINARY_DIR}/pandaVersion.h
+ addHash.I addHash.h
+ atomicAdjust.h
+ atomicAdjustDummyImpl.h atomicAdjustDummyImpl.I
+ atomicAdjustGccImpl.h atomicAdjustGccImpl.I
+ atomicAdjustI386Impl.h atomicAdjustI386Impl.I
+ atomicAdjustPosixImpl.h atomicAdjustPosixImpl.I
+ atomicAdjustWin32Impl.h atomicAdjustWin32Impl.I
+ cmath.I cmath.h
+ deletedBufferChain.h deletedBufferChain.I
+ deletedChain.h deletedChain.T
+ dtoolbase.h dtoolbase_cc.h dtoolsymbols.h
+ dtool_platform.h
+ fakestringstream.h
+ indent.I indent.h
+ memoryBase.h
+ memoryHook.h memoryHook.I
+ mutexImpl.h
+ mutexDummyImpl.h mutexDummyImpl.I
+ mutexPosixImpl.h mutexPosixImpl.I
+ mutexWin32Impl.h mutexWin32Impl.I
+ mutexSpinlockImpl.h mutexSpinlockImpl.I
+ nearly_zero.h
+ neverFreeMemory.h neverFreeMemory.I
+ numeric_types.h
+ pdtoa.h
+ pstrtod.h
+ register_type.I register_type.h
+ selectThreadImpl.h
+ stl_compares.I stl_compares.h
+ typeHandle.I typeHandle.h
+ typeRegistry.I typeRegistry.h
+ typeRegistryNode.I typeRegistryNode.h
+ typedObject.I typedObject.h
+ pallocator.T pallocator.h
+ pdeque.h plist.h pmap.h pset.h
+ pvector.h epvector.h
+ lookup3.h
+ version.h
+)
+
+set(P3DTOOLBASE_SOURCES
+ ${CMAKE_CURRENT_BINARY_DIR}/checkPandaVersion.cxx
+ addHash.cxx
+ atomicAdjustDummyImpl.cxx
+ atomicAdjustI386Impl.cxx
+ atomicAdjustPosixImpl.cxx
+ atomicAdjustWin32Impl.cxx
+ deletedBufferChain.cxx
+ dtoolbase.cxx
+ indent.cxx
+ lookup3.c
+ memoryBase.cxx
+ memoryHook.cxx
+ mutexDummyImpl.cxx
+ mutexPosixImpl.cxx
+ mutexWin32Impl.cxx
+ mutexSpinlockImpl.cxx
+ neverFreeMemory.cxx
+ pdtoa.cxx
+ pstrtod.cxx
+ register_type.cxx
+ typeHandle.cxx
+ typeRegistry.cxx typeRegistryNode.cxx
+ typedObject.cxx
+)
+
+set(P3DTOOLBASE_IGATEEXT
+ typeHandle_ext.cxx
+ typeHandle_ext.h
+)
+
+set_source_files_properties(indent.cxx PROPERTIES SKIP_UNITY_BUILD_INCLUSION YES)
+
+composite_sources(p3dtoolbase P3DTOOLBASE_SOURCES)
+add_component_library(p3dtoolbase NOINIT SYMBOL BUILDING_DTOOL_DTOOLBASE
+ ${P3DTOOLBASE_HEADERS} ${P3DTOOLBASE_SOURCES})
+# Help other libraries find the autogenerated headers
+target_include_directories(p3dtoolbase PUBLIC
+ $
+ $)
+target_link_libraries(p3dtoolbase PKG::EIGEN PKG::THREADS)
+target_interrogate(p3dtoolbase ${P3DTOOLBASE_SOURCES} EXTENSIONS ${P3DTOOLBASE_IGATEEXT})
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3dtoolbase
+ EXPORT Core COMPONENT Core
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT CoreDevel)
+endif()
+install(FILES ${P3DTOOLBASE_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/dtool/src/dtoolbase/atomicAdjustWin32Impl.cxx b/dtool/src/dtoolbase/atomicAdjustWin32Impl.cxx
index 8128a8d2dd..19abfd3583 100644
--- a/dtool/src/dtoolbase/atomicAdjustWin32Impl.cxx
+++ b/dtool/src/dtoolbase/atomicAdjustWin32Impl.cxx
@@ -13,8 +13,8 @@
#include "selectThreadImpl.h"
-#ifdef WIN32_VC
+#ifdef _WIN32
#include "atomicAdjustWin32Impl.h"
-#endif // WIN32_VC
+#endif // _WIN32
diff --git a/dtool/src/dtoolbase/atomicAdjustWin32Impl.h b/dtool/src/dtoolbase/atomicAdjustWin32Impl.h
index 25f2e78066..f83ee0150b 100644
--- a/dtool/src/dtoolbase/atomicAdjustWin32Impl.h
+++ b/dtool/src/dtoolbase/atomicAdjustWin32Impl.h
@@ -17,7 +17,7 @@
#include "dtoolbase.h"
#include "selectThreadImpl.h"
-#ifdef WIN32_VC
+#ifdef _WIN32
#include "numeric_types.h"
@@ -62,6 +62,6 @@ public:
#include "atomicAdjustWin32Impl.I"
-#endif // WIN32_VC
+#endif // _WIN32
#endif
diff --git a/dtool/src/dtoolbase/checkPandaVersion.cxx.in b/dtool/src/dtoolbase/checkPandaVersion.cxx.in
new file mode 100644
index 0000000000..e62f0184c8
--- /dev/null
+++ b/dtool/src/dtoolbase/checkPandaVersion.cxx.in
@@ -0,0 +1,21 @@
+/* Filename: checkPandaVersion.cxx
+ * Created by: drose (26Jan05)
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * PANDA 3D SOFTWARE
+ * Copyright (c) Carnegie Mellon University. All rights reserved.
+ *
+ * All use of this software is subject to the terms of the revised BSD
+ * license. You should have received a copy of this license along
+ * with this source code in a file named "LICENSE."
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*******************************************************************
+ * Generated automatically by CMake.
+ ***************************** DO NOT EDIT *************************/
+
+#include "dtoolbase.h"
+
+EXPCL_DTOOL_DTOOLBASE int @PANDA_VERSION_SYMBOL@ = 0;
diff --git a/dtool/src/dtoolbase/checkPandaVersion.h.in b/dtool/src/dtoolbase/checkPandaVersion.h.in
new file mode 100644
index 0000000000..6f4b7ae403
--- /dev/null
+++ b/dtool/src/dtoolbase/checkPandaVersion.h.in
@@ -0,0 +1,64 @@
+/* Filename: checkPandaVersion.h
+ * Created by: drose (26Jan05)
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * PANDA 3D SOFTWARE
+ * Copyright (c) Carnegie Mellon University. All rights reserved.
+ *
+ * All use of this software is subject to the terms of the revised BSD
+ * license. You should have received a copy of this license along
+ * with this source code in a file named "LICENSE."
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*******************************************************************
+ * Generated automatically by CMake.
+ ***************************** DO NOT EDIT *************************/
+
+/* Include this file in code that compiles with Panda to guarantee
+ that it is linking with the same version of the Panda DLL's that it
+ was compiled with. */
+
+/* We guarantee this by defining an external symbol which is based on
+ the version number. If that symbol is defined, then our DLL's
+ (probably) match. Otherwise, we must be running with the wrong
+ DLL; but the system linker will prevent the DLL from loading with
+ an undefined symbol. */
+
+#ifndef CHECKPANDAVERSION_H
+#define CHECKPANDAVERSION_H
+
+#include "dtoolbase.h"
+
+extern EXPCL_DTOOL_DTOOLBASE int @PANDA_VERSION_SYMBOL@;
+
+/* Just declaring the symbol isn't good enough. We need to force the
+ compiler and linker to preserve the external reference long enough
+ to end up in the output DLL. Therefore, we have to reference that
+ symbol somehow.
+
+ Forcing the compiler to include a reference in its output object
+ file is easy enough: just define a function that makes use of it
+ in some way. The problem is the linker, which will enforce the
+ C++ One-Definition Rule and get upset about said definition
+ appearing in multiple places in the program. We can appease the
+ linker by forcing the compiler to emit a weak symbol. Many
+ compilers have syntax to request this explicitly, but since it
+ varies from compiler to compiler, that wouldn't be very portable.
+
+ Fortunately, the C++ ODR itself has some exceptions, where a
+ definition can occur in multiple translation units *if and only if*
+ it's the same definition each time. In these cases, the compiler
+ must emit a weak symbol, because the ODR does not guarantee that
+ the same definition isn't repeated in any other translation units.
+ One such exception is template instantiation, which we use thus: */
+template
+class CheckPandaVersion {
+public:
+ int check_version() { return @PANDA_VERSION_SYMBOL@; }
+};
+
+template class CheckPandaVersion;
+
+#endif
diff --git a/dtool/src/dtoolbase/dtoolbase.cxx b/dtool/src/dtoolbase/dtoolbase.cxx
index 3bd34815c9..0b7c874db2 100644
--- a/dtool/src/dtoolbase/dtoolbase.cxx
+++ b/dtool/src/dtoolbase/dtoolbase.cxx
@@ -18,7 +18,7 @@
#error Buildsystem error: BUILDING_DTOOL_DTOOLBASE not defined
#endif
-#if defined(USE_TAU) && defined(WIN32)
+#if defined(USE_TAU) && defined(_WIN32)
// Hack around tau's lack of DLL export declarations for Profiler class.
bool __tau_shutdown = false;
#endif
diff --git a/dtool/src/dtoolbase/dtoolbase.h b/dtool/src/dtoolbase/dtoolbase.h
index 2207915f28..67dee423da 100644
--- a/dtool/src/dtoolbase/dtoolbase.h
+++ b/dtool/src/dtoolbase/dtoolbase.h
@@ -21,19 +21,7 @@
#include "dtool_config.h"
-/* Make sure WIN32 and WIN32_VC are defined when using MSVC */
-#if defined(_WIN32) || defined(_WIN64)
-#ifndef WIN32
-#define WIN32
-#endif
#ifdef _MSC_VER
-#ifndef WIN32_VC
-#define WIN32_VC
-#endif
-#endif
-#endif
-
-#ifdef WIN32_VC
/* These warning pragmas must appear before anything else for VC++ to
respect them. Sheesh. */
@@ -58,11 +46,11 @@
#pragma warning (disable : 4267)
/* C4577: 'noexcept' used with no exception handling mode specified */
#pragma warning (disable : 4577)
-#endif /* WIN32_VC */
+#endif /* _MSC_VER */
/* Windows likes to define min() and max() macros, which will conflict with
std::min() and std::max() respectively, unless we do this: */
-#ifdef WIN32
+#ifdef _WIN32
#ifndef NOMINMAX
#define NOMINMAX
#endif
@@ -485,7 +473,7 @@ typedef struct _object PyObject;
#endif
/* These symbols are used in dtoolsymbols.h and pandasymbols.h. */
-#if defined(WIN32_VC) && !defined(CPPPARSER) && !defined(LINK_ALL_STATIC)
+#if defined(_WIN32) && !defined(CPPPARSER) && !defined(LINK_ALL_STATIC)
#define EXPORT_CLASS __declspec(dllexport)
#define IMPORT_CLASS __declspec(dllimport)
#elif __GNUC__ >= 4 && !defined(CPPPARSER) && !defined(LINK_ALL_STATIC)
diff --git a/dtool/src/dtoolbase/dtoolbase_cc.h b/dtool/src/dtoolbase/dtoolbase_cc.h
index 8894469422..674462f6ac 100644
--- a/dtool/src/dtoolbase/dtoolbase_cc.h
+++ b/dtool/src/dtoolbase/dtoolbase_cc.h
@@ -251,7 +251,7 @@ INLINE void thread_consider_yield() {
#endif // HAVE_THREADS && SIMPLE_THREADS
-#if defined(USE_TAU) && defined(WIN32)
+#if defined(USE_TAU) && defined(_WIN32)
// Hack around tau's lack of DLL export declarations for Profiler class.
extern EXPCL_DTOOL_DTOOLBASE bool __tau_shutdown;
class EXPCL_DTOOL_DTOOLBASE TauProfile {
diff --git a/dtool/src/dtoolbase/memoryHook.cxx b/dtool/src/dtoolbase/memoryHook.cxx
index 24d5f11a11..4abc0661d8 100644
--- a/dtool/src/dtoolbase/memoryHook.cxx
+++ b/dtool/src/dtoolbase/memoryHook.cxx
@@ -16,7 +16,7 @@
#include
#include "typeRegistry.h"
-#ifdef WIN32
+#ifdef _WIN32
// Windows case.
#ifndef WIN32_LEAN_AND_MEAN
@@ -191,7 +191,7 @@ ptr_to_alloc(void *ptr, size_t &size) {
*/
MemoryHook::
MemoryHook() {
-#ifdef WIN32
+#ifdef _WIN32
// Windows case.
SYSTEM_INFO sysinfo;
@@ -487,7 +487,7 @@ heap_trim(size_t pad) {
_lock.unlock();
#endif
-#ifdef WIN32
+#ifdef _WIN32
// Also, on Windows we have _heapmin().
if (_heapmin() == 0) {
trimmed = true;
@@ -516,7 +516,7 @@ mmap_alloc(size_t size, bool allow_exec) {
_total_mmap_size += size;
#endif
-#ifdef WIN32
+#ifdef _WIN32
// Windows case.
void *ptr = VirtualAlloc(nullptr, size, MEM_COMMIT | MEM_RESERVE,
@@ -571,7 +571,7 @@ mmap_free(void *ptr, size_t size) {
_total_mmap_size -= size;
#endif
-#ifdef WIN32
+#ifdef _WIN32
VirtualFree(ptr, 0, MEM_RELEASE);
#else
munmap(ptr, size);
diff --git a/dtool/src/dtoolbase/mutexImpl.h b/dtool/src/dtoolbase/mutexImpl.h
index add705bc39..cebd4e0de7 100644
--- a/dtool/src/dtoolbase/mutexImpl.h
+++ b/dtool/src/dtoolbase/mutexImpl.h
@@ -49,7 +49,7 @@ typedef ReMutexPosixImpl ReMutexImpl;
// Also define what a true OS-provided lock will be, even if we don't have
// threading enabled in the build. Sometimes we need to interface with an
// external program or something that wants real locks.
-#if defined(WIN32_VC)
+#if defined(_WIN32)
#include "mutexWin32Impl.h"
typedef MutexWin32Impl TrueMutexImpl;
diff --git a/dtool/src/dtoolbase/mutexWin32Impl.cxx b/dtool/src/dtoolbase/mutexWin32Impl.cxx
index 4488c637ae..04d3ac0ec9 100644
--- a/dtool/src/dtoolbase/mutexWin32Impl.cxx
+++ b/dtool/src/dtoolbase/mutexWin32Impl.cxx
@@ -13,7 +13,7 @@
#include "selectThreadImpl.h"
-#ifdef WIN32_VC
+#if defined(_WIN32) && !defined(CPPPARSER)
#include "mutexWin32Impl.h"
@@ -28,4 +28,4 @@ ReMutexWin32Impl() {
InitializeCriticalSectionAndSpinCount(&_lock, spin_count);
}
-#endif // WIN32_VC
+#endif // _WIN32
diff --git a/dtool/src/dtoolbase/mutexWin32Impl.h b/dtool/src/dtoolbase/mutexWin32Impl.h
index 0df0808459..debee81113 100644
--- a/dtool/src/dtoolbase/mutexWin32Impl.h
+++ b/dtool/src/dtoolbase/mutexWin32Impl.h
@@ -17,7 +17,7 @@
#include "dtoolbase.h"
#include "selectThreadImpl.h"
-#ifdef WIN32_VC
+#ifdef _WIN32
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1
#endif
@@ -68,6 +68,6 @@ private:
#include "mutexWin32Impl.I"
-#endif // WIN32_VC
+#endif // _WIN32
#endif
diff --git a/dtool/src/dtoolbase/pandaVersion.h.in b/dtool/src/dtoolbase/pandaVersion.h.in
new file mode 100644
index 0000000000..ecaed20cd7
--- /dev/null
+++ b/dtool/src/dtoolbase/pandaVersion.h.in
@@ -0,0 +1,73 @@
+/* Filename: pandaVersion.h
+ * Created by: drose (26Jan05)
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ * PANDA 3D SOFTWARE
+ * Copyright (c) Carnegie Mellon University. All rights reserved.
+ *
+ * All use of this software is subject to the terms of the revised BSD
+ * license. You should have received a copy of this license along
+ * with this source code in a file named "LICENSE."
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*******************************************************************
+ * Generated automatically by CMake.
+ ***************************** DO NOT EDIT *************************
+
+ Do NOT attempt to edit the version number in this file. This is a
+ generated file, and your changes to this file will not persist. To
+ increment the version number, modify dtool/PandaVersion.cmake and
+ re-run ppremake.
+
+ ***************************** DO NOT EDIT *************************/
+
+/* Include this file anywhere you need to determine the Panda version
+ number at compile time. If you need the runtime Panda version, use
+ pandaSystem.h instead. */
+
+/* Try to avoid including this file from another .h file; include it
+ only from .cxx instead. This helps prevent unnecessarily long
+ rebuilds just because the version number changes; if this file is
+ included in a .h file, then any other files which also include that
+ .h file will need to be rebuilt when the version number changes. */
+
+#define PANDA_MAJOR_VERSION @PROJECT_VERSION_MAJOR@
+#define PANDA_MINOR_VERSION @PROJECT_VERSION_MINOR@
+#define PANDA_SEQUENCE_VERSION @PROJECT_VERSION_PATCH@
+
+/* Define if this is an "official" version, undefine otherwise. */
+#cmakedefine PANDA_OFFICIAL_VERSION
+
+/* This is the panda numeric version as a single number, with three
+ digits reserved for each component. */
+#define PANDA_NUMERIC_VERSION @PANDA_NUMERIC_VERSION@
+
+/* This is the panda version expressed as a string. It ends in the
+ letter "c" if this is not an "official" version (e.g. it was checked
+ out from CVS by the builder). */
+#define PANDA_VERSION_STR "@PANDA_VERSION_STR@"
+
+/* This is the Git commit we built Panda from, or an empty string if this isn't
+ known. */
+#define PANDA_GIT_COMMIT_STR "@PANDA_GIT_COMMIT_STR@"
+
+/* This is the version of the Panda3D ABI expressed as a string.
+ This usually means the major and minor version. It should be the
+ same for Panda3D versions that are supposed to be backward
+ ABI compatible with each other. */
+#define PANDA_ABI_VERSION_STR "@PROJECT_VERSION_MAJOR@.@PROJECT_VERSION_MINOR@"
+
+/* This is a string indicating who has provided this distribution. */
+#define PANDA_DISTRIBUTOR "@PANDA_DISTRIBUTOR@"
+
+/* The string indicating the version number of the associated Panda3D
+ distributable package, or empty string if there is no associated
+ package. */
+#define PANDA_PACKAGE_VERSION_STR "@PANDA_PACKAGE_VERSION@"
+
+/* The string indicating the URL from which the associated Panda3D
+ distributable package may be downloaded, or empty string if there
+ is no associated package. */
+#define PANDA_PACKAGE_HOST_URL "@PANDA_PACKAGE_HOST_URL@"
diff --git a/dtool/src/dtoolbase/selectThreadImpl.h b/dtool/src/dtoolbase/selectThreadImpl.h
index 743ea98af7..4ef55dc6f3 100644
--- a/dtool/src/dtoolbase/selectThreadImpl.h
+++ b/dtool/src/dtoolbase/selectThreadImpl.h
@@ -47,7 +47,7 @@
#undef TVOLATILE
#define TVOLATILE
-#elif defined(WIN32_VC)
+#elif defined(_WIN32)
// In Windows, use the native threading library.
#define THREAD_WIN32_IMPL 1
diff --git a/dtool/src/dtoolutil/CMakeLists.txt b/dtool/src/dtoolutil/CMakeLists.txt
new file mode 100644
index 0000000000..c3a43c319b
--- /dev/null
+++ b/dtool/src/dtoolutil/CMakeLists.txt
@@ -0,0 +1,153 @@
+set(P3DTOOLUTIL_HEADERS
+ config_dtoolutil.h
+ dSearchPath.I dSearchPath.h
+ executionEnvironment.I executionEnvironment.h filename.I
+ filename.h
+ globPattern.I globPattern.h
+ lineStream.I lineStream.h
+ lineStreamBuf.I lineStreamBuf.h
+ load_dso.h
+ pandaFileStream.h pandaFileStream.I
+ pandaFileStreamBuf.h
+ pandaSystem.h
+ panda_getopt.h panda_getopt_long.h panda_getopt_impl.h
+ pfstream.h pfstream.I pfstreamBuf.h
+ preprocess_argv.h
+ string_utils.h string_utils.I
+ stringDecoder.h stringDecoder.I
+ textEncoder.h textEncoder.I
+ unicodeLatinMap.h
+ vector_double.h
+ vector_float.h
+ vector_int.h
+ vector_stdfloat.h
+ vector_string.h
+ vector_uchar.h
+ vector_src.h
+ win32ArgParser.h
+)
+
+if(APPLE)
+ set(P3DTOOLUTIL_HEADERS ${P3DTOOLUTIL_HEADERS}
+ filename_assist.mm filename_assist.h)
+
+ set_source_files_properties(
+ filename_assist.mm filename_assist.h PROPERTIES
+ WRAP_EXCLUDE YES
+ SKIP_UNITY_BUILD_INCLUSION YES)
+endif()
+
+set(P3DTOOLUTIL_SOURCES
+ config_dtoolutil.cxx
+ dSearchPath.cxx
+ executionEnvironment.cxx filename.cxx
+ globPattern.cxx
+ lineStream.cxx lineStreamBuf.cxx
+ load_dso.cxx
+ pandaFileStream.cxx pandaFileStreamBuf.cxx
+ pandaSystem.cxx
+ panda_getopt_impl.cxx
+ pfstreamBuf.cxx pfstream.cxx
+ preprocess_argv.cxx
+ string_utils.cxx
+ stringDecoder.cxx
+ textEncoder.cxx
+ unicodeLatinMap.cxx
+ vector_double.cxx
+ vector_float.cxx
+ vector_int.cxx
+ vector_string.cxx
+ vector_uchar.cxx
+ win32ArgParser.cxx
+)
+
+set(P3DTOOLUTIL_IGATEEXT
+ filename_ext.cxx
+ filename_ext.h
+ globPattern_ext.cxx
+ globPattern_ext.h
+ iostream_ext.cxx
+ iostream_ext.h
+ textEncoder_ext.cxx
+ textEncoder_ext.h
+)
+
+composite_sources(p3dtoolutil P3DTOOLUTIL_SOURCES)
+add_component_library(p3dtoolutil SYMBOL BUILDING_DTOOL_DTOOLUTIL
+ ${P3DTOOLUTIL_HEADERS} ${P3DTOOLUTIL_SOURCES})
+target_link_libraries(p3dtoolutil p3dtoolbase ${CMAKE_DL_LIBS})
+target_interrogate(p3dtoolutil ALL EXTENSIONS ${P3DTOOLUTIL_IGATEEXT})
+
+if(APPLE)
+ find_library(FOUNDATION_LIBRARY Foundation)
+ find_library(APPKIT_LIBRARY AppKit)
+ target_link_libraries(p3dtoolutil ${FOUNDATION_LIBRARY} ${APPKIT_LIBRARY})
+endif()
+
+# These are all used by executionEnvironment.cxx/filename.cxx
+foreach(var
+ # executionEnvironment.cxx:
+ HAVE_GLOBAL_ARGV
+ PROTOTYPE_GLOBAL_ARGV
+ GLOBAL_ARGV
+ GLOBAL_ARGC
+
+ HAVE_PROC_CURPROC_CMDLINE
+ HAVE_PROC_CURPROC_FILE
+ HAVE_PROC_CURPROC_MAP
+ HAVE_PROC_SELF_CMDLINE
+ HAVE_PROC_SELF_ENVIRON
+ HAVE_PROC_SELF_EXE
+ HAVE_PROC_SELF_MAPS
+
+ STATIC_INIT_GETENV
+
+ # filename.cxx:
+ HAVE_IOS_BINARY
+ PHAVE_DIRENT_H
+ PHAVE_GLOB_H
+ PHAVE_LOCKF
+ PHAVE_UTIME_H
+)
+
+ if(${var})
+ target_compile_definitions(p3dtoolutil PRIVATE "${var}=${${var}}")
+ endif()
+
+endforeach(var)
+
+if(BUILD_SHARED_LIBS)
+ # executionEnvironment.cxx needs to know the name(s) of the library file it
+ # will be linked into
+ if(BUILD_METALIBS)
+ set(library "p3dtool")
+ else()
+ set(library "p3dtoolutil")
+ endif()
+
+ set(filenames)
+ foreach(prop TARGET_FILE_NAME TARGET_SONAME_FILE_NAME TARGET_LINKER_FILE_NAME)
+ list(APPEND filenames "$<${prop}:${library}>")
+
+ if(CMAKE_IMPORT_LIBRARY_SUFFIX)
+ # Only the first property is valid/relevant on DLL platforms; bail out
+ # now and skip the others.
+ # (Yes, CMAKE_IMPORT_LIBRARY_SUFFIX being non-empty is how CMake defines
+ # a DLL platform where TARGET_SONAME_FILE_NAME is invalid.)
+ break()
+ endif()
+ endforeach(prop)
+
+ target_compile_definitions(p3dtoolutil
+ PRIVATE "LIBP3DTOOL_FILENAMES=\"$\">\"")
+endif()
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3dtoolutil
+ EXPORT Core COMPONENT Core
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT CoreDevel)
+endif()
+install(FILES ${P3DTOOLUTIL_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/dtool/src/dtoolutil/executionEnvironment.cxx b/dtool/src/dtoolutil/executionEnvironment.cxx
index 4a10c9d168..5f40578f3d 100644
--- a/dtool/src/dtoolutil/executionEnvironment.cxx
+++ b/dtool/src/dtoolutil/executionEnvironment.cxx
@@ -101,7 +101,7 @@ static const char *const libp3dtool_filenames[] = {
// libp3dtool dynamic library - no guesswork needed.
LIBP3DTOOL_FILENAMES
-#elif defined(WIN32_VC)
+#elif defined(_WIN32)
#ifdef _DEBUG
"libp3dtool_d.dll",
@@ -223,7 +223,7 @@ get_cwd() {
Filename cwd = Filename::from_os_specific_w(buffer);
cwd.make_true_case();
return cwd;
-#else // WIN32_VC
+#else // _WIN32
// getcwd() requires us to allocate a dynamic buffer and grow it on demand.
static size_t bufsize = 1024;
static char *buffer = nullptr;
@@ -246,7 +246,7 @@ get_cwd() {
Filename cwd = Filename::from_os_specific(buffer);
cwd.make_true_case();
return cwd;
-#endif // WIN32_VC
+#endif // _WIN32
}
/**
@@ -585,7 +585,7 @@ read_args() {
// the p3dtool library.
#ifndef LINK_ALL_STATIC
-#if defined(WIN32_VC)
+#if defined(_WIN32)
for (const char *filename : libp3dtool_filenames) {
if (!_dtool_name.empty()) break;
@@ -704,7 +704,7 @@ read_args() {
// Now, we need to fill in _binary_name. This contains the full path to the
// currently running executable.
-#ifdef WIN32_VC
+#ifdef _WIN32
if (_binary_name.empty()) {
static const DWORD buffer_size = 1024;
wchar_t buffer[buffer_size];
@@ -766,7 +766,7 @@ read_args() {
// Next we need to fill in _args, which is a vector containing the command-
// line arguments that the executable was invoked with.
-#if defined(WIN32_VC)
+#if defined(_WIN32)
// We cannot rely on __argv when Python is linked in Unicode mode. Instead,
// let's use GetCommandLine.
diff --git a/dtool/src/dtoolutil/filename.cxx b/dtool/src/dtoolutil/filename.cxx
index ba1db02198..e59aeb448e 100644
--- a/dtool/src/dtoolutil/filename.cxx
+++ b/dtool/src/dtoolutil/filename.cxx
@@ -70,15 +70,13 @@ TypeHandle Filename::_type_handle;
string Filename::_internal_data_dir;
#endif
-#ifdef WIN32
+#ifdef _WIN32
/* begin Win32-specific code */
-#ifdef WIN32_VC
#include
#include
#include
#include
-#endif
// The MSVC 6.0 Win32 SDK lacks the following definitions, so we define them
// here for compatibility.
@@ -289,7 +287,7 @@ convert_executable_pathname(const string &unix_style_pathname) {
return convert_pathname(unix_style_pathname);
}
-#endif //WIN32
+#endif // _WIN32
/**
* This constructor composes the filename out of a directory part and a
@@ -326,7 +324,7 @@ Filename(const Filename &dirname, const Filename &basename) {
*/
Filename Filename::
from_os_specific(const string &os_specific, Filename::Type type) {
-#ifdef WIN32
+#ifdef _WIN32
string result = back_to_front_slash(os_specific);
const string &panda_root = get_panda_root();
@@ -378,12 +376,12 @@ from_os_specific(const string &os_specific, Filename::Type type) {
Filename filename(result);
filename.set_type(type);
return filename;
-#else // WIN32
+#else // _WIN32
// Generic Unix-style filenames--no conversion necessary.
Filename filename(os_specific);
filename.set_type(type);
return filename;
-#endif // WIN32
+#endif // _WIN32
}
/**
@@ -487,7 +485,7 @@ get_home_directory() {
}
if (home_directory.empty()) {
-#ifdef WIN32
+#ifdef _WIN32
wchar_t buffer[MAX_PATH];
// On Windows, fall back to the "My Documents" folder.
@@ -513,7 +511,7 @@ get_home_directory() {
#else
// Posix case: check etcpasswd?
-#endif // WIN32
+#endif // _WIN32
}
if (home_directory.empty()) {
@@ -540,7 +538,7 @@ get_temp_directory() {
if (AtomicAdjust::get_ptr(_temp_directory) == nullptr) {
Filename temp_directory;
-#ifdef WIN32
+#ifdef _WIN32
static const size_t buffer_size = 4096;
wchar_t buffer[buffer_size];
if (GetTempPathW(buffer_size, buffer) != 0) {
@@ -562,7 +560,7 @@ get_temp_directory() {
#else
// Posix case.
temp_directory = "/tmp";
-#endif // WIN32
+#endif // _WIN32
if (temp_directory.empty()) {
// Fallback case.
@@ -590,7 +588,7 @@ get_user_appdata_directory() {
if (AtomicAdjust::get_ptr(_user_appdata_directory) == nullptr) {
Filename user_appdata_directory;
-#ifdef WIN32
+#ifdef _WIN32
wchar_t buffer[MAX_PATH];
if (SHGetSpecialFolderPathW(nullptr, buffer, CSIDL_LOCAL_APPDATA, true)) {
@@ -619,7 +617,7 @@ get_user_appdata_directory() {
user_appdata_directory = Filename(get_home_directory(), ".local/share");
}
-#endif // WIN32
+#endif // _WIN32
if (user_appdata_directory.empty()) {
// Fallback case.
@@ -646,7 +644,7 @@ get_common_appdata_directory() {
if (AtomicAdjust::get_ptr(_common_appdata_directory) == nullptr) {
Filename common_appdata_directory;
-#ifdef WIN32
+#ifdef _WIN32
wchar_t buffer[MAX_PATH];
if (SHGetSpecialFolderPathW(nullptr, buffer, CSIDL_COMMON_APPDATA, true)) {
@@ -669,7 +667,7 @@ get_common_appdata_directory() {
common_appdata_directory = "/usr/local/share";
#else
common_appdata_directory = "/usr/share";
-#endif // WIN32
+#endif // _WIN32
if (common_appdata_directory.empty()) {
// Fallback case.
@@ -1019,7 +1017,7 @@ make_canonical() {
return true;
}
-#ifndef WIN32
+#ifndef _WIN32
// Use realpath in order to resolve symlinks properly
char newpath [PATH_MAX + 1];
if (realpath(c_str(), newpath) != nullptr) {
@@ -1057,7 +1055,7 @@ make_true_case() {
return true;
}
-#ifdef WIN32
+#ifdef _WIN32
wstring os_specific = to_os_specific_w();
// First, we have to convert it to its short name, then back to its long
@@ -1105,9 +1103,9 @@ make_true_case() {
(*this) = true_case;
return true;
-#else // WIN32
+#else // _WIN32
return true;
-#endif // WIN32
+#endif // _WIN32
}
/**
@@ -1142,7 +1140,7 @@ to_os_specific() const {
}
#endif
-#ifdef WIN32
+#ifdef _WIN32
switch (get_type()) {
case T_dso:
return convert_dso_pathname(standard.get_fullpath());
@@ -1151,9 +1149,9 @@ to_os_specific() const {
default:
return convert_pathname(standard.get_fullpath());
}
-#else // WIN32
+#else // _WIN32
return standard.c_str();
-#endif // WIN32
+#endif // _WIN32
}
/**
@@ -1182,11 +1180,11 @@ string Filename::
to_os_generic() const {
assert(!get_pattern());
-#ifdef WIN32
+#ifdef _WIN32
return back_to_front_slash(to_os_specific());
-#else // WIN32
+#else // _WIN32
return to_os_specific();
-#endif // WIN32
+#endif // _WIN32
}
/**
@@ -1202,7 +1200,7 @@ string Filename::
to_os_short_name() const {
assert(!get_pattern());
-#ifdef WIN32
+#ifdef _WIN32
wstring os_specific = to_os_specific_w();
wchar_t short_name[MAX_PATH + 1];
@@ -1222,9 +1220,9 @@ to_os_short_name() const {
encoder.set_wtext(short_name);
return encoder.get_text();
-#else // WIN32
+#else // _WIN32
return to_os_specific();
-#endif // WIN32
+#endif // _WIN32
}
/**
@@ -1236,7 +1234,7 @@ string Filename::
to_os_long_name() const {
assert(!get_pattern());
-#ifdef WIN32
+#ifdef _WIN32
wstring os_specific = to_os_specific_w();
wchar_t long_name[MAX_PATH + 1];
@@ -1253,9 +1251,9 @@ to_os_long_name() const {
encoder.set_wtext(long_name);
return encoder.get_text();
-#else // WIN32
+#else // _WIN32
return to_os_specific();
-#endif // WIN32
+#endif // _WIN32
}
/**
@@ -1265,7 +1263,7 @@ to_os_long_name() const {
*/
bool Filename::
exists() const {
-#ifdef WIN32_VC
+#ifdef _WIN32
wstring os_specific = get_filename_index(0).to_os_specific_w();
bool exists = false;
@@ -1275,7 +1273,7 @@ exists() const {
exists = true;
}
-#else // WIN32_VC
+#else // _WIN32
string os_specific = get_filename_index(0).to_os_specific();
struct stat this_buf;
@@ -1295,7 +1293,7 @@ exists() const {
*/
bool Filename::
is_regular_file() const {
-#ifdef WIN32_VC
+#ifdef _WIN32
wstring os_specific = get_filename_index(0).to_os_specific_w();
bool isreg = false;
@@ -1305,7 +1303,7 @@ is_regular_file() const {
isreg = ((results & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE)) == 0);
}
-#else // WIN32_VC
+#else // _WIN32
string os_specific = get_filename_index(0).to_os_specific();
struct stat this_buf;
@@ -1327,7 +1325,7 @@ bool Filename::
is_writable() const {
bool writable = false;
-#ifdef WIN32_VC
+#ifdef _WIN32
wstring os_specific = get_filename_index(0).to_os_specific_w();
DWORD results = GetFileAttributesW(os_specific.c_str());
@@ -1340,7 +1338,7 @@ is_writable() const {
writable = true;
}
}
-#else // WIN32_VC
+#else // _WIN32
string os_specific = get_filename_index(0).to_os_specific();
if (access(os_specific.c_str(), W_OK) == 0) {
@@ -1357,7 +1355,7 @@ is_writable() const {
*/
bool Filename::
is_directory() const {
-#ifdef WIN32_VC
+#ifdef _WIN32
wstring os_specific = get_filename_index(0).to_os_specific_w();
bool isdir = false;
@@ -1366,7 +1364,7 @@ is_directory() const {
if (results != -1) {
isdir = (results & FILE_ATTRIBUTE_DIRECTORY) != 0;
}
-#else // WIN32_VC
+#else // _WIN32
string os_specific = get_filename_index(0).to_os_specific();
struct stat this_buf;
@@ -1385,7 +1383,7 @@ is_directory() const {
*/
bool Filename::
is_executable() const {
-#ifdef WIN32_VC
+#ifdef _WIN32
// no access() in windows, but to our advantage executables can only end in
// .exe or .com
string extension = get_extension();
@@ -1393,12 +1391,12 @@ is_executable() const {
return exists();
}
-#else /* WIN32_VC */
+#else // _WIN32
string os_specific = get_filename_index(0).to_os_specific();
if (access(os_specific.c_str(), X_OK) == 0) {
return true;
}
-#endif /* WIN32_VC */
+#endif // _WIN32
return false;
}
@@ -1417,7 +1415,7 @@ int Filename::
compare_timestamps(const Filename &other,
bool this_missing_is_old,
bool other_missing_is_old) const {
-#ifdef WIN32_VC
+#ifdef _WIN32
wstring os_specific = get_filename_index(0).to_os_specific_w();
wstring other_os_specific = other.get_filename_index(0).to_os_specific_w();
@@ -1434,7 +1432,7 @@ compare_timestamps(const Filename &other,
if (_wstat(other_os_specific.c_str(), &other_buf) == 0) {
other_exists = true;
}
-#else // WIN32_VC
+#else // _WIN32
string os_specific = get_filename_index(0).to_os_specific();
string other_os_specific = other.get_filename_index(0).to_os_specific();
@@ -1495,7 +1493,7 @@ compare_timestamps(const Filename &other,
*/
time_t Filename::
get_timestamp() const {
-#ifdef WIN32_VC
+#ifdef _WIN32
wstring os_specific = get_filename_index(0).to_os_specific_w();
struct _stat this_buf;
@@ -1503,7 +1501,7 @@ get_timestamp() const {
if (_wstat(os_specific.c_str(), &this_buf) == 0) {
return this_buf.st_mtime;
}
-#else // WIN32_VC
+#else // _WIN32
string os_specific = get_filename_index(0).to_os_specific();
struct stat this_buf;
@@ -1523,7 +1521,7 @@ get_timestamp() const {
*/
time_t Filename::
get_access_timestamp() const {
-#ifdef WIN32_VC
+#ifdef _WIN32
wstring os_specific = get_filename_index(0).to_os_specific_w();
struct _stat this_buf;
@@ -1531,7 +1529,7 @@ get_access_timestamp() const {
if (_wstat(os_specific.c_str(), &this_buf) == 0) {
return this_buf.st_atime;
}
-#else // WIN32_VC
+#else // _WIN32
string os_specific = get_filename_index(0).to_os_specific();
struct stat this_buf;
@@ -1549,7 +1547,7 @@ get_access_timestamp() const {
*/
std::streamsize Filename::
get_file_size() const {
-#ifdef WIN32_VC
+#ifdef _WIN32
wstring os_specific = get_filename_index(0).to_os_specific_w();
struct _stat64 this_buf;
@@ -1559,7 +1557,7 @@ get_file_size() const {
if (_wstati64(os_specific.c_str(), &this_buf) == 0) {
return this_buf.st_size;
}
-#else // WIN32_VC
+#else // _WIN32
string os_specific = get_filename_index(0).to_os_specific();
struct stat this_buf;
@@ -1718,7 +1716,7 @@ bool Filename::
scan_directory(vector_string &contents) const {
assert(!get_pattern());
-#if defined(WIN32_VC)
+#if defined(_WIN32)
// Use Windows' FindFirstFile() FindNextFile() to walk through the list of
// files in a directory.
size_t orig_size = contents.size();
@@ -1874,13 +1872,13 @@ open_read(std::ifstream &stream) const {
#endif
stream.clear();
-#ifdef WIN32_VC
+#ifdef _WIN32
wstring os_specific = to_os_specific_w();
stream.open(os_specific.c_str(), open_mode);
#else
string os_specific = to_os_specific();
stream.open(os_specific.c_str(), open_mode);
-#endif // WIN32_VC
+#endif // _WIN32
return (!stream.fail());
}
@@ -1924,11 +1922,11 @@ open_write(std::ofstream &stream, bool truncate) const {
#endif
stream.clear();
-#ifdef WIN32_VC
+#ifdef _WIN32
wstring os_specific = to_os_specific_w();
#else
string os_specific = to_os_specific();
-#endif // WIN32_VC
+#endif // _WIN32
stream.open(os_specific.c_str(), open_mode);
return (!stream.fail());
@@ -1956,11 +1954,11 @@ open_append(std::ofstream &stream) const {
#endif
stream.clear();
-#ifdef WIN32_VC
+#ifdef _WIN32
wstring os_specific = to_os_specific_w();
#else
string os_specific = to_os_specific();
-#endif // WIN32_VC
+#endif // _WIN32
stream.open(os_specific.c_str(), open_mode);
return (!stream.fail());
@@ -1998,11 +1996,11 @@ open_read_write(std::fstream &stream, bool truncate) const {
#endif
stream.clear();
-#ifdef WIN32_VC
+#ifdef _WIN32
wstring os_specific = to_os_specific_w();
#else
string os_specific = to_os_specific();
-#endif // WIN32_VC
+#endif // _WIN32
stream.open(os_specific.c_str(), open_mode);
return (!stream.fail());
@@ -2030,11 +2028,11 @@ open_read_append(std::fstream &stream) const {
#endif
stream.clear();
-#ifdef WIN32_VC
+#ifdef _WIN32
wstring os_specific = to_os_specific_w();
#else
string os_specific = to_os_specific();
-#endif // WIN32_VC
+#endif // _WIN32
stream.open(os_specific.c_str(), open_mode);
return (!stream.fail());
@@ -2224,7 +2222,7 @@ open_read_append(pfstream &stream) const {
bool Filename::
touch() const {
assert(!get_pattern());
-#ifdef WIN32_VC
+#ifdef _WIN32
// In Windows, we have to use the Windows API to do this reliably.
// First, guarantee the file exists (and also get its handle).
@@ -2285,14 +2283,14 @@ touch() const {
return false;
}
return true;
-#else // WIN32, PHAVE_UTIME_H
+#else // _WIN32, PHAVE_UTIME_H
// Other systems may not have an explicit control over the modification
// time. For these systems, we'll just temporarily open the file in append
// mode, then close it again (it gets closed when the pfstream goes out of
// scope).
pfstream file;
return open_append(file);
-#endif // WIN32, PHAVE_UTIME_H
+#endif // _WIN32, PHAVE_UTIME_H
}
/**
@@ -2301,13 +2299,13 @@ touch() const {
*/
bool Filename::
chdir() const {
-#ifdef WIN32_VC
+#ifdef _WIN32
wstring os_specific = to_os_specific_w();
return (_wchdir(os_specific.c_str()) >= 0);
#else
string os_specific = to_os_specific();
return (::chdir(os_specific.c_str()) >= 0);
-#endif // WIN32_VC
+#endif // _WIN32
}
/**
@@ -2318,7 +2316,7 @@ chdir() const {
bool Filename::
unlink() const {
assert(!get_pattern());
-#ifdef WIN32_VC
+#ifdef _WIN32
// Windows can't delete a file if it's read-only. Weird.
wstring os_specific = to_os_specific_w();
_wchmod(os_specific.c_str(), 0644);
@@ -2326,7 +2324,7 @@ unlink() const {
#else
string os_specific = to_os_specific();
return (::unlink(os_specific.c_str()) == 0);
-#endif // WIN32_VC
+#endif // _WIN32
}
@@ -2344,7 +2342,7 @@ rename_to(const Filename &other) const {
return true;
}
-#ifdef WIN32_VC
+#ifdef _WIN32
wstring os_specific = to_os_specific_w();
wstring other_os_specific = other.to_os_specific_w();
@@ -2383,7 +2381,7 @@ rename_to(const Filename &other) const {
unlink();
return true;
}
-#else // WIN32_VC
+#else // _WIN32
string os_specific = to_os_specific();
string other_os_specific = other.to_os_specific();
@@ -2422,7 +2420,7 @@ rename_to(const Filename &other) const {
unlink();
return true;
}
-#endif // WIN32_VC
+#endif // _WIN32
// Failed.
temp.unlink();
@@ -2555,7 +2553,7 @@ mkdir() const {
*/
bool Filename::
rmdir() const {
-#ifdef WIN32_VC
+#ifdef _WIN32
wstring os_specific = to_os_specific_w();
int result = _wrmdir(os_specific.c_str());
@@ -2566,10 +2564,10 @@ rmdir() const {
result = _wrmdir(os_specific.c_str());
}
-#else // WIN32_VC
+#else // _WIN32
string os_specific = to_os_specific();
int result = ::rmdir(os_specific.c_str());
-#endif // WIN32_VC
+#endif // _WIN32
return (result == 0);
}
@@ -3046,7 +3044,7 @@ r_make_canonical(const Filename &cwd) {
return false;
}
-#ifdef WIN32_VC
+#ifdef _WIN32
// First, try to cd to the filename directly.
wstring os_specific = to_os_specific_w();
if (_wchdir(os_specific.c_str()) >= 0) {
@@ -3060,7 +3058,7 @@ r_make_canonical(const Filename &cwd) {
}
return true;
}
-#else // WIN32_VC
+#else // _WIN32
// First, try to cd to the filename directly.
string os_specific = to_os_specific();
if (::chdir(os_specific.c_str()) >= 0) {
@@ -3074,7 +3072,7 @@ r_make_canonical(const Filename &cwd) {
}
return true;
}
-#endif // WIN32_VC
+#endif // _WIN32
// That didn't work; maybe it's not a directory. Recursively go to the
// directory above.
diff --git a/dtool/src/dtoolutil/load_dso.cxx b/dtool/src/dtoolutil/load_dso.cxx
index fcd0c9fffe..95650b88c2 100644
--- a/dtool/src/dtoolutil/load_dso.cxx
+++ b/dtool/src/dtoolutil/load_dso.cxx
@@ -32,7 +32,7 @@ static Filename resolve_dso(const DSearchPath &path, const Filename &filename) {
}
}
-#if defined(WIN32)
+#if defined(_WIN32)
/* begin Win32-specific code */
#define WINDOWS_LEAN_AND_MEAN
diff --git a/dtool/src/dtoolutil/pfstreamBuf.h b/dtool/src/dtoolutil/pfstreamBuf.h
index 50875b2179..c72dff12ae 100644
--- a/dtool/src/dtoolutil/pfstreamBuf.h
+++ b/dtool/src/dtoolutil/pfstreamBuf.h
@@ -22,7 +22,7 @@
// compiling under Windows. Turn this off to use popen(), even on Windows.
// (popen() doesn't seem to work on Win9x, although it does work on NT-based
// variants.)
-#ifdef WIN32_VC
+#ifdef _WIN32
#define WIN_PIPE_CALLS 1
#endif
@@ -34,7 +34,7 @@
#else // WIN_PIPE_CALLS
-#ifdef WIN32_VC
+#ifdef _WIN32
#define popen _popen
#define pclose _pclose
#endif
diff --git a/dtool/src/dtoolutil/vector_src.h b/dtool/src/dtoolutil/vector_src.h
index fae382b7e6..f2a57646ca 100644
--- a/dtool/src/dtoolutil/vector_src.h
+++ b/dtool/src/dtoolutil/vector_src.h
@@ -34,7 +34,7 @@
#include "pvector.h"
-#if defined(WIN32_VC) && !defined(CPPPARSER)
+#if defined(_MSC_VER) && !defined(CPPPARSER)
#ifdef HAVE_DINKUM
// With the Dinkum library, we must first export the base class, _Vector_val.
diff --git a/dtool/src/dtoolutil/win32ArgParser.cxx b/dtool/src/dtoolutil/win32ArgParser.cxx
index 4faf6bff95..81fb6ba7e9 100644
--- a/dtool/src/dtoolutil/win32ArgParser.cxx
+++ b/dtool/src/dtoolutil/win32ArgParser.cxx
@@ -22,7 +22,7 @@
#include "executionEnvironment.h"
#include
-#include
+#include
using std::string;
diff --git a/dtool/src/interrogate/CMakeLists.txt b/dtool/src/interrogate/CMakeLists.txt
new file mode 100644
index 0000000000..1ecba4623d
--- /dev/null
+++ b/dtool/src/interrogate/CMakeLists.txt
@@ -0,0 +1,128 @@
+set(INTERROGATE_HEADERS
+ functionRemap.h
+ functionWriter.h
+ functionWriterPtrFromPython.h functionWriterPtrToPython.h
+ functionWriters.h
+ interfaceMaker.h
+ interfaceMakerC.h
+ interfaceMakerPython.h interfaceMakerPythonObj.h
+ interfaceMakerPythonSimple.h
+ interfaceMakerPythonNative.h
+ interrogate.h interrogateBuilder.h parameterRemap.I
+ parameterRemap.h
+ parameterRemapBasicStringPtrToString.h
+ parameterRemapBasicStringRefToString.h
+ parameterRemapBasicStringToString.h
+ parameterRemapCharStarToString.h
+ parameterRemapConcreteToPointer.h
+ parameterRemapConstToNonConst.h parameterRemapEnumToInt.h
+ parameterRemapPTToPointer.h
+ parameterRemapReferenceToConcrete.h
+ parameterRemapReferenceToPointer.h parameterRemapThis.h
+ parameterRemapToString.h
+ parameterRemapHandleToInt.h
+ parameterRemapUnchanged.h
+ typeManager.h
+)
+
+set(INTERROGATE_SOURCES
+ functionRemap.cxx
+ functionWriter.cxx
+ functionWriterPtrFromPython.cxx functionWriterPtrToPython.cxx
+ functionWriters.cxx
+ interfaceMaker.cxx
+ interfaceMakerC.cxx
+ interfaceMakerPython.cxx interfaceMakerPythonObj.cxx
+ interfaceMakerPythonSimple.cxx
+ interfaceMakerPythonNative.cxx
+ interrogate.cxx interrogateBuilder.cxx parameterRemap.cxx
+ parameterRemapBasicStringPtrToString.cxx
+ parameterRemapBasicStringRefToString.cxx
+ parameterRemapBasicStringToString.cxx
+ parameterRemapCharStarToString.cxx
+ parameterRemapConcreteToPointer.cxx
+ parameterRemapConstToNonConst.cxx
+ parameterRemapEnumToInt.cxx parameterRemapPTToPointer.cxx
+ parameterRemapReferenceToConcrete.cxx
+ parameterRemapReferenceToPointer.cxx parameterRemapThis.cxx
+ parameterRemapToString.cxx
+ parameterRemapHandleToInt.cxx
+ parameterRemapUnchanged.cxx
+ typeManager.cxx
+)
+
+set(INTERROGATE_PREAMBLE_PYTHON_NATIVE
+ ../interrogatedb/py_panda.cxx
+ ../interrogatedb/py_compat.cxx
+ ../interrogatedb/py_wrappers.cxx
+ ../interrogatedb/dtool_super_base.cxx
+)
+
+composite_sources(interrogate INTERROGATE_SOURCES)
+add_executable(interrogate ${INTERROGATE_HEADERS} ${INTERROGATE_SOURCES})
+target_link_libraries(interrogate p3cppParser p3interrogatedb
+ PKG::OPENSSL)
+
+# Python preamble for interrogate_module
+set(_preamble_files)
+foreach(_file ${INTERROGATE_PREAMBLE_PYTHON_NATIVE})
+ # Resolve symlinks, use absolute path, and add a `#line 1 ...` directive
+ get_filename_component(_file "${_file}" REALPATH)
+
+ string(SHA1 _hash "${_file}")
+ set(_line_file "${CMAKE_CURRENT_BINARY_DIR}/.${_hash}.h")
+ file(WRITE "${_line_file}" "#line 1 \"${_file}\"\n")
+
+ list(APPEND _preamble_files "${_line_file}")
+ list(APPEND _preamble_files "${_file}")
+endforeach(_file)
+
+add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/interrogate_preamble_python_native.cxx
+ COMMAND ${CMAKE_COMMAND}
+ -D OUTPUT_FILE="${CMAKE_CURRENT_BINARY_DIR}/interrogate_preamble_python_native.cxx"
+ -D INPUT_FILES="${_preamble_files}"
+ -D SYMBOL_NAME="interrogate_preamble_python_native"
+ -P ${PROJECT_SOURCE_DIR}/cmake/scripts/ConcatenateToCXX.cmake
+ DEPENDS ${INTERROGATE_PREAMBLE_PYTHON_NATIVE}
+ WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
+
+add_executable(interrogate_module interrogate_module.cxx
+ ${CMAKE_CURRENT_BINARY_DIR}/interrogate_preamble_python_native.cxx)
+target_link_libraries(interrogate_module p3cppParser p3interrogatedb
+ PKG::OPENSSL)
+
+if(NOT CMAKE_CROSSCOMPILING)
+ add_executable(host_interrogate ALIAS interrogate)
+ add_executable(host_interrogate_module ALIAS interrogate_module)
+
+else()
+ # When cross-compiling, we must find the host Interrogate.
+ # TODO: We should also try to find_package(Panda3D ...) before falling back
+ # to searching manually.
+ find_program(HOST_PATH_INTERROGATE interrogate)
+ find_program(HOST_PATH_INTERROGATE_MODULE interrogate_module)
+
+ add_executable(host_interrogate IMPORTED GLOBAL)
+ if(HOST_PATH_INTERROGATE)
+ set_target_properties(host_interrogate PROPERTIES
+ IMPORTED_LOCATION "${HOST_PATH_INTERROGATE}")
+ endif()
+
+ add_executable(host_interrogate_module IMPORTED GLOBAL)
+ if(HOST_PATH_INTERROGATE_MODULE)
+ set_target_properties(host_interrogate_module PROPERTIES
+ IMPORTED_LOCATION "${HOST_PATH_INTERROGATE_MODULE}")
+ endif()
+
+endif()
+
+if(WANT_INTERROGATE)
+ install(TARGETS interrogate interrogate_module EXPORT Core COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_BINDIR})
+ install(FILES ${INTERROGATE_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
+
+else()
+ set_target_properties(interrogate interrogate_module
+ PROPERTIES EXCLUDE_FROM_ALL ON)
+
+endif()
diff --git a/dtool/src/interrogate/typeManager.cxx b/dtool/src/interrogate/typeManager.cxx
index ab1fbffce3..dba10f4520 100644
--- a/dtool/src/interrogate/typeManager.cxx
+++ b/dtool/src/interrogate/typeManager.cxx
@@ -1442,7 +1442,7 @@ is_void(CPPType *type) {
/**
* Returns true if the indicated type is some class that derives from
- * ReferenceCount, or false otherwise.
+ * ReferenceCount, or defines ref and unref(), or false otherwise.
*/
bool TypeManager::
is_reference_count(CPPType *type) {
@@ -1459,6 +1459,14 @@ is_reference_count(CPPType *type) {
case CPPDeclaration::ST_struct:
{
CPPStructType *stype = type->as_struct_type();
+
+ // If we have methods named ref() and unref(), this is good enough.
+ if (stype->_scope->_functions.count("ref") &&
+ stype->_scope->_functions.count("unref") &&
+ stype->_scope->_functions.count("get_ref_count")) {
+ return true;
+ }
+
CPPStructType::Derivation::const_iterator di;
for (di = stype->_derivation.begin();
di != stype->_derivation.end();
diff --git a/dtool/src/interrogatedb/CMakeLists.txt b/dtool/src/interrogatedb/CMakeLists.txt
new file mode 100644
index 0000000000..adadd5a24b
--- /dev/null
+++ b/dtool/src/interrogatedb/CMakeLists.txt
@@ -0,0 +1,76 @@
+set(P3INTERROGATEDB_HEADERS
+ config_interrogatedb.h indexRemapper.h interrogateComponent.I
+ interrogateComponent.h interrogateDatabase.I
+ interrogateDatabase.h interrogateElement.I
+ interrogateElement.h interrogateFunction.I
+ interrogateFunction.h interrogateFunctionWrapper.I
+ interrogateFunctionWrapper.h
+ interrogateMakeSeq.I interrogateMakeSeq.h
+ interrogateManifest.I interrogateManifest.h
+ interrogateType.I interrogateType.h
+ interrogate_datafile.I interrogate_datafile.h
+ interrogate_interface.h interrogate_request.h
+)
+
+set(P3INTERROGATEDB_SOURCES
+ config_interrogatedb.cxx
+ indexRemapper.cxx
+ interrogateComponent.cxx interrogateDatabase.cxx
+ interrogateElement.cxx interrogateFunction.cxx
+ interrogateFunctionWrapper.cxx
+ interrogateMakeSeq.cxx
+ interrogateManifest.cxx
+ interrogateType.cxx interrogate_datafile.cxx
+ interrogate_interface.cxx interrogate_request.cxx
+)
+
+set(P3INTERROGATEDB_IGATE
+ interrogate_interface.h
+ interrogate_request.h
+)
+
+set(P3IGATERUNTIME_HEADERS
+ extension.h py_compat.h py_panda.h py_panda.I py_wrappers.h
+)
+
+composite_sources(p3interrogatedb P3INTERROGATEDB_SOURCES)
+add_library(p3interrogatedb
+ ${P3INTERROGATEDB_HEADERS} ${P3INTERROGATEDB_SOURCES})
+set_target_properties(p3interrogatedb PROPERTIES DEFINE_SYMBOL BUILDING_INTERROGATEDB)
+target_link_libraries(p3interrogatedb p3dconfig p3prc)
+
+install(TARGETS p3interrogatedb
+ EXPORT Core COMPONENT Core
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT CoreDevel)
+install(FILES ${P3INTERROGATEDB_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
+install(FILES ${P3IGATERUNTIME_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
+
+# ALSO: This has an Interrogate binding! Take care of that if we want it.
+# Note we don't use the regular Interrogate macros; this has some custom flags
+# that would make it not worthwhile.
+
+if(NOT INTERROGATE_PYTHON_INTERFACE)
+ return()
+endif()
+
+add_custom_command(
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/interrogatedb_module.cxx"
+ COMMAND host_interrogate
+ -D EXPCL_INTERROGATEDB=
+ -nodb -python -promiscuous
+ -module panda3d.interrogatedb
+ -library interrogatedb
+ -string -true-names -do-module
+ -srcdir "${CMAKE_CURRENT_SOURCE_DIR}"
+ -oc "${CMAKE_CURRENT_BINARY_DIR}/interrogatedb_module.cxx"
+ ${P3INTERROGATEDB_IGATE}
+
+ DEPENDS host_interrogate ${P3INTERROGATEDB_IGATE}
+ COMMENT "Interrogating interrogatedb")
+
+add_python_target(panda3d.interrogatedb
+ "${CMAKE_CURRENT_BINARY_DIR}/interrogatedb_module.cxx")
+target_link_libraries(panda3d.interrogatedb p3interrogatedb)
diff --git a/dtool/src/interrogatedb/config_interrogatedb.cxx b/dtool/src/interrogatedb/config_interrogatedb.cxx
index 4971443cc1..16986de56b 100644
--- a/dtool/src/interrogatedb/config_interrogatedb.cxx
+++ b/dtool/src/interrogatedb/config_interrogatedb.cxx
@@ -17,7 +17,7 @@
#include "configVariableSearchPath.h"
#include "dconfig.h"
-#if defined(WIN32_VC) && defined(_DEBUG)
+#if defined(_MSC_VER) && defined(_DEBUG)
// _DEBUG assumes you are linking to msvcrt70d.dll, not msvcrt70.dll
#define USE_WIN32_DBGHEAP
#include
diff --git a/dtool/src/prc/CMakeLists.txt b/dtool/src/prc/CMakeLists.txt
new file mode 100644
index 0000000000..f2985662bd
--- /dev/null
+++ b/dtool/src/prc/CMakeLists.txt
@@ -0,0 +1,157 @@
+set(P3PRC_HEADERS
+ androidLogStream.h
+ bigEndian.h
+ config_prc.h
+ configDeclaration.I configDeclaration.h
+ configFlags.I configFlags.h
+ configPage.I configPage.h
+ configPageManager.I configPageManager.h
+ configVariable.I configVariable.h
+ configVariableBase.I configVariableBase.h
+ configVariableBool.I configVariableBool.h
+ configVariableCore.I configVariableCore.h
+ configVariableDouble.I configVariableDouble.h
+ configVariableEnum.I configVariableEnum.h
+ configVariableFilename.I configVariableFilename.h
+ configVariableInt.I configVariableInt.h
+ configVariableInt64.I configVariableInt64.h
+ configVariableList.I configVariableList.h
+ configVariableManager.I configVariableManager.h
+ configVariableSearchPath.I configVariableSearchPath.h
+ configVariableString.I configVariableString.h
+ encryptStreamBuf.h encryptStreamBuf.I encryptStream.h encryptStream.I
+ littleEndian.h
+ nativeNumericData.I nativeNumericData.h
+ pnotify.I pnotify.h
+ notifyCategory.I notifyCategory.h
+ notifyCategoryProxy.I notifyCategoryProxy.h
+ notifySeverity.h
+ prcKeyRegistry.h prcKeyRegistry.I
+ reversedNumericData.I reversedNumericData.h
+ streamReader.I streamReader.h
+ streamWrapper.I streamWrapper.h
+ streamWriter.I streamWriter.h
+ ${CMAKE_CURRENT_BINARY_DIR}/prc_parameters.h
+)
+
+set(P3PRC_SOURCES
+ config_prc.cxx
+ configDeclaration.cxx
+ configFlags.cxx
+ configPage.cxx
+ configPageManager.cxx
+ configVariable.cxx
+ configVariableBase.cxx
+ configVariableBool.cxx
+ configVariableCore.cxx
+ configVariableDouble.cxx
+ configVariableEnum.cxx
+ configVariableFilename.cxx
+ configVariableInt.cxx
+ configVariableInt64.cxx
+ configVariableList.cxx
+ configVariableManager.cxx
+ configVariableSearchPath.cxx
+ configVariableString.cxx
+ nativeNumericData.cxx
+ notify.cxx
+ notifyCategory.cxx
+ notifySeverity.cxx
+ prcKeyRegistry.cxx
+ reversedNumericData.cxx
+ streamReader.cxx streamWrapper.cxx streamWriter.cxx
+)
+
+configure_file(prc_parameters.h.in prc_parameters.h)
+
+if(ANDROID)
+ set(P3PRC_SOURCES ${P3PRC_SOURCES}
+ androidLogStream.cxx)
+endif()
+
+if(HAVE_OPENSSL)
+ list(APPEND P3PRC_SOURCES encryptStreamBuf.cxx encryptStream.cxx)
+endif()
+
+set(P3PRC_IGATEEXT
+ streamReader_ext.cxx
+ streamReader_ext.h
+ streamWriter_ext.cxx
+ streamWriter_ext.h
+)
+
+composite_sources(p3prc P3PRC_SOURCES)
+add_library(p3prc
+ ${P3PRC_HEADERS} ${P3PRC_SOURCES})
+set_target_properties(p3prc PROPERTIES DEFINE_SYMBOL BUILDING_DTOOL_PRC)
+target_include_directories(p3prc PUBLIC $)
+target_link_libraries(p3prc p3dtool PKG::OPENSSL)
+target_interrogate(p3prc ALL EXTENSIONS ${P3PRC_IGATEEXT})
+
+if(ANDROID)
+ target_link_libraries(p3prc log)
+endif()
+
+install(TARGETS p3prc
+ EXPORT Core COMPONENT Core
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT CoreDevel)
+
+install(FILES ${P3PRC_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
+
+# Also install under the old name "p3dtoolconfig"
+# TODO: Remove this once "p3dtoolconfig" is deprecated
+if(WIN32)
+ # Symlinks aren't pretty under WIN32
+ set(_symlink "copy")
+else()
+ set(_symlink "create_symlink")
+endif()
+
+get_target_property(_type p3prc TYPE)
+if(_type STREQUAL "SHARED_LIBRARY")
+
+ set(_suffix "${CMAKE_SHARED_LIBRARY_SUFFIX}")
+ if(UNIX)
+ get_target_property(_soversion p3prc SOVERSION)
+ if(APPLE)
+ set(_suffix ".${_soversion}${_suffix}")
+ else()
+ set(_suffix "${_suffix}.${_soversion}")
+ endif()
+
+ set(_file_genex "TARGET_SONAME_FILE")
+ set(_install_dir "${CMAKE_INSTALL_LIBDIR}")
+
+ else()
+ # Win32?
+ set(_file_genex "TARGET_FILE")
+ set(_install_dir "${CMAKE_INSTALL_BINDIR}")
+
+ endif()
+
+ set(_soname "${CMAKE_SHARED_LIBRARY_PREFIX}p3dtoolconfig${_suffix}")
+
+ add_custom_command(TARGET p3prc POST_BUILD
+ COMMAND "${CMAKE_COMMAND}" -E chdir "$<${_file_genex}_DIR:p3prc>"
+ "${CMAKE_COMMAND}" -E "${_symlink}"
+ "$<${_file_genex}_NAME:p3prc>" "${_soname}"
+ )
+ install(FILES "$<${_file_genex}_DIR:p3prc>/${_soname}"
+ DESTINATION "${_install_dir}")
+endif()
+
+if(WIN32)
+ set(_libname "${CMAKE_IMPORT_LIBRARY_PREFIX}p3dtoolconfig${CMAKE_IMPORT_LIBRARY_SUFFIX}")
+else()
+ set(_libname "${CMAKE_${_type}_PREFIX}p3dtoolconfig${CMAKE_${_type}_SUFFIX}")
+endif()
+add_custom_command(TARGET p3prc POST_BUILD
+ COMMAND "${CMAKE_COMMAND}" -E chdir "$"
+ "${CMAKE_COMMAND}" -E "${_symlink}"
+ "$" "${_libname}"
+)
+install(FILES "$/${_libname}"
+ DESTINATION "${CMAKE_INSTALL_LIBDIR}")
diff --git a/dtool/src/prc/configPageManager.cxx b/dtool/src/prc/configPageManager.cxx
index 737d25026b..39b4adcc6c 100644
--- a/dtool/src/prc/configPageManager.cxx
+++ b/dtool/src/prc/configPageManager.cxx
@@ -162,7 +162,7 @@ reload_implicit_pages() {
_prc_patterns.reserve(pat_list.size());
for (size_t i = 0; i < pat_list.size(); ++i) {
GlobPattern glob(pat_list[i]);
-#ifdef WIN32
+#ifdef _WIN32
// On windows, the file system is case-insensitive, so the pattern
// should be too.
glob.set_case_sensitive(false);
@@ -184,7 +184,7 @@ reload_implicit_pages() {
_prc_encrypted_patterns.reserve(pat_list.size());
for (size_t i = 0; i < pat_list.size(); ++i) {
GlobPattern glob(pat_list[i]);
-#ifdef WIN32
+#ifdef _WIN32
glob.set_case_sensitive(false);
#endif // WIN32
_prc_encrypted_patterns.push_back(glob);
@@ -204,7 +204,7 @@ reload_implicit_pages() {
_prc_executable_patterns.reserve(pat_list.size());
for (size_t i = 0; i < pat_list.size(); ++i) {
GlobPattern glob(pat_list[i]);
-#ifdef WIN32
+#ifdef _WIN32
glob.set_case_sensitive(false);
#endif // WIN32
_prc_executable_patterns.push_back(glob);
@@ -481,7 +481,7 @@ reload_implicit_pages() {
PandaFileStreamBuf::_newline_mode = newline_mode;
#endif // USE_PANDAFILESTREAM
-#ifdef WIN32
+#ifdef _WIN32
// We don't necessarily want an error dialog when we fail to load a .dll
// file. But sometimes it is useful for debugging.
ConfigVariableBool show_dll_error_dialog
diff --git a/dtool/src/prc/notify.cxx b/dtool/src/prc/notify.cxx
index 9c2ea8b79a..eff61c5696 100644
--- a/dtool/src/prc/notify.cxx
+++ b/dtool/src/prc/notify.cxx
@@ -355,7 +355,7 @@ assert_failure(const char *expression, int line,
// Make sure the error message has been flushed to the output.
nout.flush();
-#ifdef WIN32
+#ifdef _MSC_VER
// How to trigger an exception in VC++ that offers to take us into the
// debugger? abort() doesn't do it. We used to be able to assert(false),
// but in VC++ 7 that just throws an exception, and an uncaught exception
@@ -373,9 +373,9 @@ assert_failure(const char *expression, int line,
int *ptr = nullptr;
*ptr = 1;
-#else // WIN32
+#else // _MSC_VER
abort();
-#endif // WIN32
+#endif // _MSC_VER
}
return true;
diff --git a/dtool/src/prc/prc_parameters.h.in b/dtool/src/prc/prc_parameters.h.in
new file mode 100644
index 0000000000..80d4dcdb8d
--- /dev/null
+++ b/dtool/src/prc/prc_parameters.h.in
@@ -0,0 +1,56 @@
+/* prc_parameters.h. Generated automatically by CMake. */
+/********************************** DO NOT EDIT ****************************/
+
+
+/* The compiled-in default directory to look for the Configrc file, in
+ the absence of the PRC_DIR environment variable set, and in
+ the absence of anything specified via the configpath directive. */
+#define DEFAULT_PRC_DIR "@DEFAULT_PRC_DIR@"
+
+/* The compiled-in name of the environment variable(s) that contain
+ the name of a single directory in which to search for prc files. */
+#define PRC_DIR_ENVVARS "@PRC_DIR_ENVVARS@"
+
+/* The compiled-in name of the environment variable(s) that contain
+ the name of multiple directories, separated by DEFAULT_PATHSEP, in
+ which to search for prc files. */
+#define PRC_PATH_ENVVARS "@PRC_PATH_ENVVARS@"
+
+/* This is a special variable that is rarely used; it exists primarily
+ to support the Cygwin-based "ctattach" tools used by the Walt
+ Disney VR Studio. This defines a set of environment variable(s)
+ that define a search path, as above; except that the directory
+ names on these search paths are Panda-style filenames, not
+ Windows-style filenames; and the path separator is always a space
+ character, regardless of DEFAULT_PATHSEP. */
+#define PRC_PATH2_ENVVARS "@PRC_PATH2_ENVVARS@"
+
+/* The filename(s) to search for in the above paths. Normally this is
+ *.prc. */
+#define PRC_PATTERNS "@PRC_PATTERNS@"
+
+/* The filename(s) for encrypted prc files. */
+#define PRC_ENCRYPTED_PATTERNS "@PRC_ENCRYPTED_PATTERNS@"
+
+/* The encryption key used to decrypt any encrypted prc files
+ identified by PRC_ENCRYPTED_PATTERNS. */
+#define PRC_ENCRYPTION_KEY "@PRC_ENCRYPTION_KEY@"
+
+/* The filename(s) to search for, and execute, in the above paths.
+ Normally this is empty. */
+#define PRC_EXECUTABLE_PATTERNS "@PRC_EXECUTABLE_PATTERNS@"
+
+/* The environment variable that defines optional args to pass to
+ executables found that match one of the above patterns. */
+#define PRC_EXECUTABLE_ARGS_ENVVAR "@PRC_EXECUTABLE_ARGS_ENVVAR@"
+
+/* Define if we want to enable the "trust_level" feature of prc config
+ variables. This requires OpenSSL and PRC_PUBLIC_KEYS_FILENAME,
+ above. */
+#cmakedefine PRC_RESPECT_TRUST_LEVEL
+
+/* The trust level value for any legacy (DConfig) variables. */
+#define PRC_DCONFIG_TRUST_LEVEL @PRC_DCONFIG_TRUST_LEVEL@
+
+/* The amount by which we globally increment the trust level. */
+#define PRC_INC_TRUST_LEVEL @PRC_INC_TRUST_LEVEL@
diff --git a/dtool/src/prc/streamWrapper.I b/dtool/src/prc/streamWrapper.I
index 6d2578262c..dcc953fa24 100644
--- a/dtool/src/prc/streamWrapper.I
+++ b/dtool/src/prc/streamWrapper.I
@@ -124,7 +124,7 @@ INLINE OStreamWrapper::
OStreamWrapper(std::ostream *stream, bool owns_pointer, bool stringstream_hack) :
_ostream(stream),
_owns_pointer(owns_pointer)
-#ifdef WIN32_VC
+#ifdef _MSC_VER
, _stringstream_hack(stringstream_hack)
#endif
{
@@ -137,7 +137,7 @@ INLINE OStreamWrapper::
OStreamWrapper(std::ostream &stream) :
_ostream(&stream),
_owns_pointer(false)
-#ifdef WIN32_VC
+#ifdef _MSC_VER
, _stringstream_hack(false)
#endif
{
diff --git a/dtool/src/prc/streamWrapper.cxx b/dtool/src/prc/streamWrapper.cxx
index 3c59fb3a90..2df9ebbe49 100644
--- a/dtool/src/prc/streamWrapper.cxx
+++ b/dtool/src/prc/streamWrapper.cxx
@@ -25,7 +25,7 @@ IStreamWrapper::
// stream pointer does not call the appropriate global delete function;
// instead apparently calling the system delete function. So we call the
// delete function by hand instead.
-#if !defined(WIN32_VC) && !defined(USE_MEMORY_NOWRAPPERS) && defined(REDEFINE_GLOBAL_OPERATOR_NEW)
+#if !defined(_WIN32) && !defined(USE_MEMORY_NOWRAPPERS) && defined(REDEFINE_GLOBAL_OPERATOR_NEW)
_istream->~istream();
(*global_operator_delete)(_istream);
#else
@@ -140,7 +140,7 @@ OStreamWrapper::
// stream pointer does not call the appropriate global delete function;
// instead apparently calling the system delete function. So we call the
// delete function by hand instead.
-#if !defined(WIN32_VC) && !defined(USE_MEMORY_NOWRAPPERS) && defined(REDEFINE_GLOBAL_OPERATOR_NEW)
+#if !defined(_WIN32) && !defined(USE_MEMORY_NOWRAPPERS) && defined(REDEFINE_GLOBAL_OPERATOR_NEW)
_ostream->~ostream();
(*global_operator_delete)(_ostream);
#else
@@ -184,13 +184,13 @@ seek_write(streamsize pos, const char *buffer, streamsize num_bytes,
_ostream->clear();
_ostream->seekp(pos);
-#ifdef WIN32_VC
+#ifdef _MSC_VER
if (_ostream->fail() && _stringstream_hack && pos == 0) {
// Ignore an unsuccessful attempt to seekp(0) if _stringstream_hack is
// true.
_ostream->clear();
}
-#endif // WIN32_VC
+#endif // _MSC_VER
_ostream->write(buffer, num_bytes);
fail = _ostream->fail();
@@ -208,13 +208,13 @@ seek_eof_write(const char *buffer, streamsize num_bytes, bool &fail) {
_ostream->clear();
_ostream->seekp(0, std::ios::end);
-#ifdef WIN32_VC
+#ifdef _MSC_VER
if (_ostream->fail() && _stringstream_hack) {
// Ignore an unsuccessful attempt to seekp(0) if _stringstream_hack is
// true.
_ostream->clear();
}
-#endif // WIN32_VC
+#endif // _MSC_VER
_ostream->write(buffer, num_bytes);
fail = _ostream->fail();
@@ -232,7 +232,7 @@ seek_ppos_eof() {
acquire();
_ostream->seekp(0, std::ios::end);
-#ifdef WIN32_VC
+#ifdef _MSC_VER
if (_ostream->fail() && _stringstream_hack) {
// Ignore an unsuccessful attempt to seekp(0) if _stringstream_hack is
// true.
@@ -240,7 +240,7 @@ seek_ppos_eof() {
release();
return 0;
}
-#endif // WIN32_VC
+#endif // _MSC_VER
pos = _ostream->tellp();
release();
@@ -258,7 +258,7 @@ StreamWrapper::
// stream pointer does not call the appropriate global delete function;
// instead apparently calling the system delete function. So we call the
// delete function by hand instead.
-#if !defined(WIN32_VC) && !defined(USE_MEMORY_NOWRAPPERS) && defined(REDEFINE_GLOBAL_OPERATOR_NEW)
+#if !defined(_WIN32) && !defined(USE_MEMORY_NOWRAPPERS) && defined(REDEFINE_GLOBAL_OPERATOR_NEW)
_iostream->~iostream();
(*global_operator_delete)(_iostream);
#else
diff --git a/dtool/src/prc/streamWrapper.h b/dtool/src/prc/streamWrapper.h
index a837540129..94c7c7fac2 100644
--- a/dtool/src/prc/streamWrapper.h
+++ b/dtool/src/prc/streamWrapper.h
@@ -110,7 +110,7 @@ private:
// until some data has been written to the stream. When this flag is set
// true, we know we have a possibly-empty stringstream, so we allow seekp(0)
// to fail silently, knowing that there's no harm in this case.
-#ifdef WIN32_VC
+#ifdef _MSC_VER
bool _stringstream_hack;
#endif
};
diff --git a/dtool/src/test_interrogate/test_interrogate.cxx b/dtool/src/test_interrogate/test_interrogate.cxx
index 426de102de..a518f12cc4 100644
--- a/dtool/src/test_interrogate/test_interrogate.cxx
+++ b/dtool/src/test_interrogate/test_interrogate.cxx
@@ -582,7 +582,7 @@ main(int argc, char **argv) {
Filename pathname = Filename::dso_filename(argv[i]);
cerr << "Loading " << pathname << "\n";
-#ifdef WIN32
+#ifdef _WIN32
// test_interrogate always wants to show an error dialog.
SetErrorMode(0);
#endif
diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py
index 455d2b31fb..8e88a40930 100755
--- a/makepanda/makepanda.py
+++ b/makepanda/makepanda.py
@@ -397,6 +397,20 @@ elif target == 'linux' and (os.path.isfile("/lib/libc-2.5.so") or os.path.isfile
else:
PLATFORM = 'manylinux1-i686'
+elif target == 'linux' and (os.path.isfile("/lib/libc-2.12.so") or os.path.isfile("/lib64/libc-2.12.so")) and os.path.isdir("/opt/python"):
+ # Same sloppy check for manylinux2010.
+ if GetTargetArch() in ('x86_64', 'amd64'):
+ PLATFORM = 'manylinux2010-x86_64'
+ else:
+ PLATFORM = 'manylinux2010-i686'
+
+elif target == 'linux' and (os.path.isfile("/lib/libc-2.17.so") or os.path.isfile("/lib64/libc-2.17.so")) and os.path.isdir("/opt/python"):
+ # Same sloppy check for manylinux2014.
+ if GetTargetArch() in ('x86_64', 'amd64'):
+ PLATFORM = 'manylinux2014-x86_64'
+ else:
+ PLATFORM = 'manylinux2014-i686'
+
elif not CrossCompiling():
if HasTargetArch():
# Replace the architecture in the platform string.
@@ -797,6 +811,60 @@ if (COMPILER=="GCC"):
elif os.path.isfile(GetThirdpartyDir() + "ffmpeg/lib/libavcodec.a"):
# Needed when linking ffmpeg statically on Linux.
LibName("FFMPEG", "-Wl,-Bsymbolic")
+ # Don't export ffmpeg symbols from libp3ffmpeg when linking statically.
+ for ffmpeg_lib in ffmpeg_libs:
+ LibName("FFMPEG", "-Wl,--exclude-libs,%s.a" % (ffmpeg_lib))
+
+ if GetTarget() != "darwin":
+ for fcollada_lib in fcollada_libs:
+ LibName("FCOLLADA", "-Wl,--exclude-libs,lib%s.a" % (fcollada_lib))
+
+ if not PkgSkip("SWSCALE"):
+ LibName("SWSCALE", "-Wl,--exclude-libs,libswscale.a")
+
+ if not PkgSkip("SWRESAMPLE"):
+ LibName("SWRESAMPLE", "-Wl,--exclude-libs,libswresample.a")
+
+ if not PkgSkip("JPEG"):
+ LibName("JPEG", "-Wl,--exclude-libs,libjpeg.a")
+
+ if not PkgSkip("TIFF"):
+ LibName("TIFF", "-Wl,--exclude-libs,libtiff.a")
+
+ if not PkgSkip("PNG"):
+ LibName("PNG", "-Wl,--exclude-libs,libpng.a")
+ LibName("PNG", "-Wl,--exclude-libs,libpng16.a")
+
+ if not PkgSkip("SQUISH"):
+ LibName("SQUISH", "-Wl,--exclude-libs,libsquish.a")
+
+ if not PkgSkip("OPENEXR"):
+ LibName("OPENEXR", "-Wl,--exclude-libs,libHalf.a")
+ LibName("OPENEXR", "-Wl,--exclude-libs,libIex.a")
+ LibName("OPENEXR", "-Wl,--exclude-libs,libIexMath.a")
+ LibName("OPENEXR", "-Wl,--exclude-libs,libIlmImf.a")
+ LibName("OPENEXR", "-Wl,--exclude-libs,libIlmImfUtil.a")
+ LibName("OPENEXR", "-Wl,--exclude-libs,libIlmThread.a")
+ LibName("OPENEXR", "-Wl,--exclude-libs,libImath.a")
+
+ if not PkgSkip("VORBIS"):
+ LibName("VORBIS", "-Wl,--exclude-libs,libogg.a")
+ LibName("VORBIS", "-Wl,--exclude-libs,libvorbis.a")
+ LibName("VORBIS", "-Wl,--exclude-libs,libvorbisenc.a")
+ LibName("VORBIS", "-Wl,--exclude-libs,libvorbisfile.a")
+
+ if not PkgSkip("OPUS"):
+ LibName("OPUS", "-Wl,--exclude-libs,libogg.a")
+ LibName("OPUS", "-Wl,--exclude-libs,libopus.a")
+ LibName("OPUS", "-Wl,--exclude-libs,libopusfile.a")
+
+ if not PkgSkip("VRPN"):
+ LibName("VRPN", "-Wl,--exclude-libs,libvrpn.a")
+ LibName("VRPN", "-Wl,--exclude-libs,libquat.a")
+
+ if not PkgSkip("ARTOOLKIT"):
+ LibName("ARTOOLKIT", "-Wl,--exclude-libs,libAR.a")
+ LibName("ARTOOLKIT", "-Wl,--exclude-libs,libARMulti.a")
if PkgSkip("FFMPEG") or GetTarget() == "darwin":
cv_lib = ChooseLib(("opencv_core", "cv"), "OPENCV")
@@ -809,10 +877,13 @@ if (COMPILER=="GCC"):
else:
PkgDisable("OPENCV")
- if GetTarget() == "darwin" and not PkgSkip("OPENAL"):
- LibName("OPENAL", "-framework AudioUnit")
- LibName("OPENAL", "-framework AudioToolbox")
- LibName("OPENAL", "-framework CoreAudio")
+ if not PkgSkip("OPENAL"):
+ if GetTarget() == "darwin":
+ LibName("OPENAL", "-framework AudioUnit")
+ LibName("OPENAL", "-framework AudioToolbox")
+ LibName("OPENAL", "-framework CoreAudio")
+ else:
+ LibName("OPENAL", "-Wl,--exclude-libs,libopenal.a")
if not PkgSkip("ASSIMP") and \
os.path.isfile(GetThirdpartyDir() + "assimp/lib/libassimp.a"):
@@ -821,6 +892,10 @@ if (COMPILER=="GCC"):
if os.path.isfile(irrxml):
LibName("ASSIMP", irrxml)
+ if GetTarget() != "darwin":
+ LibName("ASSIMP", "-Wl,--exclude-libs,libassimp.a")
+ LibName("ASSIMP", "-Wl,--exclude-libs,libIrrXML.a")
+
if not PkgSkip("PYTHON"):
python_lib = SDK["PYTHONVERSION"]
SmartPkgEnable("PYTHON", "", python_lib, (SDK["PYTHONVERSION"], SDK["PYTHONVERSION"] + "/Python.h"))
@@ -833,6 +908,10 @@ if (COMPILER=="GCC"):
SmartPkgEnable("ZLIB", "zlib", ("z"), "zlib.h")
SmartPkgEnable("GTK2", "gtk+-2.0")
+ if not PkgSkip("OPENSSL") and GetTarget() != "darwin":
+ LibName("OPENSSL", "-Wl,--exclude-libs,libssl.a")
+ LibName("OPENSSL", "-Wl,--exclude-libs,libcrypto.a")
+
if GetTarget() != 'darwin':
# CgGL is covered by the Cg framework, and we don't need X11 components on OSX
if not PkgSkip("NVIDIACG"):
@@ -1056,7 +1135,7 @@ def CompileCxx(obj,src,opts):
if ("BIGOBJ" in opts) or GetTargetArch() == 'x64':
cmd += " /bigobj"
- cmd += " /Zm300 /DWIN32_VC /DWIN32"
+ cmd += " /Zm300"
if 'EXCEPTIONS' in opts:
cmd += " /EHsc"
else:
@@ -1065,9 +1144,6 @@ def CompileCxx(obj,src,opts):
if 'RTTI' not in opts:
cmd += " /GR-"
- if GetTargetArch() == 'x64':
- cmd += " /DWIN64_VC /DWIN64"
-
cmd += " /W3 " + BracketNameWithQuotes(src)
oscmd(cmd)
else:
@@ -1148,9 +1224,7 @@ def CompileCxx(obj,src,opts):
cmd += " /Qopt-report:2 /Qopt-report-phase:hlo /Qopt-report-phase:hpo" # some optimization reports
else:
cmd += " /W1 "
- cmd += " /EHa /Zm300 /DWIN32_VC /DWIN32"
- if GetTargetArch() == 'x64':
- cmd += " /DWIN64_VC /DWIN64"
+ cmd += " /EHa /Zm300"
cmd += " " + BracketNameWithQuotes(src)
oscmd(cmd)
@@ -1389,9 +1463,9 @@ def CompileIgate(woutd,wsrc,opts):
cmd += ' -srcdir %s -I%s' % (srcdir, srcdir)
cmd += ' -DCPPPARSER -D__STDC__=1 -D__cplusplus=201103L'
if (COMPILER=="MSVC"):
- cmd += ' -DWIN32_VC -DWIN32 -D_WIN32'
+ cmd += ' -D_WIN32'
if GetTargetArch() == 'x64':
- cmd += ' -DWIN64_VC -DWIN64 -D_WIN64 -D_M_X64 -D_M_AMD64'
+ cmd += ' -D_WIN64 -D_M_X64 -D_M_AMD64'
else:
cmd += ' -D_M_IX86'
# NOTE: this 1600 value is the version number for VC2010.
@@ -2655,14 +2729,28 @@ else:
# otherwise, disable it.
confautoprc = confautoprc.replace('#st#', '#')
-if PkgSkip("ASSIMP"):
+confautoprc = confautoprc.replace('\r\n', '\n')
+
+if PkgSkip("ASSIMP") or GetLinkAllStatic():
confautoprc = confautoprc.replace("load-file-type p3assimp", "#load-file-type p3assimp")
+if PkgSkip("EGG") or GetLinkAllStatic():
+ confautoprc = confautoprc.replace("load-file-type egg pandaegg", "#load-file-type egg pandaegg")
+
+if PkgSkip("PANDATOOL") or PkgSkip("EGG") or GetLinkAllStatic():
+ confautoprc = confautoprc.replace("load-file-type p3ptloader", "#load-file-type p3ptloader")
+
+if PkgSkip("FFMPEG") or GetLinkAllStatic():
+ confautoprc = confautoprc.replace("load-audio-type * p3ffmpeg", "#load-audio-type * p3ffmpeg")
+ confautoprc = confautoprc.replace("load-video-type * p3ffmpeg", "#load-video-type * p3ffmpeg")
+
if (os.path.isfile("makepanda/myconfig.in")):
configprc = ReadFile("makepanda/myconfig.in")
else:
configprc = ReadFile("makepanda/config.in")
+configprc = configprc.replace('\r\n', '\n')
+
if (GetTarget() == 'windows'):
configprc = configprc.replace("$XDG_CACHE_HOME/panda3d", "$USER_APPDATA/Panda3D-%s" % MAJOR_VERSION)
else:
@@ -2671,6 +2759,21 @@ else:
if (GetTarget() == 'darwin'):
configprc = configprc.replace("$XDG_CACHE_HOME/panda3d", "$HOME/Library/Caches/Panda3D-%s" % MAJOR_VERSION)
+if PkgSkip("GL") or GetLinkAllStatic():
+ configprc = configprc.replace("\nload-display pandagl", "\n#load-display pandagl")
+
+if PkgSkip("GLES") or GetLinkAllStatic():
+ configprc = configprc.replace("\n#load-display pandagles", "")
+
+if PkgSkip("DX9") or GetLinkAllStatic():
+ configprc = configprc.replace("\n#load-display pandadx9", "")
+
+if PkgSkip("TINYDISPLAY") or GetLinkAllStatic():
+ configprc = configprc.replace("\n#load-display p3tinydisplay", "")
+
+if PkgSkip("OPENAL") or GetLinkAllStatic():
+ configprc = configprc.replace("audio-library-name p3openal_audio", "#audio-library-name p3openal_audio")
+
if GetTarget() == 'windows':
# Convert to Windows newlines.
ConditionalWriteFile(GetOutputDir()+"/etc/Config.prc", configprc, newline='\r\n')
@@ -3207,7 +3310,7 @@ TargetAdd('interrogate.exe', input='interrogate_composite2.obj')
TargetAdd('interrogate.exe', input='libp3cppParser.ilb')
TargetAdd('interrogate.exe', input=COMMON_DTOOL_LIBS)
TargetAdd('interrogate.exe', input='libp3interrogatedb.dll')
-TargetAdd('interrogate.exe', opts=['ADVAPI', 'OPENSSL', 'WINSHELL', 'WINGDI', 'WINUSER'])
+TargetAdd('interrogate.exe', opts=['ADVAPI', 'WINSHELL', 'WINGDI', 'WINUSER'])
preamble = WriteEmbeddedStringFile('interrogate_preamble_python_native', inputs=[
'dtool/src/interrogatedb/py_panda.cxx',
@@ -3222,14 +3325,14 @@ TargetAdd('interrogate_module.exe', input='interrogate_module_preamble_python_na
TargetAdd('interrogate_module.exe', input='libp3cppParser.ilb')
TargetAdd('interrogate_module.exe', input=COMMON_DTOOL_LIBS)
TargetAdd('interrogate_module.exe', input='libp3interrogatedb.dll')
-TargetAdd('interrogate_module.exe', opts=['ADVAPI', 'OPENSSL', 'WINSHELL', 'WINGDI', 'WINUSER'])
+TargetAdd('interrogate_module.exe', opts=['ADVAPI', 'WINSHELL', 'WINGDI', 'WINUSER'])
TargetAdd('parse_file_parse_file.obj', opts=OPTS, input='parse_file.cxx')
TargetAdd('parse_file.exe', input='parse_file_parse_file.obj')
TargetAdd('parse_file.exe', input='libp3cppParser.ilb')
TargetAdd('parse_file.exe', input=COMMON_DTOOL_LIBS)
TargetAdd('parse_file.exe', input='libp3interrogatedb.dll')
-TargetAdd('parse_file.exe', opts=['ADVAPI', 'OPENSSL', 'WINSHELL', 'WINGDI', 'WINUSER'])
+TargetAdd('parse_file.exe', opts=['ADVAPI', 'WINSHELL', 'WINGDI', 'WINUSER'])
#
# DIRECTORY: dtool/src/prckeys/
@@ -3240,7 +3343,7 @@ if (PkgSkip("OPENSSL")==0):
TargetAdd('make-prc-key_makePrcKey.obj', opts=OPTS, input='makePrcKey.cxx')
TargetAdd('make-prc-key.exe', input='make-prc-key_makePrcKey.obj')
TargetAdd('make-prc-key.exe', input=COMMON_DTOOL_LIBS)
- TargetAdd('make-prc-key.exe', opts=['ADVAPI', 'OPENSSL', 'WINSHELL', 'WINGDI', 'WINUSER'])
+ TargetAdd('make-prc-key.exe', opts=['ADVAPI', 'OPENSSL', 'WINSHELL', 'WINGDI', 'WINUSER'])
#
# DIRECTORY: dtool/src/test_interrogate/
@@ -3251,7 +3354,7 @@ TargetAdd('test_interrogate_test_interrogate.obj', opts=OPTS, input='test_interr
TargetAdd('test_interrogate.exe', input='test_interrogate_test_interrogate.obj')
TargetAdd('test_interrogate.exe', input='libp3interrogatedb.dll')
TargetAdd('test_interrogate.exe', input=COMMON_DTOOL_LIBS)
-TargetAdd('test_interrogate.exe', opts=['ADVAPI', 'OPENSSL', 'WINSHELL', 'WINGDI', 'WINUSER'])
+TargetAdd('test_interrogate.exe', opts=['ADVAPI', 'WINSHELL', 'WINGDI', 'WINUSER'])
#
# DIRECTORY: dtool/src/dtoolbase/
@@ -3352,7 +3455,7 @@ TargetAdd('libpandaexpress.dll', input='p3express_composite1.obj')
TargetAdd('libpandaexpress.dll', input='p3express_composite2.obj')
TargetAdd('libpandaexpress.dll', input='p3pandabase_pandabase.obj')
TargetAdd('libpandaexpress.dll', input=COMMON_DTOOL_LIBS)
-TargetAdd('libpandaexpress.dll', opts=['ADVAPI', 'WINSOCK2', 'OPENSSL', 'ZLIB', 'WINGDI', 'WINUSER', 'ANDROID'])
+TargetAdd('libpandaexpress.dll', opts=['ADVAPI', 'WINSOCK2', 'OPENSSL', 'ZLIB', 'WINGDI', 'WINUSER', 'ANDROID'])
#
# DIRECTORY: panda/src/pipeline/
@@ -3478,10 +3581,10 @@ PyTargetAdd('p3pnmimage_pfmFile_ext.obj', opts=OPTS, input='pfmFile_ext.cxx')
# DIRECTORY: panda/src/nativenet/
#
-OPTS=['DIR:panda/src/nativenet', 'OPENSSL', 'BUILDING:PANDA']
+OPTS=['DIR:panda/src/nativenet', 'BUILDING:PANDA']
TargetAdd('p3nativenet_composite1.obj', opts=OPTS, input='p3nativenet_composite1.cxx')
-OPTS=['DIR:panda/src/nativenet', 'OPENSSL']
+OPTS=['DIR:panda/src/nativenet']
IGATEFILES=GetDirectoryContents('panda/src/nativenet', ["*.h", "*_composite*.cxx"])
TargetAdd('libp3nativenet.in', opts=OPTS, input=IGATEFILES)
TargetAdd('libp3nativenet.in', opts=['IMOD:panda3d.core', 'ILIB:libp3nativenet', 'SRCDIR:panda/src/nativenet'])
@@ -3794,7 +3897,7 @@ TargetAdd('libp3dxml.in', opts=['IMOD:panda3d.core', 'ILIB:libp3dxml', 'SRCDIR:p
#
OPTS=['DIR:panda/metalibs/panda', 'BUILDING:PANDA', 'JPEG', 'PNG', 'HARFBUZZ',
- 'TIFF', 'OPENEXR', 'ZLIB', 'OPENSSL', 'FREETYPE', 'FFTW', 'ADVAPI', 'WINSOCK2',
+ 'TIFF', 'OPENEXR', 'ZLIB', 'FREETYPE', 'FFTW', 'ADVAPI', 'WINSOCK2',
'SQUISH', 'NVIDIACG', 'VORBIS', 'OPUS', 'WINUSER', 'WINMM', 'WINGDI', 'IPHLPAPI',
'SETUPAPI', 'IOKIT']
@@ -4151,7 +4254,7 @@ if PkgSkip("OPENAL") == 0:
#
if (PkgSkip("OPENSSL")==0 and PkgSkip("DEPLOYTOOLS")==0):
- OPTS=['DIR:panda/src/downloadertools', 'OPENSSL', 'ADVAPI', 'WINSOCK2', 'WINSHELL', 'WINGDI', 'WINUSER']
+ OPTS=['DIR:panda/src/downloadertools', 'ADVAPI', 'WINSOCK2', 'WINSHELL', 'WINGDI', 'WINUSER']
TargetAdd('pdecrypt_pdecrypt.obj', opts=OPTS, input='pdecrypt.cxx')
TargetAdd('pdecrypt.exe', input=['pdecrypt_pdecrypt.obj'])
@@ -4168,7 +4271,7 @@ if (PkgSkip("OPENSSL")==0 and PkgSkip("DEPLOYTOOLS")==0):
#
if (PkgSkip("ZLIB")==0 and PkgSkip("DEPLOYTOOLS")==0):
- OPTS=['DIR:panda/src/downloadertools', 'ZLIB', 'OPENSSL', 'ADVAPI', 'WINSOCK2', 'WINSHELL', 'WINGDI', 'WINUSER']
+ OPTS=['DIR:panda/src/downloadertools', 'ZLIB', 'ADVAPI', 'WINSOCK2', 'WINSHELL', 'WINGDI', 'WINUSER']
TargetAdd('multify_multify.obj', opts=OPTS, input='multify.cxx')
TargetAdd('multify.exe', input=['multify_multify.obj'])
@@ -4717,7 +4820,7 @@ if (PkgSkip("DIRECT")==0):
OPTS=['DIR:direct/src/dcparser', 'BUILDING:DIRECT_DCPARSER', 'WITHINPANDA', 'BISONPREFIX_dcyy']
CreateFile(GetOutputDir()+"/include/dcParser.h")
TargetAdd('p3dcparser_dcParser.obj', opts=OPTS, input='dcParser.yxx')
- #TargetAdd('dcParser.h', input='p3dcparser_dcParser.obj', opts=['DEPENDENCYONLY'])
+ TargetAdd('dcParser.h', input='p3dcparser_dcParser.obj', opts=['DEPENDENCYONLY'])
TargetAdd('p3dcparser_dcLexer.obj', opts=OPTS, input='dcLexer.lxx')
TargetAdd('p3dcparser_composite1.obj', opts=OPTS, input='p3dcparser_composite1.cxx')
TargetAdd('p3dcparser_composite2.obj', opts=OPTS, input='p3dcparser_composite2.cxx')
@@ -4748,10 +4851,10 @@ if (PkgSkip("DIRECT")==0):
#
if (PkgSkip("DIRECT")==0):
- OPTS=['DIR:direct/src/distributed', 'DIR:direct/src/dcparser', 'WITHINPANDA', 'BUILDING:DIRECT', 'OPENSSL']
+ OPTS=['DIR:direct/src/distributed', 'DIR:direct/src/dcparser', 'WITHINPANDA', 'BUILDING:DIRECT']
TargetAdd('p3distributed_config_distributed.obj', opts=OPTS, input='config_distributed.cxx')
- OPTS=['DIR:direct/src/distributed', 'WITHINPANDA', 'OPENSSL']
+ OPTS=['DIR:direct/src/distributed', 'WITHINPANDA']
IGATEFILES=GetDirectoryContents('direct/src/distributed', ["*.h", "*.cxx"])
TargetAdd('libp3distributed.in', opts=OPTS, input=IGATEFILES)
TargetAdd('libp3distributed.in', opts=['IMOD:panda3d.direct', 'ILIB:libp3distributed', 'SRCDIR:direct/src/distributed'])
@@ -4819,7 +4922,7 @@ if (PkgSkip("DIRECT")==0):
TargetAdd('libp3direct.dll', input='p3motiontrail_config_motiontrail.obj')
TargetAdd('libp3direct.dll', input='p3motiontrail_cMotionTrail.obj')
TargetAdd('libp3direct.dll', input=COMMON_PANDA_LIBS)
- TargetAdd('libp3direct.dll', opts=['ADVAPI', 'OPENSSL', 'WINUSER', 'WINGDI'])
+ TargetAdd('libp3direct.dll', opts=['ADVAPI', 'WINUSER', 'WINGDI'])
PyTargetAdd('direct_module.obj', input='libp3dcparser.in')
PyTargetAdd('direct_module.obj', input='libp3showbase.in')
@@ -4847,7 +4950,7 @@ if (PkgSkip("DIRECT")==0):
PyTargetAdd('direct.pyd', input='libp3direct.dll')
PyTargetAdd('direct.pyd', input='libp3interrogatedb.dll')
PyTargetAdd('direct.pyd', input=COMMON_PANDA_LIBS)
- PyTargetAdd('direct.pyd', opts=['OPENSSL', 'WINUSER', 'WINGDI', 'WINSOCK2'])
+ PyTargetAdd('direct.pyd', opts=['WINUSER', 'WINGDI', 'WINSOCK2'])
#
# DIRECTORY: direct/src/dcparse/
diff --git a/makepanda/makepanda.vcproj b/makepanda/makepanda.vcproj
index 288a50784d..f777f99a85 100644
--- a/makepanda/makepanda.vcproj
+++ b/makepanda/makepanda.vcproj
@@ -3848,7 +3848,6 @@
-
@@ -3859,7 +3858,6 @@
-
diff --git a/makepanda/makewheel.py b/makepanda/makewheel.py
index f1129a133d..a62417588f 100644
--- a/makepanda/makewheel.py
+++ b/makepanda/makewheel.py
@@ -92,7 +92,7 @@ EXCLUDE_EXT = [".pyc", ".pyo", ".N", ".prebuilt", ".xcf", ".plist", ".vcproj", "
# Plug-ins to install.
PLUGIN_LIBS = ["pandagl", "pandagles", "pandagles2", "pandadx9", "p3tinydisplay", "p3ptloader", "p3assimp", "p3ffmpeg", "p3openal_audio", "p3fmod_audio"]
-# Libraries included in manylinux ABI that should be ignored. See PEP 513/571.
+# Libraries included in manylinux ABI that should be ignored. See PEP 513/571/599.
MANYLINUX_LIBS = [
"libgcc_s.so.1", "libstdc++.so.6", "libm.so.6", "libdl.so.2", "librt.so.1",
"libcrypt.so.1", "libc.so.6", "libnsl.so.1", "libutil.so.1",
@@ -530,10 +530,14 @@ def makewheel(version, output_dir, platform=None):
else:
print("Could not find platform.dat in build directory")
platform = get_platform()
- if platform.startswith("linux-"):
- # Is this manylinux1?
- if os.path.isfile("/lib/libc-2.5.so") and os.path.isdir("/opt/python"):
+ if platform.startswith("linux-") and os.path.isdir("/opt/python"):
+ # Is this manylinux?
+ if os.path.isfile("/lib/libc-2.5.so") or os.path.isfile("/lib64/libc-2.5.so"):
platform = platform.replace("linux", "manylinux1")
+ elif os.path.isfile("/lib/libc-2.12.so") or os.path.isfile("/lib64/libc-2.12.so"):
+ platform = platform.replace("linux", "manylinux2010")
+ elif os.path.isfile("/lib/libc-2.17.so") or os.path.isfile("/lib64/libc-2.17.so"):
+ platform = platform.replace("linux", "manylinux2014")
platform = platform.replace('-', '_').replace('.', '_')
@@ -735,7 +739,12 @@ if __debug__:
pylib_path = os.path.join(get_config_var('LIBDIR'), pylib_name)
else:
pylib_name = get_config_var('LDLIBRARY')
- pylib_path = os.path.join(get_config_var('LIBDIR'), pylib_name)
+ pylib_arch = get_config_var('MULTIARCH')
+ libdir = get_config_var('LIBDIR')
+ if pylib_arch and os.path.exists(os.path.join(libdir, pylib_arch, pylib_name)):
+ pylib_path = os.path.join(libdir, pylib_arch, pylib_name)
+ else:
+ pylib_path = os.path.join(libdir, pylib_name)
whl.write_file('deploy_libs/' + pylib_name, pylib_path)
whl.close()
diff --git a/makepanda/selfdestruct.py b/makepanda/selfdestruct.py
new file mode 100755
index 0000000000..67d0303c20
--- /dev/null
+++ b/makepanda/selfdestruct.py
@@ -0,0 +1,47 @@
+#!/usr/bin/env python2
+
+import os
+import re
+import sys
+import shutil
+
+# Ensure user WANTS th
+if len(sys.argv) < 2 or sys.argv[1] != '--yes':
+ print('======== MAKEPANDA SELF-DESTRUCT ========')
+ print('This script will destroy every trace of')
+ print('makepanda from the Panda3D directory that')
+ print('contains it. This is for testing CMake\'s')
+ print('dependencies and fully removing makepanda')
+ print('should the latter buildsystem no longer')
+ print('be desired.')
+ print('')
+ print('If you are sure, pass --yes')
+ sys.exit(1)
+
+# Some sanity-checks to make sure this script is in the right location:
+scriptdir = os.path.abspath(os.path.dirname(__file__))
+assert os.path.split(scriptdir)[1] == 'makepanda'
+root = os.path.dirname(scriptdir)
+assert os.path.isfile(os.path.join(root, 'LICENSE'))
+assert os.path.isdir(os.path.join(root, 'pandatool'))
+
+# Now we get to work! First, the makepanda directory isn't needed:
+shutil.rmtree(os.path.join(root, 'makepanda'))
+
+# Then we look under each of the separate project trees:
+projects = ['contrib', 'direct', 'dtool', 'panda', 'pandatool']
+for project in projects:
+ # Remove non-CMakeLists.txt files from */metalibs/*/
+ for path, dirs, files in os.walk(os.path.join(root, project, 'metalibs')):
+ for filename in files:
+ if filename.lower() != 'cmakelists.txt':
+ os.unlink(os.path.join(path, filename))
+ # Unlink the directory itself, if empty
+ if not os.listdir(path):
+ os.rmdir(path)
+
+ for path, dirs, files in os.walk(os.path.join(root, project)):
+ # Get rid of _composite#.cxx files
+ for filename in files:
+ if re.match(r'.*_composite[0-9]*\.(cxx|h|mm)', filename):
+ os.unlink(os.path.join(path, filename))
diff --git a/panda/CMakeLists.txt b/panda/CMakeLists.txt
new file mode 100644
index 0000000000..a545ef14bd
--- /dev/null
+++ b/panda/CMakeLists.txt
@@ -0,0 +1,174 @@
+if(NOT BUILD_DTOOL)
+ message(FATAL_ERROR "Cannot build panda without dtool! Please enable the BUILD_DTOOL option.")
+endif()
+
+# Include panda source directories
+add_subdirectory(src/audio)
+add_subdirectory(src/audiotraits)
+add_subdirectory(src/chan)
+add_subdirectory(src/char)
+add_subdirectory(src/cocoadisplay)
+add_subdirectory(src/collide)
+add_subdirectory(src/configfiles)
+add_subdirectory(src/cull)
+add_subdirectory(src/device)
+add_subdirectory(src/dgraph)
+add_subdirectory(src/display)
+add_subdirectory(src/distort)
+add_subdirectory(src/downloader)
+add_subdirectory(src/downloadertools)
+add_subdirectory(src/dxgsg9)
+add_subdirectory(src/dxml)
+add_subdirectory(src/egg)
+add_subdirectory(src/egg2pg)
+add_subdirectory(src/egldisplay)
+add_subdirectory(src/event)
+add_subdirectory(src/express)
+add_subdirectory(src/ffmpeg)
+add_subdirectory(src/framework)
+add_subdirectory(src/glesgsg)
+add_subdirectory(src/gles2gsg)
+add_subdirectory(src/glgsg)
+add_subdirectory(src/glstuff)
+add_subdirectory(src/glxdisplay)
+add_subdirectory(src/gobj)
+add_subdirectory(src/grutil)
+add_subdirectory(src/gsgbase)
+add_subdirectory(src/linmath)
+add_subdirectory(src/mathutil)
+add_subdirectory(src/movies)
+add_subdirectory(src/nativenet)
+add_subdirectory(src/net)
+add_subdirectory(src/pandabase)
+add_subdirectory(src/parametrics)
+add_subdirectory(src/pgraph)
+add_subdirectory(src/pgraphnodes)
+add_subdirectory(src/pgui)
+add_subdirectory(src/pipeline)
+add_subdirectory(src/pnmimage)
+add_subdirectory(src/pnmimagetypes)
+add_subdirectory(src/pnmtext)
+add_subdirectory(src/pstatclient)
+add_subdirectory(src/putil)
+add_subdirectory(src/recorder)
+add_subdirectory(src/testbed)
+add_subdirectory(src/text)
+add_subdirectory(src/tform)
+add_subdirectory(src/vision)
+add_subdirectory(src/vrpn)
+add_subdirectory(src/wgldisplay)
+add_subdirectory(src/windisplay)
+add_subdirectory(src/x11display)
+
+# For other components
+# bullet
+add_subdirectory(src/bullet)
+# ode
+add_subdirectory(src/ode)
+# physics
+add_subdirectory(src/particlesystem)
+add_subdirectory(src/physics)
+
+# Include panda metalibs
+add_subdirectory(metalibs/panda)
+add_subdirectory(metalibs/pandadx9)
+add_subdirectory(metalibs/pandaegg)
+add_subdirectory(metalibs/pandaexpress)
+add_subdirectory(metalibs/pandagl)
+add_subdirectory(metalibs/pandagles)
+add_subdirectory(metalibs/pandagles2)
+add_subdirectory(metalibs/pandaphysics)
+
+# Now add the Python modules:
+set(CORE_MODULE_COMPONENTS
+ p3chan p3char p3collide p3cull p3device p3dgraph p3display
+ p3downloader p3dxml p3event p3express p3gobj p3grutil p3gsgbase p3linmath
+ p3mathutil p3movies p3parametrics p3pgraph p3pgraphnodes p3pgui
+ p3pipeline p3pnmimage p3pstatclient p3putil p3recorder p3text p3tform
+ p3prc p3dtoolutil p3dtoolbase
+)
+
+if(WANT_NATIVE_NET)
+ list(APPEND CORE_MODULE_COMPONENTS p3nativenet)
+ if(HAVE_NET)
+ list(APPEND CORE_MODULE_COMPONENTS p3net)
+ endif()
+endif()
+
+if(HAVE_AUDIO)
+ list(APPEND CORE_MODULE_COMPONENTS p3audio)
+endif()
+
+if(HAVE_FREETYPE)
+ list(APPEND CORE_MODULE_COMPONENTS p3pnmtext)
+endif()
+
+if(INTERROGATE_PYTHON_INTERFACE)
+ add_python_module(panda3d.core ${CORE_MODULE_COMPONENTS} LINK panda)
+
+ # Generate our __init__.py
+ if(WIN32)
+ file(READ "${PROJECT_SOURCE_DIR}/cmake/templates/win32_python/__init__.py" win32_init)
+ else()
+ set(win32_init "")
+ endif()
+
+ file(WRITE "${PROJECT_BINARY_DIR}/panda3d/__init__.py"
+ "\"Python bindings for the Panda3D libraries\"
+
+__version__ = '${PROJECT_VERSION}'
+
+if __debug__:
+ import sys
+ if sys.version_info < (3, 0):
+ sys.stderr.write('''\\
+WARNING: Python 2.7 has reached EOL as of January 1, 2020.
+To suppress this warning, upgrade to Python 3.
+''')
+ sys.stdout.flush()
+ del sys
+
+${win32_init}")
+
+ if(BUILD_SHARED_LIBS)
+ install_python_package(panda3d ARCH)
+ endif()
+
+ if(HAVE_BULLET)
+ add_python_module(panda3d.bullet p3bullet IMPORT panda3d.core COMPONENT BulletPython)
+
+ export_targets(BulletPython NAMESPACE "Panda3D::Python::" COMPONENT BulletDevel)
+ endif()
+
+ if(HAVE_EGG)
+ add_python_module(panda3d.egg p3egg p3egg2pg LINK pandaegg IMPORT panda3d.core COMPONENT EggPython)
+
+ export_targets(EggPython NAMESPACE "Panda3D::Python::" COMPONENT EggDevel)
+ endif()
+
+ add_python_module(panda3d.fx pandafx IMPORT panda3d.core)
+ add_python_module(panda3d.physics p3physics p3particlesystem LINK pandaphysics IMPORT panda3d.core)
+
+ if(HAVE_ODE)
+ add_python_module(panda3d.ode p3ode IMPORT panda3d.core COMPONENT ODEPython)
+
+ export_targets(ODEPython NAMESPACE "Panda3D::Python::" COMPONENT ODEDevel)
+ endif()
+
+ if(HAVE_OPENCV OR HAVE_ARTOOLKIT)
+ add_python_module(panda3d.vision p3vision IMPORT panda3d.core COMPONENT VisionPython)
+
+ export_targets(VisionPython NAMESPACE "Panda3D::Python::" COMPONENT VisionDevel)
+ endif()
+
+ if(HAVE_VRPN)
+ add_python_module(panda3d.vrpn p3vrpn IMPORT panda3d.core COMPONENT VRPNPython)
+ set_target_properties(panda3d.vrpn PROPERTIES CXX_EXCEPTIONS ON)
+
+ export_targets(VRPNPython NAMESPACE "Panda3D::Python::" COMPONENT VRPNDevel)
+ endif()
+
+ export_targets(Python NAMESPACE "Panda3D::Python::" COMPONENT CoreDevel)
+endif()
+
+export_targets(Core COMPONENT CoreDevel)
diff --git a/panda/metalibs/panda/CMakeLists.txt b/panda/metalibs/panda/CMakeLists.txt
new file mode 100644
index 0000000000..d9dd160c8b
--- /dev/null
+++ b/panda/metalibs/panda/CMakeLists.txt
@@ -0,0 +1,32 @@
+set(PANDA_LINK_TARGETS
+ p3chan p3char p3collide p3cull p3device p3dgraph p3display p3dxml
+ p3event p3gobj p3grutil p3gsgbase p3linmath p3mathutil
+ p3movies p3parametrics p3pgraph p3pgraphnodes p3pgui p3pipeline
+ p3pnmimage p3pnmimagetypes p3pstatclient p3putil p3recorder p3text p3tform
+)
+
+if(WANT_NATIVE_NET)
+ list(APPEND PANDA_LINK_TARGETS p3nativenet)
+ if(HAVE_NET)
+ list(APPEND PANDA_LINK_TARGETS p3net)
+ endif()
+endif()
+
+if(HAVE_AUDIO)
+ list(APPEND PANDA_LINK_TARGETS p3audio)
+endif()
+
+if(HAVE_FREETYPE)
+ list(APPEND PANDA_LINK_TARGETS p3pnmtext)
+endif()
+
+set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME "CoreDevel")
+add_metalib(panda INIT init_libpanda panda.h COMPONENTS ${PANDA_LINK_TARGETS})
+unset(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME)
+
+install(TARGETS panda
+ EXPORT Core COMPONENT Core
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT CoreDevel)
diff --git a/panda/metalibs/pandadx9/CMakeLists.txt b/panda/metalibs/pandadx9/CMakeLists.txt
new file mode 100644
index 0000000000..70c8e2ff3a
--- /dev/null
+++ b/panda/metalibs/pandadx9/CMakeLists.txt
@@ -0,0 +1,18 @@
+if(NOT HAVE_DX9)
+ return()
+endif()
+
+set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME "DX9Devel")
+add_metalib(pandadx9 ${MODULE_TYPE}
+ INCLUDE wdxGraphicsPipe9.h
+ INIT init_libpandadx9 pandadx9.h
+ EXPORT int get_pipe_type_pandadx9 "wdxGraphicsPipe9::get_class_type().get_index()"
+ COMPONENTS p3dxgsg9 p3windisplay)
+unset(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME)
+
+install(TARGETS pandadx9
+ EXPORT DX9 COMPONENT DX9
+ DESTINATION ${MODULE_DESTINATION}
+ ARCHIVE COMPONENT DX9Devel)
+
+export_targets(DX9 COMPONENT DX9Devel)
diff --git a/panda/metalibs/pandaegg/CMakeLists.txt b/panda/metalibs/pandaegg/CMakeLists.txt
new file mode 100644
index 0000000000..b8c4ba3730
--- /dev/null
+++ b/panda/metalibs/pandaegg/CMakeLists.txt
@@ -0,0 +1,19 @@
+if(NOT HAVE_EGG)
+ return()
+endif()
+
+set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME "EggDevel")
+add_metalib(pandaegg
+ INIT init_libpandaegg pandaegg.h
+ COMPONENTS p3egg p3egg2pg)
+unset(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME)
+target_link_libraries(pandaegg panda)
+
+install(TARGETS pandaegg
+ EXPORT Egg COMPONENT Egg
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT EggDevel)
+
+export_targets(Egg COMPONENT EggDevel)
diff --git a/panda/metalibs/pandaexpress/CMakeLists.txt b/panda/metalibs/pandaexpress/CMakeLists.txt
new file mode 100644
index 0000000000..0132dea0e9
--- /dev/null
+++ b/panda/metalibs/pandaexpress/CMakeLists.txt
@@ -0,0 +1,12 @@
+set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME "CoreDevel")
+add_metalib(pandaexpress
+ INIT init_libpandaexpress pandaexpress.h
+ COMPONENTS p3downloader p3express)
+unset(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME)
+
+install(TARGETS pandaexpress
+ EXPORT Core COMPONENT Core
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT CoreDevel)
diff --git a/panda/metalibs/pandagl/CMakeLists.txt b/panda/metalibs/pandagl/CMakeLists.txt
new file mode 100644
index 0000000000..f3bd4e8db9
--- /dev/null
+++ b/panda/metalibs/pandagl/CMakeLists.txt
@@ -0,0 +1,45 @@
+if(NOT HAVE_GL)
+ return()
+endif()
+
+set(PANDAGL_LINK_TARGETS p3glgsg p3glstuff)
+
+if(HAVE_GLX)
+ list(APPEND PANDAGL_LINK_TARGETS p3glxdisplay p3x11display)
+ set(PANDAGL_PIPE_TYPE "glxGraphicsPipe")
+
+elseif(HAVE_WGL)
+ list(APPEND PANDAGL_LINK_TARGETS p3wgldisplay p3windisplay)
+ set(PANDAGL_PIPE_TYPE "wglGraphicsPipe")
+
+elseif(HAVE_COCOA)
+ list(APPEND PANDAGL_LINK_TARGETS p3cocoadisplay)
+ set(PANDAGL_PIPE_TYPE "CocoaGraphicsPipe")
+ set(PANDAGL_PIPE_INCLUDE "cocoaGraphicsPipe.h")
+
+else()
+ message("") # Add extra line before error
+ message(SEND_ERROR
+ "When compiling with OpenGL (HAVE_GL), at least one of:
+ HAVE_WGL, HAVE_COCOA, or HAVE_GLX must be defined.")
+
+endif()
+
+if(NOT PANDAGL_PIPE_INCLUDE)
+ set(PANDAGL_PIPE_INCLUDE "${PANDAGL_PIPE_TYPE}.h")
+endif()
+
+set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME "OpenGLDevel")
+add_metalib(pandagl ${MODULE_TYPE}
+ INCLUDE "${PANDAGL_PIPE_INCLUDE}"
+ INIT init_libpandagl pandagl.h
+ EXPORT int get_pipe_type_pandagl "${PANDAGL_PIPE_TYPE}::get_class_type().get_index()"
+ COMPONENTS ${PANDAGL_LINK_TARGETS})
+unset(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME)
+
+install(TARGETS pandagl
+ EXPORT OpenGL COMPONENT OpenGL
+ DESTINATION ${MODULE_DESTINATION}
+ ARCHIVE COMPONENT OpenGLDevel)
+
+export_targets(OpenGL NAMESPACE "Panda3D::OpenGL::" COMPONENT OpenGLDevel)
diff --git a/panda/metalibs/pandagles/CMakeLists.txt b/panda/metalibs/pandagles/CMakeLists.txt
new file mode 100644
index 0000000000..d8563d4993
--- /dev/null
+++ b/panda/metalibs/pandagles/CMakeLists.txt
@@ -0,0 +1,28 @@
+if(NOT HAVE_GLES1 OR NOT HAVE_EGL)
+ return()
+endif()
+
+if(ANDROID)
+ set(GLES1_PIPE_TYPE "AndroidGraphicsPipe")
+ set(GLES1_PIPE_INCLUDE "androidGraphicsPipe.h")
+
+else()
+ set(GLES1_PIPE_TYPE "eglGraphicsPipe")
+ set(GLES1_PIPE_INCLUDE "eglGraphicsPipe.h")
+
+endif()
+
+set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME "OpenGLES1Devel")
+add_metalib(pandagles ${MODULE_TYPE}
+ INCLUDE "${GLES1_PIPE_INCLUDE}"
+ INIT init_libpandagles pandagles.h
+ EXPORT int get_pipe_type_pandagles "${GLES1_PIPE_TYPE}::get_class_type().get_index()"
+ COMPONENTS p3egldisplay_gles1 p3glesgsg p3glstuff p3x11display)
+unset(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME)
+
+install(TARGETS pandagles
+ EXPORT OpenGLES1 COMPONENT OpenGLES1
+ DESTINATION ${MODULE_DESTINATION}
+ ARCHIVE COMPONENT OpenGLES1Devel)
+
+export_targets(OpenGLES1 COMPONENT OpenGLES1Devel)
diff --git a/panda/metalibs/pandagles2/CMakeLists.txt b/panda/metalibs/pandagles2/CMakeLists.txt
new file mode 100644
index 0000000000..f3e90f9dfb
--- /dev/null
+++ b/panda/metalibs/pandagles2/CMakeLists.txt
@@ -0,0 +1,18 @@
+if(NOT HAVE_GLES2 OR NOT HAVE_EGL)
+ return()
+endif()
+
+set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME "OpenGLES2Devel")
+add_metalib(pandagles2 ${MODULE_TYPE}
+ INCLUDE eglGraphicsPipe.h
+ INIT init_libpandagles2 pandagles2.h
+ EXPORT int get_pipe_type_pandagles2 "eglGraphicsPipe::get_class_type().get_index()"
+ COMPONENTS p3egldisplay_gles2 p3gles2gsg p3glstuff p3x11display)
+unset(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME)
+
+install(TARGETS pandagles2
+ EXPORT OpenGLES2 COMPONENT OpenGLES2
+ DESTINATION ${MODULE_DESTINATION}
+ ARCHIVE COMPONENT OpenGLES2Devel)
+
+export_targets(OpenGLES2 COMPONENT OpenGLES2Devel)
diff --git a/panda/metalibs/pandaphysics/CMakeLists.txt b/panda/metalibs/pandaphysics/CMakeLists.txt
new file mode 100644
index 0000000000..49041f5973
--- /dev/null
+++ b/panda/metalibs/pandaphysics/CMakeLists.txt
@@ -0,0 +1,12 @@
+set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME "CoreDevel")
+add_metalib(pandaphysics
+ INIT init_libpandaphysics pandaphysics.h
+ COMPONENTS p3physics p3particlesystem)
+unset(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME)
+
+install(TARGETS pandaphysics
+ EXPORT Core COMPONENT Core
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT CoreDevel)
diff --git a/panda/src/audio/CMakeLists.txt b/panda/src/audio/CMakeLists.txt
new file mode 100644
index 0000000000..3d37816b00
--- /dev/null
+++ b/panda/src/audio/CMakeLists.txt
@@ -0,0 +1,39 @@
+if(NOT HAVE_AUDIO)
+ return()
+endif()
+
+set(P3AUDIO_HEADERS
+ config_audio.h
+ filterProperties.h filterProperties.I
+ audioLoadRequest.h audioLoadRequest.I
+ audioManager.h audioManager.I
+ audioSound.h audioSound.I
+ nullAudioManager.h
+ nullAudioSound.h
+)
+
+set(P3AUDIO_SOURCES
+ config_audio.cxx
+ filterProperties.cxx
+ audioLoadRequest.cxx
+ audioManager.cxx
+ audioSound.cxx
+ nullAudioManager.cxx
+ nullAudioSound.cxx
+)
+
+composite_sources(p3audio P3AUDIO_SOURCES)
+add_component_library(p3audio NOINIT SYMBOL BUILDING_PANDA_AUDIO
+ ${P3AUDIO_HEADERS} ${P3AUDIO_SOURCES})
+target_link_libraries(p3audio p3putil p3event p3movies p3linmath)
+target_interrogate(p3audio ALL)
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3audio
+ EXPORT Core COMPONENT Core
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT CoreDevel)
+endif()
+install(FILES ${P3AUDIO_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/panda/src/audio/audioManager.cxx b/panda/src/audio/audioManager.cxx
index cae10e675c..39f7588307 100644
--- a/panda/src/audio/audioManager.cxx
+++ b/panda/src/audio/audioManager.cxx
@@ -21,7 +21,7 @@
#include "config_putil.h"
#include "load_dso.h"
-#ifdef WIN32
+#ifdef _WIN32
#include // For GetSystemDirectory()
#endif
@@ -285,7 +285,7 @@ get_dls_pathname() {
return dls_filename;
}
-#ifdef WIN32
+#ifdef _WIN32
Filename pathname;
// Get the registry key from DirectMusic
diff --git a/panda/src/audio/config_audio.h b/panda/src/audio/config_audio.h
index 895ee000e4..deac9704be 100644
--- a/panda/src/audio/config_audio.h
+++ b/panda/src/audio/config_audio.h
@@ -22,7 +22,7 @@
#include "configVariableString.h"
#include "configVariableFilename.h"
-#if defined(WIN32_VC) || defined(WIN64_VC)
+#ifdef _MVC_VER
#pragma warning (disable : 4231)
#endif
diff --git a/panda/src/audiotraits/CMakeLists.txt b/panda/src/audiotraits/CMakeLists.txt
new file mode 100644
index 0000000000..27b70e1bb6
--- /dev/null
+++ b/panda/src/audiotraits/CMakeLists.txt
@@ -0,0 +1,61 @@
+if(NOT HAVE_AUDIO)
+ return()
+elseif(NOT HAVE_FMODEX AND NOT HAVE_OPENAL)
+ message(SEND_ERROR
+ "You must have an audio backend for audio support! Turn off HAVE_AUDIO to ignore this.")
+endif()
+
+if(HAVE_FMODEX)
+ set(P3FMOD_HEADERS
+ config_fmodAudio.h
+ fmodAudioManager.h
+ fmodAudioSound.I fmodAudioSound.h
+ )
+
+ set(P3FMOD_SOURCES
+ config_fmodAudio.cxx fmodAudioManager.cxx fmodAudioSound.cxx
+ )
+
+ composite_sources(p3fmod_audio P3FMOD_SOURCES)
+ add_library(p3fmod_audio ${MODULE_TYPE} ${P3FMOD_HEADERS} ${P3FMOD_SOURCES})
+ set_target_properties(p3fmod_audio PROPERTIES DEFINE_SYMBOL BUILDING_FMOD_AUDIO)
+ target_link_libraries(p3fmod_audio panda PKG::FMODEX)
+
+ install(TARGETS p3fmod_audio
+ EXPORT FMOD COMPONENT FMOD
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT FMODDevel)
+ install(FILES ${P3FMOD_HEADERS} COMPONENT FMODDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
+
+ export_targets(FMOD NAMESPACE "Panda3D::FMOD::" COMPONENT FMODDevel)
+endif()
+
+if(HAVE_OPENAL)
+ set(P3OPENAL_HEADERS
+ config_openalAudio.h
+ openalAudioManager.h
+ openalAudioSound.I openalAudioSound.h
+ )
+
+ set(P3OPENAL_SOURCES
+ config_openalAudio.cxx openalAudioManager.cxx openalAudioSound.cxx
+ )
+
+
+ composite_sources(p3openal_audio P3OPENAL_SOURCES)
+ add_library(p3openal_audio ${MODULE_TYPE} ${P3OPENAL_HEADERS} ${P3OPENAL_SOURCES})
+ set_target_properties(p3openal_audio PROPERTIES DEFINE_SYMBOL BUILDING_OPENAL_AUDIO)
+ target_link_libraries(p3openal_audio panda PKG::OPENAL)
+
+ install(TARGETS p3openal_audio
+ EXPORT OpenAL COMPONENT OpenAL
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT OpenALDevel)
+ install(FILES ${P3OPENAL_HEADERS} COMPONENT OpenALDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
+
+ export_targets(OpenAL NAMESPACE "Panda3D::OpenAL::" COMPONENT OpenALDevel)
+endif()
diff --git a/panda/src/bullet/CMakeLists.txt b/panda/src/bullet/CMakeLists.txt
new file mode 100644
index 0000000000..26c6b8762e
--- /dev/null
+++ b/panda/src/bullet/CMakeLists.txt
@@ -0,0 +1,130 @@
+if(NOT HAVE_BULLET)
+ return()
+endif()
+
+set(P3BULLET_HEADERS
+ config_bullet.h
+ bullet_includes.h
+ bullet_utils.I bullet_utils.h
+ bulletAllHitsRayResult.I bulletAllHitsRayResult.h
+ bulletBaseCharacterControllerNode.I bulletBaseCharacterControllerNode.h
+ bulletBodyNode.I bulletBodyNode.h
+ bulletBoxShape.I bulletBoxShape.h
+ bulletCapsuleShape.I bulletCapsuleShape.h
+ bulletCharacterControllerNode.I bulletCharacterControllerNode.h
+ bulletClosestHitRayResult.I bulletClosestHitRayResult.h
+ bulletClosestHitSweepResult.I bulletClosestHitSweepResult.h
+ bulletConeShape.I bulletConeShape.h
+ bulletConeTwistConstraint.I bulletConeTwistConstraint.h
+ bulletConstraint.I bulletConstraint.h
+ bulletContactCallbackData.I bulletContactCallbackData.h
+ bulletContactCallbacks.h
+ bulletContactResult.I bulletContactResult.h
+ bulletConvexHullShape.I bulletConvexHullShape.h
+ bulletConvexPointCloudShape.I bulletConvexPointCloudShape.h
+ bulletCylinderShape.I bulletCylinderShape.h
+ bulletDebugNode.I bulletDebugNode.h
+ bulletFilterCallbackData.I bulletFilterCallbackData.h
+ bulletGenericConstraint.I bulletGenericConstraint.h
+ bulletGhostNode.I bulletGhostNode.h
+ bulletHeightfieldShape.I bulletHeightfieldShape.h
+ bulletHelper.I bulletHelper.h
+ bulletHingeConstraint.I bulletHingeConstraint.h
+ bulletManifoldPoint.I bulletManifoldPoint.h
+ bulletMinkowskiSumShape.I bulletMinkowskiSumShape.h
+ bulletMultiSphereShape.I bulletMultiSphereShape.h
+ bulletPersistentManifold.I bulletPersistentManifold.h
+ bulletPlaneShape.I bulletPlaneShape.h
+ bulletRigidBodyNode.I bulletRigidBodyNode.h
+ bulletRotationalLimitMotor.I bulletRotationalLimitMotor.h
+ bulletShape.I bulletShape.h
+ bulletSliderConstraint.I bulletSliderConstraint.h
+ bulletSoftBodyConfig.I bulletSoftBodyConfig.h
+ bulletSoftBodyControl.I bulletSoftBodyControl.h
+ bulletSoftBodyMaterial.I bulletSoftBodyMaterial.h
+ bulletSoftBodyNode.I bulletSoftBodyNode.h
+ bulletSoftBodyShape.I bulletSoftBodyShape.h
+ bulletSoftBodyWorldInfo.I bulletSoftBodyWorldInfo.h
+ bulletSphereShape.I bulletSphereShape.h
+ bulletSphericalConstraint.I bulletSphericalConstraint.h
+ bulletTickCallbackData.I bulletTickCallbackData.h
+ bulletTranslationalLimitMotor.I bulletTranslationalLimitMotor.h
+ bulletTriangleMesh.I bulletTriangleMesh.h
+ bulletTriangleMeshShape.I bulletTriangleMeshShape.h
+ bulletVehicle.I bulletVehicle.h
+ bulletWheel.I bulletWheel.h
+ bulletWorld.I bulletWorld.h
+)
+
+set(P3BULLET_SOURCES
+ config_bullet.cxx
+ bullet_utils.cxx
+ bulletAllHitsRayResult.cxx
+ bulletBaseCharacterControllerNode.cxx
+ bulletBodyNode.cxx
+ bulletBoxShape.cxx
+ bulletCapsuleShape.cxx
+ bulletCharacterControllerNode.cxx
+ bulletClosestHitRayResult.cxx
+ bulletClosestHitSweepResult.cxx
+ bulletConeShape.cxx
+ bulletConeTwistConstraint.cxx
+ bulletConstraint.cxx
+ bulletContactCallbackData.cxx
+ bulletContactResult.cxx
+ bulletConvexHullShape.cxx
+ bulletConvexPointCloudShape.cxx
+ bulletCylinderShape.cxx
+ bulletDebugNode.cxx
+ bulletFilterCallbackData.cxx
+ bulletGenericConstraint.cxx
+ bulletGhostNode.cxx
+ bulletHeightfieldShape.cxx
+ bulletHelper.cxx
+ bulletHingeConstraint.cxx
+ bulletManifoldPoint.cxx
+ bulletMinkowskiSumShape.cxx
+ bulletMultiSphereShape.cxx
+ bulletPersistentManifold.cxx
+ bulletPlaneShape.cxx
+ bulletRigidBodyNode.cxx
+ bulletRotationalLimitMotor.cxx
+ bulletShape.cxx
+ bulletSliderConstraint.cxx
+ bulletSoftBodyConfig.cxx
+ bulletSoftBodyControl.cxx
+ bulletSoftBodyMaterial.cxx
+ bulletSoftBodyNode.cxx
+ bulletSoftBodyShape.cxx
+ bulletSoftBodyWorldInfo.cxx
+ bulletSphereShape.cxx
+ bulletSphericalConstraint.cxx
+ bulletTickCallbackData.cxx
+ bulletTranslationalLimitMotor.cxx
+ bulletTriangleMesh.cxx
+ bulletTriangleMeshShape.cxx
+ bulletVehicle.cxx
+ bulletWheel.cxx
+ bulletWorld.cxx
+)
+
+composite_sources(p3bullet P3BULLET_SOURCES)
+add_library(p3bullet ${P3BULLET_SOURCES} ${P3BULLET_HEADERS})
+set_target_properties(p3bullet PROPERTIES DEFINE_SYMBOL BUILDING_PANDABULLET)
+target_link_libraries(p3bullet panda PKG::BULLET)
+target_interrogate(p3bullet ALL)
+
+if(MSVC AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
+ # Clang emulating MSVC; it has builtin defines for __m128 + __m128 and co.
+ target_compile_definitions(p3bullet PUBLIC BT_NO_SIMD_OPERATOR_OVERLOADS)
+endif()
+
+install(TARGETS p3bullet
+ EXPORT Bullet COMPONENT Bullet
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT BulletDevel)
+install(FILES ${P3BULLET_HEADERS} COMPONENT BulletDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
+
+export_targets(Bullet COMPONENT BulletDevel)
diff --git a/panda/src/bullet/bulletHeightfieldShape.cxx b/panda/src/bullet/bulletHeightfieldShape.cxx
index 08f91bd036..55ed86d16e 100644
--- a/panda/src/bullet/bulletHeightfieldShape.cxx
+++ b/panda/src/bullet/bulletHeightfieldShape.cxx
@@ -200,7 +200,7 @@ fillin(DatagramIterator &scan, BamReader *manager) {
size_t size = (size_t)_num_rows * (size_t)_num_cols;
delete [] _data;
- _data = new float[size];
+ _data = new btScalar[size];
for (size_t i = 0; i < size; ++i) {
_data[i] = scan.get_stdfloat();
diff --git a/panda/src/chan/CMakeLists.txt b/panda/src/chan/CMakeLists.txt
new file mode 100644
index 0000000000..0b1565d198
--- /dev/null
+++ b/panda/src/chan/CMakeLists.txt
@@ -0,0 +1,69 @@
+set(P3CHAN_HEADERS
+ animBundle.I animBundle.h
+ animBundleNode.I animBundleNode.h
+ animChannel.I animChannel.h animChannelBase.I
+ animChannelBase.h
+ animChannelFixed.I animChannelFixed.h
+ animChannelMatrixDynamic.I animChannelMatrixDynamic.h
+ animChannelMatrixFixed.I animChannelMatrixFixed.h
+ animChannelMatrixXfmTable.I animChannelMatrixXfmTable.h
+ animChannelScalarDynamic.I animChannelScalarDynamic.h
+ animChannelScalarTable.I animChannelScalarTable.h
+ animControl.I
+ animControl.h animControlCollection.I
+ animControlCollection.h animGroup.I animGroup.h
+ animPreloadTable.I animPreloadTable.h
+ auto_bind.h
+ bindAnimRequest.I bindAnimRequest.h
+ config_chan.h
+ movingPart.I movingPart.h
+ movingPartBase.I movingPartBase.h
+ movingPartMatrix.I movingPartMatrix.h movingPartScalar.I
+ movingPartScalar.h partBundle.I partBundle.h
+ partBundleHandle.I partBundleHandle.h
+ partBundleNode.I partBundleNode.h
+ partGroup.I partGroup.h
+ partSubset.I partSubset.h
+ vector_PartGroupStar.h
+)
+
+set(P3CHAN_SOURCES
+ animBundle.cxx
+ animBundleNode.cxx
+ animChannel.cxx
+ animChannelBase.cxx
+ animChannelFixed.cxx
+ animChannelMatrixDynamic.cxx
+ animChannelMatrixFixed.cxx
+ animChannelMatrixXfmTable.cxx
+ animChannelScalarDynamic.cxx
+ animChannelScalarTable.cxx
+ animControl.cxx
+ animControlCollection.cxx animGroup.cxx
+ animPreloadTable.cxx
+ auto_bind.cxx
+ bindAnimRequest.cxx
+ config_chan.cxx movingPartBase.cxx movingPartMatrix.cxx
+ movingPartScalar.cxx partBundle.cxx
+ partBundleHandle.cxx
+ partBundleNode.cxx
+ partGroup.cxx
+ partSubset.cxx
+ vector_PartGroupStar.cxx
+)
+
+composite_sources(p3chan P3CHAN_SOURCES)
+add_component_library(p3chan NOINIT SYMBOL BUILDING_PANDA_CHAN
+ ${P3CHAN_HEADERS} ${P3CHAN_SOURCES})
+target_link_libraries(p3chan p3pgraph)
+target_interrogate(p3chan ALL)
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3chan
+ EXPORT Core COMPONENT Core
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT CoreDevel)
+endif()
+install(FILES ${P3CHAN_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/panda/src/chan/animChannelScalarTable.h b/panda/src/chan/animChannelScalarTable.h
index 10e54815e3..db92167f56 100644
--- a/panda/src/chan/animChannelScalarTable.h
+++ b/panda/src/chan/animChannelScalarTable.h
@@ -30,9 +30,10 @@ protected:
AnimChannelScalarTable();
AnimChannelScalarTable(AnimGroup *parent, const AnimChannelScalarTable ©);
-public:
+PUBLISHED:
AnimChannelScalarTable(AnimGroup *parent, const std::string &name);
+public:
virtual bool has_changed(int last_frame, double last_frac,
int this_frame, double this_frac);
virtual void get_value(int frame, PN_stdfloat &value);
diff --git a/panda/src/chan/movingPartScalar.I b/panda/src/chan/movingPartScalar.I
index 1b585746e4..e67dad0562 100644
--- a/panda/src/chan/movingPartScalar.I
+++ b/panda/src/chan/movingPartScalar.I
@@ -25,7 +25,7 @@ MovingPartScalar(const MovingPartScalar ©) :
*/
INLINE MovingPartScalar::
MovingPartScalar(PartGroup *parent, const std::string &name,
- const PN_stdfloat &default_value)
+ PN_stdfloat default_value)
: MovingPart(parent, name, default_value) {
}
diff --git a/panda/src/chan/movingPartScalar.h b/panda/src/chan/movingPartScalar.h
index d05e58f4e7..ee55f2e7b8 100644
--- a/panda/src/chan/movingPartScalar.h
+++ b/panda/src/chan/movingPartScalar.h
@@ -31,7 +31,7 @@ protected:
public:
INLINE MovingPartScalar(PartGroup *parent, const std::string &name,
- const PN_stdfloat &default_value = 0);
+ PN_stdfloat default_value = 0);
virtual ~MovingPartScalar();
virtual void get_blend_value(const PartBundle *root);
diff --git a/panda/src/chan/partBundleNode.I b/panda/src/chan/partBundleNode.I
index e9da42359c..d1e2e5597f 100644
--- a/panda/src/chan/partBundleNode.I
+++ b/panda/src/chan/partBundleNode.I
@@ -46,6 +46,7 @@ PartBundleNode(const PartBundleNode ©) :
*/
INLINE int PartBundleNode::
get_num_bundles() const {
+ LightMutexHolder holder(_lock);
return _bundles.size();
}
@@ -54,6 +55,7 @@ get_num_bundles() const {
*/
INLINE PartBundle *PartBundleNode::
get_bundle(int n) const {
+ LightMutexHolder holder(_lock);
nassertr(n >= 0 && n < (int)_bundles.size(), nullptr);
return _bundles[n]->get_bundle();
}
@@ -65,6 +67,7 @@ get_bundle(int n) const {
*/
INLINE PartBundleHandle *PartBundleNode::
get_bundle_handle(int n) const {
+ LightMutexHolder holder(_lock);
nassertr(n >= 0 && n < (int)_bundles.size(), nullptr);
return _bundles[n];
}
diff --git a/panda/src/chan/partBundleNode.cxx b/panda/src/chan/partBundleNode.cxx
index 9fe5473fe0..5d54b194e4 100644
--- a/panda/src/chan/partBundleNode.cxx
+++ b/panda/src/chan/partBundleNode.cxx
@@ -25,9 +25,9 @@ TypeHandle PartBundleNode::_type_handle;
*/
PartBundleNode::
~PartBundleNode() {
- Bundles::iterator bi;
- for (bi = _bundles.begin(); bi != _bundles.end(); ++bi) {
- (*bi)->get_bundle()->remove_node(this);
+ LightMutexHolder holder(_lock);
+ for (PartBundleHandle *handle : _bundles) {
+ handle->get_bundle()->remove_node(this);
}
}
@@ -44,9 +44,8 @@ void PartBundleNode::
apply_attribs_to_vertices(const AccumulatedAttribs &attribs, int attrib_types,
GeomTransformer &transformer) {
if ((attrib_types & SceneGraphReducer::TT_transform) != 0) {
- Bundles::iterator bi;
- for (bi = _bundles.begin(); bi != _bundles.end(); ++bi) {
- PT(PartBundleHandle) handle = (*bi);
+ LightMutexHolder holder(_lock);
+ for (PT(PartBundleHandle) handle : _bundles) {
PartBundle *bundle = handle->get_bundle();
PT(PartBundle) new_bundle = bundle->apply_transform(attribs._transform);
update_bundle(handle, new_bundle);
@@ -71,9 +70,8 @@ xform(const LMatrix4 &mat) {
return;
}
- Bundles::iterator bi;
- for (bi = _bundles.begin(); bi != _bundles.end(); ++bi) {
- PT(PartBundleHandle) handle = (*bi);
+ LightMutexHolder holder(_lock);
+ for (PT(PartBundleHandle) handle : _bundles) {
PartBundle *bundle = handle->get_bundle();
if (bundle->get_num_nodes() > 1) {
PT(PartBundle) new_bundle = DCAST(PartBundle, bundle->copy_subgraph());
@@ -90,14 +88,15 @@ xform(const LMatrix4 &mat) {
void PartBundleNode::
add_bundle(PartBundle *bundle) {
PT(PartBundleHandle) handle = new PartBundleHandle(bundle);
- add_bundle_handle(handle);
+ LightMutexHolder holder(_lock);
+ do_add_bundle_handle(handle);
}
/**
- *
+ * Assumes the lock is held.
*/
void PartBundleNode::
-add_bundle_handle(PartBundleHandle *handle) {
+do_add_bundle_handle(PartBundleHandle *handle) {
Bundles::iterator bi = find(_bundles.begin(), _bundles.end(), handle);
if (bi != _bundles.end()) {
// This handle is already within the node.
@@ -117,11 +116,15 @@ steal_bundles(PartBundleNode *other) {
return;
}
- Bundles::iterator bi;
- for (bi = other->_bundles.begin(); bi != other->_bundles.end(); ++bi) {
- PartBundleHandle *handle = (*bi);
+ LightMutexHolder other_holder(other->_lock);
+ if (other->_bundles.empty()) {
+ return;
+ }
+
+ LightMutexHolder holder(_lock);
+ for (PartBundleHandle *handle : other->_bundles) {
handle->get_bundle()->remove_node(other);
- add_bundle_handle(handle);
+ do_add_bundle_handle(handle);
}
other->_bundles.clear();
}
@@ -129,6 +132,8 @@ steal_bundles(PartBundleNode *other) {
/**
* Replaces the contents of the indicated PartBundleHandle (presumably stored
* within this node) with new_bundle.
+ *
+ * Assumes the lock is held.
*/
void PartBundleNode::
update_bundle(PartBundleHandle *old_bundle_handle, PartBundle *new_bundle) {
@@ -146,10 +151,10 @@ void PartBundleNode::
write_datagram(BamWriter *manager, Datagram &dg) {
PandaNode::write_datagram(manager, dg);
+ LightMutexHolder holder(_lock);
dg.add_uint16(_bundles.size());
- Bundles::iterator bi;
- for (bi = _bundles.begin(); bi != _bundles.end(); ++bi) {
- manager->write_pointer(dg, (*bi)->get_bundle());
+ for (PartBundleHandle *handle : _bundles) {
+ manager->write_pointer(dg, handle->get_bundle());
}
}
@@ -161,11 +166,11 @@ int PartBundleNode::
complete_pointers(TypedWritable **p_list, BamReader* manager) {
int pi = PandaNode::complete_pointers(p_list, manager);
- Bundles::iterator bi;
- for (bi = _bundles.begin(); bi != _bundles.end(); ++bi) {
+ LightMutexHolder holder(_lock);
+ for (PT(PartBundleHandle) &handle : _bundles) {
PT(PartBundle) bundle = DCAST(PartBundle, p_list[pi++]);
bundle->add_node(this);
- (*bi) = new PartBundleHandle(bundle);
+ handle = new PartBundleHandle(bundle);
}
return pi;
diff --git a/panda/src/chan/partBundleNode.h b/panda/src/chan/partBundleNode.h
index 6cb98638d1..a681af1d7c 100644
--- a/panda/src/chan/partBundleNode.h
+++ b/panda/src/chan/partBundleNode.h
@@ -18,7 +18,7 @@
#include "partBundle.h"
#include "partBundleHandle.h"
-
+#include "lightMutex.h"
#include "pandaNode.h"
#include "dcast.h"
#include "pvector.h"
@@ -59,12 +59,13 @@ PUBLISHED:
protected:
void add_bundle(PartBundle *bundle);
- void add_bundle_handle(PartBundleHandle *handle);
+ void do_add_bundle_handle(PartBundleHandle *handle);
void steal_bundles(PartBundleNode *other);
virtual void update_bundle(PartBundleHandle *old_bundle_handle,
PartBundle *new_bundle);
protected:
+ LightMutex _lock;
typedef pvector< PT(PartBundleHandle) > Bundles;
Bundles _bundles;
diff --git a/panda/src/char/CMakeLists.txt b/panda/src/char/CMakeLists.txt
new file mode 100644
index 0000000000..d33bd470b0
--- /dev/null
+++ b/panda/src/char/CMakeLists.txt
@@ -0,0 +1,36 @@
+set(P3CHAR_HEADERS
+ character.I character.h
+ characterJoint.I characterJoint.h
+ characterJointBundle.I characterJointBundle.h
+ characterJointEffect.h characterJointEffect.I
+ characterSlider.h
+ characterVertexSlider.I characterVertexSlider.h
+ config_char.h
+ jointVertexTransform.I jointVertexTransform.h
+)
+
+set(P3CHAR_SOURCES
+ character.cxx
+ characterJoint.cxx characterJointBundle.cxx
+ characterJointEffect.cxx
+ characterSlider.cxx
+ characterVertexSlider.cxx
+ config_char.cxx
+ jointVertexTransform.cxx
+)
+
+composite_sources(p3char P3CHAR_SOURCES)
+add_component_library(p3char SYMBOL BUILDING_PANDA_CHAR
+ ${P3CHAR_HEADERS} ${P3CHAR_SOURCES})
+target_link_libraries(p3char p3chan)
+target_interrogate(p3char ALL)
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3char
+ EXPORT Core COMPONENT Core
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT CoreDevel)
+endif()
+install(FILES ${P3CHAR_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/panda/src/char/character.cxx b/panda/src/char/character.cxx
index eb894fe99c..d25b4e96ee 100644
--- a/panda/src/char/character.cxx
+++ b/panda/src/char/character.cxx
@@ -44,29 +44,29 @@ Character(const Character ©, bool copy_bundles) :
_lod_delay_factor(copy._lod_delay_factor),
_do_lod_animation(copy._do_lod_animation),
_joints_pcollector(copy._joints_pcollector),
- _skinning_pcollector(copy._skinning_pcollector)
+ _skinning_pcollector(copy._skinning_pcollector),
+ _last_auto_update(-1.0),
+ _view_frame(-1),
+ _view_distance2(0.0f)
{
set_cull_callback();
+ LightMutexHolder holder(copy._lock);
+
if (copy_bundles) {
// Copy the bundle(s).
- int num_bundles = copy.get_num_bundles();
- for (int i = 0; i < num_bundles; ++i) {
- PartBundle *orig_bundle = copy.get_bundle(i);
+ for (PartBundleHandle *handle : copy._bundles) {
+ PartBundle *orig_bundle = handle->get_bundle();
PT(PartBundle) new_bundle = DCAST(PartBundle, orig_bundle->copy_subgraph());
- add_bundle(new_bundle);
+ do_add_bundle_handle(new PartBundleHandle(new_bundle));
}
} else {
// Share the bundles.
- int num_bundles = copy.get_num_bundles();
- for (int i = 0; i < num_bundles; ++i) {
- PartBundle *orig_bundle = copy.get_bundle(i);
- add_bundle(orig_bundle);
+ for (PartBundleHandle *handle : copy._bundles) {
+ PartBundle *orig_bundle = handle->get_bundle();
+ do_add_bundle_handle(new PartBundleHandle(orig_bundle));
}
}
- _last_auto_update = -1.0;
- _view_frame = -1;
- _view_distance2 = 0.0f;
}
/**
@@ -76,13 +76,13 @@ Character::
Character(const std::string &name) :
PartBundleNode(name, new CharacterJointBundle(name)),
_joints_pcollector(PStatCollector(_animation_pcollector, name), "Joints"),
- _skinning_pcollector(PStatCollector(_animation_pcollector, name), "Vertices")
+ _skinning_pcollector(PStatCollector(_animation_pcollector, name), "Vertices"),
+ _last_auto_update(-1.0),
+ _view_frame(-1),
+ _view_distance2(0.0f)
{
set_cull_callback();
clear_lod_animation();
- _last_auto_update = -1.0;
- _view_frame = -1;
- _view_distance2 = 0.0f;
}
/**
@@ -90,9 +90,9 @@ Character(const std::string &name) :
*/
Character::
~Character() {
- int num_bundles = get_num_bundles();
- for (int i = 0; i < num_bundles; ++i) {
- r_clear_joint_characters(get_bundle(i));
+ LightMutexHolder holder(_lock);
+ for (PartBundleHandle *handle : _bundles) {
+ r_clear_joint_characters(handle->get_bundle());
}
}
@@ -237,36 +237,6 @@ calc_tight_bounds(LPoint3 &min_point, LPoint3 &max_point, bool &found_any,
found_any, transform, current_thread);
}
-/**
- * Merges old_bundle with new_bundle. old_bundle must be one of the
- * PartBundles within this node. At the end of this call, the old_bundle
- * pointer within this node will be replaced with the new_bundle pointer, and
- * all geometry within this node will be updated to reference new_bundle.
- *
- * @deprecated Use the newer version of this method, below.
- */
-void Character::
-merge_bundles(PartBundle *old_bundle, PartBundle *new_bundle) {
- if (old_bundle == new_bundle) {
- // Trivially return.
- return;
- }
-
- // Find the PartBundleHandle of old_bundle.
- PT(PartBundleHandle) old_bundle_handle;
- Bundles::const_iterator bi;
- for (bi = _bundles.begin(); bi != _bundles.end(); ++bi) {
- if ((*bi)->get_bundle() == old_bundle) {
- old_bundle_handle = (*bi);
- break;
- }
- }
- nassertv(!old_bundle_handle.is_null());
-
- PT(PartBundleHandle) new_bundle_handle = new PartBundleHandle(new_bundle);
- merge_bundles(old_bundle_handle, new_bundle_handle);
-}
-
/**
* Merges old_bundle_handle->get_bundle() with new_bundle. old_bundle_handle
* must be one of the PartBundleHandle within this node. At the end of this
@@ -293,6 +263,7 @@ merge_bundles(PartBundleHandle *old_bundle_handle,
PartBundle *new_bundle = new_bundle_handle->get_bundle();
new_bundle->merge_anim_preloads(old_bundle);
+ LightMutexHolder holder(_lock);
update_bundle(old_bundle_handle, new_bundle);
}
@@ -356,11 +327,11 @@ clear_lod_animation() {
*/
CharacterJoint *Character::
find_joint(const std::string &name) const {
- int num_bundles = get_num_bundles();
- for (int i = 0; i < num_bundles; ++i) {
- PartGroup *part = get_bundle(i)->find_child(name);
+ LightMutexHolder holder(_lock);
+ for (PartBundleHandle *handle : _bundles) {
+ PartGroup *part = handle->get_bundle()->find_child(name);
if (part != nullptr && part->is_character_joint()) {
- return DCAST(CharacterJoint, part);
+ return (CharacterJoint *)part;
}
}
@@ -374,12 +345,12 @@ find_joint(const std::string &name) const {
*/
CharacterSlider *Character::
find_slider(const std::string &name) const {
- int num_bundles = get_num_bundles();
- for (int i = 0; i < num_bundles; ++i) {
- PartGroup *part = get_bundle(i)->find_child(name);
+ LightMutexHolder holder(_lock);
+ for (PartBundleHandle *handle : _bundles) {
+ PartGroup *part = handle->get_bundle()->find_child(name);
if (part != nullptr &&
part->is_of_type(CharacterSlider::get_class_type())) {
- return DCAST(CharacterSlider, part);
+ return (CharacterSlider *)part;
}
}
@@ -392,9 +363,9 @@ find_slider(const std::string &name) const {
*/
void Character::
write_parts(std::ostream &out) const {
- int num_bundles = get_num_bundles();
- for (int i = 0; i < num_bundles; ++i) {
- get_bundle(i)->write(out, 0);
+ LightMutexHolder holder(_lock);
+ for (PartBundleHandle *handle : _bundles) {
+ handle->get_bundle()->write(out, 0);
}
}
@@ -405,9 +376,9 @@ write_parts(std::ostream &out) const {
*/
void Character::
write_part_values(std::ostream &out) const {
- int num_bundles = get_num_bundles();
- for (int i = 0; i < num_bundles; ++i) {
- get_bundle(i)->write_with_value(out, 0);
+ LightMutexHolder holder(_lock);
+ for (PartBundleHandle *handle : _bundles) {
+ handle->get_bundle()->write_with_value(out, 0);
}
}
@@ -431,6 +402,7 @@ update_to_now() {
*/
void Character::
update() {
+ LightMutexHolder holder(_lock);
double now = ClockObject::get_global_clock()->get_frame_time();
if (now != _last_auto_update) {
_last_auto_update = now;
@@ -451,13 +423,14 @@ update() {
*/
void Character::
force_update() {
+ LightMutexHolder holder(_lock);
+
// Statistics
PStatTimer timer(_joints_pcollector);
// Update all the joints and sliders.
- int num_bundles = get_num_bundles();
- for (int i = 0; i < num_bundles; ++i) {
- get_bundle(i)->force_update();
+ for (PartBundleHandle *handle : _bundles) {
+ handle->get_bundle()->force_update();
}
}
@@ -486,11 +459,13 @@ r_copy_children(const PandaNode *from, PandaNode::InstanceMap &inst_map,
NodeMap node_map;
JointMap joint_map;
- int num_bundles = get_num_bundles();
- nassertv(from_char->get_num_bundles() == num_bundles);
- int i;
- for (i = 0; i < num_bundles; ++i) {
- fill_joint_map(joint_map, get_bundle(i), from_char->get_bundle(i));
+ LightMutexHolder from_holder(from_char->_lock);
+ LightMutexHolder holder(_lock);
+
+ size_t num_bundles = _bundles.size();
+ nassertv(from_char->_bundles.size() == num_bundles);
+ for (size_t i = 0; i < num_bundles; ++i) {
+ fill_joint_map(joint_map, _bundles[i]->get_bundle(), from_char->_bundles[i]->get_bundle());
}
GeomVertexMap gvmap;
@@ -499,14 +474,16 @@ r_copy_children(const PandaNode *from, PandaNode::InstanceMap &inst_map,
r_copy_char(this, from_char, from_char, node_map, joint_map,
gvmap, gjmap, gsmap);
- for (i = 0; i < num_bundles; ++i) {
- copy_node_pointers(node_map, get_bundle(i), from_char->get_bundle(i));
+ for (size_t i = 0; i < num_bundles; ++i) {
+ copy_node_pointers(node_map, _bundles[i]->get_bundle(), from_char->_bundles[i]->get_bundle());
}
}
/**
* Replaces the contents of the indicated PartBundleHandle (presumably stored
* within this node) with new_bundle.
+ *
+ * Assumes the lock is held.
*/
void Character::
update_bundle(PartBundleHandle *old_bundle_handle, PartBundle *new_bundle) {
@@ -560,20 +537,18 @@ get_rel_transform(CullTraverser *trav, CullTraverserData &data) {
/**
* The actual implementation of update(). Assumes the appropriate
- * PStatCollector has already been started.
+ * PStatCollector has already been started, and that the lock is held.
*/
void Character::
do_update() {
// Update all the joints and sliders.
if (even_animation) {
- int num_bundles = get_num_bundles();
- for (int i = 0; i < num_bundles; ++i) {
- get_bundle(i)->force_update();
+ for (PartBundleHandle *handle : _bundles) {
+ handle->get_bundle()->force_update();
}
} else {
- int num_bundles = get_num_bundles();
- for (int i = 0; i < num_bundles; ++i) {
- get_bundle(i)->update();
+ for (PartBundleHandle *handle : _bundles) {
+ handle->get_bundle()->update();
}
}
}
@@ -584,9 +559,9 @@ do_update() {
*/
void Character::
set_lod_current_delay(double delay) {
- int num_bundles = get_num_bundles();
- for (int i = 0; i < num_bundles; ++i) {
- get_bundle(i)->set_update_delay(delay);
+ LightMutexHolder holder(_lock);
+ for (PartBundleHandle *handle : _bundles) {
+ handle->get_bundle()->set_update_delay(delay);
}
}
@@ -594,6 +569,8 @@ set_lod_current_delay(double delay) {
* After the joint hierarchy has already been copied from the indicated
* hierarchy, this recursively walks through the joints and builds up a
* mapping from old to new.
+ *
+ * Assumes the lock is held.
*/
void Character::
fill_joint_map(Character::JointMap &joint_map,
@@ -624,6 +601,8 @@ fill_joint_map(Character::JointMap &joint_map,
* Recursively checks the two bundles for a matching hierarchy, and adds nodes
* as necessary to "new_group" where they are not already present. Also fills
* joint_map in the same manner as fill_joint_map().
+ *
+ * Assumes the lock is held.
*/
void Character::
r_merge_bundles(Character::JointMap &joint_map,
@@ -730,11 +709,12 @@ r_merge_bundles(Character::JointMap &joint_map,
new_group->_children.swap(new_children);
}
-
/**
* Recursively walks the scene graph hierarchy below the Character node,
* duplicating it while noting the orig:copy node mappings, and also updates
* any GeomNodes found.
+ *
+ * Assumes the lock is held.
*/
void Character::
r_copy_char(PandaNode *dest, const PandaNode *source,
diff --git a/panda/src/char/character.h b/panda/src/char/character.h
index a7c6c79f13..83aa754ee8 100644
--- a/panda/src/char/character.h
+++ b/panda/src/char/character.h
@@ -59,7 +59,6 @@ PUBLISHED:
virtual PandaNode *combine_with(PandaNode *other);
INLINE CharacterJointBundle *get_bundle(int i) const;
- void merge_bundles(PartBundle *old_bundle, PartBundle *other_bundle);
void merge_bundles(PartBundleHandle *old_bundle_handle,
PartBundleHandle *other_bundle_handle);
diff --git a/panda/src/char/characterSlider.cxx b/panda/src/char/characterSlider.cxx
index b4ced5e782..26d0f35053 100644
--- a/panda/src/char/characterSlider.cxx
+++ b/panda/src/char/characterSlider.cxx
@@ -40,8 +40,9 @@ CharacterSlider(const CharacterSlider ©) :
*
*/
CharacterSlider::
-CharacterSlider(PartGroup *parent, const std::string &name)
- : MovingPartScalar(parent, name) {
+CharacterSlider(PartGroup *parent, const std::string &name,
+ PN_stdfloat default_value)
+ : MovingPartScalar(parent, name, default_value) {
}
/**
diff --git a/panda/src/char/characterSlider.h b/panda/src/char/characterSlider.h
index 9871095afd..6a5da971b8 100644
--- a/panda/src/char/characterSlider.h
+++ b/panda/src/char/characterSlider.h
@@ -31,7 +31,8 @@ protected:
CharacterSlider(const CharacterSlider ©);
PUBLISHED:
- explicit CharacterSlider(PartGroup *parent, const std::string &name);
+ explicit CharacterSlider(PartGroup *parent, const std::string &name,
+ PN_stdfloat default_value = 0);
virtual ~CharacterSlider();
public:
diff --git a/panda/src/cocoadisplay/CMakeLists.txt b/panda/src/cocoadisplay/CMakeLists.txt
new file mode 100644
index 0000000000..ed6e4ca521
--- /dev/null
+++ b/panda/src/cocoadisplay/CMakeLists.txt
@@ -0,0 +1,47 @@
+if(NOT APPLE OR NOT HAVE_GL OR NOT HAVE_COCOA)
+ return()
+endif()
+
+set(P3COCOADISPLAY_HEADERS
+ config_cocoadisplay.h
+ cocoaGraphicsBuffer.h cocoaGraphicsBuffer.I
+ cocoaGraphicsPipe.h cocoaGraphicsPipe.I
+ cocoaGraphicsWindow.h cocoaGraphicsWindow.I
+ cocoaGraphicsStateGuardian.h cocoaGraphicsStateGuardian.I
+ cocoaPandaApp.h
+ cocoaPandaView.h
+ cocoaPandaWindow.h
+ cocoaPandaWindowDelegate.h
+ cocoaPandaAppDelegate.h
+)
+
+set(P3COCOADISPLAY_SOURCES
+ config_cocoadisplay.mm
+ cocoaGraphicsBuffer.mm
+ cocoaGraphicsPipe.mm
+ cocoaGraphicsStateGuardian.mm
+ cocoaGraphicsWindow.mm
+ cocoaPandaApp.mm
+ cocoaPandaView.mm
+ cocoaPandaWindow.mm
+ cocoaPandaWindowDelegate.mm
+ cocoaPandaAppDelegate.mm
+)
+
+composite_sources(p3cocoadisplay P3COCOADISPLAY_SOURCES)
+add_component_library(p3cocoadisplay SYMBOL BUILDING_PANDA_COCOADISPLAY
+ ${P3COCOADISPLAY_HEADERS} ${P3COCOADISPLAY_SOURCES})
+target_link_libraries(p3cocoadisplay p3glgsg panda)
+
+# Frameworks:
+find_library(APPLICATIONSERVICES_LIBRARY ApplicationServices)
+find_library(APPKIT_LIBRARY AppKit)
+find_library(CARBON_LIBRARY Carbon)
+find_library(CORE_VIDEO_LIBRARY CoreVideo)
+target_link_libraries(p3cocoadisplay
+ ${APPLICATIONSERVICES_LIBRARY} ${APPKIT_LIBRARY} ${CARBON_LIBRARY}
+ ${CORE_VIDEO_LIBRARY})
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3cocoadisplay EXPORT OpenGL COMPONENT OpenGL DESTINATION ${CMAKE_INSTALL_LIBDIR})
+endif()
diff --git a/panda/src/cocoadisplay/cocoaGraphicsWindow.h b/panda/src/cocoadisplay/cocoaGraphicsWindow.h
index 5fb49093d3..1381339630 100644
--- a/panda/src/cocoadisplay/cocoaGraphicsWindow.h
+++ b/panda/src/cocoadisplay/cocoaGraphicsWindow.h
@@ -74,8 +74,11 @@ protected:
virtual void mouse_mode_relative();
private:
+ NSData *load_image_data(const Filename &filename);
NSImage *load_image(const Filename &filename);
+ NSCursor *load_cursor(const Filename &filename);
+
void handle_modifier(NSUInteger modifierFlags, NSUInteger mask, ButtonHandle button);
ButtonHandle map_key(unsigned short c) const;
ButtonHandle map_raw_key(unsigned short keycode) const;
@@ -94,7 +97,7 @@ private:
CGDisplayModeRef _fullscreen_mode;
CGDisplayModeRef _windowed_mode;
- typedef pmap IconImages;
+ typedef pmap IconImages;
IconImages _images;
public:
diff --git a/panda/src/cocoadisplay/cocoaGraphicsWindow.mm b/panda/src/cocoadisplay/cocoaGraphicsWindow.mm
index 7d19c6bb9e..1b941a5d84 100644
--- a/panda/src/cocoadisplay/cocoaGraphicsWindow.mm
+++ b/panda/src/cocoadisplay/cocoaGraphicsWindow.mm
@@ -568,17 +568,17 @@ open_window() {
}
if (_properties.has_cursor_filename()) {
- NSImage *image = load_image(_properties.get_cursor_filename());
- NSCursor *cursor = nil;
- // TODO: allow setting the hotspot, read it from file when loading .cur.
- if (image != nil) {
- cursor = [[NSCursor alloc] initWithImage:image hotSpot:NSMakePoint(0, 0)];
- }
+ NSCursor *cursor = load_cursor(_properties.get_cursor_filename());
+
if (cursor != nil) {
+ if (_cursor != nil) {
+ [_cursor release];
+ }
_cursor = cursor;
} else {
_properties.clear_cursor_filename();
}
+
// This will ensure that NSView's resetCursorRects gets called, which sets
// the appropriate cursor rects.
[[_view window] invalidateCursorRectsForView:_view];
@@ -1031,19 +1031,15 @@ set_properties_now(WindowProperties &properties) {
properties.set_cursor_filename(cursor_filename);
properties.clear_cursor_filename();
} else {
- NSImage *image = load_image(cursor_filename);
- if (image != nil) {
- NSCursor *cursor;
- cursor = [[NSCursor alloc] initWithImage:image hotSpot:NSMakePoint(0, 0)];
- if (cursor != nil) {
- // Replace the existing cursor.
- if (_cursor != nil) {
- [_cursor release];
- }
- _cursor = cursor;
- _properties.set_cursor_filename(cursor_filename);
- properties.clear_cursor_filename();
+ NSCursor *cursor = load_cursor(cursor_filename);
+ if (cursor != nil) {
+ // Replace the existing cursor.
+ if (_cursor != nil) {
+ [_cursor release];
}
+ _cursor = cursor;
+ _properties.set_cursor_filename(cursor_filename);
+ properties.clear_cursor_filename();
}
}
// This will ensure that NSView's resetCursorRects gets called, which sets
@@ -1235,11 +1231,12 @@ do_switch_fullscreen(CGDisplayModeRef mode) {
}
/**
- * Loads the indicated filename and returns an NSImage pointer, or NULL on
- * failure. Must be called from the window thread.
+ * Loads the indicated filename and returns an NSData pointer (which can then
+ * be used to create a CGImageSource or NSImage), or NULL on failure. Must be
+ * called from the window thread. May return nil.
*/
-NSImage *CocoaGraphicsWindow::
-load_image(const Filename &filename) {
+NSData *CocoaGraphicsWindow::
+load_image_data(const Filename &filename) {
if (filename.empty()) {
return nil;
}
@@ -1259,7 +1256,6 @@ load_image(const Filename &filename) {
}
// Look in our index.
- NSImage *image = nil;
IconImages::const_iterator it = _images.find(resolved);
if (it != _images.end()) {
// Found it.
@@ -1269,7 +1265,7 @@ load_image(const Filename &filename) {
cocoadisplay_cat.info()
<< "Loading NSImage from file " << resolved << "\n";
- PT(VirtualFile) vfile = vfs->get_file(filename);
+ PT(VirtualFile) vfile = vfs->get_file(resolved);
if (vfile == NULL) {
return nil;
}
@@ -1287,21 +1283,81 @@ load_image(const Filename &filename) {
NSData *data = [NSData dataWithBytesNoCopy:buffer length:size];
if (data == nil) {
+ cocoadisplay_cat.error()
+ << "Could not load image data from file " << filename << "\n";
return nil;
}
- image = [[NSImage alloc] initWithData:data];
- [data release];
+ _images[resolved] = data;
+ return data;
+}
+
+/**
+ * Wraps image data loaded by load_image_data with an NSImage. The returned
+ * pointer is autoreleased. May return nil.
+ */
+NSImage *CocoaGraphicsWindow::
+load_image(const Filename &filename) {
+ NSData *image_data = load_image_data(filename);
+ NSImage *image = [[[NSImage alloc] initWithData:image_data] autorelease];
if (image == nil) {
cocoadisplay_cat.error()
<< "Could not load image from file " << filename << "\n";
return nil;
}
-
- _images[resolved] = image;
return image;
}
+/**
+ * Returns a cursor with the proper hotspot if a .cur filename is passed in.
+ * You must release the returned pointer. May return nil.
+ */
+NSCursor *CocoaGraphicsWindow::
+load_cursor(const Filename &filename) {
+ NSData *image_data = load_image_data(cursor_filename);
+ if (image_data == nil) {
+ return nil;
+ }
+
+ // Read the metadata from the image, which should contain hotspotX and
+ // hotspotY properties.
+ CGImageSourceRef cg_image = CGImageSourceCreateWithData((CFDataRef)image_data, nullptr);
+ if (cg_image == NULL) {
+ return nil;
+ }
+
+ NSDictionary *image_props = (NSDictionary *)CGImageSourceCopyPropertiesAtIndex(cg_image, 0, nil);
+ CFRelease(cg_image);
+
+ if (image_props == nil) {
+ return nil;
+ }
+
+ CGFloat hotspot_x = 0.0f;
+ CGFloat hotspot_y = 0.0f;
+ if (NSNumber *number = image_props[@"hotspotX"]) {
+ hotspot_x = [number floatValue];
+ }
+ if (NSNumber *number = image_props[@"hotspotY"]) {
+ hotspot_y = [number floatValue];
+ }
+ [image_props release];
+
+ NSImage *image = [[NSImage alloc] initWithData:image_data];
+
+ NSCursor *cursor = nil;
+ if (image != nil) {
+ // Apple recognizes that hotspots are usually specified from a .cur
+ // file, whose origin is in the top-left, so there's no need to flip
+ // it like most other Cocoa coordinates.
+ cursor = [[NSCursor alloc] initWithImage:image
+ hotSpot:NSMakePoint(hotspot_x, hotspot_y)];
+ [image release];
+ }
+
+ return cursor;
+}
+
/**
* Called by CocoaPandaView or the window delegate when the frame rect
* changes.
diff --git a/panda/src/collide/CMakeLists.txt b/panda/src/collide/CMakeLists.txt
new file mode 100644
index 0000000000..63ac4163e8
--- /dev/null
+++ b/panda/src/collide/CMakeLists.txt
@@ -0,0 +1,82 @@
+set(P3COLLIDE_HEADERS
+ collisionBox.I collisionBox.h
+ collisionCapsule.I collisionCapsule.h
+ collisionEntry.I collisionEntry.h
+ collisionGeom.I collisionGeom.h
+ collisionHandler.I collisionHandler.h
+ collisionHandlerEvent.I collisionHandlerEvent.h
+ collisionHandlerHighestEvent.h
+ collisionHandlerFloor.I collisionHandlerFloor.h
+ collisionHandlerGravity.I collisionHandlerGravity.h
+ collisionHandlerPhysical.I collisionHandlerPhysical.h
+ collisionHandlerPusher.I collisionHandlerPusher.h
+ collisionHandlerFluidPusher.I collisionHandlerFluidPusher.h
+ collisionHandlerQueue.h
+ collisionInvSphere.I collisionInvSphere.h
+ collisionLine.I collisionLine.h
+ collisionLevelStateBase.I collisionLevelStateBase.h
+ collisionLevelState.I collisionLevelState.h
+ collisionNode.I collisionNode.h
+ collisionParabola.I collisionParabola.h
+ collisionPlane.I collisionPlane.h
+ collisionPolygon.I collisionPolygon.h
+ collisionFloorMesh.I collisionFloorMesh.h
+ collisionRay.I collisionRay.h
+ collisionRecorder.I collisionRecorder.h
+ collisionSegment.I collisionSegment.h
+ collisionSolid.I collisionSolid.h
+ collisionSphere.I collisionSphere.h
+ collisionTraverser.I collisionTraverser.h
+ collisionTube.h
+ collisionVisualizer.I collisionVisualizer.h
+ config_collide.h
+)
+
+set(P3COLLIDE_SOURCES
+ collisionBox.cxx
+ collisionCapsule.cxx
+ collisionEntry.cxx
+ collisionGeom.cxx
+ collisionHandler.cxx
+ collisionHandlerEvent.cxx
+ collisionHandlerHighestEvent.cxx
+ collisionHandlerFloor.cxx
+ collisionHandlerGravity.cxx
+ collisionHandlerPhysical.cxx
+ collisionHandlerPusher.cxx
+ collisionHandlerFluidPusher.cxx
+ collisionHandlerQueue.cxx
+ collisionLevelStateBase.cxx
+ collisionLevelState.cxx
+ collisionInvSphere.cxx
+ collisionLine.cxx
+ collisionNode.cxx
+ collisionParabola.cxx
+ collisionPlane.cxx
+ collisionPolygon.cxx
+ collisionFloorMesh.cxx
+ collisionRay.cxx
+ collisionRecorder.cxx
+ collisionSegment.cxx
+ collisionSolid.cxx
+ collisionSphere.cxx
+ collisionTraverser.cxx
+ collisionVisualizer.cxx
+ config_collide.cxx
+)
+
+composite_sources(p3collide P3COLLIDE_SOURCES)
+add_component_library(p3collide SYMBOL BUILDING_PANDA_COLLIDE
+ ${P3COLLIDE_HEADERS} ${P3COLLIDE_SOURCES})
+target_link_libraries(p3collide p3tform)
+target_interrogate(p3collide ALL)
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3collide
+ EXPORT Core COMPONENT Core
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT CoreDevel)
+endif()
+install(FILES ${P3COLLIDE_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/panda/src/configfiles/CMakeLists.txt b/panda/src/configfiles/CMakeLists.txt
new file mode 100644
index 0000000000..58003c93e1
--- /dev/null
+++ b/panda/src/configfiles/CMakeLists.txt
@@ -0,0 +1,79 @@
+# Set some variables that are used in panda.prc.in.
+set(AUX_DISPLAYS)
+
+if(HAVE_GL)
+ set(AUX_DISPLAYS "${AUX_DISPLAYS}\naux-display pandagl")
+endif()
+
+if(HAVE_DX9)
+ set(AUX_DISPLAYS "${AUX_DISPLAYS}\naux-display pandadx9")
+endif()
+
+if(HAVE_TINYDISPLAY)
+ set(AUX_DISPLAYS "${AUX_DISPLAYS}\naux-display p3tinydisplay")
+endif()
+
+if(HAVE_OPENAL)
+ set(AUDIO_LIBRARY_NAME p3openal_audio)
+elseif(HAVE_FMODEX)
+ set(AUDIO_LIBRARY_NAME p3fmod_audio)
+else()
+ set(AUDIO_LIBRARY_NAME none)
+endif()
+
+if(WIN32)
+ set(BAM_CACHE_DIR
+ "$USER_APPDATA/Panda3D-${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}")
+elseif(APPLE)
+ set(BAM_CACHE_DIR
+ "$HOME/Library/Caches/Panda3D-${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}")
+else()
+ set(BAM_CACHE_DIR
+ "$XDG_CACHE_HOME/panda3d")
+endif()
+
+if(UNIX)
+ # On Unices, ask the GNUInstallDirs module where /etc is -- and then install
+ # ourselves into /etc/panda3d
+ set(prc_install_path "${CMAKE_INSTALL_FULL_SYSCONFDIR}/panda3d")
+ set(prc_build_path "${PANDA_OUTPUT_DIR}/etc/panda3d")
+else()
+ set(prc_install_path "etc")
+ set(prc_build_path "${PANDA_OUTPUT_DIR}/etc")
+endif()
+
+# Path from the directory containing *.prc to the directory containing plugins
+file(RELATIVE_PATH PLUGINS_PATH
+ "${prc_build_path}" "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}")
+
+# Path from the directory containing *.prc to the *parent of* models/
+# In the build tree, reckoning this is pretty easy
+file(RELATIVE_PATH MODELS_PARENT_PATH "${prc_build_path}" "${PANDA_OUTPUT_DIR}")
+configure_file(panda.prc.in "${CMAKE_CURRENT_BINARY_DIR}/20_panda.prc")
+
+# For the install tree, we need to introspect our paths
+set(abs_prc_install_path "${prc_install_path}")
+set(abs_datadir "${CMAKE_INSTALL_DATADIR}")
+set(abs_plugindir "${MODULE_DESTINATION}")
+if(NOT IS_ABSOLUTE "${abs_prc_install_path}")
+ set(abs_prc_install_path "${CMAKE_INSTALL_PREFIX}/${abs_prc_install_path}")
+endif()
+if(NOT IS_ABSOLUTE "${abs_datadir}")
+ set(abs_datadir "${CMAKE_INSTALL_PREFIX}/${abs_datadir}")
+endif()
+if(NOT IS_ABSOLUTE "${abs_plugindir}")
+ set(abs_plugindir "${CMAKE_INSTALL_PREFIX}/${abs_plugindir}")
+endif()
+file(RELATIVE_PATH PLUGINS_PATH
+ "${abs_prc_install_path}" "${abs_plugindir}")
+file(RELATIVE_PATH MODELS_PARENT_PATH
+ "${abs_prc_install_path}" "${abs_datadir}/panda3d")
+configure_file(panda.prc.in "${CMAKE_CURRENT_BINARY_DIR}/20_panda.prc.install")
+
+file(GENERATE OUTPUT "${prc_build_path}/20_panda.prc"
+ INPUT "${CMAKE_CURRENT_BINARY_DIR}/20_panda.prc")
+file(GENERATE OUTPUT "${prc_build_path}/20_panda.prc.install"
+ INPUT "${CMAKE_CURRENT_BINARY_DIR}/20_panda.prc.install")
+
+install(FILES "${prc_build_path}/20_panda.prc.install" RENAME "20_panda.prc"
+ COMPONENT Core DESTINATION ${prc_install_path})
diff --git a/panda/src/configfiles/panda.prc.in b/panda/src/configfiles/panda.prc.in
new file mode 100644
index 0000000000..bd04ccbe17
--- /dev/null
+++ b/panda/src/configfiles/panda.prc.in
@@ -0,0 +1,130 @@
+#### Generated automatically by CMake ${CMAKE_VERSION} from panda.prc.in.
+################################# DO NOT EDIT ###########################
+
+# Some paths first...
+plugin-path $THIS_PRC_DIR/${PLUGINS_PATH}
+model-path $MAIN_DIR
+model-path $THIS_PRC_DIR/${MODELS_PARENT_PATH}
+model-path $THIS_PRC_DIR/${MODELS_PARENT_PATH}/models
+
+# Let's set up a default window size of 800x600. The user can
+# override this in a separate, personal prc file.
+win-origin -2 -2
+win-size 800 600
+
+# For debugging, it's nice to have notify-level at the default setting of
+# "info", but everywhere else we turn the verbosity down to "warning"
+$<$:#>notify-level warning
+
+# Define the display types that have been compiled in. Panda will
+# pick one of these by going through the list in this order until one
+# is found that works, unless the user specifically requests a
+# particular display type with the load-display directive.
+${AUX_DISPLAYS}
+
+# Define an appropriate default audio library.
+audio-library-name ${AUDIO_LIBRARY_NAME}
+
+# The egg loader is handy to have available by default. This allows
+# clients to load egg files. (The bam loader is built-in so bam files
+# are always loadable).
+
+# By qualifying with the extension "egg", we indicate the egg loader
+# should be made available only if you explicitly name a file with an
+# .egg extension.
+
+# Also see ptloader, which is built as part of pandatool; it allows
+# files of more exotic types (like .flt, .mb, .lwo, and .dxf) to be
+# loaded directly into Panda.
+
+load-file-type egg pandaegg
+default-model-extension .egg
+
+# Enable the model-cache, but only for models, not textures.
+model-cache-dir ${BAM_CACHE_DIR}
+model-cache-textures #f
+
+
+# These entries work very similar to load-file-type, except they are
+# used by the MovieVideo and MovieAudio code to determine which module
+# should be loaded in order to decode files of the given extension.
+
+# ffmpeg is added by default because it used to be compiled in.
+# The * is a special catch-all extension that is consulted unless a
+# loader has been defined with an explicit extension.
+
+load-audio-type * p3ffmpeg
+load-video-type * p3ffmpeg
+
+
+# The following lines define some handy object types to use within the
+# egg syntax. This remaps { name } into whatever egg
+# syntax is given by egg-object-type-name, which makes a handy
+# abbreviation for modeling packages (like Maya) to insert
+# sophisticated egg syntax into the generated egg file, using a single
+# object type string.
+
+egg-object-type-portal portal { 1 }
+egg-object-type-polylight polylight { 1 }
+egg-object-type-seq24 { 1 } fps { 24 }
+egg-object-type-seq12 { 1 } fps { 12 }
+egg-object-type-seq10 { 1 } fps { 10 }
+egg-object-type-seq8 { 1 } fps { 8 }
+egg-object-type-seq6 { 1} fps { 6 }
+egg-object-type-seq4 { 1} fps { 4 }
+egg-object-type-seq2 { 1} fps { 2 }
+egg-object-type-indexed indexed { 1 }
+
+egg-object-type-binary alpha { binary }
+egg-object-type-dual alpha { dual }
+egg-object-type-glass alpha { blend_no_occlude }
+
+# These are just shortcuts to define the Model and DCS flags, which
+# indicate nodes that should not be flattened out of the hierarchy
+# during the conversion process. DCS goes one step further and
+# indicates that the node's transform is important and should be
+# preserved (DCS stands for Dynamic Coordinate System). Notouch is
+# even stronger, and means not to do any flattening below the node at
+# all.
+egg-object-type-model { 1 }
+egg-object-type-dcs { 1 }
+egg-object-type-notouch { no_touch }
+
+# The following define various kinds of collision geometry. These
+# mark the geometry at this level and below as invisible collision
+# polygons, which can be used by Panda's collision system to detect
+# collisions more optimally than regular visible polygons.
+egg-object-type-barrier { Polyset descend }
+egg-object-type-sphere { Sphere descend }
+egg-object-type-invsphere { InvSphere descend }
+egg-object-type-tube { Tube descend }
+
+# As above, but these are flagged to be "intangible", so that they
+# will trigger an event but not stop an object from passing through.
+egg-object-type-trigger { Polyset descend intangible }
+egg-object-type-trigger-sphere { Sphere descend intangible }
+
+# "floor" and "dupefloor" define the nodes in question as floor
+# polygons. dupefloor means to duplicate the geometry first so that
+# the same polygons serve both as visible geometry and as collision
+# polygons.
+egg-object-type-floor { Polyset descend level }
+egg-object-type-dupefloor { Polyset keep descend level }
+
+# "bubble" puts an invisible bubble around an object, but does not
+# otherwise remove the geometry.
+egg-object-type-bubble { Sphere keep descend }
+
+# "ghost" turns off the normal collide bit that is set on visible
+# geometry by default, so that if you are using visible geometry for
+# collisions, this particular geometry will not be part of those
+# collisions--it is ghostlike.
+egg-object-type-ghost collide-mask { 0 }
+
+# "glow" is useful for halo effects and things of that ilk. It
+# renders the object in add mode instead of the normal opaque mode.
+egg-object-type-glow blend { add }
+
+# This isn't used in the egg loader, it controls a setting only within
+# maya2egg itself. So if it appears in an egg file, it means nothing.
+egg-object-type-keep-all-uvsets
diff --git a/panda/src/cull/CMakeLists.txt b/panda/src/cull/CMakeLists.txt
new file mode 100644
index 0000000000..0e5e099b00
--- /dev/null
+++ b/panda/src/cull/CMakeLists.txt
@@ -0,0 +1,37 @@
+set(P3CULL_HEADERS
+ binCullHandler.h binCullHandler.I
+ config_cull.h
+ cullBinBackToFront.h cullBinBackToFront.I
+ cullBinFixed.h cullBinFixed.I
+ cullBinFrontToBack.h cullBinFrontToBack.I
+ cullBinStateSorted.h cullBinStateSorted.I
+ cullBinUnsorted.h cullBinUnsorted.I
+ drawCullHandler.h drawCullHandler.I
+)
+
+set(P3CULL_SOURCES
+ binCullHandler.cxx
+ config_cull.cxx
+ cullBinBackToFront.cxx
+ cullBinFixed.cxx
+ cullBinFrontToBack.cxx
+ cullBinStateSorted.cxx
+ cullBinUnsorted.cxx
+ drawCullHandler.cxx
+)
+
+composite_sources(p3cull P3CULL_SOURCES)
+add_component_library(p3cull SYMBOL BUILDING_PANDA_CULL
+ ${P3CULL_HEADERS} ${P3CULL_SOURCES})
+target_link_libraries(p3cull p3pgraph)
+target_interrogate(p3cull ALL)
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3cull
+ EXPORT Core COMPONENT Core
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT CoreDevel)
+endif()
+install(FILES ${P3CULL_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/panda/src/device/CMakeLists.txt b/panda/src/device/CMakeLists.txt
new file mode 100644
index 0000000000..f7c80e60f8
--- /dev/null
+++ b/panda/src/device/CMakeLists.txt
@@ -0,0 +1,80 @@
+set(P3DEVICE_HEADERS
+ analogNode.h analogNode.I
+ buttonNode.h buttonNode.I
+ clientAnalogDevice.h clientAnalogDevice.I
+ clientBase.h clientBase.I
+ clientButtonDevice.h clientButtonDevice.I
+ clientDevice.h clientDevice.I
+ clientDialDevice.h clientDialDevice.I
+ clientTrackerDevice.h clientTrackerDevice.I
+ config_device.h
+ dialNode.h dialNode.I
+ evdevInputDevice.h evdevInputDevice.I
+ inputDevice.h inputDevice.I
+ inputDeviceManager.h inputDeviceManager.I
+ inputDeviceNode.h
+ inputDeviceSet.h inputDeviceSet.I
+ ioKitInputDevice.h
+ ioKitInputDeviceManager.h
+ linuxInputDeviceManager.h
+ linuxJoystickDevice.h linuxJoystickDevice.I
+ trackerData.h trackerData.I
+ trackerNode.h trackerNode.I
+ virtualMouse.h
+ winInputDeviceManager.h
+ winRawInputDevice.h
+ xInputDevice.h
+)
+
+set(P3DEVICE_SOURCES
+ analogNode.cxx
+ buttonNode.cxx
+ clientAnalogDevice.cxx
+ clientBase.cxx
+ clientButtonDevice.cxx
+ clientDevice.cxx
+ clientDialDevice.cxx
+ clientTrackerDevice.cxx
+ config_device.cxx
+ dialNode.cxx
+ evdevInputDevice.cxx
+ inputDevice.cxx
+ inputDeviceManager.cxx
+ inputDeviceNode.cxx
+ inputDeviceSet.cxx
+ ioKitInputDevice.cxx
+ ioKitInputDeviceManager.cxx
+ linuxInputDeviceManager.cxx
+ linuxJoystickDevice.cxx
+ trackerData.cxx
+ trackerNode.cxx
+ virtualMouse.cxx
+ winInputDeviceManager.cxx
+ winRawInputDevice.cxx
+ xInputDevice.cxx
+)
+
+composite_sources(p3device P3DEVICE_SOURCES)
+add_component_library(p3device SYMBOL BUILDING_PANDA_DEVICE
+ ${P3DEVICE_HEADERS} ${P3DEVICE_SOURCES})
+target_link_libraries(p3device p3dgraph)
+target_interrogate(p3device ALL)
+
+if(WIN32)
+ target_link_libraries(p3device cfgmgr32.lib)
+
+elseif(APPLE)
+ find_library(IOKIT_LIBRARY IOKit)
+ target_link_libraries(p3device ${IOKIT_LIBRARY})
+
+endif()
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3device
+ EXPORT Core COMPONENT Core
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT CoreDevel)
+endif()
+install(FILES ${P3DEVICE_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/panda/src/device/inputDeviceNode.cxx b/panda/src/device/inputDeviceNode.cxx
index bdf849b93b..b5e749b2d6 100644
--- a/panda/src/device/inputDeviceNode.cxx
+++ b/panda/src/device/inputDeviceNode.cxx
@@ -54,7 +54,7 @@ void InputDeviceNode::
do_transmit_data(DataGraphTraverser *, const DataNodeTransmit &,
DataNodeTransmit &output) {
- if (_device == nullptr && !_device->is_connected()) {
+ if (_device == nullptr || !_device->is_connected()) {
return;
}
diff --git a/panda/src/device/ioKitInputDevice.cxx b/panda/src/device/ioKitInputDevice.cxx
index 079614a99f..e80dfccd94 100644
--- a/panda/src/device/ioKitInputDevice.cxx
+++ b/panda/src/device/ioKitInputDevice.cxx
@@ -23,15 +23,6 @@
#include "gamepadButton.h"
#include "mouseButton.h"
-static void removal_callback(void *ctx, IOReturn result, void *sender) {
- // We need to hold a reference to this because it may otherwise be destroyed
- // during the call to on_remove().
- PT(IOKitInputDevice) input_device = (IOKitInputDevice *)ctx;
- nassertv(input_device != nullptr);
- nassertv(input_device->test_ref_count_integrity());
- input_device->on_remove();
-}
-
/**
* Protected constructor.
*/
@@ -139,7 +130,6 @@ IOKitInputDevice(IOHIDDeviceRef device) :
}
_is_connected = true;
- IOHIDDeviceRegisterRemovalCallback(device, removal_callback, this);
}
/**
@@ -149,31 +139,6 @@ IOKitInputDevice::
~IOKitInputDevice() {
}
-/**
- * The nonstatic version of on_remove_device.
- */
-void IOKitInputDevice::
-on_remove() {
- {
- LightMutexHolder holder(_lock);
- if (!_is_connected) {
- return;
- }
- _is_connected = false;
- }
-
- if (device_cat.is_debug()) {
- device_cat.debug()
- << "Removed input device " << *this << "\n";
- }
-
- IOHIDDeviceClose(_device, kIOHIDOptionsTypeNone);
-
- InputDeviceManager *mgr = InputDeviceManager::get_global_ptr();
- nassertv(mgr != nullptr);
- mgr->remove_device(this);
-}
-
/**
*
*/
diff --git a/panda/src/device/ioKitInputDevice.h b/panda/src/device/ioKitInputDevice.h
index f32f9c4256..e355a95826 100644
--- a/panda/src/device/ioKitInputDevice.h
+++ b/panda/src/device/ioKitInputDevice.h
@@ -30,8 +30,6 @@ public:
IOKitInputDevice(IOHIDDeviceRef device);
~IOKitInputDevice();
- void on_remove();
-
private:
void parse_element(IOHIDElementRef element);
diff --git a/panda/src/device/ioKitInputDeviceManager.cxx b/panda/src/device/ioKitInputDeviceManager.cxx
index 6874d9baba..3f1c807469 100644
--- a/panda/src/device/ioKitInputDeviceManager.cxx
+++ b/panda/src/device/ioKitInputDeviceManager.cxx
@@ -59,6 +59,7 @@ IOKitInputDeviceManager() {
CFRelease(match);
IOHIDManagerRegisterDeviceMatchingCallback(_hid_manager, on_match_device, this);
+ IOHIDManagerRegisterDeviceRemovalCallback(_hid_manager, on_remove_device, this);
IOHIDManagerScheduleWithRunLoop(_hid_manager, CFRunLoopGetMain(), kCFRunLoopCommonModes);
IOHIDManagerOpen(_hid_manager, kIOHIDOptionsTypeNone);
}
@@ -78,16 +79,43 @@ IOKitInputDeviceManager::
*/
void IOKitInputDeviceManager::
on_match_device(void *ctx, IOReturn result, void *sender, IOHIDDeviceRef device) {
- InputDeviceManager *mgr = (InputDeviceManager *)ctx;
+ IOKitInputDeviceManager *mgr = (IOKitInputDeviceManager *)ctx;
nassertv(mgr != nullptr);
nassertv(device);
- PT(InputDevice) input_device = new IOKitInputDevice(device);
+ IOKitInputDevice *input_device = new IOKitInputDevice(device);
if (device_cat.is_debug()) {
device_cat.debug()
<< "Discovered input device " << *input_device << "\n";
}
mgr->add_device(input_device);
+ mgr->_devices_by_hidref[device] = input_device;
}
+/**
+ * Called by IOKit when an input device has disappeared.
+ */
+void IOKitInputDeviceManager::
+on_remove_device(void *ctx, IOReturn result, void *sender, IOHIDDeviceRef device) {
+ IOKitInputDeviceManager *mgr = (IOKitInputDeviceManager *)ctx;
+ nassertv(mgr != nullptr);
+ nassertv(device);
+
+ auto it = mgr->_devices_by_hidref.find(device);
+ nassertv(it != mgr->_devices_by_hidref.end());
+ IOKitInputDevice *input_device = it->second;
+
+ input_device->set_connected(false);
+
+ mgr->_devices_by_hidref.erase(device);
+
+ IOHIDDeviceClose(device, kIOHIDOptionsTypeNone);
+
+ if (device_cat.is_debug()) {
+ device_cat.debug()
+ << "Removed input device " << *input_device << "\n";
+ }
+
+ mgr->remove_device(input_device);
+}
#endif
diff --git a/panda/src/device/ioKitInputDeviceManager.h b/panda/src/device/ioKitInputDeviceManager.h
index f028a5f153..80005f99ab 100644
--- a/panda/src/device/ioKitInputDeviceManager.h
+++ b/panda/src/device/ioKitInputDeviceManager.h
@@ -19,6 +19,8 @@
#if defined(__APPLE__) && !defined(CPPPARSER)
#include
+class IOKitInputDevice;
+
/**
* The macOS implementation of InputDeviceManager.
*/
@@ -30,7 +32,16 @@ protected:
protected:
IOHIDManagerRef _hid_manager;
+ // The device removal callback method we need to use requires us to remember
+ // which IOKitInputDevice corresponds to which IOHIDDeviceRef. This is the
+ // same strategy used by winInputDevice and friends.
+ //
+ // We can make this a mapping to raw pointers since we know _devices will be
+ // holding a reference until remove_device is called.
+ pmap _devices_by_hidref;
+
static void on_match_device(void *ctx, IOReturn result, void *sender, IOHIDDeviceRef device);
+ static void on_remove_device(void *ctx, IOReturn result, void *sender, IOHIDDeviceRef device);
friend class InputDeviceManager;
};
diff --git a/panda/src/device/winInputDeviceManager.h b/panda/src/device/winInputDeviceManager.h
index 13cab3d7c0..e98a42a0bb 100644
--- a/panda/src/device/winInputDeviceManager.h
+++ b/panda/src/device/winInputDeviceManager.h
@@ -20,7 +20,7 @@
#include "xInputDevice.h"
-#include
+#include
#include
class WinRawInputDevice;
diff --git a/panda/src/device/winRawInputDevice.cxx b/panda/src/device/winRawInputDevice.cxx
index 9411ad508b..010766edf0 100644
--- a/panda/src/device/winRawInputDevice.cxx
+++ b/panda/src/device/winRawInputDevice.cxx
@@ -19,7 +19,7 @@
#if defined(_WIN32) && !defined(CPPPARSER)
-#include
+#include
#include
#include "phidsdi.h"
diff --git a/panda/src/device/xInputDevice.cxx b/panda/src/device/xInputDevice.cxx
index 74783f8751..bcc44cd3b1 100644
--- a/panda/src/device/xInputDevice.cxx
+++ b/panda/src/device/xInputDevice.cxx
@@ -19,8 +19,8 @@
#include "inputDeviceManager.h"
#include "string_utils.h"
-#include
-#include
+#include
+#include
#ifndef XUSER_MAX_COUNT
#define XUSER_MAX_COUNT 4
diff --git a/panda/src/device/xInputDevice.h b/panda/src/device/xInputDevice.h
index 2088c19182..c4a1f58d27 100644
--- a/panda/src/device/xInputDevice.h
+++ b/panda/src/device/xInputDevice.h
@@ -19,7 +19,7 @@
#if defined(_WIN32) && !defined(CPPPARSER)
-#include
+#include
class InputDeviceManager;
diff --git a/panda/src/dgraph/CMakeLists.txt b/panda/src/dgraph/CMakeLists.txt
new file mode 100644
index 0000000000..10caff45ef
--- /dev/null
+++ b/panda/src/dgraph/CMakeLists.txt
@@ -0,0 +1,29 @@
+set(P3DGRAPH_HEADERS
+ config_dgraph.h
+ dataGraphTraverser.I dataGraphTraverser.h
+ dataNode.I dataNode.h
+ dataNodeTransmit.I dataNodeTransmit.h
+)
+
+set(P3DGRAPH_SOURCES
+ config_dgraph.cxx
+ dataGraphTraverser.cxx
+ dataNode.cxx
+ dataNodeTransmit.cxx
+)
+
+composite_sources(p3dgraph P3DGRAPH_SOURCES)
+add_component_library(p3dgraph NOINIT SYMBOL BUILDING_PANDA_DGRAPH
+ ${P3DGRAPH_HEADERS} ${P3DGRAPH_SOURCES})
+target_link_libraries(p3dgraph p3pgraph)
+target_interrogate(p3dgraph ALL)
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3dgraph
+ EXPORT Core COMPONENT Core
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT CoreDevel)
+endif()
+install(FILES ${P3DGRAPH_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/panda/src/display/CMakeLists.txt b/panda/src/display/CMakeLists.txt
new file mode 100644
index 0000000000..d2e50e5fc9
--- /dev/null
+++ b/panda/src/display/CMakeLists.txt
@@ -0,0 +1,116 @@
+set(P3DISPLAY_HEADERS
+ standardMunger.I standardMunger.h
+ config_display.h
+ callbackGraphicsWindow.I callbackGraphicsWindow.h
+ drawableRegion.I drawableRegion.h
+ displayRegion.I displayRegion.h
+ displayRegionCullCallbackData.I displayRegionCullCallbackData.h
+ displayRegionDrawCallbackData.I displayRegionDrawCallbackData.h
+ frameBufferProperties.I frameBufferProperties.h
+ get_x11.h pre_x11_include.h post_x11_include.h
+ graphicsEngine.I graphicsEngine.h
+ graphicsOutput.I graphicsOutput.h
+ graphicsBuffer.I graphicsBuffer.h
+ graphicsDevice.h graphicsDevice.I
+ graphicsPipe.I graphicsPipe.h
+ graphicsPipeSelection.I graphicsPipeSelection.h
+ graphicsStateGuardian.I graphicsStateGuardian.h
+ graphicsThreadingModel.I graphicsThreadingModel.h
+ graphicsWindow.I graphicsWindow.h
+ graphicsWindowInputDevice.I graphicsWindowInputDevice.h
+ graphicsWindowProc.h
+ graphicsWindowProcCallbackData.I graphicsWindowProcCallbackData.h
+ mouseAndKeyboard.h
+ nativeWindowHandle.I nativeWindowHandle.h
+ parasiteBuffer.I parasiteBuffer.h
+ pStatGPUTimer.I pStatGPUTimer.h
+ windowHandle.I windowHandle.h
+ windowProperties.I windowProperties.h
+ renderBuffer.h
+ stereoDisplayRegion.I stereoDisplayRegion.h
+ displaySearchParameters.h
+ displayInformation.h
+ subprocessWindow.h subprocessWindow.I
+ touchInfo.h
+)
+
+set(P3DISPLAY_SOURCES
+ standardMunger.cxx
+ config_display.cxx
+ callbackGraphicsWindow.cxx
+ drawableRegion.cxx
+ displayRegion.cxx
+ displayRegionCullCallbackData.cxx
+ displayRegionDrawCallbackData.cxx
+ displaySearchParameters.cxx
+ displayInformation.cxx
+ frameBufferProperties.cxx
+ graphicsEngine.cxx
+ graphicsOutput.cxx
+ graphicsBuffer.cxx
+ graphicsPipe.cxx
+ graphicsPipeSelection.cxx
+ graphicsStateGuardian.cxx
+ graphicsThreadingModel.cxx
+ graphicsWindow.cxx graphicsWindowInputDevice.cxx
+ graphicsWindowProc.cxx
+ graphicsWindowProcCallbackData.cxx
+ graphicsDevice.cxx
+ mouseAndKeyboard.cxx
+ nativeWindowHandle.cxx
+ parasiteBuffer.cxx
+ windowHandle.cxx
+ windowProperties.cxx
+ stereoDisplayRegion.cxx
+ subprocessWindow.cxx
+ touchInfo.cxx
+)
+
+set(P3DISPLAY_IGATEEXT
+ graphicsStateGuardian_ext.cxx
+ graphicsStateGuardian_ext.h
+ graphicsWindow_ext.cxx
+ graphicsWindow_ext.h
+ pythonGraphicsWindowProc.cxx
+ pythonGraphicsWindowProc.h
+ windowProperties_ext.cxx
+ windowProperties_ext.h
+)
+
+if(APPLE)
+ set(P3DISPLAY_HEADERS
+ ${P3DISPLAY_HEADERS}
+ subprocessWindowBuffer.h
+ subprocessWindowBuffer.I
+ )
+
+ set(P3DISPLAY_SOURCES
+ ${P3DISPLAY_SOURCES}
+ subprocessWindowBuffer.cxx
+ )
+endif()
+
+# This is a large file; let's build it separately
+set_source_files_properties(graphicsStateGuardian.cxx PROPERTIES SKIP_UNITY_BUILD_INCLUSION YES)
+
+composite_sources(p3display P3DISPLAY_SOURCES)
+add_component_library(p3display SYMBOL BUILDING_PANDA_DISPLAY
+ ${P3DISPLAY_HEADERS} ${P3DISPLAY_SOURCES})
+target_link_libraries(p3display p3cull p3device p3pgraphnodes
+ PKG::X11)
+target_interrogate(p3display ALL EXTENSIONS ${P3DISPLAY_IGATEEXT})
+
+if(HAVE_EIGEN)
+ # Eigen puts this over the threshold where bigobj is needed on MSVC
+ set_target_properties(p3display PROPERTIES MSVC_BIGOBJ ON)
+endif()
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3display
+ EXPORT Core COMPONENT Core
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT CoreDevel)
+endif()
+install(FILES ${P3DISPLAY_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/panda/src/display/graphicsEngine.cxx b/panda/src/display/graphicsEngine.cxx
index 39a1e73aa2..9843f818ba 100644
--- a/panda/src/display/graphicsEngine.cxx
+++ b/panda/src/display/graphicsEngine.cxx
@@ -54,9 +54,9 @@
#include "winInputDeviceManager.h"
#endif
-#if defined(WIN32)
+#if defined(_WIN32)
#define WINDOWS_LEAN_AND_MEAN
- #include
+ #include
#include
#undef WINDOWS_LEAN_AND_MEAN
#else
diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx
index 46c5bfa0f6..c36eea42ae 100644
--- a/panda/src/display/graphicsStateGuardian.cxx
+++ b/panda/src/display/graphicsStateGuardian.cxx
@@ -876,6 +876,22 @@ compute_distance_to(const LPoint3 &point) const {
}
}
+/**
+ * A shader can request a number of values from the current render state. These
+ * are stored in the form of a matrix. Each ShaderContext caches the current
+ * value of these matrices, and calls this routine to update the matrices that
+ * have changed based on the aspects of the render state that were altered.
+ */
+void GraphicsStateGuardian::
+update_shader_matrix_cache(Shader *shader, LMatrix4 *cache, int altered) {
+ for (Shader::ShaderMatPart &part : shader->_mat_parts) {
+ if (altered & part._dep) {
+ fetch_specified_part(part._part, part._arg, cache, part._count);
+ }
+ cache += part._count;
+ }
+}
+
/**
* The gsg contains a large number of useful matrices:
*
@@ -902,54 +918,45 @@ compute_distance_to(const LPoint3 &point) const {
*
*/
const LMatrix4 *GraphicsStateGuardian::
-fetch_specified_value(Shader::ShaderMatSpec &spec, int altered) {
+fetch_specified_value(Shader::ShaderMatSpec &spec, const LMatrix4 *cache, int altered) {
LVecBase3 v;
- if (altered & spec._dep[0]) {
- const LMatrix4 *t = fetch_specified_part(spec._part[0], spec._arg[0], spec._cache[0], spec._index);
- if (t != &spec._cache[0]) {
- spec._cache[0] = *t;
- }
- }
- if (altered & spec._dep[1]) {
- const LMatrix4 *t = fetch_specified_part(spec._part[1], spec._arg[1], spec._cache[1], spec._index);
- if (t != &spec._cache[1]) {
- spec._cache[1] = *t;
- }
- }
+ const LMatrix4 *cache0 = cache + spec._cache_offset[0];
+ const LMatrix4 *cache1 = cache + spec._cache_offset[1];
- switch(spec._func) {
+
+ switch (spec._func) {
case Shader::SMF_compose:
- spec._value.multiply(spec._cache[0], spec._cache[1]);
+ spec._value.multiply((*cache0), (*cache1));
return &spec._value;
case Shader::SMF_transform_dlight:
- spec._value = spec._cache[0];
- v = spec._cache[1].xform_vec(spec._cache[0].get_row3(2));
+ spec._value = (*cache0);
+ v = (*cache1).xform_vec((*cache0).get_row3(2));
v.normalize();
spec._value.set_row(2, v);
- v = spec._cache[1].xform_vec(spec._cache[0].get_row3(3));
+ v = (*cache1).xform_vec((*cache0).get_row3(3));
v.normalize();
spec._value.set_row(3, v);
return &spec._value;
case Shader::SMF_transform_plight:
{
// Careful not to touch the w component, which contains the near value.
- spec._value = spec._cache[0];
- LPoint3 point = spec._cache[1].xform_point(spec._cache[0].get_row3(2));
+ spec._value = *cache0;
+ LPoint3 point = (*cache1).xform_point((*cache0).get_row3(2));
spec._value(2, 0) = point[0];
spec._value(2, 1) = point[1];
spec._value(2, 2) = point[2];
return &spec._value;
}
case Shader::SMF_transform_slight:
- spec._value = spec._cache[0];
- spec._value.set_row(2, spec._cache[1].xform_point(spec._cache[0].get_row3(2)));
- v = spec._cache[1].xform_vec(spec._cache[0].get_row3(3));
+ spec._value = *cache0;
+ spec._value.set_row(2, (*cache1).xform_point((*cache0).get_row3(2)));
+ v = (*cache1).xform_vec((*cache0).get_row3(3));
v.normalize();
spec._value.set_row(3, v);
return &spec._value;
case Shader::SMF_first:
- return &spec._cache[0];
+ return cache0;
default:
// should never get here
spec._value = LMatrix4::ident_mat();
@@ -960,57 +967,62 @@ fetch_specified_value(Shader::ShaderMatSpec &spec, int altered) {
/**
* See fetch_specified_value
*/
-const LMatrix4 *GraphicsStateGuardian::
+void GraphicsStateGuardian::
fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
- LMatrix4 &t, int index) {
+ LMatrix4 *into, int count) {
+ nassertv(count > 0);
+
switch (part) {
case Shader::SMO_identity: {
- return &LMatrix4::ident_mat();
+ for (int i = 0; i < count; ++i) {
+ into[i] = LMatrix4::ident_mat();
+ }
+ return;
}
case Shader::SMO_window_size:
case Shader::SMO_pixel_size: {
LVecBase2i pixel_size = _current_display_region->get_pixel_size();
- t = LMatrix4::translate_mat(pixel_size[0], pixel_size[1], 0);
- return &t;
+ into[0] = LMatrix4::translate_mat(pixel_size[0], pixel_size[1], 0);
+ return;
}
case Shader::SMO_frame_time: {
PN_stdfloat time = ClockObject::get_global_clock()->get_frame_time();
- t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, time, time, time, time);
- return &t;
+ into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, time, time, time, time);
+ return;
}
case Shader::SMO_frame_delta: {
PN_stdfloat dt = ClockObject::get_global_clock()->get_dt();
- t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, dt, dt, dt, dt);
- return &t;
+ into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, dt, dt, dt, dt);
+ return;
}
case Shader::SMO_texpad_x: {
Texture *tex = _target_shader->get_shader_input_texture(name);
- nassertr(tex != nullptr, &LMatrix4::zeros_mat());
+ nassertv(tex != nullptr);
int sx = tex->get_x_size() - tex->get_pad_x_size();
int sy = tex->get_y_size() - tex->get_pad_y_size();
int sz = tex->get_z_size() - tex->get_pad_z_size();
double cx = (sx * 0.5) / tex->get_x_size();
double cy = (sy * 0.5) / tex->get_y_size();
double cz = (sz * 0.5) / tex->get_z_size();
- t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, cx, cy, cz, 0);
- return &t;
+ into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, cx, cy, cz, 0);
+ return;
}
case Shader::SMO_texpix_x: {
Texture *tex = _target_shader->get_shader_input_texture(name);
- nassertr(tex != nullptr, &LMatrix4::zeros_mat());
+ nassertv(tex != nullptr);
double px = 1.0 / tex->get_x_size();
double py = 1.0 / tex->get_y_size();
double pz = 1.0 / tex->get_z_size();
- t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, px, py, pz, 0);
- return &t;
+ into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, px, py, pz, 0);
+ return;
}
case Shader::SMO_attr_material: {
const MaterialAttrib *target_material = (const MaterialAttrib *)
_target_rs->get_attrib_def(MaterialAttrib::get_class_slot());
// Material matrix contains AMBIENT, DIFFUSE, EMISSION, SPECULAR+SHININESS
if (target_material->is_off()) {
- t.set(1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0);
- return &t;
+ into[0].set(1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0);
+ return;
}
Material *m = target_material->get_material();
LVecBase4 const &amb = m->get_ambient();
@@ -1018,148 +1030,152 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
LVecBase4 const &emm = m->get_emission();
LVecBase4 spc = m->get_specular();
spc[3] = m->get_shininess();
- t.set(amb[0], amb[1], amb[2], amb[3],
- dif[0], dif[1], dif[2], dif[3],
- emm[0], emm[1], emm[2], emm[3],
- spc[0], spc[1], spc[2], spc[3]);
- return &t;
+ into[0].set(amb[0], amb[1], amb[2], amb[3],
+ dif[0], dif[1], dif[2], dif[3],
+ emm[0], emm[1], emm[2], emm[3],
+ spc[0], spc[1], spc[2], spc[3]);
+ return;
}
case Shader::SMO_attr_material2: {
const MaterialAttrib *target_material = (const MaterialAttrib *)
_target_rs->get_attrib_def(MaterialAttrib::get_class_slot());
if (target_material->is_off()) {
- t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
- return &t;
+ into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);
+ return;
}
Material *m = target_material->get_material();
- t.set_row(0, m->get_base_color());
- t.set_row(3, LVecBase4(m->get_metallic(), m->get_refractive_index(), 0, m->get_roughness()));
- return &t;
+ into[0].set_row(0, m->get_base_color());
+ into[0].set_row(3, LVecBase4(m->get_metallic(), m->get_refractive_index(), 0, m->get_roughness()));
+ return;
}
case Shader::SMO_attr_color: {
const ColorAttrib *target_color = (const ColorAttrib *)
_target_rs->get_attrib_def(ColorAttrib::get_class_slot());
if (target_color->get_color_type() != ColorAttrib::T_flat) {
- return &LMatrix4::ones_mat();
+ into[0] = LMatrix4::ones_mat();
+ return;
}
LVecBase4 c = target_color->get_color();
- t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, c[0], c[1], c[2], c[3]);
- return &t;
+ into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, c[0], c[1], c[2], c[3]);
+ return;
}
case Shader::SMO_attr_colorscale: {
const ColorScaleAttrib *target_color = (const ColorScaleAttrib *)
_target_rs->get_attrib_def(ColorScaleAttrib::get_class_slot());
if (target_color->is_identity()) {
- return &LMatrix4::ones_mat();
+ into[0] = LMatrix4::ones_mat();
+ return;
}
LVecBase4 cs = target_color->get_scale();
- t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, cs[0], cs[1], cs[2], cs[3]);
- return &t;
+ into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, cs[0], cs[1], cs[2], cs[3]);
+ return;
}
case Shader::SMO_attr_fog: {
const FogAttrib *target_fog = (const FogAttrib *)
_target_rs->get_attrib_def(FogAttrib::get_class_slot());
Fog *fog = target_fog->get_fog();
if (fog == nullptr) {
- return &LMatrix4::ones_mat();
+ into[0] = LMatrix4::ones_mat();
+ return;
}
PN_stdfloat start, end;
fog->get_linear_range(start, end);
- t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- fog->get_exp_density(), start, end, 1.0f / (end - start));
- return &t;
+ into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ fog->get_exp_density(), start, end, 1.0f / (end - start));
+ return;
}
case Shader::SMO_attr_fogcolor: {
const FogAttrib *target_fog = (const FogAttrib *)
_target_rs->get_attrib_def(FogAttrib::get_class_slot());
Fog *fog = target_fog->get_fog();
if (fog == nullptr) {
- return &LMatrix4::ones_mat();
+ into[0] = LMatrix4::ones_mat();
+ return;
}
LVecBase4 c = fog->get_color();
- t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, c[0], c[1], c[2], c[3]);
- return &t;
+ into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, c[0], c[1], c[2], c[3]);
+ return;
}
case Shader::SMO_alight_x: {
const NodePath &np = _target_shader->get_shader_input_nodepath(name);
- nassertr(!np.is_empty(), &LMatrix4::zeros_mat());
+ nassertv(!np.is_empty());
AmbientLight *lt;
- DCAST_INTO_R(lt, np.node(), &LMatrix4::zeros_mat());
+ DCAST_INTO_V(lt, np.node());
LColor const &c = lt->get_color();
- t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, c[0], c[1], c[2], c[3]);
- return &t;
+ into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, c[0], c[1], c[2], c[3]);
+ return;
}
case Shader::SMO_satten_x: {
const NodePath &np = _target_shader->get_shader_input_nodepath(name);
- nassertr(!np.is_empty(), &LMatrix4::ones_mat());
+ nassertv(!np.is_empty());
Spotlight *lt;
- DCAST_INTO_R(lt, np.node(), &LMatrix4::ones_mat());
+ DCAST_INTO_V(lt, np.node());
LVecBase3 const &a = lt->get_attenuation();
PN_stdfloat x = lt->get_exponent();
- t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, a[0], a[1], a[2], x);
- return &t;
+ into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, a[0], a[1], a[2], x);
+ return;
}
case Shader::SMO_dlight_x: {
// The dlight matrix contains COLOR, SPECULAR, DIRECTION, PSEUDOHALFANGLE
const NodePath &np = _target_shader->get_shader_input_nodepath(name);
- nassertr(!np.is_empty(), &LMatrix4::zeros_mat());
+ nassertv(!np.is_empty());
DirectionalLight *lt;
- DCAST_INTO_R(lt, np.node(), &LMatrix4::zeros_mat());
+ DCAST_INTO_V(lt, np.node());
LColor const &c = lt->get_color();
LColor const &s = lt->get_specular_color();
- t = np.get_net_transform()->get_mat() *
- _scene_setup->get_world_transform()->get_mat();
- LVecBase3 d = -(t.xform_vec(lt->get_direction()));
+ *into = np.get_net_transform()->get_mat() *
+ _scene_setup->get_world_transform()->get_mat();
+ LVecBase3 d = -(into[0].xform_vec(lt->get_direction()));
d.normalize();
LVecBase3 h = d + LVecBase3(0,-1,0);
h.normalize();
- t.set(c[0], c[1], c[2], c[3],
- s[0], s[1], s[2], c[3],
- d[0], d[1], d[2], 0,
- h[0], h[1], h[2], 0);
- return &t;
+ into[0].set(c[0], c[1], c[2], c[3],
+ s[0], s[1], s[2], c[3],
+ d[0], d[1], d[2], 0,
+ h[0], h[1], h[2], 0);
+ return;
}
case Shader::SMO_plight_x: {
// The plight matrix contains COLOR, SPECULAR, POINT, ATTENUATION
const NodePath &np = _target_shader->get_shader_input_nodepath(name);
- nassertr(!np.is_empty(), &LMatrix4::ones_mat());
+ nassertv(!np.is_empty());
PointLight *lt;
- DCAST_INTO_R(lt, np.node(), &LMatrix4::zeros_mat());
+ DCAST_INTO_V(lt, np.node());
LColor const &c = lt->get_color();
LColor const &s = lt->get_specular_color();
- t = np.get_net_transform()->get_mat() *
- _scene_setup->get_world_transform()->get_mat();
- LVecBase3 p = (t.xform_point(lt->get_point()));
+ into[0] = np.get_net_transform()->get_mat() *
+ _scene_setup->get_world_transform()->get_mat();
+ LVecBase3 p = (into[0].xform_point(lt->get_point()));
LVecBase3 a = lt->get_attenuation();
Lens *lens = lt->get_lens(0);
PN_stdfloat lnear = lens->get_near();
PN_stdfloat lfar = lens->get_far();
- t.set(c[0], c[1], c[2], c[3],
- s[0], s[1], s[2], s[3],
- p[0], p[1], p[2], lnear,
- a[0], a[1], a[2], lfar);
- return &t;
+ into[0].set(c[0], c[1], c[2], c[3],
+ s[0], s[1], s[2], s[3],
+ p[0], p[1], p[2], lnear,
+ a[0], a[1], a[2], lfar);
+ return;
}
case Shader::SMO_slight_x: {
// The slight matrix contains COLOR, SPECULAR, POINT, DIRECTION
const NodePath &np = _target_shader->get_shader_input_nodepath(name);
- nassertr(!np.is_empty(), &LMatrix4::zeros_mat());
+ nassertv(!np.is_empty());
Spotlight *lt;
- DCAST_INTO_R(lt, np.node(), &LMatrix4::zeros_mat());
+ DCAST_INTO_V(lt, np.node());
Lens *lens = lt->get_lens();
- nassertr(lens != nullptr, &LMatrix4::zeros_mat());
+ nassertv(lens != nullptr);
LColor const &c = lt->get_color();
LColor const &s = lt->get_specular_color();
PN_stdfloat cutoff = ccos(deg_2_rad(lens->get_hfov() * 0.5f));
- t = np.get_net_transform()->get_mat() *
- _scene_setup->get_world_transform()->get_mat();
- LVecBase3 p = t.xform_point(lens->get_nodal_point());
- LVecBase3 d = -(t.xform_vec(lens->get_view_vector()));
- t.set(c[0], c[1], c[2], c[3],
- s[0], s[1], s[2], s[3],
- p[0], p[1], p[2], 0,
- d[0], d[1], d[2], cutoff);
- return &t;
+ into[0] = np.get_net_transform()->get_mat() *
+ _scene_setup->get_world_transform()->get_mat();
+ LVecBase3 p = into[0].xform_point(lens->get_nodal_point());
+ LVecBase3 d = -(into[0].xform_vec(lens->get_view_vector()));
+ into[0].set(c[0], c[1], c[2], c[3],
+ s[0], s[1], s[2], s[3],
+ p[0], p[1], p[2], 0,
+ d[0], d[1], d[2], cutoff);
+ return;
}
case Shader::SMO_light_ambient: {
LColor cur_ambient_light(0.0f, 0.0f, 0.0f, 0.0f);
@@ -1169,89 +1185,127 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
if (!target_light->has_any_on_light()) {
// There are no lights at all. This means, to follow the fixed-
// function model, we pretend there is an all-white ambient light.
- t.set_row(3, LVecBase4(1, 1, 1, 1));
+ into[0].set_row(3, LVecBase4(1, 1, 1, 1));
} else {
- t.set_row(3, target_light->get_ambient_contribution());
+ into[0].set_row(3, target_light->get_ambient_contribution());
}
- return &t;
+ return;
}
case Shader::SMO_texmat_i: {
const TexMatrixAttrib *tma;
const TextureAttrib *ta;
- if (_target_rs->get_attrib(ta) && _target_rs->get_attrib(tma) &&
- index < ta->get_num_on_stages()) {
- return &tma->get_mat(ta->get_on_stage(index));
- } else {
- return &LMatrix4::ident_mat();
+
+ int num_stages = 0;
+ if (_target_rs->get_attrib(ta) && _target_rs->get_attrib(tma)) {
+ num_stages = std::min(count, (int)ta->get_num_on_stages());
}
+
+ int i = 0;
+ for (; i < num_stages; ++i) {
+ into[i] = tma->get_mat(ta->get_on_stage(i));
+ }
+ for (; i < count; ++i) {
+ into[i] = LMatrix4::ident_mat();
+ }
+ return;
}
case Shader::SMO_inv_texmat_i: {
const TexMatrixAttrib *tma;
const TextureAttrib *ta;
- if (_target_rs->get_attrib(ta) && _target_rs->get_attrib(tma) &&
- index < ta->get_num_on_stages()) {
- t = tma->get_transform(ta->get_on_stage(index))->get_inverse()->get_mat();
- return &t;
- } else {
- return &LMatrix4::ident_mat();
+
+ int num_stages = 0;
+ if (_target_rs->get_attrib(ta) && _target_rs->get_attrib(tma)) {
+ num_stages = std::min(count, (int)ta->get_num_on_stages());
}
+
+ int i = 0;
+ for (; i < num_stages; ++i) {
+ into[i] = tma->get_transform(ta->get_on_stage(i))->get_inverse()->get_mat();
+ }
+ for (; i < count; ++i) {
+ into[i] = LMatrix4::ident_mat();
+ }
+ return;
}
case Shader::SMO_texscale_i: {
const TexMatrixAttrib *tma;
const TextureAttrib *ta;
- if (_target_rs->get_attrib(ta) && _target_rs->get_attrib(tma) &&
- index < ta->get_num_on_stages()) {
- LVecBase3 scale = tma->get_transform(ta->get_on_stage(index))->get_scale();
- t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, scale[0], scale[1], scale[2], 0);
- return &t;
- } else {
- return &LMatrix4::ident_mat();
+
+ int num_stages = 0;
+ if (_target_rs->get_attrib(ta) && _target_rs->get_attrib(tma)) {
+ num_stages = std::min(count, (int)ta->get_num_on_stages());
}
+
+ int i = 0;
+ for (; i < num_stages; ++i) {
+ LVecBase3 scale = tma->get_transform(ta->get_on_stage(i))->get_scale();
+ into[i].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, scale[0], scale[1], scale[2], 0);
+ }
+ for (; i < count; ++i) {
+ into[i] = LMatrix4::ident_mat();
+ }
+ return;
}
case Shader::SMO_texcolor_i: {
const TextureAttrib *ta;
- if (_target_rs->get_attrib(ta) && index < ta->get_num_on_stages()) {
- TextureStage *ts = ta->get_on_stage(index);
- t.set_row(3, ts->get_color());
- return &t;
- } else {
- return &LMatrix4::zeros_mat();
+
+ int num_stages = 0;
+ if (_target_rs->get_attrib(ta)) {
+ num_stages = std::min(count, (int)ta->get_num_on_stages());
}
+
+ int i = 0;
+ for (; i < num_stages; ++i) {
+ TextureStage *ts = ta->get_on_stage(i);
+ into[i].set_row(3, ts->get_color());
+ }
+ for (; i < count; ++i) {
+ into[i] = LMatrix4::ident_mat();
+ }
+ return;
}
case Shader::SMO_tex_is_alpha_i: {
// This is a hack so we can support both F_alpha and other formats in the
// default shader, to fix font rendering in GLES2
const TextureAttrib *ta;
- if (_target_rs->get_attrib(ta) &&
- index < ta->get_num_on_stages()) {
- TextureStage *ts = ta->get_on_stage(index);
- PN_stdfloat v = (ta->get_on_texture(ts)->get_format() == Texture::F_alpha);
- t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, v, v, v, 0);
- return &t;
- } else {
- return &LMatrix4::zeros_mat();
+
+ int num_stages = 0;
+ if (_target_rs->get_attrib(ta)) {
+ num_stages = std::min(count, (int)ta->get_num_on_stages());
}
+
+ int i = 0;
+ for (; i < num_stages; ++i) {
+ TextureStage *ts = ta->get_on_stage(i);
+ PN_stdfloat v = (ta->get_on_texture(ts)->get_format() == Texture::F_alpha);
+ into[i].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, v, v, v, 0);
+ }
+ for (; i < count; ++i) {
+ into[i] = LMatrix4::zeros_mat();
+ }
+ return;
}
case Shader::SMO_plane_x: {
const NodePath &np = _target_shader->get_shader_input_nodepath(name);
- nassertr(!np.is_empty(), &LMatrix4::zeros_mat());
+ nassertv(!np.is_empty());
const PlaneNode *plane_node;
- DCAST_INTO_R(plane_node, np.node(), &LMatrix4::zeros_mat());
+ DCAST_INTO_V(plane_node, np.node());
LPlane p = plane_node->get_plane();
- t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, p[0], p[1], p[2], p[3]);
- return &t;
+ into[0].set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, p[0], p[1], p[2], p[3]);
+ return;
}
case Shader::SMO_clipplane_x: {
const ClipPlaneAttrib *cpa;
_target_rs->get_attrib_def(cpa);
int planenr = atoi(name->get_name().c_str());
if (planenr >= cpa->get_num_on_planes()) {
- return &LMatrix4::zeros_mat();
+ into[0] = LMatrix4::zeros_mat();
+ return;
}
const NodePath &np = cpa->get_on_plane(planenr);
- nassertr(!np.is_empty(), &LMatrix4::zeros_mat());
+ nassertv(!np.is_empty());
const PlaneNode *plane_node;
- DCAST_INTO_R(plane_node, np.node(), &LMatrix4::zeros_mat());
+ DCAST_INTO_V(plane_node, np.node());
// Transform plane to world space
CPT(TransformState) transform = np.get_net_transform();
@@ -1259,206 +1313,223 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
if (!transform->is_identity()) {
plane.xform(transform->get_mat());
}
- t.set_row(3, plane);
- return &t;
+ into[0].set_row(3, plane);
+ return;
}
case Shader::SMO_apiview_clipplane_i: {
const ClipPlaneAttrib *cpa;
_target_rs->get_attrib_def(cpa);
- if (index >= cpa->get_num_on_planes()) {
- return &LMatrix4::zeros_mat();
+
+ int num_planes = std::min(count, (int)cpa->get_num_on_planes());
+ int i = 0;
+ for (; i < num_planes; ++i) {
+ const NodePath &plane = cpa->get_on_plane(i);
+ nassertv(!plane.is_empty());
+ const PlaneNode *plane_node;
+ DCAST_INTO_V(plane_node, plane.node());
+
+ CPT(TransformState) transform =
+ _scene_setup->get_cs_world_transform()->compose(
+ plane.get_transform(_scene_setup->get_scene_root().get_parent()));
+
+ LPlane xformed_plane = plane_node->get_plane() * transform->get_mat();
+ into[i].set_row(3, xformed_plane);
}
- const NodePath &plane = cpa->get_on_plane(index);
- nassertr(!plane.is_empty(), &LMatrix4::zeros_mat());
- const PlaneNode *plane_node;
- DCAST_INTO_R(plane_node, plane.node(), &LMatrix4::zeros_mat());
-
- CPT(TransformState) transform =
- _scene_setup->get_cs_world_transform()->compose(
- plane.get_transform(_scene_setup->get_scene_root().get_parent()));
-
- LPlane xformed_plane = plane_node->get_plane() * transform->get_mat();
- t.set_row(3, xformed_plane);
- return &t;
+ for (; i < count; ++i) {
+ // Fill the remainder with zeroes.
+ into[i] = LMatrix4::zeros_mat();
+ }
+ return;
}
case Shader::SMO_mat_constant_x: {
- return &_target_shader->get_shader_input_matrix(name, t);
+ _target_shader->get_shader_input_matrix(name, into[0]);
+ return;
}
case Shader::SMO_vec_constant_x: {
const LVecBase4 &input = _target_shader->get_shader_input_vector(name);
const PN_stdfloat *data = input.get_data();
- t.set(data[0], data[1], data[2], data[3],
- data[0], data[1], data[2], data[3],
- data[0], data[1], data[2], data[3],
- data[0], data[1], data[2], data[3]);
- return &t;
+ into[0].set(data[0], data[1], data[2], data[3],
+ data[0], data[1], data[2], data[3],
+ data[0], data[1], data[2], data[3],
+ data[0], data[1], data[2], data[3]);
+ return;
}
case Shader::SMO_world_to_view: {
- return &(_scene_setup->get_world_transform()->get_mat());
+ into[0] = _scene_setup->get_world_transform()->get_mat();
+ return;
}
case Shader::SMO_view_to_world: {
- return &(_scene_setup->get_camera_transform()->get_mat());
+ into[0] = _scene_setup->get_camera_transform()->get_mat();
+ return;
}
case Shader::SMO_model_to_view: {
- t = _inv_cs_transform->compose(_internal_transform)->get_mat();
- return &t;
+ into[0] = _inv_cs_transform->compose(_internal_transform)->get_mat();
+ return;
}
case Shader::SMO_model_to_apiview: {
- return &(_internal_transform->get_mat());
+ into[0] = _internal_transform->get_mat();
+ return;
}
case Shader::SMO_view_to_model: {
- t = _internal_transform->invert_compose(_cs_transform)->get_mat();
- return &t;
+ into[0] = _internal_transform->invert_compose(_cs_transform)->get_mat();
+ return;
}
case Shader::SMO_apiview_to_model: {
- t = _internal_transform->get_inverse()->get_mat();
- return &t;
+ into[0] = _internal_transform->get_inverse()->get_mat();
+ return;
}
case Shader::SMO_apiview_to_view: {
- return &(_inv_cs_transform->get_mat());
+ into[0] = _inv_cs_transform->get_mat();
+ return;
}
case Shader::SMO_view_to_apiview: {
- return &(_cs_transform->get_mat());
+ into[0] = _cs_transform->get_mat();
+ return;
}
case Shader::SMO_clip_to_view: {
if (_current_lens->get_coordinate_system() == _coordinate_system) {
- return &(_current_lens->get_projection_mat_inv(_current_stereo_channel));
+ into[0] = _current_lens->get_projection_mat_inv(_current_stereo_channel);
} else {
- t = _current_lens->get_projection_mat_inv(_current_stereo_channel) *
- LMatrix4::convert_mat(_current_lens->get_coordinate_system(), _coordinate_system);
- return &t;
+ into[0] = _current_lens->get_projection_mat_inv(_current_stereo_channel) *
+ LMatrix4::convert_mat(_current_lens->get_coordinate_system(), _coordinate_system);
}
+ return;
}
case Shader::SMO_view_to_clip: {
if (_current_lens->get_coordinate_system() == _coordinate_system) {
- return &(_current_lens->get_projection_mat(_current_stereo_channel));
+ into[0] = _current_lens->get_projection_mat(_current_stereo_channel);
} else {
- t = LMatrix4::convert_mat(_coordinate_system, _current_lens->get_coordinate_system()) *
- _current_lens->get_projection_mat(_current_stereo_channel);
- return &t;
+ into[0] = LMatrix4::convert_mat(_coordinate_system, _current_lens->get_coordinate_system()) *
+ _current_lens->get_projection_mat(_current_stereo_channel);
}
+ return;
}
case Shader::SMO_apiclip_to_view: {
- t = _projection_mat_inv->get_mat() * _inv_cs_transform->get_mat();
- return &t;
+ into[0] = _projection_mat_inv->get_mat() * _inv_cs_transform->get_mat();
+ return;
}
case Shader::SMO_view_to_apiclip: {
- t = _cs_transform->get_mat() * _projection_mat->get_mat();
- return &t;
+ into[0] = _cs_transform->get_mat() * _projection_mat->get_mat();
+ return;
}
case Shader::SMO_apiclip_to_apiview: {
- return &(_projection_mat_inv->get_mat());
+ into[0] = _projection_mat_inv->get_mat();
+ return;
}
case Shader::SMO_apiview_to_apiclip: {
- return &(_projection_mat->get_mat());
+ into[0] = _projection_mat->get_mat();
+ return;
}
case Shader::SMO_view_x_to_view: {
const NodePath &np = _target_shader->get_shader_input_nodepath(name);
- nassertr(!np.is_empty(), &LMatrix4::ident_mat());
- t = np.get_net_transform()->get_mat() *
+ nassertv(!np.is_empty());
+ into[0] = np.get_net_transform()->get_mat() *
_scene_setup->get_world_transform()->get_mat();
- return &t;
+ return;
}
case Shader::SMO_view_to_view_x: {
const NodePath &np = _target_shader->get_shader_input_nodepath(name);
- nassertr(!np.is_empty(), &LMatrix4::ident_mat());
- t = _scene_setup->get_camera_transform()->get_mat() *
+ nassertv(!np.is_empty());
+ into[0] = _scene_setup->get_camera_transform()->get_mat() *
np.get_net_transform()->get_inverse()->get_mat();
- return &t;
+ return;
}
case Shader::SMO_apiview_x_to_view: {
const NodePath &np = _target_shader->get_shader_input_nodepath(name);
- nassertr(!np.is_empty(), &LMatrix4::ident_mat());
- t = LMatrix4::convert_mat(_internal_coordinate_system, _coordinate_system) *
+ nassertv(!np.is_empty());
+ into[0] = LMatrix4::convert_mat(_internal_coordinate_system, _coordinate_system) *
np.get_net_transform()->get_mat() *
_scene_setup->get_world_transform()->get_mat();
- return &t;
+ return;
}
case Shader::SMO_view_to_apiview_x: {
const NodePath &np = _target_shader->get_shader_input_nodepath(name);
- nassertr(!np.is_empty(), &LMatrix4::ident_mat());
- t = (_scene_setup->get_camera_transform()->get_mat() *
+ nassertv(!np.is_empty());
+ into[0] = (_scene_setup->get_camera_transform()->get_mat() *
np.get_net_transform()->get_inverse()->get_mat() *
LMatrix4::convert_mat(_coordinate_system, _internal_coordinate_system));
- return &t;
+ return;
}
case Shader::SMO_clip_x_to_view: {
const NodePath &np = _target_shader->get_shader_input_nodepath(name);
- nassertr(!np.is_empty(), &LMatrix4::ident_mat());
+ nassertv(!np.is_empty());
const LensNode *node;
- DCAST_INTO_R(node, np.node(), &LMatrix4::ident_mat());
+ DCAST_INTO_V(node, np.node());
const Lens *lens = node->get_lens();
- t = lens->get_projection_mat_inv(_current_stereo_channel) *
+ into[0] = lens->get_projection_mat_inv(_current_stereo_channel) *
LMatrix4::convert_mat(lens->get_coordinate_system(), _coordinate_system) *
np.get_net_transform()->get_mat() *
_scene_setup->get_world_transform()->get_mat();
- return &t;
+ return;
}
case Shader::SMO_view_to_clip_x: {
const NodePath &np = _target_shader->get_shader_input_nodepath(name);
- nassertr(!np.is_empty(), &LMatrix4::ident_mat());
+ nassertv(!np.is_empty());
const LensNode *node;
- DCAST_INTO_R(node, np.node(), &LMatrix4::ident_mat());
+ DCAST_INTO_V(node, np.node());
const Lens *lens = node->get_lens();
- t = _scene_setup->get_camera_transform()->get_mat() *
+ into[0] = _scene_setup->get_camera_transform()->get_mat() *
np.get_net_transform()->get_inverse()->get_mat() *
LMatrix4::convert_mat(_coordinate_system, lens->get_coordinate_system()) *
lens->get_projection_mat(_current_stereo_channel);
- return &t;
+ return;
}
case Shader::SMO_apiclip_x_to_view: {
const NodePath &np = _target_shader->get_shader_input_nodepath(name);
- nassertr(!np.is_empty(), &LMatrix4::ident_mat());
+ nassertv(!np.is_empty());
const LensNode *node;
- DCAST_INTO_R(node, np.node(), &LMatrix4::ident_mat());
+ DCAST_INTO_V(node, np.node());
const Lens *lens = node->get_lens();
- t = calc_projection_mat(lens)->get_inverse()->get_mat() *
+ into[0] = calc_projection_mat(lens)->get_inverse()->get_mat() *
get_cs_transform_for(lens->get_coordinate_system())->get_inverse()->get_mat() *
np.get_net_transform()->get_mat() *
_scene_setup->get_world_transform()->get_mat();
- return &t;
+ return;
}
case Shader::SMO_view_to_apiclip_x: {
const NodePath &np = _target_shader->get_shader_input_nodepath(name);
- nassertr(!np.is_empty(), &LMatrix4::ident_mat());
+ nassertv(!np.is_empty());
const LensNode *node;
- DCAST_INTO_R(node, np.node(), &LMatrix4::ident_mat());
+ DCAST_INTO_V(node, np.node());
const Lens *lens = node->get_lens();
- t = _scene_setup->get_camera_transform()->get_mat() *
+ into[0] = _scene_setup->get_camera_transform()->get_mat() *
np.get_net_transform()->get_inverse()->get_mat() *
get_cs_transform_for(lens->get_coordinate_system())->get_mat() *
calc_projection_mat(lens)->get_mat();
- return &t;
+ return;
}
case Shader::SMO_mat_constant_x_attrib: {
if (_target_shader->has_shader_input(name)) {
// There is an input specifying precisely this whole thing, with dot and
// all. Support this, even if only for backward compatibility.
- return &_target_shader->get_shader_input_matrix(name, t);
+ _target_shader->get_shader_input_matrix(name, into[0]);
+ return;
}
const NodePath &np = _target_shader->get_shader_input_nodepath(name->get_parent());
- nassertr(!np.is_empty(), &LMatrix4::ident_mat());
+ nassertv(!np.is_empty());
- return fetch_specified_member(np, name->get_basename(), t);
+ fetch_specified_member(np, name->get_basename(), into[0]);
+ return;
}
case Shader::SMO_vec_constant_x_attrib: {
if (_target_shader->has_shader_input(name)) {
// There is an input specifying precisely this whole thing, with dot and
// all. Support this, even if only for backward compatibility.
const LVecBase4 &data = _target_shader->get_shader_input_vector(name);
- t.set(data[0], data[1], data[2], data[3],
- data[0], data[1], data[2], data[3],
- data[0], data[1], data[2], data[3],
- data[0], data[1], data[2], data[3]);
- return &t;
+ into[0].set(data[0], data[1], data[2], data[3],
+ data[0], data[1], data[2], data[3],
+ data[0], data[1], data[2], data[3],
+ data[0], data[1], data[2], data[3]);
+ return;
}
const NodePath &np = _target_shader->get_shader_input_nodepath(name->get_parent());
- nassertr(!np.is_empty(), &LMatrix4::ident_mat());
+ nassertv(!np.is_empty());
- return fetch_specified_member(np, name->get_basename(), t);
+ fetch_specified_member(np, name->get_basename(), into[0]);
+ return;
}
case Shader::SMO_light_source_i_attrib: {
const LightAttrib *target_light;
@@ -1466,22 +1537,24 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
// We don't count ambient lights, which would be pretty silly to handle
// via this mechanism.
- size_t num_lights = target_light->get_num_non_ambient_lights();
- if (index >= 0 && (size_t)index < num_lights) {
- NodePath light = target_light->get_on_light((size_t)index);
- nassertr(!light.is_empty(), &LMatrix4::ident_mat());
- Light *light_obj = light.node()->as_light();
- nassertr(light_obj != nullptr, &LMatrix4::ident_mat());
+ size_t num_lights = std::min((size_t)count, target_light->get_num_non_ambient_lights());
- return fetch_specified_member(light, name, t);
-
- } else if (index == 0) {
- // Apply the default OpenGL lights otherwise.
- // Special exception for light 0, which defaults to white.
- string basename = name->get_basename();
- return &LMatrix4::ones_mat();
+ size_t i = 0;
+ for (i = 0; i < num_lights; ++i) {
+ NodePath light = target_light->get_on_light(i);
+ nassertv(!light.is_empty());
+ fetch_specified_member(light, name, into[i]);
}
- return fetch_specified_member(NodePath(), name, t);
+ // Apply the default OpenGL lights otherwise.
+ // Special exception for light 0, which defaults to white.
+ if (i == 0) {
+ into[0] = LMatrix4::ones_mat();
+ ++i;
+ }
+ for (; i < (size_t)count; ++i) {
+ fetch_specified_member(NodePath(), name, into[i]);
+ }
+ return;
}
case Shader::SMO_light_source_i_packed: {
// The light matrix contains COLOR, ATTENUATION, POSITION, VIEWVECTOR
@@ -1490,15 +1563,17 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
// We don't count ambient lights, which would be pretty silly to handle
// via this mechanism.
- size_t num_lights = target_light->get_num_non_ambient_lights();
- if (index >= 0 && (size_t)index < num_lights) {
- NodePath np = target_light->get_on_light((size_t)index);
- nassertr(!np.is_empty(), &LMatrix4::ident_mat());
+ size_t num_lights = std::min((size_t)count, target_light->get_num_non_ambient_lights());
+
+ size_t i = 0;
+ for (i = 0; i < num_lights; ++i) {
+ NodePath np = target_light->get_on_light(i);
+ nassertv(!np.is_empty());
PandaNode *node = np.node();
Light *light = node->as_light();
- nassertr(light != nullptr, &LMatrix4::zeros_mat());
- t.set_row(0, light->get_color());
- t.set_row(1, light->get_attenuation());
+ nassertv(light != nullptr);
+ into[i].set_row(0, light->get_color());
+ into[i].set_row(1, light->get_attenuation());
LMatrix4 mat = np.get_net_transform()->get_mat() *
_scene_setup->get_world_transform()->get_mat();
@@ -1506,42 +1581,47 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
if (node->is_of_type(DirectionalLight::get_class_type())) {
LVecBase3 d = mat.xform_vec(((const DirectionalLight *)node)->get_direction());
d.normalize();
- t.set_row(2, LVecBase4(d, 0));
- t.set_row(3, LVecBase4(-d, 0));
+ into[i].set_row(2, LVecBase4(d, 0));
+ into[i].set_row(3, LVecBase4(-d, 0));
} else if (node->is_of_type(LightLensNode::get_class_type())) {
const Lens *lens = ((const LightLensNode *)node)->get_lens();
LPoint3 p = mat.xform_point(lens->get_nodal_point());
- t.set_row(3, LVecBase4(p));
+ into[i].set_row(3, LVecBase4(p));
// For shadowed point light we need to store near/far.
// For spotlight we need to store cutoff angle.
if (node->is_of_type(Spotlight::get_class_type())) {
PN_stdfloat cutoff = ccos(deg_2_rad(lens->get_hfov() * 0.5f));
LVecBase3 d = -(mat.xform_vec(lens->get_view_vector()));
- t.set_cell(1, 3, ((const Spotlight *)node)->get_exponent());
- t.set_row(2, LVecBase4(d, cutoff));
+ into[i].set_cell(1, 3, ((const Spotlight *)node)->get_exponent());
+ into[i].set_row(2, LVecBase4(d, cutoff));
} else if (node->is_of_type(PointLight::get_class_type())) {
- t.set_cell(1, 3, lens->get_far());
- t.set_cell(3, 3, lens->get_near());
+ into[i].set_cell(1, 3, lens->get_far());
+ into[i].set_cell(3, 3, lens->get_near());
if (node->is_of_type(SphereLight::get_class_type())) {
- t.set_cell(2, 3, ((const SphereLight *)node)->get_radius());
+ into[i].set_cell(2, 3, ((const SphereLight *)node)->get_radius());
}
}
}
- } else if (index == 0) {
- // Apply the default OpenGL lights otherwise.
- // Special exception for light 0, which defaults to white.
- t.set_row(0, LVecBase4(1, 1, 1, 1));
}
- return &t;
+ // Apply the default OpenGL lights otherwise.
+ // Special exception for light 0, which defaults to white.
+ if (i == 0) {
+ into[0].set_row(0, LVecBase4(1, 1, 1, 1));
+ ++i;
+ }
+ for (; i < (size_t)count; ++i) {
+ fetch_specified_member(NodePath(), name, into[i]);
+ }
+ return;
}
default:
- nassertr(false /*should never get here*/, &LMatrix4::ident_mat());
- return &LMatrix4::ident_mat();
+ nassertv(false /*should never get here*/);
+ return;
}
}
@@ -1549,7 +1629,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name,
* Given a NodePath passed into a shader input that is a structure, fetches
* the value for the given member.
*/
-const LMatrix4 *GraphicsStateGuardian::
+void GraphicsStateGuardian::
fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t) {
// This system is not ideal. It will be improved in the future.
static const CPT_InternalName IN_color("color");
@@ -1575,20 +1655,19 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
if (attrib == IN_color) {
if (node == nullptr) {
- return &LMatrix4::ident_mat();
+ t = LMatrix4::ident_mat();
}
Light *light = node->as_light();
- nassertr(light != nullptr, &LMatrix4::ident_mat());
+ nassertv(light != nullptr);
LColor c = light->get_color();
t.set_row(3, c);
- return &t;
} else if (attrib == IN_ambient) {
if (node == nullptr) {
- return &LMatrix4::ident_mat();
+ t = LMatrix4::ident_mat();
}
Light *light = node->as_light();
- nassertr(light != nullptr, &LMatrix4::ident_mat());
+ nassertv(light != nullptr);
if (node->is_ambient_light()) {
LColor c = light->get_color();
t.set_row(3, c);
@@ -1596,14 +1675,13 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
// Non-ambient lights don't currently have an ambient color in Panda3D.
t.set_row(3, LColor(0.0f, 0.0f, 0.0f, 1.0f));
}
- return &t;
} else if (attrib == IN_diffuse) {
if (node == nullptr) {
- return &LMatrix4::ident_mat();
+ t = LMatrix4::ident_mat();
}
Light *light = node->as_light();
- nassertr(light != nullptr, &LMatrix4::ones_mat());
+ nassertv(light != nullptr);
if (node->is_ambient_light()) {
// Ambient light has no diffuse color.
t.set_row(3, LColor(0.0f, 0.0f, 0.0f, 1.0f));
@@ -1611,39 +1689,34 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
LColor c = light->get_color();
t.set_row(3, c);
}
- return &t;
} else if (attrib == IN_specular) {
if (node == nullptr) {
- return &LMatrix4::ident_mat();
+ t = LMatrix4::ident_mat();
}
Light *light = node->as_light();
- nassertr(light != nullptr, &LMatrix4::ones_mat());
+ nassertv(light != nullptr);
t.set_row(3, light->get_specular_color());
- return &t;
} else if (attrib == IN_position) {
if (np.is_empty()) {
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0);
- return &t;
} else if (node->is_ambient_light()) {
// Ambient light has no position.
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- return &t;
} else if (node->is_of_type(DirectionalLight::get_class_type())) {
DirectionalLight *light;
- DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
+ DCAST_INTO_V(light, node);
CPT(TransformState) transform = np.get_transform(_scene_setup->get_scene_root().get_parent());
LVector3 dir = -(light->get_direction() * transform->get_mat());
dir *= _scene_setup->get_cs_world_transform()->get_mat();
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, dir[0], dir[1], dir[2], 0);
- return &t;
} else {
LightLensNode *light;
- DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
+ DCAST_INTO_V(light, node);
Lens *lens = light->get_lens();
- nassertr(lens != nullptr, &LMatrix4::ident_mat());
+ nassertv(lens != nullptr);
CPT(TransformState) transform =
_scene_setup->get_cs_world_transform()->compose(
@@ -1652,20 +1725,17 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
const LMatrix4 &light_mat = transform->get_mat();
LPoint3 pos = lens->get_nodal_point() * light_mat;
t = LMatrix4::translate_mat(pos);
- return &t;
}
} else if (attrib == IN_halfVector) {
if (np.is_empty()) {
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0);
- return &t;
} else if (node->is_ambient_light()) {
// Ambient light has no half-vector.
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
- return &t;
} else if (node->is_of_type(DirectionalLight::get_class_type())) {
DirectionalLight *light;
- DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
+ DCAST_INTO_V(light, node);
CPT(TransformState) transform = np.get_transform(_scene_setup->get_scene_root().get_parent());
LVector3 dir = -(light->get_direction() * transform->get_mat());
@@ -1674,12 +1744,11 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
dir += LVector3(0, 0, 1);
dir.normalize();
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, dir[0], dir[1], dir[2], 1);
- return &t;
} else {
LightLensNode *light;
- DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
+ DCAST_INTO_V(light, node);
Lens *lens = light->get_lens();
- nassertr(lens != nullptr, &LMatrix4::ident_mat());
+ nassertv(lens != nullptr);
CPT(TransformState) transform =
_scene_setup->get_cs_world_transform()->compose(
@@ -1691,22 +1760,19 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
pos += LVector3(0, 0, 1);
pos.normalize();
t.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, pos[0],pos[1],pos[2], 1);
- return &t;
}
} else if (attrib == IN_spotDirection) {
if (node == nullptr) {
t.set_row(3, LVector3(0.0f, 0.0f, -1.0f));
- return &t;
} else if (node->is_ambient_light()) {
// Ambient light has no spot direction.
t.set_row(3, LVector3(0.0f, 0.0f, 0.0f));
- return &t;
} else {
LightLensNode *light;
- DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
+ DCAST_INTO_V(light, node);
Lens *lens = light->get_lens();
- nassertr(lens != nullptr, &LMatrix4::ident_mat());
+ nassertv(lens != nullptr);
CPT(TransformState) transform =
_scene_setup->get_cs_world_transform()->compose(
@@ -1715,93 +1781,87 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
const LMatrix4 &light_mat = transform->get_mat();
LVector3 dir = lens->get_view_vector() * light_mat;
t.set_row(3, dir);
- return &t;
}
} else if (attrib == IN_spotCutoff) {
if (node != nullptr &&
node->is_of_type(Spotlight::get_class_type())) {
LightLensNode *light;
- DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
+ DCAST_INTO_V(light, node);
Lens *lens = light->get_lens();
- nassertr(lens != nullptr, &LMatrix4::ident_mat());
+ nassertv(lens != nullptr);
float cutoff = lens->get_hfov() * 0.5f;
t.set_row(3, LVecBase4(cutoff));
- return &t;
} else {
// Other lights have no cut-off.
t.set_row(3, LVecBase4(180));
- return &t;
}
} else if (attrib == IN_spotCosCutoff) {
if (node != nullptr &&
node->is_of_type(Spotlight::get_class_type())) {
LightLensNode *light;
- DCAST_INTO_R(light, node, &LMatrix4::ident_mat());
+ DCAST_INTO_V(light, node);
Lens *lens = light->get_lens();
- nassertr(lens != nullptr, &LMatrix4::ident_mat());
+ nassertv(lens != nullptr);
float cutoff = lens->get_hfov() * 0.5f;
t.set_row(3, LVecBase4(ccos(deg_2_rad(cutoff))));
- return &t;
} else {
// Other lights have no cut-off.
t.set_row(3, LVecBase4(-1));
- return &t;
}
} else if (attrib == IN_spotExponent) {
if (node == nullptr) {
- return &LMatrix4::zeros_mat();
+ t = LMatrix4::zeros_mat();
+ return;
}
Light *light = node->as_light();
- nassertr(light != nullptr, &LMatrix4::ident_mat());
+ nassertv(light != nullptr);
t.set_row(3, LVecBase4(light->get_exponent()));
- return &t;
} else if (attrib == IN_attenuation) {
if (node != nullptr) {
Light *light = node->as_light();
- nassertr(light != nullptr, &LMatrix4::ones_mat());
+ nassertv(light != nullptr);
t.set_row(3, LVecBase4(light->get_attenuation(), 0));
} else {
t.set_row(3, LVecBase4(1, 0, 0, 0));
}
- return &t;
} else if (attrib == IN_constantAttenuation) {
if (node == nullptr) {
- return &LMatrix4::ones_mat();
+ t = LMatrix4::ones_mat();
+ return;
}
Light *light = node->as_light();
- nassertr(light != nullptr, &LMatrix4::ones_mat());
+ nassertv(light != nullptr);
t.set_row(3, LVecBase4(light->get_attenuation()[0]));
- return &t;
} else if (attrib == IN_linearAttenuation) {
if (node == nullptr) {
- return &LMatrix4::zeros_mat();
+ t = LMatrix4::zeros_mat();
+ return;
}
Light *light = node->as_light();
- nassertr(light != nullptr, &LMatrix4::ident_mat());
+ nassertv(light != nullptr);
t.set_row(3, LVecBase4(light->get_attenuation()[1]));
- return &t;
} else if (attrib == IN_quadraticAttenuation) {
if (node == nullptr) {
- return &LMatrix4::zeros_mat();
+ t = LMatrix4::zeros_mat();
+ return;
}
Light *light = node->as_light();
- nassertr(light != nullptr, &LMatrix4::ident_mat());
+ nassertv(light != nullptr);
t.set_row(3, LVecBase4(light->get_attenuation()[2]));
- return &t;
} else if (attrib == IN_shadowViewMatrix) {
static const LMatrix4 biasmat(0.5f, 0.0f, 0.0f, 0.0f,
@@ -1810,11 +1870,12 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
0.5f, 0.5f, 0.5f, 1.0f);
if (node == nullptr) {
- return &biasmat;
+ t = biasmat;
+ return;
}
LensNode *lnode;
- DCAST_INTO_R(lnode, node, &LMatrix4::ident_mat());
+ DCAST_INTO_V(lnode, node);
Lens *lens = lnode->get_lens();
t = _inv_cs_transform->get_mat() *
@@ -1825,13 +1886,12 @@ fetch_specified_member(const NodePath &np, CPT_InternalName attrib, LMatrix4 &t)
if (!node->is_of_type(PointLight::get_class_type())) {
t *= lens->get_projection_mat() * biasmat;
}
- return &t;
} else {
display_cat.error()
<< "Shader input requests invalid attribute " << *attrib
<< " from node " << np << "\n";
- return &LMatrix4::ident_mat();
+ t = LMatrix4::ident_mat();
}
}
diff --git a/panda/src/display/graphicsStateGuardian.h b/panda/src/display/graphicsStateGuardian.h
index 2e165b6dc6..8d14ab9aba 100644
--- a/panda/src/display/graphicsStateGuardian.h
+++ b/panda/src/display/graphicsStateGuardian.h
@@ -336,10 +336,12 @@ public:
virtual void clear(DrawableRegion *clearable);
- const LMatrix4 *fetch_specified_value(Shader::ShaderMatSpec &spec, int altered);
- const LMatrix4 *fetch_specified_part(Shader::ShaderMatInput input, InternalName *name,
- LMatrix4 &t, int index);
- const LMatrix4 *fetch_specified_member(const NodePath &np, CPT_InternalName member, LMatrix4 &t);
+ void update_shader_matrix_cache(Shader *shader, LMatrix4 *cache, int altered);
+ const LMatrix4 *fetch_specified_value(Shader::ShaderMatSpec &spec, const LMatrix4 *cache, int altered);
+ void fetch_specified_part(Shader::ShaderMatInput input, InternalName *name,
+ LMatrix4 *into, int count = 1);
+ void fetch_specified_member(const NodePath &np, CPT_InternalName member,
+ LMatrix4 &t);
PT(Texture) fetch_specified_texture(Shader::ShaderTexSpec &spec,
SamplerState &sampler, int &view);
const Shader::ShaderPtrData *fetch_ptr_parameter(const Shader::ShaderPtrSpec& spec);
diff --git a/panda/src/display/graphicsWindowProc.h b/panda/src/display/graphicsWindowProc.h
index a330c06a11..3e348200bb 100644
--- a/panda/src/display/graphicsWindowProc.h
+++ b/panda/src/display/graphicsWindowProc.h
@@ -16,7 +16,7 @@
#include "pandabase.h"
-#ifdef WIN32
+#ifdef _WIN32
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1
#endif
diff --git a/panda/src/display/graphicsWindowProcCallbackData.I b/panda/src/display/graphicsWindowProcCallbackData.I
index eb12340a30..2efd54115e 100644
--- a/panda/src/display/graphicsWindowProcCallbackData.I
+++ b/panda/src/display/graphicsWindowProcCallbackData.I
@@ -27,7 +27,7 @@ get_graphics_window() const {
return _graphicsWindow;
}
-#ifdef WIN32
+#ifdef _WIN32
/**
* Returns the Windows proc hwnd parameter.
diff --git a/panda/src/display/graphicsWindowProcCallbackData.cxx b/panda/src/display/graphicsWindowProcCallbackData.cxx
index 82e57ef382..e96eb7057a 100644
--- a/panda/src/display/graphicsWindowProcCallbackData.cxx
+++ b/panda/src/display/graphicsWindowProcCallbackData.cxx
@@ -21,7 +21,7 @@ TypeHandle GraphicsWindowProcCallbackData::_type_handle;
*/
void GraphicsWindowProcCallbackData::
output(std::ostream &out) const {
-#ifdef WIN32
+#ifdef _WIN32
out << get_type() << "(" << (void*)_graphicsWindow << ", " << _hwnd << ", "
<< _msg << ", " << _wparam << ", " << _lparam << ")";
#else
diff --git a/panda/src/display/graphicsWindowProcCallbackData.h b/panda/src/display/graphicsWindowProcCallbackData.h
index 23ae66d9c7..83ce91c8bb 100644
--- a/panda/src/display/graphicsWindowProcCallbackData.h
+++ b/panda/src/display/graphicsWindowProcCallbackData.h
@@ -31,7 +31,7 @@ public:
INLINE GraphicsWindow* get_graphics_window() const;
-#ifdef WIN32
+#ifdef _WIN32
INLINE void set_hwnd(uintptr_t hwnd);
INLINE void set_msg(int msg);
INLINE void set_wparam(int wparam);
@@ -41,7 +41,7 @@ public:
PUBLISHED:
virtual void output(std::ostream &out) const;
-#ifdef WIN32
+#ifdef _WIN32
INLINE uintptr_t get_hwnd() const;
INLINE int get_msg() const;
INLINE int get_wparam() const;
@@ -54,7 +54,7 @@ PUBLISHED:
private:
GraphicsWindow* _graphicsWindow;
-#ifdef WIN32
+#ifdef _WIN32
uintptr_t _hwnd;
int _msg;
int _wparam;
diff --git a/panda/src/display/nativeWindowHandle.I b/panda/src/display/nativeWindowHandle.I
index b897aa2f1c..a77163d672 100644
--- a/panda/src/display/nativeWindowHandle.I
+++ b/panda/src/display/nativeWindowHandle.I
@@ -60,7 +60,7 @@ get_handle() const {
}
#endif // HAVE_X11
-#if defined(WIN32) && !defined(CPPPARSER)
+#if defined(_WIN32) && !defined(CPPPARSER)
/**
*
*/
@@ -69,7 +69,7 @@ WinHandle(HWND handle) : _handle(handle) {
}
#endif // WIN32
-#if defined(WIN32) && !defined(CPPPARSER)
+#if defined(_WIN32) && !defined(CPPPARSER)
/**
*
*/
diff --git a/panda/src/display/nativeWindowHandle.cxx b/panda/src/display/nativeWindowHandle.cxx
index 2ae1973a6f..e04ff12066 100644
--- a/panda/src/display/nativeWindowHandle.cxx
+++ b/panda/src/display/nativeWindowHandle.cxx
@@ -22,7 +22,7 @@ TypeHandle NativeWindowHandle::SubprocessHandle::_type_handle;
#if defined(HAVE_X11) && !defined(CPPPARSER)
TypeHandle NativeWindowHandle::X11Handle::_type_handle;
#endif
-#if defined(WIN32) && !defined(CPPPARSER)
+#if defined(_WIN32) && !defined(CPPPARSER)
TypeHandle NativeWindowHandle::WinHandle::_type_handle;
#endif
@@ -60,7 +60,7 @@ make_x11(X11_Window window) {
}
#endif // HAVE_X11
-#if defined(WIN32) && !defined(CPPPARSER)
+#if defined(_WIN32) && !defined(CPPPARSER)
/**
* Constructs a new WindowHandle that references a window on Windows.
*/
@@ -68,7 +68,7 @@ PT(WindowHandle) NativeWindowHandle::
make_win(HWND window) {
return new WindowHandle(new WinHandle(window));
}
-#endif // WIN32
+#endif // _WIN32
/**
* Returns the OS-specific handle converted to an integer, if this is possible
@@ -116,7 +116,7 @@ output(ostream &out) const {
}
#endif // HAVE_X11
-#if defined(WIN32) && !defined(CPPPARSER)
+#if defined(_WIN32) && !defined(CPPPARSER)
/**
* Returns the OS-specific handle converted to an integer, if this is possible
* for the particular representation. Returns 0 if it is not.
@@ -125,9 +125,9 @@ size_t NativeWindowHandle::WinHandle::
get_int_handle() const {
return (size_t)_handle;
}
-#endif // WIN32
+#endif // _WIN32
-#if defined(WIN32) && !defined(CPPPARSER)
+#if defined(_WIN32) && !defined(CPPPARSER)
/**
*
*/
diff --git a/panda/src/display/nativeWindowHandle.h b/panda/src/display/nativeWindowHandle.h
index 14bab98815..8cabed8cb0 100644
--- a/panda/src/display/nativeWindowHandle.h
+++ b/panda/src/display/nativeWindowHandle.h
@@ -19,7 +19,7 @@
#include "windowHandle.h"
#include "get_x11.h"
-#ifdef WIN32
+#ifdef _WIN32
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1
#endif
@@ -47,7 +47,7 @@ public:
static PT(WindowHandle) make_x11(X11_Window window);
#endif // HAVE_X11
-#if defined(WIN32) && !defined(CPPPARSER)
+#if defined(_WIN32) && !defined(CPPPARSER)
static PT(WindowHandle) make_win(HWND window);
#endif // WIN32
@@ -141,7 +141,7 @@ public:
#endif // HAVE_X11
-#if defined(WIN32) && !defined(CPPPARSER)
+#if defined(_WIN32) && !defined(CPPPARSER)
class EXPCL_PANDA_DISPLAY WinHandle : public OSHandle {
public:
INLINE WinHandle(HWND handle);
@@ -186,7 +186,7 @@ public:
#if defined(HAVE_X11) && !defined(CPPPARSER)
X11Handle::init_type();
#endif
-#if defined(WIN32) && !defined(CPPPARSER)
+#if defined(_WIN32) && !defined(CPPPARSER)
WinHandle::init_type();
#endif
}
diff --git a/panda/src/distort/CMakeLists.txt b/panda/src/distort/CMakeLists.txt
new file mode 100644
index 0000000000..2a555fcdc9
--- /dev/null
+++ b/panda/src/distort/CMakeLists.txt
@@ -0,0 +1,33 @@
+set(P3DISTORT_HEADERS
+ config_distort.h
+ cylindricalLens.h cylindricalLens.I
+ fisheyeLens.h fisheyeLens.I
+ nonlinearImager.h nonlinearImager.I
+ oSphereLens.h oSphereLens.I
+ projectionScreen.h projectionScreen.I
+ pSphereLens.h pSphereLens.I
+)
+
+set(P3DISTORT_SOURCES
+ config_distort.cxx
+ cylindricalLens.cxx
+ fisheyeLens.cxx
+ nonlinearImager.cxx
+ oSphereLens.cxx
+ projectionScreen.cxx
+ pSphereLens.cxx
+)
+
+composite_sources(pandafx P3DISTORT_SOURCES)
+add_library(pandafx ${P3DISTORT_HEADERS} ${P3DISTORT_SOURCES})
+set_target_properties(pandafx PROPERTIES DEFINE_SYMBOL BUILDING_PANDAFX)
+target_link_libraries(pandafx panda)
+target_interrogate(pandafx ALL)
+
+install(TARGETS pandafx
+ EXPORT Core COMPONENT Core
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT CoreDevel)
+install(FILES ${P3DISTORT_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/panda/src/downloader/CMakeLists.txt b/panda/src/downloader/CMakeLists.txt
new file mode 100644
index 0000000000..25ba1f6efc
--- /dev/null
+++ b/panda/src/downloader/CMakeLists.txt
@@ -0,0 +1,75 @@
+set(P3DOWNLOADER_HEADERS
+ bioPtr.I bioPtr.h
+ bioStreamPtr.I bioStreamPtr.h
+ bioStream.I bioStream.h bioStreamBuf.h
+ chunkedStream.I chunkedStream.h
+ chunkedStreamBuf.h chunkedStreamBuf.I
+ config_downloader.h
+ decompressor.h decompressor.I
+ documentSpec.h documentSpec.I
+ download_utils.h downloadDb.h downloadDb.I
+ extractor.h extractor.I
+ httpAuthorization.I httpAuthorization.h
+ httpBasicAuthorization.I httpBasicAuthorization.h
+ httpChannel.I httpChannel.h
+ httpClient.I httpClient.h
+ httpCookie.I httpCookie.h
+ httpDate.I httpDate.h
+ httpDigestAuthorization.I httpDigestAuthorization.h
+ httpEntityTag.I httpEntityTag.h
+ httpEnum.h
+ identityStream.I identityStream.h
+ identityStreamBuf.h identityStreamBuf.I
+ multiplexStream.I multiplexStream.h
+ multiplexStreamBuf.I multiplexStreamBuf.h
+ patcher.h patcher.I
+ socketStream.h socketStream.I
+ urlSpec.h urlSpec.I
+ virtualFileHTTP.I virtualFileHTTP.h
+ virtualFileMountHTTP.I virtualFileMountHTTP.h
+)
+
+set(P3DOWNLOADER_SOURCES
+ config_downloader.cxx
+ bioPtr.cxx
+ bioStreamPtr.cxx
+ bioStream.cxx bioStreamBuf.cxx
+ chunkedStream.cxx chunkedStreamBuf.cxx
+ decompressor.cxx
+ documentSpec.cxx
+ downloadDb.cxx
+ download_utils.cxx
+ extractor.cxx
+ httpAuthorization.cxx
+ httpBasicAuthorization.cxx
+ httpChannel.cxx
+ httpClient.cxx
+ httpCookie.cxx
+ httpDate.cxx
+ httpDigestAuthorization.cxx
+ httpEntityTag.cxx
+ httpEnum.cxx
+ identityStream.cxx identityStreamBuf.cxx
+ multiplexStream.cxx multiplexStreamBuf.cxx
+ patcher.cxx
+ socketStream.cxx
+ urlSpec.cxx
+ virtualFileHTTP.cxx
+ virtualFileMountHTTP.cxx
+)
+
+composite_sources(p3downloader P3DOWNLOADER_SOURCES)
+add_component_library(p3downloader SYMBOL BUILDING_PANDA_DOWNLOADER
+ ${P3DOWNLOADER_HEADERS} ${P3DOWNLOADER_SOURCES})
+target_link_libraries(p3downloader p3express)
+target_interrogate(p3downloader ALL)
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3downloader
+ EXPORT Core COMPONENT Core
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT CoreDevel)
+endif()
+install(FILES ${P3DOWNLOADER_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/panda/src/downloader/bioStreamBuf.cxx b/panda/src/downloader/bioStreamBuf.cxx
index 1598b15259..ffa6a2994e 100644
--- a/panda/src/downloader/bioStreamBuf.cxx
+++ b/panda/src/downloader/bioStreamBuf.cxx
@@ -18,11 +18,11 @@
#ifdef HAVE_OPENSSL
-#if defined(WIN32_VC) || defined(WIN64_VC)
- #include
+#ifdef _WIN32
+ #include
#include // for WSAGetLastError()
#undef X509_NAME
-#endif // WIN32_VC
+#endif // _WIN32
/**
*
@@ -162,11 +162,11 @@ underflow() {
if (read_count <= 0) {
// Immediately save the os error in case we screw up and do something
// that will change its value before we can output it.
-#if defined(WIN32_VC) || defined(WIN64_VC)
+#ifdef _WIN32
int os_error = WSAGetLastError();
#else
int os_error = errno;
-#endif // WIN32_VC
+#endif // _WIN32
// Though BIO_eof() is tempting, it appears there are cases in which
// that never returns true, if the socket is closed by the server.
@@ -197,13 +197,13 @@ underflow() {
<< "\n";
}
-#if defined(WIN32_VC) || defined(WIN64_VC)
+#ifdef _WIN32
downloader_cat.warning()
<< "Windows error code: " << os_error << "\n";
#else
downloader_cat.warning()
<< "Unix error code: " << os_error << "\n";
-#endif // WIN32_VC
+#endif // _WIN32
}
gbump(num_bytes);
return EOF;
diff --git a/panda/src/downloader/httpChannel.cxx b/panda/src/downloader/httpChannel.cxx
index 365c819b0f..f066b24943 100644
--- a/panda/src/downloader/httpChannel.cxx
+++ b/panda/src/downloader/httpChannel.cxx
@@ -29,11 +29,11 @@
#include "openSSLWrapper.h"
-#if defined(WIN32_VC) || defined(WIN64_VC)
- #include
+#ifdef _WIN32
+ #include
#include // for select()
#undef X509_NAME
-#endif // WIN32_VC
+#endif // _WIN32
using std::istream;
using std::min;
diff --git a/panda/src/downloader/multiplexStreamBuf.cxx b/panda/src/downloader/multiplexStreamBuf.cxx
index aa42d33f9e..9c58593282 100644
--- a/panda/src/downloader/multiplexStreamBuf.cxx
+++ b/panda/src/downloader/multiplexStreamBuf.cxx
@@ -13,7 +13,7 @@
#include "multiplexStreamBuf.h"
-#if defined(WIN32_VC) || defined(WIN64_VC)
+#ifdef _WIN32
#define WINDOWS_LEAN_AND_MEAN
#include
#undef WINDOWS_LEAN_AND_MEAN
@@ -68,7 +68,7 @@ write_string(const string &str) {
break;
case OT_system_debug:
-#if defined(WIN32_VC) || defined(WIN64_VC)
+#ifdef _WIN32
OutputDebugString(str.c_str());
#endif
break;
diff --git a/panda/src/downloadertools/CMakeLists.txt b/panda/src/downloadertools/CMakeLists.txt
new file mode 100644
index 0000000000..47abcb727f
--- /dev/null
+++ b/panda/src/downloadertools/CMakeLists.txt
@@ -0,0 +1,46 @@
+if(NOT BUILD_PANDATOOL)
+ # It's safe to say, if the user doesn't want pandatool, they don't want these
+ # tools either.
+ return()
+endif()
+
+if(HAVE_OPENSSL)
+ add_executable(pencrypt pencrypt.cxx)
+ target_link_libraries(pencrypt panda)
+
+ add_executable(pdecrypt pdecrypt.cxx)
+ target_link_libraries(pdecrypt panda)
+
+ install(TARGETS pencrypt pdecrypt
+ EXPORT Tools COMPONENT Tools
+ DESTINATION ${CMAKE_INSTALL_BINDIR})
+endif()
+
+if(HAVE_ZLIB)
+ add_executable(pzip pzip.cxx)
+ target_link_libraries(pzip panda)
+
+ if(NOT CMAKE_CROSSCOMPILING)
+ add_executable(host_pzip ALIAS pzip)
+ else()
+ find_program(HOST_PATH_PZIP pzip)
+
+ add_executable(host_pzip IMPORTED GLOBAL)
+ if(HOST_PATH_PZIP)
+ set_target_properties(host_pzip PROPERTIES
+ IMPORTED_LOCATION "${HOST_PATH_PZIP}")
+ endif()
+
+ endif()
+
+ add_executable(punzip punzip.cxx)
+ target_link_libraries(punzip panda)
+
+ install(TARGETS pzip punzip
+ EXPORT Tools COMPONENT Tools
+ DESTINATION ${CMAKE_INSTALL_BINDIR})
+endif()
+
+add_executable(multify multify.cxx)
+target_link_libraries(multify panda)
+install(TARGETS multify EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
diff --git a/panda/src/dxgsg9/CMakeLists.txt b/panda/src/dxgsg9/CMakeLists.txt
new file mode 100644
index 0000000000..dd7ad9ff7f
--- /dev/null
+++ b/panda/src/dxgsg9/CMakeLists.txt
@@ -0,0 +1,56 @@
+if(NOT HAVE_DX9)
+ return()
+endif()
+
+set(P3DXGSG9_HEADERS
+ config_dxgsg9.h
+ dxGeomMunger9.h dxGeomMunger9.I
+ dxGraphicsDevice9.h
+ dxGraphicsStateGuardian9.h dxGraphicsStateGuardian9.I
+ dxgsg9base.h
+ dxIndexBufferContext9.h dxIndexBufferContext9.I
+ dxOcclusionQueryContext9.h dxOcclusionQueryContext9.I
+ dxShaderContext9.h dxShaderContext9.I
+ dxTextureContext9.h dxTextureContext9.I
+ dxVertexBufferContext9.h dxVertexBufferContext9.I
+ vertexElementArray.h
+ wdxGraphicsBuffer9.h wdxGraphicsBuffer9.I
+ wdxGraphicsPipe9.h wdxGraphicsPipe9.I
+ wdxGraphicsWindow9.h wdxGraphicsWindow9.I
+)
+
+set(P3DXGSG9_SOURCES
+ config_dxgsg9.cxx
+ dxGeomMunger9.cxx
+ dxGraphicsDevice9.cxx
+ dxGraphicsStateGuardian9.cxx
+ dxIndexBufferContext9.cxx
+ dxOcclusionQueryContext9.cxx
+ dxShaderContext9.cxx
+ dxTextureContext9.cxx
+ dxVertexBufferContext9.cxx
+ vertexElementArray.cxx
+ wdxGraphicsBuffer9.cxx
+ wdxGraphicsPipe9.cxx
+ wdxGraphicsWindow9.cxx
+)
+
+# This is a large file; let's build it separately
+set_source_files_properties(dxGraphicsStateGuardian9.cxx PROPERTIES SKIP_UNITY_BUILD_INCLUSION YES)
+
+composite_sources(p3dxgsg9 P3DXGSG9_SOURCES)
+add_component_library(p3dxgsg9 SYMBOL BUILDING_PANDADX
+ ${P3DXGSG9_HEADERS} ${P3DXGSG9_SOURCES})
+target_link_libraries(p3dxgsg9 p3windisplay panda
+ PKG::CG PKG::DX9)
+target_compile_definitions(p3dxgsg9 PUBLIC USE_GENERIC_DXERR_LIBRARY) # FIXME
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3dxgsg9
+ EXPORT DX9 COMPONENT DX9
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT DX9Devel)
+endif()
+install(FILES ${P3DXGSG9_HEADERS} COMPONENT DX9Devel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/panda/src/dxgsg9/dxShaderContext9.cxx b/panda/src/dxgsg9/dxShaderContext9.cxx
index a737c342bf..6c7a15d313 100644
--- a/panda/src/dxgsg9/dxShaderContext9.cxx
+++ b/panda/src/dxgsg9/dxShaderContext9.cxx
@@ -74,6 +74,8 @@ DXShaderContext9(Shader *s, GSG *gsg) : ShaderContext(s) {
}
}
#endif
+
+ _mat_part_cache = new LMatrix4[s->cp_get_mat_cache_size()];
}
/**
@@ -92,6 +94,8 @@ DXShaderContext9::
delete _vertex_element_array;
_vertex_element_array = nullptr;
}
+
+ delete[] _mat_part_cache;
}
/**
@@ -232,15 +236,20 @@ issue_parameters(GSG *gsg, int altered) {
}
}
- for (size_t i = 0; i < _shader->_mat_spec.size(); ++i) {
- Shader::ShaderMatSpec &spec = _shader->_mat_spec[i];
+ if (altered & _shader->_mat_deps) {
+ gsg->update_shader_matrix_cache(_shader, _mat_part_cache, altered);
+
+ for (Shader::ShaderMatSpec &spec : _shader->_mat_spec) {
+ if ((altered & spec._dep) == 0) {
+ continue;
+ }
- if (altered & (spec._dep[0] | spec._dep[1])) {
CGparameter p = _cg_parameter_map[spec._id._seqno];
if (p == nullptr) {
continue;
}
- const LMatrix4 *val = gsg->fetch_specified_value(spec, altered);
+
+ const LMatrix4 *val = gsg->fetch_specified_value(spec, _mat_part_cache, altered);
if (val) {
HRESULT hr;
PN_stdfloat v [4];
diff --git a/panda/src/dxgsg9/dxShaderContext9.h b/panda/src/dxgsg9/dxShaderContext9.h
index b637cb0a81..c02dcea201 100644
--- a/panda/src/dxgsg9/dxShaderContext9.h
+++ b/panda/src/dxgsg9/dxShaderContext9.h
@@ -87,6 +87,8 @@ private:
pvector _cg_parameter_map;
#endif
+ LMatrix4 *_mat_part_cache = nullptr;
+
private:
void release_resources(void);
diff --git a/panda/src/dxml/CMakeLists.txt b/panda/src/dxml/CMakeLists.txt
new file mode 100644
index 0000000000..8b67b09d35
--- /dev/null
+++ b/panda/src/dxml/CMakeLists.txt
@@ -0,0 +1,28 @@
+set(P3DXML_HEADERS
+ config_dxml.h
+ tinyxml.h
+)
+
+set(P3DXML_SOURCES
+ config_dxml.cxx
+ tinyxml.cpp
+ tinyxmlerror.cpp
+ tinyxmlparser.cpp
+)
+
+composite_sources(p3dxml P3DXML_SOURCES)
+add_definitions(-DTIXML_USE_STL)
+add_component_library(p3dxml SYMBOL BUILDING_PANDA_DXML
+ ${P3DXML_HEADERS} ${P3DXML_SOURCES})
+target_link_libraries(p3dxml pandaexpress)
+target_interrogate(p3dxml ALL)
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3dxml
+ EXPORT Core COMPONENT Core
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT CoreDevel)
+endif()
+install(FILES ${P3DXML_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/panda/src/egg/CMakeLists.txt b/panda/src/egg/CMakeLists.txt
new file mode 100644
index 0000000000..5cdd891182
--- /dev/null
+++ b/panda/src/egg/CMakeLists.txt
@@ -0,0 +1,115 @@
+if(NOT HAVE_EGG)
+ return()
+endif()
+
+set(P3EGG_HEADERS
+ config_egg.h eggAnimData.I eggAnimData.h
+ eggAnimPreload.I eggAnimPreload.h
+ eggAttributes.I
+ eggAttributes.h eggBin.h eggBinMaker.h eggComment.I
+ eggComment.h
+ eggCompositePrimitive.I eggCompositePrimitive.h
+ eggCoordinateSystem.I eggCoordinateSystem.h
+ eggCurve.I eggCurve.h eggData.I eggData.h
+ eggExternalReference.I eggExternalReference.h
+ eggFilenameNode.I eggFilenameNode.h eggGroup.I eggGroup.h
+ eggGroupNode.I eggGroupNode.h eggGroupUniquifier.h
+ eggLine.I eggLine.h
+ eggMaterial.I eggMaterial.h eggMaterialCollection.I
+ eggMaterialCollection.h
+ eggMesher.h eggMesher.I
+ eggMesherEdge.h eggMesherEdge.I
+ eggMesherFanMaker.h eggMesherFanMaker.I
+ eggMesherStrip.h eggMesherStrip.I
+ eggMiscFuncs.I eggMiscFuncs.h
+ eggMorph.I eggMorph.h eggMorphList.I eggMorphList.h
+ eggNamedObject.I eggNamedObject.h eggNameUniquifier.h
+ eggNode.I eggNode.h eggNurbsCurve.I eggNurbsCurve.h
+ eggNurbsSurface.I eggNurbsSurface.h eggObject.I eggObject.h
+ eggParameters.h
+ eggPatch.I eggPatch.h
+ eggPoint.I eggPoint.h eggPolygon.I
+ eggPolygon.h eggPolysetMaker.h eggPoolUniquifier.h
+ eggPrimitive.I eggPrimitive.h
+ eggRenderMode.I eggRenderMode.h
+ eggSAnimData.I eggSAnimData.h eggSurface.I eggSurface.h
+ eggSwitchCondition.h eggTable.I eggTable.h eggTexture.I
+ eggTexture.h eggTextureCollection.I eggTextureCollection.h
+ eggTriangleFan.I eggTriangleFan.h
+ eggTriangleStrip.I eggTriangleStrip.h
+ eggTransform.I eggTransform.h
+ eggUserData.I eggUserData.h
+ eggUtilities.I eggUtilities.h
+ eggVertex.I eggVertex.h
+ eggVertexAux.I eggVertexAux.h
+ eggVertexPool.I eggVertexPool.h
+ eggVertexUV.I eggVertexUV.h
+ eggXfmAnimData.I
+ eggXfmAnimData.h eggXfmSAnim.I eggXfmSAnim.h parserDefs.h
+ parser.yxx lexerDefs.h lexer.lxx pt_EggMaterial.h
+ vector_PT_EggMaterial.h pt_EggTexture.h
+ vector_PT_EggTexture.h pt_EggVertex.h vector_PT_EggVertex.h
+)
+
+set(P3EGG_SOURCES
+ config_egg.cxx eggAnimData.cxx
+ eggAnimPreload.cxx
+ eggAttributes.cxx eggBin.cxx
+ eggBinMaker.cxx eggComment.cxx
+ eggCompositePrimitive.cxx
+ eggCoordinateSystem.cxx
+ eggCurve.cxx eggData.cxx eggExternalReference.cxx
+ eggFilenameNode.cxx eggGroup.cxx eggGroupNode.cxx
+ eggGroupUniquifier.cxx eggLine.cxx eggMaterial.cxx
+ eggMaterialCollection.cxx
+ eggMesher.cxx
+ eggMesherEdge.cxx
+ eggMesherFanMaker.cxx
+ eggMesherStrip.cxx
+ eggMiscFuncs.cxx eggMorphList.cxx
+ eggNamedObject.cxx eggNameUniquifier.cxx eggNode.cxx
+ eggNurbsCurve.cxx eggNurbsSurface.cxx eggObject.cxx
+ eggParameters.cxx
+ eggPatch.cxx
+ eggPoint.cxx eggPolygon.cxx eggPolysetMaker.cxx
+ eggPoolUniquifier.cxx eggPrimitive.cxx eggRenderMode.cxx
+ eggSAnimData.cxx eggSurface.cxx eggSwitchCondition.cxx
+ eggTable.cxx eggTexture.cxx eggTextureCollection.cxx
+ eggTransform.cxx
+ eggTriangleFan.cxx
+ eggTriangleStrip.cxx
+ eggUserData.cxx
+ eggUtilities.cxx eggVertex.cxx
+ eggVertexAux.cxx
+ eggVertexPool.cxx eggVertexUV.cxx
+ eggXfmAnimData.cxx eggXfmSAnim.cxx pt_EggMaterial.cxx
+ vector_PT_EggMaterial.cxx pt_EggTexture.cxx
+ vector_PT_EggTexture.cxx pt_EggVertex.cxx
+ vector_PT_EggVertex.cxx
+)
+
+set(P3EGG_IGATEEXT
+ eggGroupNode_ext.cxx
+ eggGroupNode_ext.h
+)
+
+# These cannot be interrogated, and are excluded from the composites.
+add_bison_target(parser.cxx parser.yxx DEFINES parser.h PREFIX eggyy)
+add_flex_target(lexer.cxx lexer.lxx CASE_INSENSITIVE PREFIX eggyy)
+set(P3EGG_PARSER_SOURCES parser.cxx lexer.cxx)
+
+composite_sources(p3egg P3EGG_SOURCES)
+add_component_library(p3egg SYMBOL BUILDING_PANDA_EGG
+ ${P3EGG_HEADERS} ${P3EGG_SOURCES} ${P3EGG_PARSER_SOURCES})
+target_link_libraries(p3egg panda)
+target_interrogate(p3egg ${P3EGG_HEADERS} ${P3EGG_SOURCES} EXTENSIONS ${P3EGG_IGATEEXT})
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3egg
+ EXPORT Egg COMPONENT Egg
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT EggDevel)
+endif()
+install(FILES ${P3EGG_HEADERS} COMPONENT EggDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/panda/src/egg/eggGroupNode.h b/panda/src/egg/eggGroupNode.h
index 8bbf48aea0..6feaf2fab4 100644
--- a/panda/src/egg/eggGroupNode.h
+++ b/panda/src/egg/eggGroupNode.h
@@ -70,7 +70,7 @@ PUBLISHED:
// limited add_childremove_child or inserterase interface. The following
// implements this.
public:
-#if defined(WIN32_VC) || defined(WIN64_VC)
+#ifdef _WIN32
typedef const PT(EggNode) *pointer;
typedef const PT(EggNode) *const_pointer;
#else
diff --git a/panda/src/egg/eggPrimitive.h b/panda/src/egg/eggPrimitive.h
index 4b8a035952..b20c81ba73 100644
--- a/panda/src/egg/eggPrimitive.h
+++ b/panda/src/egg/eggPrimitive.h
@@ -140,7 +140,7 @@ PUBLISHED:
// through the limited add_vertexremove_vertex or inserterase interface.
// The following implements this.
public:
-#if defined(WIN32_VC) || defined(WIN64_VC)
+#ifdef _WIN32
typedef PT_EggVertex *pointer;
typedef PT_EggVertex *const_pointer;
#else
diff --git a/panda/src/egg2pg/CMakeLists.txt b/panda/src/egg2pg/CMakeLists.txt
new file mode 100644
index 0000000000..e0dcd91763
--- /dev/null
+++ b/panda/src/egg2pg/CMakeLists.txt
@@ -0,0 +1,49 @@
+if(NOT HAVE_EGG)
+ return()
+endif()
+
+set(P3EGG2PG_HEADERS
+ animBundleMaker.h
+ characterMaker.h
+ config_egg2pg.h
+ deferredNodeProperty.h
+ eggBinner.h
+ eggLoader.h eggLoader.I
+ eggRenderState.h eggRenderState.I
+ eggSaver.h eggSaver.I
+ egg_parametrics.h
+ load_egg_file.h
+ save_egg_file.h
+ loaderFileTypeEgg.h
+)
+
+set(P3EGG2PG_SOURCES
+ animBundleMaker.cxx
+ characterMaker.cxx
+ config_egg2pg.cxx
+ deferredNodeProperty.cxx
+ eggBinner.cxx
+ eggLoader.cxx
+ eggRenderState.cxx
+ eggSaver.cxx
+ egg_parametrics.cxx
+ load_egg_file.cxx
+ save_egg_file.cxx
+ loaderFileTypeEgg.cxx
+)
+
+composite_sources(p3egg2pg P3EGG2PG_SOURCES)
+add_component_library(p3egg2pg SYMBOL BUILDING_PANDA_EGG2PG
+ ${P3EGG2PG_HEADERS} ${P3EGG2PG_SOURCES})
+target_link_libraries(p3egg2pg panda p3egg)
+target_interrogate(p3egg2pg ALL)
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3egg2pg
+ EXPORT Egg COMPONENT Egg
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT EggDevel)
+endif()
+install(FILES ${P3EGG2PG_HEADERS} COMPONENT EggDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/panda/src/egldisplay/CMakeLists.txt b/panda/src/egldisplay/CMakeLists.txt
new file mode 100644
index 0000000000..d228f14f6c
--- /dev/null
+++ b/panda/src/egldisplay/CMakeLists.txt
@@ -0,0 +1,68 @@
+if(NOT HAVE_EGL OR NOT HAVE_X11)
+ return()
+endif()
+
+if(NOT HAVE_GLES1 AND NOT HAVE_GLES2)
+ return()
+endif()
+
+set(P3EGLDISPLAY_HEADERS
+ config_egldisplay.h
+ eglGraphicsBuffer.h
+ eglGraphicsPipe.h eglGraphicsPipe.I
+ eglGraphicsPixmap.h
+ eglGraphicsStateGuardian.h eglGraphicsStateGuardian.I
+ eglGraphicsWindow.h eglGraphicsWindow.I
+)
+
+set(P3EGLDISPLAY_SOURCES
+ config_egldisplay.cxx
+ eglGraphicsBuffer.cxx
+ eglGraphicsPipe.cxx
+ eglGraphicsPixmap.cxx
+ eglGraphicsStateGuardian.cxx
+ eglGraphicsWindow.cxx
+)
+
+composite_sources(p3egldisplay P3EGLDISPLAY_SOURCES)
+
+# We actually build this twice! Once for GLES1, once for GLES2.
+if(HAVE_GLES1)
+ add_component_library(p3egldisplay_gles1 SYMBOL BUILDING_PANDAGLES
+ INIT init_libegldisplay config_egldisplay.h
+ ${P3EGLDISPLAY_HEADERS} ${P3EGLDISPLAY_SOURCES})
+ target_compile_definitions(p3egldisplay_gles1 PUBLIC OPENGLES_1)
+ target_link_libraries(p3egldisplay_gles1 p3glesgsg p3x11display
+ PKG::EGL PKG::GLES1)
+
+ if(NOT BUILD_METALIBS)
+ install(TARGETS p3egldisplay_gles1
+ EXPORT OpenGLES1 COMPONENT OpenGLES1
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT OpenGLES1Devel)
+ endif()
+
+ install(FILES ${P3EGLDISPLAY_HEADERS} COMPONENT OpenGLES1Devel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
+endif()
+
+if(HAVE_GLES2)
+ add_component_library(p3egldisplay_gles2 SYMBOL BUILDING_PANDAGLES2
+ INIT init_libegldisplay config_egldisplay.h
+ ${P3EGLDISPLAY_HEADERS} ${P3EGLDISPLAY_SOURCES})
+ target_compile_definitions(p3egldisplay_gles2 PUBLIC OPENGLES_2)
+ target_link_libraries(p3egldisplay_gles2 p3gles2gsg p3x11display
+ PKG::EGL PKG::GLES2)
+
+ if(NOT BUILD_METALIBS)
+ install(TARGETS p3egldisplay_gles2
+ EXPORT OpenGLES2 COMPONENT OpenGLES2
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT OpenGLES2Devel)
+ endif()
+
+ install(FILES ${P3EGLDISPLAY_HEADERS} COMPONENT OpenGLES2Devel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
+endif()
diff --git a/panda/src/event/CMakeLists.txt b/panda/src/event/CMakeLists.txt
new file mode 100644
index 0000000000..b0464ff793
--- /dev/null
+++ b/panda/src/event/CMakeLists.txt
@@ -0,0 +1,61 @@
+set(P3EVENT_HEADERS
+ asyncFuture.h asyncFuture.I
+ asyncTask.h asyncTask.I
+ asyncTaskChain.h asyncTaskChain.I
+ asyncTaskCollection.h asyncTaskCollection.I
+ asyncTaskManager.h asyncTaskManager.I
+ asyncTaskPause.h asyncTaskPause.I
+ asyncTaskSequence.h asyncTaskSequence.I
+ config_event.h
+ buttonEvent.I buttonEvent.h
+ buttonEventList.I buttonEventList.h
+ genericAsyncTask.h genericAsyncTask.I
+ pointerEvent.I pointerEvent.h
+ pointerEventList.I pointerEventList.h
+ event.I event.h eventHandler.h eventHandler.I
+ eventParameter.I eventParameter.h
+ eventQueue.I eventQueue.h eventReceiver.h
+ pt_Event.h throw_event.I throw_event.h
+)
+
+set(P3EVENT_SOURCES
+ asyncFuture.cxx
+ asyncTask.cxx
+ asyncTaskChain.cxx
+ asyncTaskCollection.cxx
+ asyncTaskManager.cxx
+ asyncTaskPause.cxx
+ asyncTaskSequence.cxx
+ buttonEvent.cxx
+ buttonEventList.cxx
+ genericAsyncTask.cxx
+ pointerEvent.cxx
+ pointerEventList.cxx
+ config_event.cxx event.cxx eventHandler.cxx
+ eventParameter.cxx eventQueue.cxx eventReceiver.cxx
+ pt_Event.cxx
+)
+
+set(P3EVENT_IGATEEXT
+ asyncFuture_ext.cxx
+ asyncFuture_ext.h
+ pythonTask.cxx
+ pythonTask.h
+ pythonTask.I
+)
+
+composite_sources(p3event P3EVENT_SOURCES)
+add_component_library(p3event NOINIT SYMBOL BUILDING_PANDA_EVENT
+ ${P3EVENT_HEADERS} ${P3EVENT_SOURCES})
+target_link_libraries(p3event p3linmath p3pstatclient)
+target_interrogate(p3event ALL EXTENSIONS ${P3EVENT_IGATEEXT})
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3event
+ EXPORT Core COMPONENT Core
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT CoreDevel)
+endif()
+install(FILES ${P3EVENT_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/panda/src/express/CMakeLists.txt b/panda/src/express/CMakeLists.txt
new file mode 100644
index 0000000000..b45a55d11c
--- /dev/null
+++ b/panda/src/express/CMakeLists.txt
@@ -0,0 +1,176 @@
+set(P3EXPRESS_HEADERS
+ buffer.I buffer.h
+ checksumHashGenerator.I checksumHashGenerator.h circBuffer.I
+ circBuffer.h
+ compress_string.h
+ config_express.h
+ copy_stream.h
+ datagram.I datagram.h datagramGenerator.I
+ datagramGenerator.h
+ datagramIterator.I datagramIterator.h datagramSink.I datagramSink.h
+ dcast.T dcast.h
+ encrypt_string.h
+ error_utils.h
+ export_dtool.h
+ fileReference.h fileReference.I
+ hashGeneratorBase.I hashGeneratorBase.h
+ hashVal.I hashVal.h
+ indirectLess.I indirectLess.h
+ memoryInfo.I memoryInfo.h
+ memoryUsage.I memoryUsage.h
+ memoryUsagePointerCounts.I memoryUsagePointerCounts.h
+ memoryUsagePointers.I memoryUsagePointers.h
+ multifile.I multifile.h
+ namable.I
+ namable.h
+ nodePointerTo.h nodePointerTo.I
+ nodePointerToBase.h nodePointerToBase.I
+ nodeReferenceCount.h nodeReferenceCount.I
+ openSSLWrapper.h openSSLWrapper.I
+ ordered_vector.h ordered_vector.I ordered_vector.T
+ pStatCollectorForwardBase.h
+ password_hash.h
+ patchfile.I patchfile.h
+ pointerTo.I pointerTo.h
+ pointerToArray.I pointerToArray.h
+ pointerToArrayBase.I pointerToArrayBase.h
+ pointerToBase.I pointerToBase.h
+ pointerToVoid.I pointerToVoid.h
+ pta_int.h
+ pta_uchar.h pta_double.h pta_float.h
+ pta_stdfloat.h
+ ramfile.I ramfile.h
+ referenceCount.I referenceCount.h
+ stringStreamBuf.I stringStreamBuf.h
+ stringStream.I stringStream.h
+ subStream.I subStream.h subStreamBuf.h
+ subfileInfo.h subfileInfo.I
+ temporaryFile.h temporaryFile.I
+ trueClock.I trueClock.h
+ typedReferenceCount.I typedReferenceCount.h typedef.h
+ virtualFileList.I virtualFileList.h
+ virtualFileComposite.h virtualFileComposite.I
+ virtualFile.h virtualFile.I
+ virtualFileMount.h virtualFileMount.I
+ virtualFileMountAndroidAsset.h virtualFileMountAndroidAsset.I
+ virtualFileMountMultifile.h virtualFileMountMultifile.I
+ virtualFileMountRamdisk.h virtualFileMountRamdisk.I
+ virtualFileMountSystem.h virtualFileMountSystem.I
+ virtualFileSimple.h virtualFileSimple.I
+ virtualFileSystem.h virtualFileSystem.I
+ weakPointerCallback.I weakPointerCallback.h
+ weakPointerTo.I weakPointerTo.h
+ weakPointerToBase.I weakPointerToBase.h
+ weakPointerToVoid.I weakPointerToVoid.h
+ weakReferenceList.I weakReferenceList.h
+ windowsRegistry.h
+ zStream.I zStream.h zStreamBuf.h
+)
+
+set(P3EXPRESS_SOURCES
+ buffer.cxx checksumHashGenerator.cxx
+ compress_string.cxx
+ config_express.cxx
+ copy_stream.cxx
+ datagram.cxx datagramGenerator.cxx
+ datagramIterator.cxx
+ datagramSink.cxx dcast.cxx
+ encrypt_string.cxx
+ error_utils.cxx
+ fileReference.cxx
+ hashGeneratorBase.cxx hashVal.cxx
+ memoryInfo.cxx memoryUsage.cxx memoryUsagePointerCounts.cxx
+ memoryUsagePointers.cxx multifile.cxx
+ namable.cxx
+ nodePointerTo.cxx
+ nodePointerToBase.cxx
+ nodeReferenceCount.cxx
+ openSSLWrapper.cxx
+ ordered_vector.cxx
+ pStatCollectorForwardBase.cxx
+ password_hash.cxx
+ patchfile.cxx
+ pointerTo.cxx
+ pointerToArray.cxx
+ pointerToBase.cxx
+ pointerToVoid.cxx
+ pta_int.cxx
+ pta_uchar.cxx pta_double.cxx pta_float.cxx
+ ramfile.cxx
+ referenceCount.cxx
+ stringStreamBuf.cxx
+ stringStream.cxx
+ subStream.cxx subStreamBuf.cxx
+ subfileInfo.cxx
+ temporaryFile.cxx
+ trueClock.cxx
+ typedReferenceCount.cxx
+ virtualFileComposite.cxx virtualFile.cxx virtualFileList.cxx
+ virtualFileMount.cxx
+ virtualFileMountMultifile.cxx
+ virtualFileMountRamdisk.cxx
+ virtualFileMountSystem.cxx
+ virtualFileSimple.cxx virtualFileSystem.cxx
+ weakPointerCallback.cxx
+ weakPointerTo.cxx
+ weakPointerToBase.cxx
+ weakPointerToVoid.cxx
+ weakReferenceList.cxx
+ windowsRegistry.cxx
+ zStream.cxx zStreamBuf.cxx
+)
+
+if(ANDROID)
+ list(APPEND P3EXPRESS_SOURCES virtualFileMountAndroidAsset.cxx)
+endif()
+
+set(P3EXPRESS_IGATEEXT
+ datagram_ext.h
+ memoryUsagePointers_ext.cxx
+ memoryUsagePointers_ext.h
+ pointerToArray_ext.h
+ ramfile_ext.cxx
+ ramfile_ext.h
+ stringStream_ext.cxx
+ stringStream_ext.h
+ virtualFileSystem_ext.cxx
+ virtualFileSystem_ext.h
+ virtualFile_ext.cxx
+ virtualFile_ext.h
+)
+
+composite_sources(p3express P3EXPRESS_SOURCES)
+add_component_library(p3express SYMBOL BUILDING_PANDA_EXPRESS
+ ${P3EXPRESS_SOURCES} ${P3EXPRESS_HEADERS})
+target_link_libraries(p3express p3pandabase p3interrogatedb p3prc p3dtool
+ PKG::ZLIB PKG::OPENSSL)
+target_interrogate(p3express ALL EXTENSIONS ${P3EXPRESS_IGATEEXT})
+
+if(REPORT_OPENSSL_ERRORS)
+ target_compile_definitions(p3express PRIVATE REPORT_OPENSSL_ERRORS)
+endif()
+if(REPORT_OPENSSL_ERRORS_Debug)
+ target_compile_definitions(p3express PRIVATE $<$:REPORT_OPENSSL_ERRORS>)
+endif()
+
+if(GETTIMEOFDAY_ONE_PARAM)
+ target_compile_definitions(p3express PRIVATE GETTIMEOFDAY_ONE_PARAM)
+endif()
+
+if(WIN32)
+ target_link_libraries(p3express advapi32.lib ws2_32.lib)
+endif()
+
+if(ANDROID)
+ target_link_libraries(p3express android)
+endif()
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3express
+ EXPORT Core COMPONENT Core
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT CoreDevel)
+endif()
+install(FILES ${P3EXPRESS_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/panda/src/express/error_utils.cxx b/panda/src/express/error_utils.cxx
index 0ede902fbf..7859c42d26 100644
--- a/panda/src/express/error_utils.cxx
+++ b/panda/src/express/error_utils.cxx
@@ -153,7 +153,7 @@ string error_to_text(ErrorUtilCode err) {
*/
int
get_write_error() {
-#if !defined(WIN32) && !defined(WIN64)
+#ifndef _WIN32
return EU_error_abort;
#else
switch (errno) {
@@ -189,7 +189,7 @@ get_write_error() {
*
*/
string handle_socket_error() {
-#if !defined(WIN32) && !defined(WIN64)
+#ifndef _WIN32
return string(strerror(errno));
#else
int err = WSAGetLastError();
@@ -248,7 +248,7 @@ string handle_socket_error() {
*/
int
get_network_error() {
-#if !defined(WIN32) && !defined(WIN64)
+#ifndef _WIN32
return EU_error_abort;
#else
int err = WSAGetLastError();
diff --git a/panda/src/express/memoryUsage.cxx b/panda/src/express/memoryUsage.cxx
index b76ae0ed3e..15acc27cf0 100644
--- a/panda/src/express/memoryUsage.cxx
+++ b/panda/src/express/memoryUsage.cxx
@@ -18,7 +18,7 @@
#include "mutexImpl.h"
#include "interrogate_request.h"
-#if (defined(WIN32_VC) || defined (WIN64_VC)) && defined(_DEBUG)
+#if defined(_MSC_VER) && defined(_DEBUG)
#include
#endif
@@ -426,7 +426,7 @@ mark_pointer(void *ptr, size_t size, ReferenceCount *ref_ptr) {
#endif
}
-#if (defined(WIN32_VC) || defined (WIN64_VC))&& defined(_DEBUG)
+#if defined(_WIN32) && defined(_DEBUG)
/**
* This callback is attached to the Win32 debug malloc system to be called
* whenever a pointer is allocated, reallocated, or freed. It's used to track
@@ -455,7 +455,7 @@ win32_malloc_hook(int alloc_type, void *ptr,
mu->_total_size += increment;
return true;
}
-#endif // WIN32_VC && _DEBUG
+#endif // _WIN32 && _DEBUG
@@ -520,7 +520,7 @@ MemoryUsage(const MemoryHook ©) :
#error Cannot compile MemoryUsage without malloc wrappers!
#endif
-#if (defined(WIN32_VC) || defined(WIN64_VC)) && defined(_DEBUG)
+#ifdef _MSC_VER
// On a debug Windows build, we can set this malloc hook which allows
// tracking every malloc call, even from subordinate libraries.
_CrtSetAllocHook(&win32_malloc_hook);
diff --git a/panda/src/express/memoryUsage.h b/panda/src/express/memoryUsage.h
index 0371877ee0..86d1134073 100644
--- a/panda/src/express/memoryUsage.h
+++ b/panda/src/express/memoryUsage.h
@@ -55,7 +55,7 @@ protected:
virtual void mark_pointer(void *ptr, size_t orig_size, ReferenceCount *ref_ptr);
-#if (defined(WIN32_VC) || defined(WIN64_VC)) && defined(_DEBUG)
+#if defined(_WIN32) && defined(_DEBUG)
static int win32_malloc_hook(int alloc_type, void *ptr,
size_t size, int block_use, long request,
const unsigned char *filename, int line);
diff --git a/panda/src/express/multifile.cxx b/panda/src/express/multifile.cxx
index f857940774..f7055d2467 100644
--- a/panda/src/express/multifile.cxx
+++ b/panda/src/express/multifile.cxx
@@ -1631,7 +1631,7 @@ close_read_subfile(istream *stream) {
// stream pointer does not call the appropriate global delete function;
// instead apparently calling the system delete function. So we call the
// delete function by hand instead.
-#if !defined(WIN32_VC) && !defined(USE_MEMORY_NOWRAPPERS) && defined(REDEFINE_GLOBAL_OPERATOR_NEW)
+#if defined(__GNUC__) && !defined(USE_MEMORY_NOWRAPPERS) && defined(REDEFINE_GLOBAL_OPERATOR_NEW)
stream->~istream();
(*global_operator_delete)(stream);
#else
diff --git a/panda/src/express/pointerToArray.I b/panda/src/express/pointerToArray.I
index 5fb560b695..a3d5e1d4f7 100644
--- a/panda/src/express/pointerToArray.I
+++ b/panda/src/express/pointerToArray.I
@@ -297,7 +297,7 @@ erase(iterator first, iterator last) {
((To *)(this->_void_ptr))->erase(first, last);
}
-#if !defined(WIN32_VC) && !defined(WIN64_VC)
+#ifndef _WIN32
/**
*
*/
@@ -844,7 +844,7 @@ back() const {
return ((To *)(this->_void_ptr))->back();
}
-#if !defined(WIN32_VC) && !defined(WIN64_VC)
+#ifndef _WIN32
/**
*
*/
diff --git a/panda/src/express/pointerToArray.h b/panda/src/express/pointerToArray.h
index 7ff07a5ef1..ca6aab7ed4 100644
--- a/panda/src/express/pointerToArray.h
+++ b/panda/src/express/pointerToArray.h
@@ -61,7 +61,7 @@
#include "pointerToArrayBase.h"
-#if (defined(WIN32_VC) || defined(WIN64_VC)) && !defined(__INTEL_COMPILER)
+#if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
// disable mysterious MSVC warning for static inline PTA::empty_array method
// need to chk if vc 7.0 still has this problem, would like to keep it enabled
#pragma warning (disable : 4506)
@@ -179,7 +179,7 @@ public:
INLINE void erase(iterator position);
INLINE void erase(iterator first, iterator last);
-#if !defined(WIN32_VC) && !defined (WIN64_VC)
+#ifndef _WIN32
INLINE reference operator [](size_type n) const;
INLINE reference operator [](int n) const;
#endif
@@ -285,7 +285,7 @@ PUBLISHED:
typedef typename pvector::const_reference const_reference;
typedef typename pvector::const_iterator iterator;
typedef typename pvector::const_iterator const_iterator;
-#if defined(WIN32_VC) || defined(WIN64_VC)
+#ifdef _MSC_VER
// VC++ seems to break the const_reverse_iterator definition somehow.
typedef typename pvector::reverse_iterator reverse_iterator;
#else
@@ -323,7 +323,7 @@ PUBLISHED:
INLINE reference front() const;
INLINE reference back() const;
-#if !defined(WIN32_VC) && !defined(WIN64_VC)
+#ifndef _WIN32
INLINE reference operator [](size_type n) const;
INLINE reference operator [](int n) const;
#endif
diff --git a/panda/src/express/trueClock.I b/panda/src/express/trueClock.I
index 3b7a80f66d..773a0ce8f0 100644
--- a/panda/src/express/trueClock.I
+++ b/panda/src/express/trueClock.I
@@ -11,7 +11,7 @@
* @date 2000-07-04
*/
-#if defined(WIN32_VC) || defined(WIN64_VC)
+#ifdef _WIN32
/**
*
@@ -36,7 +36,7 @@ get_short_time() {
return time;
}
-#else // WIN32_VC
+#else // _WIN32
/**
*
@@ -46,7 +46,7 @@ get_short_time() {
return get_short_raw_time();
}
-#endif // WIN32_VC
+#endif // _WIN32
/**
diff --git a/panda/src/express/trueClock.cxx b/panda/src/express/trueClock.cxx
index e2298eb950..1df988e563 100644
--- a/panda/src/express/trueClock.cxx
+++ b/panda/src/express/trueClock.cxx
@@ -22,7 +22,7 @@ using std::min;
TrueClock *TrueClock::_global_ptr = nullptr;
-#if defined(WIN32_VC) || defined(WIN64_VC)
+#ifdef _WIN32
// The Win32 implementation.
@@ -471,7 +471,7 @@ set_time_scale(double time, double new_time_scale) {
_time_scale = new_time_scale;
}
-#else // !WIN32_VC
+#else // !_WIN32
// The Posix implementation.
diff --git a/panda/src/express/trueClock.h b/panda/src/express/trueClock.h
index b6255f211a..4775d02498 100644
--- a/panda/src/express/trueClock.h
+++ b/panda/src/express/trueClock.h
@@ -64,7 +64,7 @@ protected:
static TrueClock *_global_ptr;
-#ifdef WIN32
+#ifdef _WIN32
double correct_time(double time);
void set_time_scale(double time, double new_time_scale);
diff --git a/panda/src/express/virtualFileMountSystem.cxx b/panda/src/express/virtualFileMountSystem.cxx
index ebf5fa6645..2420cb6f88 100644
--- a/panda/src/express/virtualFileMountSystem.cxx
+++ b/panda/src/express/virtualFileMountSystem.cxx
@@ -30,7 +30,7 @@ TypeHandle VirtualFileMountSystem::_type_handle;
bool VirtualFileMountSystem::
has_file(const Filename &file) const {
Filename pathname(_physical_filename, file);
-#ifdef WIN32
+#ifdef _WIN32
if (VirtualFileSystem::get_global_ptr()->vfs_case_sensitive) {
Filename case_pathname = pathname;
if (!case_pathname.make_true_case()) {
@@ -115,7 +115,7 @@ make_directory(const Filename &file) {
*/
bool VirtualFileMountSystem::
is_directory(const Filename &file) const {
-#ifdef WIN32
+#ifdef _WIN32
// First ensure that the file exists to validate its case.
if (VirtualFileSystem::get_global_ptr()->vfs_case_sensitive) {
if (!has_file(file)) {
@@ -133,7 +133,7 @@ is_directory(const Filename &file) const {
*/
bool VirtualFileMountSystem::
is_regular_file(const Filename &file) const {
-#ifdef WIN32
+#ifdef _WIN32
// First ensure that the file exists to validate its case.
if (VirtualFileSystem::get_global_ptr()->vfs_case_sensitive) {
if (!has_file(file)) {
@@ -151,7 +151,7 @@ is_regular_file(const Filename &file) const {
*/
bool VirtualFileMountSystem::
is_writable(const Filename &file) const {
-#ifdef WIN32
+#ifdef _WIN32
// First ensure that the file exists to validate its case.
if (VirtualFileSystem::get_global_ptr()->vfs_case_sensitive) {
if (!has_file(file)) {
@@ -170,7 +170,7 @@ is_writable(const Filename &file) const {
*/
istream *VirtualFileMountSystem::
open_read_file(const Filename &file) const {
-#ifdef WIN32
+#ifdef _WIN32
// First ensure that the file exists to validate its case.
if (VirtualFileSystem::get_global_ptr()->vfs_case_sensitive) {
if (!has_file(file)) {
@@ -196,7 +196,7 @@ open_read_file(const Filename &file) const {
*/
ostream *VirtualFileMountSystem::
open_write_file(const Filename &file, bool truncate) {
-#ifdef WIN32
+#ifdef _WIN32
// First ensure that the file exists to validate its case.
if (VirtualFileSystem::get_global_ptr()->vfs_case_sensitive) {
if (!has_file(file)) {
@@ -222,7 +222,7 @@ open_write_file(const Filename &file, bool truncate) {
*/
ostream *VirtualFileMountSystem::
open_append_file(const Filename &file) {
-#ifdef WIN32
+#ifdef _WIN32
// First ensure that the file exists to validate its case.
if (VirtualFileSystem::get_global_ptr()->vfs_case_sensitive) {
if (!has_file(file)) {
@@ -248,7 +248,7 @@ open_append_file(const Filename &file) {
*/
iostream *VirtualFileMountSystem::
open_read_write_file(const Filename &file, bool truncate) {
-#ifdef WIN32
+#ifdef _WIN32
// First ensure that the file exists to validate its case.
if (VirtualFileSystem::get_global_ptr()->vfs_case_sensitive) {
if (!has_file(file)) {
@@ -274,7 +274,7 @@ open_read_write_file(const Filename &file, bool truncate) {
*/
iostream *VirtualFileMountSystem::
open_read_append_file(const Filename &file) {
-#ifdef WIN32
+#ifdef _WIN32
// First ensure that the file exists to validate its case.
if (VirtualFileSystem::get_global_ptr()->vfs_case_sensitive) {
if (!has_file(file)) {
@@ -368,7 +368,7 @@ get_system_info(const Filename &file, SubfileInfo &info) {
*/
bool VirtualFileMountSystem::
scan_directory(vector_string &contents, const Filename &dir) const {
-#ifdef WIN32
+#ifdef _WIN32
// First ensure that the file exists to validate its case.
if (VirtualFileSystem::get_global_ptr()->vfs_case_sensitive) {
if (!has_file(dir)) {
@@ -388,7 +388,7 @@ bool VirtualFileMountSystem::
atomic_compare_and_exchange_contents(const Filename &file, string &orig_contents,
const string &old_contents,
const string &new_contents) {
-#ifdef WIN32
+#ifdef _WIN32
// First ensure that the file exists to validate its case.
if (VirtualFileSystem::get_global_ptr()->vfs_case_sensitive) {
if (!has_file(file)) {
@@ -405,7 +405,7 @@ atomic_compare_and_exchange_contents(const Filename &file, string &orig_contents
*/
bool VirtualFileMountSystem::
atomic_read_contents(const Filename &file, string &contents) const {
-#ifdef WIN32
+#ifdef _WIN32
// First ensure that the file exists to validate its case.
if (VirtualFileSystem::get_global_ptr()->vfs_case_sensitive) {
if (!has_file(file)) {
diff --git a/panda/src/express/virtualFileSystem.cxx b/panda/src/express/virtualFileSystem.cxx
index eda84c4075..fe87f29645 100644
--- a/panda/src/express/virtualFileSystem.cxx
+++ b/panda/src/express/virtualFileSystem.cxx
@@ -870,7 +870,7 @@ close_read_file(istream *stream) {
// stream pointer does not call the appropriate global delete function;
// instead apparently calling the system delete function. So we call the
// delete function by hand instead.
-#if (!defined(WIN32_VC) && !defined(WIN64_VC)) && !defined(USE_MEMORY_NOWRAPPERS) && defined(REDEFINE_GLOBAL_OPERATOR_NEW)
+#if defined(__GNUC__) && !defined(USE_MEMORY_NOWRAPPERS) && defined(REDEFINE_GLOBAL_OPERATOR_NEW)
stream->~istream();
(*global_operator_delete)(stream);
#else
@@ -929,7 +929,7 @@ open_append_file(const Filename &filename) {
void VirtualFileSystem::
close_write_file(ostream *stream) {
if (stream != nullptr) {
-#if (!defined(WIN32_VC) && !defined(WIN64_VC)) && !defined(USE_MEMORY_NOWRAPPERS) && defined(REDEFINE_GLOBAL_OPERATOR_NEW)
+#if defined(__GNUC__) && !defined(USE_MEMORY_NOWRAPPERS) && defined(REDEFINE_GLOBAL_OPERATOR_NEW)
stream->~ostream();
(*global_operator_delete)(stream);
#else
@@ -985,7 +985,7 @@ open_read_append_file(const Filename &filename) {
void VirtualFileSystem::
close_read_write_file(iostream *stream) {
if (stream != nullptr) {
-#if (!defined(WIN32_VC) && !defined(WIN64_VC)) && !defined(USE_MEMORY_NOWRAPPERS) && defined(REDEFINE_GLOBAL_OPERATOR_NEW)
+#if defined(__GNUC__) && !defined(USE_MEMORY_NOWRAPPERS) && defined(REDEFINE_GLOBAL_OPERATOR_NEW)
stream->~iostream();
(*global_operator_delete)(stream);
#else
diff --git a/panda/src/ffmpeg/CMakeLists.txt b/panda/src/ffmpeg/CMakeLists.txt
new file mode 100644
index 0000000000..a78a3d2cdc
--- /dev/null
+++ b/panda/src/ffmpeg/CMakeLists.txt
@@ -0,0 +1,45 @@
+if(NOT HAVE_FFMPEG)
+ return()
+endif()
+
+set(P3FFMPEG_HEADERS
+ config_ffmpeg.h
+ ffmpegVideo.h ffmpegVideo.I
+ ffmpegVideoCursor.h ffmpegVideoCursor.I
+ ffmpegAudio.h ffmpegAudio.I
+ ffmpegAudioCursor.h ffmpegAudioCursor.I
+ ffmpegVirtualFile.h ffmpegVirtualFile.I
+)
+
+set(P3FFMPEG_SOURCES
+ config_ffmpeg.cxx
+ ffmpegVideo.cxx
+ ffmpegVideoCursor.cxx
+ ffmpegAudio.cxx
+ ffmpegAudioCursor.cxx
+ ffmpegVirtualFile.cxx
+)
+
+composite_sources(p3ffmpeg P3FFMPEG_SOURCES)
+add_library(p3ffmpeg ${MODULE_TYPE} ${P3FFMPEG_HEADERS} ${P3FFMPEG_SOURCES})
+set_target_properties(p3ffmpeg PROPERTIES DEFINE_SYMBOL BUILDING_FFMPEG)
+target_link_libraries(p3ffmpeg panda
+ PKG::FFMPEG PKG::SWSCALE PKG::SWRESAMPLE)
+
+if(HAVE_SWSCALE)
+ target_compile_definitions(p3ffmpeg PRIVATE HAVE_SWSCALE)
+endif()
+
+if(HAVE_SWRESAMPLE)
+ target_compile_definitions(p3ffmpeg PRIVATE HAVE_SWRESAMPLE)
+endif()
+
+install(TARGETS p3ffmpeg
+ EXPORT FFmpeg COMPONENT FFmpeg
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT FFmpegDevel)
+install(FILES ${P3FFMPEG_HEADERS} COMPONENT FFmpegDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
+
+export_targets(FFmpeg COMPONENT FFmpegDevel)
diff --git a/panda/src/framework/CMakeLists.txt b/panda/src/framework/CMakeLists.txt
new file mode 100644
index 0000000000..d299c86bd1
--- /dev/null
+++ b/panda/src/framework/CMakeLists.txt
@@ -0,0 +1,62 @@
+set(P3FRAMEWORK_HEADERS
+ config_framework.h
+ pandaFramework.I pandaFramework.h
+ windowFramework.I windowFramework.h
+)
+
+set(P3FRAMEWORK_SOURCES
+ config_framework.cxx
+ pandaFramework.cxx
+ windowFramework.cxx
+)
+
+
+set(P3FRAMEWORK_LINK_TARGETS panda)
+if(NOT BUILD_SHARED_LIBS)
+ # If we're statically linking, we need to explicitly link with
+ # at least one of the available renderers.
+ if(HAVE_GL)
+ list(APPEND P3FRAMEWORK_LINK_TARGETS pandagl)
+ elseif(HAVE_DX9)
+ list(APPEND P3FRAMEWORK_LINK_TARGETS pandadx9)
+ elseif(HAVE_TINYDISPLAY)
+ list(APPEND P3FRAMEWORK_LINK_TARGETS p3tinydisplay)
+ else()
+ message(WARNING "No renderer library available to link to p3framework.")
+ endif()
+
+ # And we might like to have the p3egg loader available.
+ if(HAVE_EGG)
+ list(APPEND P3FRAMEWORK_LINK_TARGETS pandaegg)
+ endif()
+
+endif()
+
+composite_sources(p3framework P3FRAMEWORK_SOURCES)
+# This one isn't a component library
+add_library(p3framework ${P3FRAMEWORK_HEADERS} ${P3FRAMEWORK_SOURCES})
+set_target_properties(p3framework PROPERTIES DEFINE_SYMBOL BUILDING_FRAMEWORK)
+target_link_libraries(p3framework ${P3FRAMEWORK_LINK_TARGETS})
+
+foreach(var
+ HAVE_GL
+ HAVE_TINYDISPLAY
+ HAVE_DX9
+ HAVE_EGG
+)
+
+ if(${var})
+ target_compile_definitions(p3framework PRIVATE ${var})
+ endif()
+
+endforeach(var)
+
+install(TARGETS p3framework
+ EXPORT Framework COMPONENT Framework
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT FrameworkDevel)
+install(FILES ${P3FRAMEWORK_HEADERS} COMPONENT FrameworkDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
+
+export_targets(Framework COMPONENT FrameworkDevel)
diff --git a/panda/src/gles2gsg/CMakeLists.txt b/panda/src/gles2gsg/CMakeLists.txt
new file mode 100644
index 0000000000..62c4c90c8b
--- /dev/null
+++ b/panda/src/gles2gsg/CMakeLists.txt
@@ -0,0 +1,29 @@
+if(NOT HAVE_GLES2)
+ return()
+endif()
+
+set(P3GLES2GSG_HEADERS
+ config_gles2gsg.h
+ gles2gsg.h
+)
+
+set(P3GLES2GSG_SOURCES
+ config_gles2gsg.cxx
+ gles2gsg.cxx
+)
+
+composite_sources(p3gles2gsg P3GLES2GSG_SOURCES)
+add_component_library(p3gles2gsg SYMBOL BUILDING_PANDAGLES2
+ ${P3GLE2SGSG_HEADERS} ${P3GLES2GSG_SOURCES})
+target_link_libraries(p3gles2gsg p3glstuff panda
+ PKG::GLES2)
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3gles2gsg
+ EXPORT OpenGLES2 COMPONENT OpenGLES2
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT OpenGLES2Devel)
+endif()
+install(FILES ${P3GLES2GSG_HEADERS} COMPONENT OpenGLES2Devel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/panda/src/glesgsg/CMakeLists.txt b/panda/src/glesgsg/CMakeLists.txt
new file mode 100644
index 0000000000..c956b882d6
--- /dev/null
+++ b/panda/src/glesgsg/CMakeLists.txt
@@ -0,0 +1,29 @@
+if(NOT HAVE_GLES1)
+ return()
+endif()
+
+set(P3GLESGSG_HEADERS
+ config_glesgsg.h
+ glesgsg.h
+)
+
+set(P3GLESGSG_SOURCES
+ config_glesgsg.cxx
+ glesgsg.cxx
+)
+
+composite_sources(p3glesgsg P3GLESGSG_SOURCES)
+add_component_library(p3glesgsg SYMBOL BUILDING_PANDAGLES
+ ${P3GLESGSG_HEADERS} ${P3GLESGSG_SOURCES})
+target_link_libraries(p3glesgsg p3glstuff panda
+ PKG::GLES1)
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3glesgsg
+ EXPORT OpenGLES1 COMPONENT OpenGLES1
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT OpenGLES1Devel)
+endif()
+install(FILES ${P3GLESGSG_HEADERS} COMPONENT OpenGLES1Devel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/panda/src/glgsg/CMakeLists.txt b/panda/src/glgsg/CMakeLists.txt
new file mode 100644
index 0000000000..d8ddad03bb
--- /dev/null
+++ b/panda/src/glgsg/CMakeLists.txt
@@ -0,0 +1,28 @@
+if(NOT HAVE_GL)
+ return()
+endif()
+
+set(P3GLGSG_HEADERS
+ config_glgsg.h glgsg.h
+)
+
+set(P3GLGSG_SOURCES
+ config_glgsg.cxx
+ glgsg.cxx
+)
+
+composite_sources(p3glgsg P3GLGSG_SOURCES)
+add_component_library(p3glgsg SYMBOL BUILDING_PANDA_GLGSG
+ ${P3GLGSG_HEADERS} ${P3GLGSG_SOURCES})
+target_link_libraries(p3glgsg p3glstuff panda
+ PKG::CG PKG::GL)
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3glgsg
+ EXPORT OpenGL COMPONENT OpenGL
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT OpenGLDevel)
+endif()
+install(FILES ${P3GLGSG_HEADERS} COMPONENT OpenGLDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/panda/src/glstuff/CMakeLists.txt b/panda/src/glstuff/CMakeLists.txt
new file mode 100644
index 0000000000..016dafa81a
--- /dev/null
+++ b/panda/src/glstuff/CMakeLists.txt
@@ -0,0 +1,54 @@
+if(NOT HAVE_GL)
+ return()
+endif()
+
+set(P3GLSTUFF_HEADERS
+ glGeomContext_src.I
+ glGeomContext_src.h
+ glGeomMunger_src.I
+ glGeomMunger_src.h
+ glGraphicsStateGuardian_src.I
+ glGraphicsStateGuardian_src.h
+ glGraphicsBuffer_src.I
+ glGraphicsBuffer_src.h
+ glImmediateModeSender_src.I
+ glImmediateModeSender_src.h
+ glIndexBufferContext_src.I
+ glIndexBufferContext_src.h
+ glOcclusionQueryContext_src.I
+ glOcclusionQueryContext_src.h
+ glShaderContext_src.I
+ glShaderContext_src.h
+ glTextureContext_src.I
+ glTextureContext_src.h
+ glVertexBufferContext_src.I
+ glVertexBufferContext_src.h
+ glmisc_src.h
+ glstuff_src.h
+ glstuff_undef_src.h
+ panda_glext.h
+)
+
+set(P3GLSTUFF_SOURCES
+ glpure.cxx
+)
+
+composite_sources(p3glstuff P3GLSTUFF_SOURCES)
+add_component_library(p3glstuff NOINIT ${P3GLSTUFF_HEADERS} ${P3GLSTUFF_SOURCES})
+target_link_libraries(p3glstuff panda)
+
+if(APPLE)
+ # We acknowledge Apple's hostility to open standards so that the SDK won't
+ # bother our users about it.
+ target_compile_definitions(p3glstuff PUBLIC GL_SILENCE_DEPRECATION)
+endif()
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3glstuff
+ EXPORT OpenGL COMPONENT OpenGL
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT OpenGLDevel)
+endif()
+install(FILES ${P3GLSTUFF_HEADERS} COMPONENT OpenGLDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/panda/src/glstuff/glCgShaderContext_src.cxx b/panda/src/glstuff/glCgShaderContext_src.cxx
index 8d90d1cd50..23d765b349 100644
--- a/panda/src/glstuff/glCgShaderContext_src.cxx
+++ b/panda/src/glstuff/glCgShaderContext_src.cxx
@@ -338,6 +338,8 @@ CLP(CgShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderConte
}
}
+ _mat_part_cache = new LMatrix4[_shader->cp_get_mat_cache_size()];
+
_glgsg->report_my_gl_errors();
}
@@ -347,6 +349,7 @@ CLP(CgShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderConte
CLP(CgShaderContext)::
~CLP(CgShaderContext)() {
// Don't call release_resources; we may not have an active context.
+ delete[] _mat_part_cache;
}
/**
@@ -690,14 +693,14 @@ issue_parameters(int altered) {
}
if (altered & _shader->_mat_deps) {
- for (int i = 0; i < (int)_shader->_mat_spec.size(); ++i) {
- Shader::ShaderMatSpec &spec = _shader->_mat_spec[i];
+ _glgsg->update_shader_matrix_cache(_shader, _mat_part_cache, altered);
- if ((altered & (spec._dep[0] | spec._dep[1])) == 0) {
+ for (Shader::ShaderMatSpec &spec : _shader->_mat_spec) {
+ if ((altered & spec._dep) == 0) {
continue;
}
- const LMatrix4 *val = _glgsg->fetch_specified_value(spec, altered);
+ const LMatrix4 *val = _glgsg->fetch_specified_value(spec, _mat_part_cache, altered);
if (!val) continue;
const PN_stdfloat *data = val->get_data();
diff --git a/panda/src/glstuff/glCgShaderContext_src.h b/panda/src/glstuff/glCgShaderContext_src.h
index 553cafe487..35a2d5dd36 100644
--- a/panda/src/glstuff/glCgShaderContext_src.h
+++ b/panda/src/glstuff/glCgShaderContext_src.h
@@ -75,6 +75,7 @@ private:
long _transform_table_size;
long _slider_table_size;
+ LMatrix4 *_mat_part_cache = nullptr;
pvector _cg_parameter_map;
WCPT(RenderState) _state_rs;
diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx
index a6173f28b7..ff6ed7dd3e 100644
--- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx
+++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx
@@ -1776,9 +1776,9 @@ reset() {
_shader_caps._active_gprofile = (int)CG_PROFILE_GLSLG;
}
}
- _shader_caps._ultimate_vprofile = (int)CG_PROFILE_VP40;
- _shader_caps._ultimate_fprofile = (int)CG_PROFILE_FP40;
- _shader_caps._ultimate_gprofile = (int)CG_PROFILE_GPU_GP;
+ _shader_caps._ultimate_vprofile = (int)CG_PROFILE_GLSLV;
+ _shader_caps._ultimate_fprofile = (int)CG_PROFILE_GLSLF;
+ _shader_caps._ultimate_gprofile = (int)CG_PROFILE_GLSLG;
// Bug workaround for radeons.
if (_shader_caps._active_fprofile == CG_PROFILE_ARBFP1) {
diff --git a/panda/src/glstuff/glShaderContext_src.cxx b/panda/src/glstuff/glShaderContext_src.cxx
index 6032417124..eb9c534b44 100644
--- a/panda/src/glstuff/glShaderContext_src.cxx
+++ b/panda/src/glstuff/glShaderContext_src.cxx
@@ -228,9 +228,7 @@ parse_and_set_short_hand_shader_vars(Shader::ShaderArgId &arg_id, GLenum param_t
bind._part[1] = Shader::SMO_apiclip_to_view;
}
- objShader->cp_optimize_mat_spec(bind);
- objShader->_mat_spec.push_back(bind);
- objShader->_mat_deps |= bind._dep[0] | bind._dep[1];
+ objShader->cp_add_mat_spec(bind);
if (param_size > 1) {
// We support arrays of rows and arrays of columns, so we can run the
@@ -243,7 +241,7 @@ parse_and_set_short_hand_shader_vars(Shader::ShaderArgId &arg_id, GLenum param_t
for (int i = 1; i < param_size; ++i) {
bind._id._seqno += 1;
bind._piece = (Shader::ShaderMatPiece)((int)bind._piece + 1);
- objShader->_mat_spec.push_back(bind);
+ objShader->cp_add_mat_spec(bind);
}
} else {
GLCAT.warning() << basename << "[" << param_size << "] should not be an array, only the first element will be defined\n";
@@ -380,6 +378,8 @@ CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext
} else {
_glgsg->_current_shader_context->bind();
}
+
+ _mat_part_cache = new LMatrix4[_shader->cp_get_mat_cache_size()];
}
/**
@@ -885,15 +885,22 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
bind._part[0] = inverse ? Shader::SMO_inv_texmat_i
: Shader::SMO_texmat_i;
bind._part[1] = Shader::SMO_identity;
- bind._dep[0] = Shader::SSD_general | Shader::SSD_tex_matrix;
- bind._dep[1] = 0;
// Add it once for each index.
for (bind._index = 0; bind._index < param_size; ++bind._index) {
+ // It was discovered in #846, that GLSL 4.10 and lower don't seem to
+ // guarantee that matrices occupy successive locations, and on macOS
+ // they indeed occupy four locations per element.
+ // As a big fat hack, we multiply by four on macOS, because this is
+ // hard to fix on the 1.10 branch. We'll have a proper fix on the
+ // master branch.
+#ifdef __APPLE__
+ bind._id._seqno = p + bind._index * 4;
+#else
bind._id._seqno = p + bind._index;
- _shader->_mat_spec.push_back(bind);
+#endif
+ _shader->cp_add_mat_spec(bind);
}
- _shader->_mat_deps |= bind._dep[0];
return;
} else if (matrix_name.size() > 15 &&
@@ -938,9 +945,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
GLCAT.error() << "Unrecognized uniform matrix name '" << matrix_name << "'!\n";
return;
}
- _shader->cp_optimize_mat_spec(bind);
- _shader->_mat_spec.push_back(bind);
- _shader->_mat_deps |= bind._dep[0] | bind._dep[1];
+ _shader->cp_add_mat_spec(bind);
return;
}
if (size > 7 && noprefix.substr(0, 7) == "Texture") {
@@ -973,10 +978,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
bind._func = Shader::SMF_first;
bind._part[0] = Shader::SMO_attr_material;
bind._arg[0] = nullptr;
- bind._dep[0] = Shader::SSD_general | Shader::SSD_material | Shader::SSD_frame;
bind._part[1] = Shader::SMO_identity;
bind._arg[1] = nullptr;
- bind._dep[1] = Shader::SSD_NONE;
if (noprefix == "Material.baseColor") {
if (param_type != GL_FLOAT_VEC4) {
@@ -985,9 +988,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
}
bind._part[0] = Shader::SMO_attr_material2;
bind._piece = Shader::SMP_row0;
- bind._dep[0] |= Shader::SSD_color;
- _shader->_mat_spec.push_back(bind);
- _shader->_mat_deps |= bind._dep[0];
+ _shader->cp_add_mat_spec(bind);
return;
} else if (noprefix == "Material.ambient") {
@@ -996,8 +997,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
<< "p3d_Material.ambient should be vec4\n";
}
bind._piece = Shader::SMP_row0;
- _shader->_mat_spec.push_back(bind);
- _shader->_mat_deps |= bind._dep[0];
+ _shader->cp_add_mat_spec(bind);
return;
} else if (noprefix == "Material.diffuse") {
@@ -1006,8 +1006,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
<< "p3d_Material.diffuse should be vec4\n";
}
bind._piece = Shader::SMP_row1;
- _shader->_mat_spec.push_back(bind);
- _shader->_mat_deps |= bind._dep[0];
+ _shader->cp_add_mat_spec(bind);
return;
} else if (noprefix == "Material.emission") {
@@ -1016,8 +1015,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
<< "p3d_Material.emission should be vec4\n";
}
bind._piece = Shader::SMP_row2;
- _shader->_mat_spec.push_back(bind);
- _shader->_mat_deps |= bind._dep[0];
+ _shader->cp_add_mat_spec(bind);
return;
} else if (noprefix == "Material.specular") {
@@ -1026,8 +1024,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
<< "p3d_Material.specular should be vec3\n";
}
bind._piece = Shader::SMP_row3x3;
- _shader->_mat_spec.push_back(bind);
- _shader->_mat_deps |= bind._dep[0];
+ _shader->cp_add_mat_spec(bind);
return;
} else if (noprefix == "Material.shininess") {
@@ -1036,8 +1033,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
<< "p3d_Material.shininess should be float\n";
}
bind._piece = Shader::SMP_cell15;
- _shader->_mat_spec.push_back(bind);
- _shader->_mat_deps |= bind._dep[0];
+ _shader->cp_add_mat_spec(bind);
return;
} else if (noprefix == "Material.roughness") {
@@ -1047,8 +1043,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
}
bind._part[0] = Shader::SMO_attr_material2;
bind._piece = Shader::SMP_cell15;
- _shader->_mat_spec.push_back(bind);
- _shader->_mat_deps |= bind._dep[0];
+ _shader->cp_add_mat_spec(bind);
return;
} else if (noprefix == "Material.metallic") {
@@ -1058,8 +1053,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
}
bind._part[0] = Shader::SMO_attr_material2;
bind._piece = Shader::SMP_row3x1;
- _shader->_mat_spec.push_back(bind);
- _shader->_mat_deps |= bind._dep[0];
+ _shader->cp_add_mat_spec(bind);
return;
} else if (noprefix == "Material.refractiveIndex") {
@@ -1069,8 +1063,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
}
bind._part[0] = Shader::SMO_attr_material2;
bind._piece = Shader::SMP_cell13;
- _shader->_mat_spec.push_back(bind);
- _shader->_mat_deps |= bind._dep[0];
+ _shader->cp_add_mat_spec(bind);
return;
}
}
@@ -1080,10 +1073,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
bind._func = Shader::SMF_first;
bind._part[0] = Shader::SMO_attr_colorscale;
bind._arg[0] = nullptr;
- bind._dep[0] = Shader::SSD_general | Shader::SSD_colorscale;
bind._part[1] = Shader::SMO_identity;
bind._arg[1] = nullptr;
- bind._dep[1] = Shader::SSD_NONE;
if (param_type == GL_FLOAT_VEC3) {
bind._piece = Shader::SMP_row3x3;
@@ -1094,8 +1085,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
<< "p3d_ColorScale should be vec3 or vec4\n";
return;
}
- _shader->_mat_spec.push_back(bind);
- _shader->_mat_deps |= bind._dep[0];
+ _shader->cp_add_mat_spec(bind);
return;
}
if (noprefix == "Color") {
@@ -1104,10 +1094,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
bind._func = Shader::SMF_first;
bind._part[0] = Shader::SMO_attr_color;
bind._arg[0] = nullptr;
- bind._dep[0] = Shader::SSD_general | Shader::SSD_color;
bind._part[1] = Shader::SMO_identity;
bind._arg[1] = nullptr;
- bind._dep[1] = Shader::SSD_NONE;
if (param_type == GL_FLOAT_VEC3) {
bind._piece = Shader::SMP_row3x3;
@@ -1118,8 +1106,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
<< "p3d_Color should be vec3 or vec4\n";
return;
}
- _shader->_mat_spec.push_back(bind);
- _shader->_mat_deps |= bind._dep[0];
+ _shader->cp_add_mat_spec(bind);
return;
}
if (noprefix == "ClipPlane") {
@@ -1137,12 +1124,9 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
bind._index = i;
bind._part[0] = Shader::SMO_apiview_clipplane_i;
bind._arg[0] = nullptr;
- bind._dep[0] = Shader::SSD_general | Shader::SSD_clip_planes;
bind._part[1] = Shader::SMO_identity;
bind._arg[1] = nullptr;
- bind._dep[1] = Shader::SSD_NONE;
- _shader->_mat_spec.push_back(bind);
- _shader->_mat_deps |= bind._dep[0];
+ _shader->cp_add_mat_spec(bind);
}
return;
}
@@ -1151,10 +1135,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
bind._id = arg_id;
bind._func = Shader::SMF_first;
bind._arg[0] = nullptr;
- bind._dep[0] = Shader::SSD_general | Shader::SSD_fog;
bind._part[1] = Shader::SMO_identity;
bind._arg[1] = nullptr;
- bind._dep[1] = Shader::SSD_NONE;
if (noprefix == "Fog.color") {
bind._part[0] = Shader::SMO_attr_fogcolor;
@@ -1214,8 +1196,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
}
}
- _shader->_mat_spec.push_back(bind);
- _shader->_mat_deps |= bind._dep[0];
+ _shader->cp_add_mat_spec(bind);
return;
}
if (noprefix == "LightModel.ambient") {
@@ -1224,10 +1205,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
bind._func = Shader::SMF_first;
bind._part[0] = Shader::SMO_light_ambient;
bind._arg[0] = nullptr;
- bind._dep[0] = Shader::SSD_general | Shader::SSD_light;
bind._part[1] = Shader::SMO_identity;
bind._arg[1] = nullptr;
- bind._dep[1] = Shader::SSD_NONE;
if (param_type == GL_FLOAT_VEC3) {
bind._piece = Shader::SMP_row3x3;
@@ -1238,8 +1217,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
<< "p3d_LightModel.ambient should be vec3 or vec4\n";
return;
}
- _shader->_mat_spec.push_back(bind);
- _shader->_mat_deps |= bind._dep[0];
+ _shader->cp_add_mat_spec(bind);
return;
}
if (size > 15 && noprefix.substr(0, 12) == "LightSource[") {
@@ -1279,15 +1257,8 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
bind._index = index;
bind._part[0] = Shader::SMO_light_source_i_attrib;
bind._arg[0] = InternalName::make(member_name);
- bind._dep[0] = Shader::SSD_general | Shader::SSD_light | Shader::SSD_frame;
bind._part[1] = Shader::SMO_identity;
bind._arg[1] = nullptr;
- bind._dep[1] = Shader::SSD_NONE;
-
- if (member_name == "position" || member_name == "halfVector" ||
- member_name == "spotDirection") {
- bind._dep[0] |= Shader::SSD_view_transform;
- }
switch (param_type) {
case GL_FLOAT:
@@ -1311,8 +1282,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
<< "p3d_LightSource[]." << member_name << " should be float or vec\n";
return;
}
- _shader->_mat_spec.push_back(bind);
- _shader->_mat_deps |= bind._dep[0] | bind._dep[1];
+ _shader->cp_add_mat_spec(bind);
return;
}
}
@@ -1344,13 +1314,10 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
bind._index = 0;
bind._part[0] = Shader::SMO_tex_is_alpha_i;
bind._arg[0] = nullptr;
- bind._dep[0] = Shader::SSD_general | Shader::SSD_texture | Shader::SSD_frame;
bind._part[1] = Shader::SMO_identity;
bind._arg[1] = nullptr;
- bind._dep[1] = Shader::SSD_NONE;
bind._piece = Shader::SMP_row3;
- _shader->_mat_spec.push_back(bind);
- _shader->_mat_deps |= bind._dep[0] | bind._dep[1];
+ _shader->cp_add_mat_spec(bind);
return;
}
GLCAT.error() << "Unrecognized uniform name '" << param_name << "'!\n";
@@ -1371,10 +1338,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
bind._func = Shader::SMF_compose;
bind._part[0] = Shader::SMO_world_to_view;
bind._part[1] = Shader::SMO_view_to_apiview;
- bind._dep[0] = Shader::SSD_general | Shader::SSD_view_transform;
- bind._dep[1] = Shader::SSD_general;
- _shader->_mat_spec.push_back(bind);
- _shader->_mat_deps |= bind._dep[0] | bind._dep[1];
+ _shader->cp_add_mat_spec(bind);
return;
} else if (noprefix == "InverseViewMatrix" || noprefix == "ViewMatrixInverse") {
@@ -1382,10 +1346,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
bind._func = Shader::SMF_compose;
bind._part[0] = Shader::SMO_apiview_to_view;
bind._part[1] = Shader::SMO_view_to_world;
- bind._dep[0] = Shader::SSD_general;
- bind._dep[1] = Shader::SSD_general | Shader::SSD_view_transform;
- _shader->_mat_spec.push_back(bind);
- _shader->_mat_deps |= bind._dep[0] | bind._dep[1];
+ _shader->cp_add_mat_spec(bind);
return;
} else if (noprefix == "FrameTime") {
@@ -1393,10 +1354,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
bind._func = Shader::SMF_first;
bind._part[0] = Shader::SMO_frame_time;
bind._part[1] = Shader::SMO_identity;
- bind._dep[0] = Shader::SSD_general | Shader::SSD_frame;
- bind._dep[1] = Shader::SSD_NONE;
- _shader->_mat_spec.push_back(bind);
- _shader->_mat_deps |= bind._dep[0] | bind._dep[1];
+ _shader->cp_add_mat_spec(bind);
return;
} else if (noprefix == "DeltaFrameTime") {
@@ -1404,10 +1362,7 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
bind._func = Shader::SMF_first;
bind._part[0] = Shader::SMO_frame_delta;
bind._part[1] = Shader::SMO_identity;
- bind._dep[0] = Shader::SSD_general | Shader::SSD_frame;
- bind._dep[1] = Shader::SSD_NONE;
- _shader->_mat_spec.push_back(bind);
- _shader->_mat_deps |= bind._dep[0] | bind._dep[1];
+ _shader->cp_add_mat_spec(bind);
return;
} else if (noprefix == "FrameNumber") {
@@ -1491,12 +1446,9 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
bind._func = Shader::SMF_first;
bind._part[0] = Shader::SMO_mat_constant_x;
bind._arg[0] = InternalName::make(param_name);
- bind._dep[0] = Shader::SSD_general | Shader::SSD_shaderinputs | Shader::SSD_frame;
bind._part[1] = Shader::SMO_identity;
bind._arg[1] = nullptr;
- bind._dep[1] = Shader::SSD_NONE;
- _shader->_mat_spec.push_back(bind);
- _shader->_mat_deps |= bind._dep[0];
+ _shader->cp_add_mat_spec(bind);
return;
}
case GL_FLOAT_MAT4: {
@@ -1506,7 +1458,6 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
bind._func = Shader::SMF_first;
bind._part[1] = Shader::SMO_identity;
bind._arg[1] = nullptr;
- bind._dep[1] = Shader::SSD_NONE;
PT(InternalName) iname = InternalName::make(param_name);
if (iname->get_parent() != InternalName::get_root()) {
// It might be something like an attribute of a shader input, like a
@@ -1527,22 +1478,17 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
bind._func = Shader::SMF_compose;
bind._part[0] = Shader::SMO_model_to_apiview;
bind._arg[0] = nullptr;
- bind._dep[0] = Shader::SSD_general | Shader::SSD_transform;
bind._part[1] = Shader::SMO_mat_constant_x_attrib;
bind._arg[1] = iname->get_parent()->append("shadowViewMatrix");
- bind._dep[1] = Shader::SSD_general | Shader::SSD_shaderinputs | Shader::SSD_frame | Shader::SSD_view_transform;
} else {
bind._part[0] = Shader::SMO_mat_constant_x_attrib;
bind._arg[0] = InternalName::make(param_name);
- bind._dep[0] = Shader::SSD_general | Shader::SSD_shaderinputs | Shader::SSD_frame | Shader::SSD_view_transform;
}
} else {
bind._part[0] = Shader::SMO_mat_constant_x;
bind._arg[0] = InternalName::make(param_name);
- bind._dep[0] = Shader::SSD_general | Shader::SSD_shaderinputs | Shader::SSD_frame;
}
- _shader->_mat_spec.push_back(bind);
- _shader->_mat_deps |= bind._dep[0];
+ _shader->cp_add_mat_spec(bind);
return;
}
case GL_FLOAT:
@@ -1572,14 +1518,9 @@ reflect_uniform(int i, char *name_buffer, GLsizei name_buflen) {
bind._func = Shader::SMF_first;
bind._part[0] = Shader::SMO_vec_constant_x_attrib;
bind._arg[0] = iname;
- // We need SSD_view_transform since some attributes (eg. light
- // position) have to be transformed to view space.
- bind._dep[0] = Shader::SSD_general | Shader::SSD_shaderinputs | Shader::SSD_frame | Shader::SSD_view_transform;
bind._part[1] = Shader::SMO_identity;
bind._arg[1] = nullptr;
- bind._dep[1] = Shader::SSD_NONE;
- _shader->_mat_spec.push_back(bind);
- _shader->_mat_deps |= bind._dep[0];
+ _shader->cp_add_mat_spec(bind);
return;
} // else fall through
}
@@ -1913,6 +1854,7 @@ get_sampler_texture_type(int &out, GLenum param_type) {
CLP(ShaderContext)::
~CLP(ShaderContext)() {
// Don't call release_resources; we may not have an active context.
+ delete[] _mat_part_cache;
}
/**
@@ -2230,14 +2172,14 @@ issue_parameters(int altered) {
}
if (altered & _shader->_mat_deps) {
- for (int i = 0; i < (int)_shader->_mat_spec.size(); ++i) {
- Shader::ShaderMatSpec &spec = _shader->_mat_spec[i];
+ _glgsg->update_shader_matrix_cache(_shader, _mat_part_cache, altered);
- if ((altered & (spec._dep[0] | spec._dep[1])) == 0) {
+ for (Shader::ShaderMatSpec &spec : _shader->_mat_spec) {
+ if ((altered & spec._dep) == 0) {
continue;
}
- const LMatrix4 *val = _glgsg->fetch_specified_value(spec, altered);
+ const LMatrix4 *val = _glgsg->fetch_specified_value(spec, _mat_part_cache, altered);
if (!val) continue;
#ifndef STDFLOAT_DOUBLE
// In this case, the data is already single-precision.
diff --git a/panda/src/glstuff/glShaderContext_src.h b/panda/src/glstuff/glShaderContext_src.h
index 0ccb99fe90..06561336fa 100644
--- a/panda/src/glstuff/glShaderContext_src.h
+++ b/panda/src/glstuff/glShaderContext_src.h
@@ -114,6 +114,8 @@ private:
};
pvector _glsl_img_inputs;
+ LMatrix4 *_mat_part_cache = nullptr;
+
CLP(GraphicsStateGuardian) *_glgsg;
bool _uses_standard_vertex_arrays;
diff --git a/panda/src/glstuff/glmisc_src.h b/panda/src/glstuff/glmisc_src.h
index 415286c674..b77143ce70 100644
--- a/panda/src/glstuff/glmisc_src.h
+++ b/panda/src/glstuff/glmisc_src.h
@@ -87,7 +87,7 @@ extern ConfigVariableEnum gl_coordinate_system;
extern EXPCL_GL void CLP(init_classes)();
-#if !defined(WIN32) && defined(GSG_VERBOSE)
+#if !defined(_WIN32) && defined(GSG_VERBOSE)
std::ostream &output_gl_enum(std::ostream &out, GLenum v);
INLINE std::ostream &operator << (std::ostream &out, GLenum v) {
return output_gl_enum(out, v);
diff --git a/panda/src/glstuff/glpure.cxx b/panda/src/glstuff/glpure.cxx
index 15d3c7c4aa..c3913fccee 100644
--- a/panda/src/glstuff/glpure.cxx
+++ b/panda/src/glstuff/glpure.cxx
@@ -16,7 +16,7 @@
// This is the one file in this directory which is actually compiled. It
// exists just so we can have some symbols and make the compiler happy.
-#if (defined(WIN32_VC) || defined(WIN64_VC)) && !defined(CPPPARSER) && !defined(LINK_ALL_STATIC)
+#if defined(_WIN32) && !defined(CPPPARSER) && !defined(LINK_ALL_STATIC)
__declspec(dllexport)
#endif
int glpure;
diff --git a/panda/src/glxdisplay/CMakeLists.txt b/panda/src/glxdisplay/CMakeLists.txt
new file mode 100644
index 0000000000..06dcc5cc0e
--- /dev/null
+++ b/panda/src/glxdisplay/CMakeLists.txt
@@ -0,0 +1,33 @@
+if(NOT HAVE_GLX)
+ return()
+endif()
+
+set(P3GLXDISPLAY_HEADERS
+ config_glxdisplay.h
+ glxGraphicsBuffer.h glxGraphicsBuffer.I
+ glxGraphicsPipe.h glxGraphicsPipe.I
+ glxGraphicsPixmap.h glxGraphicsPixmap.I
+ glxGraphicsWindow.h glxGraphicsWindow.I
+ glxGraphicsStateGuardian.h glxGraphicsStateGuardian.I
+ posixGraphicsStateGuardian.h posixGraphicsStateGuardian.I
+ panda_glxext.h
+)
+
+set(P3GLXDISPLAY_SOURCES
+ config_glxdisplay.cxx
+ glxGraphicsBuffer.cxx
+ glxGraphicsPipe.cxx
+ glxGraphicsPixmap.cxx
+ glxGraphicsWindow.cxx
+ glxGraphicsStateGuardian.cxx
+ posixGraphicsStateGuardian.cxx
+)
+
+composite_sources(p3glxdisplay P3GLXDISPLAY_SOURCES)
+add_component_library(p3glxdisplay SYMBOL BUILDING_PANDA_GLXDISPLAY
+ ${P3GLXDISPLAY_HEADERS} ${P3GLXDISPLAY_SOURCES})
+target_link_libraries(p3glxdisplay p3glgsg p3x11display)
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3glxdisplay EXPORT OpenGL COMPONENT OpenGL DESTINATION ${CMAKE_INSTALL_LIBDIR})
+endif()
diff --git a/panda/src/gobj/CMakeLists.txt b/panda/src/gobj/CMakeLists.txt
new file mode 100644
index 0000000000..8ab4223467
--- /dev/null
+++ b/panda/src/gobj/CMakeLists.txt
@@ -0,0 +1,195 @@
+set(P3GOBJ_HEADERS
+ adaptiveLru.I adaptiveLru.h
+ animateVerticesRequest.I animateVerticesRequest.h
+ bufferContext.I bufferContext.h
+ bufferContextChain.I bufferContextChain.h
+ bufferResidencyTracker.I bufferResidencyTracker.h
+ config_gobj.h
+ geom.h geom.I
+ geomContext.I geomContext.h
+ geomEnums.h
+ geomMunger.h geomMunger.I
+ geomPrimitive.h geomPrimitive.I
+ geomPatches.h
+ geomTriangles.h
+ geomTrianglesAdjacency.h
+ geomTristrips.h
+ geomTristripsAdjacency.h
+ geomTrifans.h
+ geomLines.h
+ geomLinesAdjacency.h
+ geomLinestrips.h
+ geomLinestripsAdjacency.h
+ geomPoints.h
+ geomVertexArrayData.h geomVertexArrayData.I
+ geomVertexArrayFormat.h geomVertexArrayFormat.I
+ geomCacheEntry.h geomCacheEntry.I
+ geomCacheManager.h geomCacheManager.I
+ geomVertexAnimationSpec.h geomVertexAnimationSpec.I
+ geomVertexData.h geomVertexData.I
+ geomVertexColumn.h geomVertexColumn.I
+ geomVertexFormat.h geomVertexFormat.I
+ geomVertexReader.h geomVertexReader.I
+ geomVertexRewriter.h geomVertexRewriter.I
+ geomVertexWriter.h geomVertexWriter.I
+ indexBufferContext.I indexBufferContext.h
+ internalName.I internalName.h
+ lens.h lens.I
+ material.I material.h materialPool.I materialPool.h
+ matrixLens.I matrixLens.h
+ occlusionQueryContext.I occlusionQueryContext.h
+ orthographicLens.I orthographicLens.h
+ paramTexture.I paramTexture.h
+ perspectiveLens.I perspectiveLens.h
+ preparedGraphicsObjects.I preparedGraphicsObjects.h
+ queryContext.I queryContext.h
+ samplerContext.h samplerContext.I
+ samplerState.h samplerState.I
+ savedContext.I savedContext.h
+ shader.I shader.h
+ shaderBuffer.h shaderBuffer.I
+ shaderContext.h shaderContext.I
+ simpleAllocator.h simpleAllocator.I
+ simpleLru.h simpleLru.I
+ sliderTable.I sliderTable.h
+ texture.I texture.h
+ textureCollection.I textureCollection.h
+ textureContext.I textureContext.h
+ texturePeeker.I texturePeeker.h
+ texturePool.I texturePool.h
+ texturePoolFilter.I texturePoolFilter.h
+ textureReloadRequest.I textureReloadRequest.h
+ textureStage.I textureStage.h
+ textureStagePool.I textureStagePool.h
+ timerQueryContext.I timerQueryContext.h
+ transformBlend.I transformBlend.h
+ transformBlendTable.I transformBlendTable.h
+ transformTable.I transformTable.h
+ userVertexSlider.I userVertexSlider.h
+ userVertexTransform.I userVertexTransform.h
+ vertexBufferContext.I vertexBufferContext.h
+ vertexDataBlock.I vertexDataBlock.h
+ vertexDataBook.I vertexDataBook.h
+ vertexDataBuffer.I vertexDataBuffer.h
+ vertexDataPage.I vertexDataPage.h
+ vertexDataSaveFile.I vertexDataSaveFile.h
+ vertexSlider.I vertexSlider.h
+ vertexTransform.I vertexTransform.h
+ videoTexture.I videoTexture.h
+)
+
+set(P3GOBJ_SOURCES
+ adaptiveLru.cxx
+ animateVerticesRequest.cxx
+ bufferContext.cxx
+ bufferContextChain.cxx
+ bufferResidencyTracker.cxx
+ config_gobj.cxx
+ geomContext.cxx
+ geom.cxx
+ geomEnums.cxx
+ geomMunger.cxx
+ geomPrimitive.cxx
+ geomPatches.cxx
+ geomTriangles.cxx
+ geomTrianglesAdjacency.cxx
+ geomTristrips.cxx
+ geomTristripsAdjacency.cxx
+ geomTrifans.cxx
+ geomLines.cxx
+ geomLinesAdjacency.cxx
+ geomLinestrips.cxx
+ geomLinestripsAdjacency.cxx
+ geomPoints.cxx
+ geomVertexArrayData.cxx
+ geomVertexArrayFormat.cxx
+ geomCacheEntry.cxx
+ geomCacheManager.cxx
+ geomVertexAnimationSpec.cxx
+ geomVertexData.cxx
+ geomVertexColumn.cxx
+ geomVertexFormat.cxx
+ geomVertexReader.cxx
+ geomVertexRewriter.cxx
+ geomVertexWriter.cxx
+ indexBufferContext.cxx
+ material.cxx
+ internalName.cxx
+ lens.cxx
+ materialPool.cxx matrixLens.cxx
+ occlusionQueryContext.cxx
+ orthographicLens.cxx
+ paramTexture.cxx
+ perspectiveLens.cxx
+ preparedGraphicsObjects.cxx
+ queryContext.cxx
+ samplerContext.cxx
+ samplerState.cxx
+ savedContext.cxx
+ shader.cxx
+ shaderBuffer.cxx
+ shaderContext.cxx
+ simpleAllocator.cxx
+ simpleLru.cxx
+ sliderTable.cxx
+ texture.cxx
+ textureCollection.cxx
+ textureContext.cxx
+ texturePeeker.cxx
+ texturePool.cxx
+ texturePoolFilter.cxx
+ textureReloadRequest.cxx
+ textureStage.cxx
+ textureStagePool.cxx
+ timerQueryContext.cxx
+ transformBlend.cxx
+ transformBlendTable.cxx
+ transformTable.cxx
+ userVertexSlider.cxx
+ userVertexTransform.cxx
+ vertexBufferContext.cxx
+ vertexDataBlock.cxx
+ vertexDataBook.cxx
+ vertexDataBuffer.cxx
+ vertexDataPage.cxx
+ vertexDataSaveFile.cxx
+ vertexSlider.cxx
+ vertexTransform.cxx
+ videoTexture.cxx
+)
+
+set(P3GOBJ_IGATEEXT
+ internalName_ext.cxx
+ internalName_ext.h
+ geomVertexArrayData_ext.cxx
+ geomVertexArrayData_ext.h
+ texture_ext.cxx
+ texture_ext.h
+ textureCollection_ext.cxx
+ textureCollection_ext.h
+)
+
+composite_sources(p3gobj P3GOBJ_SOURCES)
+add_component_library(p3gobj NOINIT SYMBOL BUILDING_PANDA_GOBJ
+ ${P3GOBJ_HEADERS} ${P3GOBJ_SOURCES})
+target_link_libraries(p3gobj p3gsgbase p3pnmimage
+ PKG::ZLIB PKG::SQUISH PKG::CG)
+target_interrogate(p3gobj ALL EXTENSIONS ${P3GOBJ_IGATEEXT})
+
+if(HAVE_SQUISH)
+ target_compile_definitions(p3gobj PRIVATE HAVE_SQUISH)
+endif()
+
+if(PHAVE_LOCKF)
+ target_compile_definitions(p3gobj PRIVATE PHAVE_LOCKF)
+endif()
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3gobj
+ EXPORT Core COMPONENT Core
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT CoreDevel)
+endif()
+install(FILES ${P3GOBJ_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/panda/src/gobj/shader.cxx b/panda/src/gobj/shader.cxx
index cf9631f660..a1067e9c9e 100644
--- a/panda/src/gobj/shader.cxx
+++ b/panda/src/gobj/shader.cxx
@@ -384,7 +384,7 @@ cp_dependency(ShaderMatInput inp) {
if (inp == SMO_attr_material || inp == SMO_attr_material2) {
dep |= SSD_material | SSD_frame;
}
- if (inp == SMO_attr_color) {
+ if (inp == SMO_attr_color || inp == SMO_attr_material2) {
dep |= SSD_color;
}
if (inp == SMO_attr_colorscale) {
@@ -422,6 +422,7 @@ cp_dependency(ShaderMatInput inp) {
(inp == SMO_slight_x) ||
(inp == SMO_satten_x) ||
(inp == SMO_mat_constant_x) ||
+ (inp == SMO_mat_constant_x_attrib) ||
(inp == SMO_vec_constant_x) ||
(inp == SMO_vec_constant_x_attrib) ||
(inp == SMO_view_x_to_view) ||
@@ -441,6 +442,8 @@ cp_dependency(ShaderMatInput inp) {
(inp == SMO_plight_x) ||
(inp == SMO_slight_x) ||
(inp == SMO_satten_x) ||
+ (inp == SMO_mat_constant_x) ||
+ (inp == SMO_mat_constant_x_attrib) ||
(inp == SMO_vec_constant_x_attrib) ||
(inp == SMO_view_x_to_view) ||
(inp == SMO_view_to_view_x) ||
@@ -459,10 +462,13 @@ cp_dependency(ShaderMatInput inp) {
(inp == SMO_light_source_i_attrib) ||
(inp == SMO_light_source_i_packed)) {
dep |= SSD_light | SSD_frame;
- if (inp == SMO_light_source_i_attrib ||
- inp == SMO_light_source_i_packed) {
- dep |= SSD_view_transform;
- }
+ }
+ if (inp == SMO_light_source_i_attrib ||
+ inp == SMO_light_source_i_packed ||
+ inp == SMO_mat_constant_x_attrib ||
+ inp == SMO_vec_constant_x_attrib) {
+ // Some light attribs (eg. position) need to be transformed to view space.
+ dep |= SSD_view_transform;
}
if ((inp == SMO_light_product_i_ambient) ||
(inp == SMO_light_product_i_diffuse) ||
@@ -499,14 +505,10 @@ cp_dependency(ShaderMatInput inp) {
}
/**
- * Analyzes a ShaderMatSpec and decides what it should use its cache for. It
- * can cache the results of any one opcode, or, it can cache the entire
- * result. This routine needs to be smart enough to know which data items can
- * be correctly cached, and which cannot.
+ * Adds the given ShaderMatSpec to the shader's mat spec table.
*/
void Shader::
-cp_optimize_mat_spec(ShaderMatSpec &spec) {
-
+cp_add_mat_spec(ShaderMatSpec &spec) {
// If we're composing with identity, simplify.
if (spec._func == SMF_first) {
@@ -563,10 +565,92 @@ cp_optimize_mat_spec(ShaderMatSpec &spec) {
}
}
- // Calculate state and transform dependencies.
+ // Determine which part is an array, for determining which one the count and
+ // index refer to. (It can't be the case that both parts are arrays.)
+ int begin[2] = {0, 0};
+ int end[2] = {1, 1};
+ if (spec._index > 0) {
+ for (int i = 0; i < 2; ++i) {
+ if (spec._part[i] == SMO_texmat_i ||
+ spec._part[i] == SMO_inv_texmat_i ||
+ spec._part[i] == SMO_light_source_i_attrib ||
+ spec._part[i] == SMO_light_product_i_ambient ||
+ spec._part[i] == SMO_light_product_i_diffuse ||
+ spec._part[i] == SMO_light_product_i_specular ||
+ spec._part[i] == SMO_apiview_clipplane_i ||
+ spec._part[i] == SMO_tex_is_alpha_i ||
+ spec._part[i] == SMO_transform_i ||
+ spec._part[i] == SMO_slider_i ||
+ spec._part[i] == SMO_light_source_i_packed ||
+ spec._part[i] == SMO_texscale_i ||
+ spec._part[i] == SMO_texcolor_i) {
+ begin[i] = spec._index;
+ end[i] = spec._index + 1;
+ }
+ }
+ nassertv(end[0] == 1 || end[1] == 1);
+ }
- spec._dep[0] = cp_dependency(spec._part[0]);
- spec._dep[1] = cp_dependency(spec._part[1]);
+ // Make sure that we have a place in the part cache for both parts.
+ int num_parts = (spec._func != SMF_first) ? 2 : 1;
+
+ for (int p = 0; p < num_parts; ++p) {
+ int dep = cp_dependency(spec._part[p]);
+ spec._dep |= dep;
+
+ // Do we already have a spot in the cache for this part?
+ size_t i;
+ size_t offset = 0;
+ for (i = 0; i < _mat_parts.size(); ++i) {
+ ShaderMatPart &part = _mat_parts[i];
+ if (part._part == spec._part[p] && part._arg == spec._arg[p]) {
+ int diff = end[p] - part._count;
+ if (diff <= 0) {
+ // The existing cache entry is big enough.
+ break;
+ } else {
+ // It's not big enough. Enlarge it, which means we have to change the
+ // offset of some of the other spec entries.
+ for (ShaderMatSpec &spec : _mat_spec) {
+ if (spec._cache_offset[0] >= offset + part._count) {
+ spec._cache_offset[0] += diff;
+ }
+ if (spec._cache_offset[1] >= offset + part._count) {
+ spec._cache_offset[1] += diff;
+ }
+ }
+ part._count = end[p];
+ break;
+ }
+ }
+ offset += part._count;
+ }
+ if (i == _mat_parts.size()) {
+ // Didn't find this part yet, create a new one.
+ ShaderMatPart part;
+ part._part = spec._part[p];
+ part._count = end[p];
+ part._arg = spec._arg[p];
+ part._dep = dep;
+ _mat_parts.push_back(std::move(part));
+ }
+ spec._cache_offset[p] = offset + begin[p];
+ }
+
+ _mat_spec.push_back(spec);
+ _mat_deps |= spec._dep;
+}
+
+/**
+ * Returns the total size of the matrix part cache.
+ */
+size_t Shader::
+cp_get_mat_cache_size() const {
+ size_t size = 0;
+ for (const ShaderMatPart &part : _mat_parts) {
+ size += part._count;
+ }
+ return size;
}
#ifdef HAVE_CG
@@ -776,9 +860,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
bind._arg[0] = nullptr;
bind._index = atoi(pieces[2].c_str());
- cp_optimize_mat_spec(bind);
- _mat_spec.push_back(bind);
- _mat_deps |= bind._dep[0] | bind._dep[1];
+ cp_add_mat_spec(bind);
return true;
}
@@ -931,9 +1013,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
if (!cp_parse_eol(p, pieces, next)) {
return false;
}
- cp_optimize_mat_spec(bind);
- _mat_spec.push_back(bind);
- _mat_deps |= bind._dep[0] | bind._dep[1];
+ cp_add_mat_spec(bind);
return true;
}
@@ -1041,9 +1121,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
return false;
}
- cp_optimize_mat_spec(bind);
- _mat_spec.push_back(bind);
- _mat_deps |= bind._dep[0] | bind._dep[1];
+ cp_add_mat_spec(bind);
return true;
}
@@ -1055,9 +1133,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
}
ShaderMatSpec bind;
- cp_optimize_mat_spec(bind);
- _mat_spec.push_back(bind);
- _mat_deps |= bind._dep[0] | bind._dep[1];
+ cp_add_mat_spec(bind);
return true;
}
@@ -1079,9 +1155,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
bind._part[1] = SMO_identity;
bind._arg[1] = nullptr;
- cp_optimize_mat_spec(bind);
- _mat_spec.push_back(bind);
- _mat_deps |= bind._dep[0] | bind._dep[1];
+ cp_add_mat_spec(bind);
return true;
}
@@ -1101,9 +1175,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
bind._part[1] = SMO_identity;
bind._arg[1] = nullptr;
- cp_optimize_mat_spec(bind);
- _mat_spec.push_back(bind);
- _mat_deps |= bind._dep[0] | bind._dep[1];
+ cp_add_mat_spec(bind);
return true;
}
@@ -1143,9 +1215,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
if (!cp_parse_eol(p, pieces, next)) {
return false;
}
- cp_optimize_mat_spec(bind);
- _mat_spec.push_back(bind);
- _mat_deps |= bind._dep[0] | bind._dep[1];
+ cp_add_mat_spec(bind);
return true;
}
@@ -1166,9 +1236,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
bind._arg[1] = nullptr;
bind._index = atoi(pieces[1].c_str());
- cp_optimize_mat_spec(bind);
- _mat_spec.push_back(bind);
- _mat_deps |= bind._dep[0] | bind._dep[1];
+ cp_add_mat_spec(bind);
return true;
}
@@ -1189,9 +1257,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
bind._arg[1] = nullptr;
bind._index = atoi(pieces[1].c_str());
- cp_optimize_mat_spec(bind);
- _mat_spec.push_back(bind);
- _mat_deps |= bind._dep[0] | bind._dep[1];
+ cp_add_mat_spec(bind);
return true;
}
@@ -1212,9 +1278,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
bind._arg[1] = nullptr;
bind._index = atoi(pieces[1].c_str());
- cp_optimize_mat_spec(bind);
- _mat_spec.push_back(bind);
- _mat_deps |= bind._dep[0] | bind._dep[1];
+ cp_add_mat_spec(bind);
return true;
}
@@ -1234,9 +1298,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
bind._part[1] = SMO_identity;
bind._arg[1] = nullptr;
- cp_optimize_mat_spec(bind);
- _mat_spec.push_back(bind);
- _mat_deps |= bind._dep[0] | bind._dep[1];
+ cp_add_mat_spec(bind);
return true;
}
@@ -1256,9 +1318,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
bind._part[1] = SMO_identity;
bind._arg[1] = nullptr;
- cp_optimize_mat_spec(bind);
- _mat_spec.push_back(bind);
- _mat_deps |= bind._dep[0] | bind._dep[1];
+ cp_add_mat_spec(bind);
return true;
}
@@ -1303,9 +1363,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
return false;
}
- cp_optimize_mat_spec(bind);
- _mat_spec.push_back(bind);
- _mat_deps |= bind._dep[0] | bind._dep[1];
+ cp_add_mat_spec(bind);
return true;
}
@@ -1388,9 +1446,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
bind._arg[0] = InternalName::make(pieces[1]);
bind._part[1] = SMO_identity;
bind._arg[1] = nullptr;
- cp_optimize_mat_spec(bind);
- _mat_spec.push_back(bind);
- _mat_deps |= bind._dep[0] | bind._dep[1];
+ cp_add_mat_spec(bind);
return true;
}
@@ -1409,9 +1465,7 @@ compile_parameter(ShaderArgInfo &p, int *arg_dim) {
bind._arg[0] = InternalName::make(pieces[1]);
bind._part[1] = SMO_identity;
bind._arg[1] = nullptr;
- cp_optimize_mat_spec(bind);
- _mat_spec.push_back(bind);
- _mat_deps |= bind._dep[0] | bind._dep[1];
+ cp_add_mat_spec(bind);
return true;
}
@@ -2362,7 +2416,6 @@ Shader(ShaderLanguage lang) :
_loaded(false),
_language(lang),
_last_modified(0),
- _mat_deps(0),
_cache_compiled_shader(false)
{
#ifdef HAVE_CG
@@ -2461,9 +2514,10 @@ read(const ShaderFile &sfile, BamCacheRecord *record) {
// Determine which language the shader is written in.
if (_language == SL_Cg) {
#ifdef HAVE_CG
- cg_get_profile_from_header(_default_caps);
+ ShaderCaps caps = _default_caps;
+ cg_get_profile_from_header(caps);
- if (!cg_analyze_shader(_default_caps)) {
+ if (!cg_analyze_shader(caps)) {
shader_cat.error()
<< "Shader encountered an error.\n";
return false;
@@ -2553,9 +2607,10 @@ load(const ShaderFile &sbody, BamCacheRecord *record) {
// Determine which language the shader is written in.
if (_language == SL_Cg) {
#ifdef HAVE_CG
- cg_get_profile_from_header(_default_caps);
+ ShaderCaps caps = _default_caps;
+ cg_get_profile_from_header(caps);
- if (!cg_analyze_shader(_default_caps)) {
+ if (!cg_analyze_shader(caps)) {
shader_cat.error()
<< "Shader encountered an error.\n";
return false;
diff --git a/panda/src/gobj/shader.h b/panda/src/gobj/shader.h
index 720025d7b0..0cc7ce1dae 100644
--- a/panda/src/gobj/shader.h
+++ b/panda/src/gobj/shader.h
@@ -402,15 +402,30 @@ public:
INLINE void read_datagram(DatagramIterator &source);
};
+ /**
+ * Describes a matrix making up a single part of the ShaderMatInput cache.
+ * The cache is made up of a continuous array of matrices, as described by
+ * a successive list of ShaderMatPart (each of which takes up _count matrices)
+ */
+ struct ShaderMatPart {
+ ShaderMatInput _part;
+ PT(InternalName) _arg;
+ int _count = 1;
+ int _dep = SSD_NONE;
+ };
+
+ /**
+ * Describes a shader input that is sourced from the render state.
+ */
struct ShaderMatSpec {
- LMatrix4 _cache[2];
- LMatrix4 _value;
+ size_t _cache_offset[2];
ShaderArgId _id;
ShaderMatFunc _func;
ShaderMatInput _part[2];
PT(InternalName) _arg[2];
- int _dep[2];
- int _index;
+ LMatrix4 _value;
+ int _dep = SSD_NONE;
+ int _index = 0;
ShaderMatPiece _piece;
};
@@ -514,7 +529,8 @@ public:
vector_string &pieces, int &next,
ShaderMatSpec &spec, bool fromflag);
int cp_dependency(ShaderMatInput inp);
- void cp_optimize_mat_spec(ShaderMatSpec &spec);
+ void cp_add_mat_spec(ShaderMatSpec &spec);
+ size_t cp_get_mat_cache_size() const;
#ifdef HAVE_CG
void cg_recurse_parameters(CGparameter parameter,
@@ -578,7 +594,9 @@ public:
epvector _mat_spec;
pvector _tex_spec;
pvector _var_spec;
- int _mat_deps;
+ pvector _mat_parts;
+ int _mat_deps = 0;
+ int _mat_cache_size = 0;
bool _error_flag;
ShaderFile _text;
diff --git a/panda/src/grutil/CMakeLists.txt b/panda/src/grutil/CMakeLists.txt
new file mode 100644
index 0000000000..bffcce6559
--- /dev/null
+++ b/panda/src/grutil/CMakeLists.txt
@@ -0,0 +1,66 @@
+set(P3GRUTIL_HEADERS
+ pipeOcclusionCullTraverser.I pipeOcclusionCullTraverser.h
+ cardMaker.I cardMaker.h
+ config_grutil.h
+ movieTexture.I movieTexture.h
+ fisheyeMaker.I fisheyeMaker.h
+ frameRateMeter.I frameRateMeter.h
+ meshDrawer.I meshDrawer.h
+ meshDrawer2D.I meshDrawer2D.h
+ geoMipTerrain.I geoMipTerrain.h
+ sceneGraphAnalyzerMeter.I sceneGraphAnalyzerMeter.h
+ heightfieldTesselator.I heightfieldTesselator.h
+ shaderTerrainMesh.I shaderTerrainMesh.h
+ lineSegs.I lineSegs.h
+ multitexReducer.I multitexReducer.h
+ nodeVertexTransform.I nodeVertexTransform.h
+ pfmVizzer.I pfmVizzer.h
+ rigidBodyCombiner.I rigidBodyCombiner.h
+)
+
+set(P3GRUTIL_SOURCES
+ cardMaker.cxx
+ movieTexture.cxx
+ fisheyeMaker.cxx
+ config_grutil.cxx
+ frameRateMeter.cxx
+ meshDrawer.cxx
+ meshDrawer2D.cxx
+ geoMipTerrain.cxx
+ sceneGraphAnalyzerMeter.cxx
+ heightfieldTesselator.cxx
+ shaderTerrainMesh.cxx
+ multitexReducer.cxx
+ nodeVertexTransform.cxx
+ pfmVizzer.cxx
+ pipeOcclusionCullTraverser.cxx
+ lineSegs.cxx
+ rigidBodyCombiner.cxx
+)
+
+# This is a large file; let's build it separately
+set_source_files_properties(multitexReducer.cxx PROPERTIES SKIP_UNITY_BUILD_INCLUSION YES)
+
+composite_sources(p3grutil P3GRUTIL_SOURCES)
+add_component_library(p3grutil SYMBOL BUILDING_PANDA_GRUTIL
+ ${P3GRUTIL_HEADERS} ${P3GRUTIL_SOURCES})
+target_link_libraries(p3grutil p3display p3text p3movies)
+if(HAVE_AUDIO)
+ target_link_libraries(p3grutil p3audio)
+endif()
+target_interrogate(p3grutil ALL)
+
+if(HAVE_EIGEN)
+ # Eigen puts this over the threshold where bigobj is needed on MSVC
+ set_target_properties(p3grutil PROPERTIES MSVC_BIGOBJ ON)
+endif()
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3grutil
+ EXPORT Core COMPONENT Core
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT CoreDevel)
+endif()
+install(FILES ${P3GRUTIL_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/panda/src/grutil/frameRateMeter.cxx b/panda/src/grutil/frameRateMeter.cxx
index f015e0ab55..cb734110e3 100644
--- a/panda/src/grutil/frameRateMeter.cxx
+++ b/panda/src/grutil/frameRateMeter.cxx
@@ -214,7 +214,7 @@ do_update(Thread *current_thread) {
static const size_t buffer_size = 1024;
char buffer[buffer_size];
-#if defined(WIN32_VC) || defined(WIN64_VC)
+#ifdef _WIN32
// Windows doesn't define snprintf(). Hope we don't overflow.
sprintf(buffer, _text_pattern.c_str(), value, deviation);
#else
diff --git a/panda/src/grutil/sceneGraphAnalyzerMeter.cxx b/panda/src/grutil/sceneGraphAnalyzerMeter.cxx
index 7b64422699..ad3ec115e8 100644
--- a/panda/src/grutil/sceneGraphAnalyzerMeter.cxx
+++ b/panda/src/grutil/sceneGraphAnalyzerMeter.cxx
@@ -206,7 +206,7 @@ do_update(Thread *current_thread) {
"Points: %d\n"
"Texture memory: %.1f KB\n";
-#if defined(WIN32_VC) || defined(WIN64_VC)
+#ifdef _WIN32
_snprintf(buffer, buffer_size, pattern,
_scene_graph_analyzer.get_num_nodes(),
_scene_graph_analyzer.get_num_instances(),
diff --git a/panda/src/gsgbase/CMakeLists.txt b/panda/src/gsgbase/CMakeLists.txt
new file mode 100644
index 0000000000..8060686e04
--- /dev/null
+++ b/panda/src/gsgbase/CMakeLists.txt
@@ -0,0 +1,27 @@
+set(P3GSGBASE_HEADERS
+ config_gsgbase.h
+ graphicsOutputBase.I graphicsOutputBase.h
+ graphicsStateGuardianBase.h
+)
+
+set(P3GSGBASE_SOURCES
+ config_gsgbase.cxx
+ graphicsOutputBase.cxx
+ graphicsStateGuardianBase.cxx
+)
+
+composite_sources(p3gsgbase P3GSGBASE_SOURCES)
+add_component_library(p3gsgbase NOINIT SYMBOL BUILDING_PANDA_GSGBASE
+ ${P3GSGBASE_HEADERS} ${P3GSGBASE_SOURCES})
+target_link_libraries(p3gsgbase p3putil p3linmath)
+target_interrogate(p3gsgbase ALL)
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3gsgbase
+ EXPORT Core COMPONENT Core
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT CoreDevel)
+endif()
+install(FILES ${P3GSGBASE_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/panda/src/linmath/CMakeLists.txt b/panda/src/linmath/CMakeLists.txt
new file mode 100644
index 0000000000..acbe732e93
--- /dev/null
+++ b/panda/src/linmath/CMakeLists.txt
@@ -0,0 +1,63 @@
+set(P3LINMATH_HEADERS
+ aa_luse.h
+ compose_matrix.h compose_matrix_src.I
+ compose_matrix_src.h config_linmath.h
+ configVariableColor.h configVariableColor.I
+ coordinateSystem.h dbl2fltnames.h dblnames.h
+ deg_2_rad.h deg_2_rad.I
+ flt2dblnames.h fltnames.h
+ intnames.h
+ lcast_to.h lcast_to_src.h lcast_to_src.I
+ lmatrix.h lmatrix_ext.h
+ lmat_ops.h lmat_ops_src.h lmat_ops_src.I
+ lmatrix3_src.h lmatrix3_src.I
+ lmatrix4_src.h lmatrix4_src.I
+ lorientation.h lorientation_src.h lorientation_src.I
+ lpoint2.h lpoint2_src.I lpoint2_src.h
+ lpoint3.h lpoint3_src.I lpoint3_src.h
+ lpoint4.h lpoint4_src.I lpoint4_src.h
+ lquaternion.h lquaternion_src.I
+ lquaternion_src.h lrotation.h lrotation_src.I
+ lrotation_src.h
+ lsimpleMatrix.h lsimpleMatrix.I
+ luse.I luse.N luse.h
+ lvec2_ops.h lvec2_ops_src.I lvec2_ops_src.h lvec3_ops.h
+ lvec3_ops_src.I lvec3_ops_src.h lvec4_ops.h lvec4_ops_src.I
+ lvec4_ops_src.h
+ lvecBase2.h lvecBase2_src.I lvecBase2_src.h
+ lvecBase3.h lvecBase3_src.I lvecBase3_src.h
+ lvecBase4.h lvecBase4_src.I lvecBase4_src.h
+ lvector2.h lvector2_src.I lvector2_src.h
+ lvector3.h lvector3_src.I lvector3_src.h
+ lvector4.h lvector4_src.I lvector4_src.h
+ lvector4.h lvector4_src.I lvector4_src.h
+ lvecBase2_ext.h lvecBase3_ext.h lvecBase4_ext.h
+ lpoint2_ext.h lpoint3_ext.h lpoint4_ext.h
+ lvector2_ext.h lvector3_ext.h lvector4_ext.h
+ mathNumbers.h mathNumbers.I
+)
+
+set(P3LINMATH_SOURCES
+ compose_matrix.cxx config_linmath.cxx configVariableColor.cxx
+ coordinateSystem.cxx lmatrix.cxx
+ lorientation.cxx lpoint2.cxx
+ lpoint3.cxx lpoint4.cxx lquaternion.cxx lrotation.cxx
+ luse.cxx lvecBase2.cxx lvecBase3.cxx lvecBase4.cxx
+ lvector2.cxx lvector3.cxx lvector4.cxx mathNumbers.cxx
+)
+
+composite_sources(p3linmath P3LINMATH_SOURCES)
+add_component_library(p3linmath SYMBOL BUILDING_PANDA_LINMATH
+ ${P3LINMATH_HEADERS} ${P3LINMATH_SOURCES})
+target_link_libraries(p3linmath p3pandabase pandaexpress PKG::EIGEN)
+target_interrogate(p3linmath ALL)
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3linmath
+ EXPORT Core COMPONENT Core
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT CoreDevel)
+endif()
+install(FILES ${P3LINMATH_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/panda/src/mathutil/CMakeLists.txt b/panda/src/mathutil/CMakeLists.txt
new file mode 100644
index 0000000000..0716f4538d
--- /dev/null
+++ b/panda/src/mathutil/CMakeLists.txt
@@ -0,0 +1,82 @@
+set(P3MATHUTIL_HEADERS
+ boundingHexahedron.I boundingHexahedron.h boundingLine.I
+ boundingLine.h
+ boundingBox.I boundingBox.h
+ boundingPlane.I boundingPlane.h
+ boundingSphere.I boundingSphere.h
+ boundingVolume.I boundingVolume.h config_mathutil.h
+ fftCompressor.h finiteBoundingVolume.h frustum.h
+ frustum_src.I frustum_src.h geometricBoundingVolume.I
+ geometricBoundingVolume.h
+ intersectionBoundingVolume.h intersectionBoundingVolume.I
+ linmath_events.h
+ look_at.h look_at_src.I
+ look_at_src.h
+ linmath_events.h
+ mersenne.h
+ omniBoundingVolume.I
+ omniBoundingVolume.h
+ parabola.h parabola_src.I parabola_src.h
+ perlinNoise.h perlinNoise.I
+ perlinNoise2.h perlinNoise2.I
+ perlinNoise3.h perlinNoise3.I
+ plane.h plane_src.I plane_src.h
+ pta_LMatrix4.h pta_LMatrix3.h pta_LVecBase3.h
+ pta_LVecBase4.h pta_LVecBase2.h
+ randomizer.h randomizer.I
+ rotate_to.h
+ stackedPerlinNoise2.h stackedPerlinNoise2.I
+ stackedPerlinNoise3.h stackedPerlinNoise3.I
+ triangulator.h triangulator.I
+ triangulator3.h triangulator3.I
+ unionBoundingVolume.h unionBoundingVolume.I
+)
+
+set(P3MATHUTIL_SOURCES
+ boundingHexahedron.cxx boundingLine.cxx
+ boundingBox.cxx
+ boundingPlane.cxx
+ boundingSphere.cxx
+ boundingVolume.cxx config_mathutil.cxx fftCompressor.cxx
+ finiteBoundingVolume.cxx geometricBoundingVolume.cxx
+ intersectionBoundingVolume.cxx
+ look_at.cxx
+ linmath_events.cxx
+ mersenne.cxx
+ omniBoundingVolume.cxx
+ parabola.cxx
+ perlinNoise.cxx
+ perlinNoise2.cxx
+ perlinNoise3.cxx
+ plane.cxx
+ pta_LMatrix4.cxx pta_LMatrix3.cxx pta_LVecBase3.cxx
+ pta_LVecBase4.cxx pta_LVecBase2.cxx
+ randomizer.cxx
+ rotate_to.cxx
+ stackedPerlinNoise2.cxx
+ stackedPerlinNoise3.cxx
+ triangulator.cxx
+ triangulator3.cxx
+ unionBoundingVolume.cxx
+)
+
+composite_sources(p3mathutil P3MATHUTIL_SOURCES)
+add_component_library(p3mathutil SYMBOL BUILDING_PANDA_MATHUTIL
+ ${P3MATHUTIL_HEADERS} ${P3MATHUTIL_SOURCES})
+target_link_libraries(p3mathutil p3event
+ PKG::FFTW)
+target_interrogate(p3mathutil ALL)
+
+if(HAVE_FFTW)
+ target_compile_definitions(p3mathutil PRIVATE HAVE_FFTW)
+endif()
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3mathutil
+ EXPORT Core COMPONENT Core
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT CoreDevel)
+endif()
+install(FILES ${P3MATHUTIL_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/panda/src/movies/CMakeLists.txt b/panda/src/movies/CMakeLists.txt
new file mode 100644
index 0000000000..30e01d254a
--- /dev/null
+++ b/panda/src/movies/CMakeLists.txt
@@ -0,0 +1,62 @@
+set(P3MOVIES_HEADERS
+ dr_flac.h
+ config_movies.h
+ flacAudio.h flacAudio.I
+ flacAudioCursor.h flacAudioCursor.I
+ inkblotVideo.h inkblotVideo.I
+ inkblotVideoCursor.h inkblotVideoCursor.I
+ microphoneAudio.h microphoneAudio.I
+ movieAudio.h movieAudio.I
+ movieAudioCursor.h movieAudioCursor.I
+ movieTypeRegistry.h movieTypeRegistry.I
+ movieVideo.h movieVideo.I
+ movieVideoCursor.h movieVideoCursor.I
+ opusAudio.h opusAudio.I
+ opusAudioCursor.h opusAudioCursor.I
+ userDataAudio.h userDataAudio.I
+ userDataAudioCursor.h userDataAudioCursor.I
+ vorbisAudio.h vorbisAudio.I
+ vorbisAudioCursor.h vorbisAudioCursor.I
+ wavAudio.h wavAudio.I
+ wavAudioCursor.h wavAudioCursor.I
+)
+
+set(P3MOVIES_SOURCES
+ config_movies.cxx
+ flacAudio.cxx
+ flacAudioCursor.cxx
+ inkblotVideo.cxx
+ inkblotVideoCursor.cxx
+ microphoneAudio.cxx
+ microphoneAudioDS.cxx
+ movieAudio.cxx
+ movieAudioCursor.cxx
+ movieTypeRegistry.cxx
+ movieVideo.cxx
+ movieVideoCursor.cxx
+ opusAudio.cxx
+ opusAudioCursor.cxx
+ userDataAudio.cxx
+ userDataAudioCursor.cxx
+ vorbisAudio.cxx
+ vorbisAudioCursor.cxx
+ wavAudio.cxx
+ wavAudioCursor.cxx
+)
+
+composite_sources(p3movies P3MOVIES_SOURCES)
+add_component_library(p3movies SYMBOL BUILDING_PANDA_MOVIES
+ ${P3MOVIES_HEADERS} ${P3MOVIES_SOURCES})
+target_link_libraries(p3movies p3pstatclient p3gobj p3pandabase pandaexpress
+ PKG::VORBIS PKG::OPUS)
+target_interrogate(p3movies ALL)
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3movies
+ EXPORT Core COMPONENT Core
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT CoreDevel)
+endif()
+install(FILES ${P3MOVIES_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/panda/src/nativenet/CMakeLists.txt b/panda/src/nativenet/CMakeLists.txt
new file mode 100644
index 0000000000..614af16d33
--- /dev/null
+++ b/panda/src/nativenet/CMakeLists.txt
@@ -0,0 +1,47 @@
+if(NOT WANT_NATIVE_NET)
+ return()
+endif()
+
+set(P3NATIVENET_HEADERS
+ config_nativenet.h
+ buffered_datagramconnection.h
+ buffered_datagramreader.h buffered_datagramreader.I
+ ringbuffer.h ringbuffer.I socket_ip.h
+ socket_tcp.h socket_tcp_listen.h
+ time_accumulator.h time_out.h
+ socket_address.I socket_address.h
+ socket_portable.h time_base.h time_span.h buffered_datagramwriter.h
+ socket_base.h socket_selector.h
+ socket_udp.h
+ socket_udp_incoming.h time_clock.h
+ membuffer.h membuffer.I socket_fdset.h
+ socket_udp_outgoing.h time_general.h
+)
+
+set(P3NATIVENET_SOURCES
+ config_nativenet.cxx
+ buffered_datagramconnection.cxx
+ socket_address.cxx
+ socket_ip.cxx
+ socket_tcp.cxx
+ socket_tcp_listen.cxx
+ socket_udp.cxx
+ socket_udp_incoming.cxx
+ socket_udp_outgoing.cxx
+)
+
+composite_sources(p3nativenet P3NATIVENET_SOURCES)
+add_component_library(p3nativenet SYMBOL BUILDING_PANDA_NATIVENET
+ ${P3NATIVENET_HEADERS} ${P3NATIVENET_SOURCES})
+target_link_libraries(p3nativenet p3pandabase pandaexpress)
+target_interrogate(p3nativenet ALL)
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3nativenet
+ EXPORT Core COMPONENT Core
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT CoreDevel)
+endif()
+install(FILES ${P3NATIVENET_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/panda/src/nativenet/config_nativenet.cxx b/panda/src/nativenet/config_nativenet.cxx
index f90e106e81..af8b2d77cf 100644
--- a/panda/src/nativenet/config_nativenet.cxx
+++ b/panda/src/nativenet/config_nativenet.cxx
@@ -16,7 +16,6 @@
#include "socket_ip.h"
#include "socket_tcp.h"
#include "socket_tcp_listen.h"
-#include "socket_tcp_ssl.h"
#include "socket_udp_incoming.h"
#include "socket_udp_outgoing.h"
#include "socket_udp.h"
@@ -55,9 +54,6 @@ init_libnativenet() {
Socket_IP::init_type();
Socket_TCP::init_type();
Socket_TCP_Listen::init_type();
-#ifdef HAVE_OPENSSL
- Socket_TCP_SSL::init_type();
-#endif
Socket_UDP_Incoming::init_type();
Socket_UDP_Outgoing::init_type();
Socket_UDP::init_type();
diff --git a/panda/src/nativenet/p3nativenet_composite1.cxx b/panda/src/nativenet/p3nativenet_composite1.cxx
index 1c842ac105..015473f8f8 100644
--- a/panda/src/nativenet/p3nativenet_composite1.cxx
+++ b/panda/src/nativenet/p3nativenet_composite1.cxx
@@ -4,7 +4,6 @@
#include "socket_ip.cxx"
#include "socket_tcp.cxx"
#include "socket_tcp_listen.cxx"
-#include "socket_tcp_ssl.cxx"
#include "socket_udp.cxx"
#include "socket_udp_incoming.cxx"
#include "socket_udp_outgoing.cxx"
diff --git a/panda/src/nativenet/socket_fdset.h b/panda/src/nativenet/socket_fdset.h
index 7da876c0f8..7af32a9d68 100644
--- a/panda/src/nativenet/socket_fdset.h
+++ b/panda/src/nativenet/socket_fdset.h
@@ -52,7 +52,7 @@ inline Socket_fdset::Socket_fdset() {
inline void Socket_fdset::setForSocketNative(SOCKET inid)
{
assert( inid >= 0);
-#ifndef WIN32
+#ifndef _WIN32
assert(inid < FD_SETSIZE);
#endif
@@ -68,7 +68,7 @@ inline void Socket_fdset::setForSocketNative(SOCKET inid)
inline bool Socket_fdset::isSetForNative(SOCKET inid) const
{
assert( inid >= 0);
-#ifndef WIN32
+#ifndef _WIN32
assert(inid < FD_SETSIZE);
#endif
diff --git a/panda/src/nativenet/socket_ip.h b/panda/src/nativenet/socket_ip.h
index 3c03db2b3b..4b3ab34c7e 100644
--- a/panda/src/nativenet/socket_ip.h
+++ b/panda/src/nativenet/socket_ip.h
@@ -56,7 +56,6 @@ private:
friend class Socket_TCP_Listen;
friend class Socket_UDP_Incoming;
friend class Socket_UDP_Outgoing;
- friend class Socket_TCP_SSL;
public:
static TypeHandle get_class_type() {
diff --git a/panda/src/nativenet/socket_portable.h b/panda/src/nativenet/socket_portable.h
index a4a249f92e..2ac1c89248 100644
--- a/panda/src/nativenet/socket_portable.h
+++ b/panda/src/nativenet/socket_portable.h
@@ -53,7 +53,7 @@ typedef unsigned long SOCKET;
************************************************************************/
#elif defined(_WIN32)
#include
-#include
+#include
typedef u_short sa_family_t;
diff --git a/panda/src/nativenet/socket_tcp_ssl.cxx b/panda/src/nativenet/socket_tcp_ssl.cxx
deleted file mode 100644
index 0444d41802..0000000000
--- a/panda/src/nativenet/socket_tcp_ssl.cxx
+++ /dev/null
@@ -1,21 +0,0 @@
-/**
- * PANDA 3D SOFTWARE
- * Copyright (c) Carnegie Mellon University. All rights reserved.
- *
- * All use of this software is subject to the terms of the revised BSD
- * license. You should have received a copy of this license along
- * with this source code in a file named "LICENSE."
- *
- * @file socket_tcp_ssl.cxx
- * @author drose
- * @date 2007-03-01
- */
-
-#include "socket_tcp_ssl.h"
-
-#ifdef HAVE_OPENSSL
-
-SSL_CTX *global_ssl_ctx;
-TypeHandle Socket_TCP_SSL::_type_handle;
-
-#endif // HAVE_OPENSSL
diff --git a/panda/src/nativenet/socket_tcp_ssl.h b/panda/src/nativenet/socket_tcp_ssl.h
deleted file mode 100644
index 8f16f188dc..0000000000
--- a/panda/src/nativenet/socket_tcp_ssl.h
+++ /dev/null
@@ -1,299 +0,0 @@
-#ifndef __SOCKET_TCP_SSL_H__
-#define __SOCKET_TCP_SSL_H__
-
-#include "pandabase.h"
-#include "config_nativenet.h"
-#include "socket_ip.h"
-#include "numeric_types.h"
-
-#ifdef HAVE_OPENSSL
-
-#include /* SSLeay stuff */
-#include
-#include
-#include
-#include
-#include
-
-extern EXPCL_PANDA_NATIVENET SSL_CTX *global_ssl_ctx;
-
-struct SSlStartup {
- SSlStartup() {
- const SSL_METHOD *meth;
- SSLeay_add_ssl_algorithms();
- // meth = SSLv23_server_method();
- meth = SSLv23_method();
- SSL_load_error_strings();
- // I hate this cast, but older versions of OpenSSL need it.
- global_ssl_ctx = SSL_CTX_new((SSL_METHOD *) meth);
- }
-
- ~SSlStartup() {
- SSL_CTX_free (global_ssl_ctx);
- global_ssl_ctx = nullptr;
- }
-
- bool isactive() { return global_ssl_ctx != nullptr; };
-};
-
-/**
- *
- */
-class EXPCL_PANDA_NATIVENET Socket_TCP_SSL : public Socket_IP {
-public:
- inline Socket_TCP_SSL(SOCKET);
- inline Socket_TCP_SSL() : _ssl(nullptr) {}
-
- virtual inline ~Socket_TCP_SSL()
- {
- CleanSslUp();
- }
-
- inline int SetNoDelay();
- inline int SetLinger(int interval_seconds = 0);
- inline int DontLinger();
-
- inline int SetSendBufferSize(int insize);
- inline bool ActiveOpen(const Socket_Address &theaddress);
- inline int SendData(const char *data, int size);
- inline int RecvData(char *data, int size);
- inline bool ErrorIs_WouldBlocking(int err);
-
- inline SSL *get_ssl() { return _ssl; };
-
- inline void DetailErrorFormat(void);
-
-private:
- SSL *_ssl;
-
- void CleanSslUp() {
- if (_ssl != nullptr) {
- SSL_shutdown(_ssl);
- SSL_free(_ssl);
- _ssl = nullptr;
- }
- }
-
-public:
- static TypeHandle get_class_type() {
- return _type_handle;
- }
- static void init_type() {
- Socket_IP::init_type();
- register_type(_type_handle, "Socket_TCP_SSL",
- Socket_IP::get_class_type());
- }
- virtual TypeHandle get_type() const {
- return get_class_type();
- }
- virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
-
-private:
- static TypeHandle _type_handle;
-};
-
-/**
- *
- */
-inline Socket_TCP_SSL::
-Socket_TCP_SSL(SOCKET sck) : ::Socket_IP(sck) {
- // right know this will only work for a accepted ie a server socket ??
- SetNonBlocking(); // maybe should be blocking?
-
- _ssl = SSL_new(global_ssl_ctx);
- if (_ssl == nullptr) {
- return;
- }
-
- SSL_set_fd(_ssl, (int)GetSocket());
-
- SSL_accept(_ssl);
- ERR_clear_error();
-
- // printf(" Ssl Accept = %d \n",err);
-}
-
-/**
- * Disable Nagle algorithm. Don't delay send to coalesce packets
- */
-inline int Socket_TCP_SSL::
-SetNoDelay() {
- int nodel = 1;
- int ret1;
- ret1 = setsockopt(_socket, IPPROTO_TCP, TCP_NODELAY, (char *)&nodel, sizeof(nodel));
-
- if (ret1 != 0) {
- return BASIC_ERROR;
- }
- return ALL_OK;
-}
-
-/**
- * will control the behavior of SO_LINGER for a TCP socket
- */
-int Socket_TCP_SSL::
-SetLinger(int interval_seconds) {
- linger ll;
- ll.l_linger = interval_seconds;
- ll.l_onoff = 1;
- int ret1 = setsockopt(_socket, SOL_SOCKET, SO_LINGER, (const char *)&ll, sizeof(linger));
- if (ret1 != 0) {
- return BASIC_ERROR;
- }
- return ALL_OK;
-}
-
-/**
- * Turn off the linger flag. The socket will quickly release buffered items
- * and free up OS resources. You may lose a stream if you use this flag and
- * do not negotiate the close at the application layer.
- */
-int Socket_TCP_SSL::
-DontLinger() {
- linger ll;
- ll.l_linger = 0;
- ll.l_onoff = 0;
- int ret1 = setsockopt(_socket, SOL_SOCKET, SO_LINGER, (const char *)&ll, sizeof(linger));
- if (ret1 != 0) {
- return BASIC_ERROR;
- }
- return ALL_OK;
-}
-
-/**
- * Just like it sounds. Sets a buffered socket recv buffer size. This
- * function does not refuse ranges outside hard-coded OS limits
- */
-int Socket_TCP_SSL::
-SetSendBufferSize(int insize) {
- if (setsockopt(_socket, (int) SOL_SOCKET, (int) SO_SNDBUF, (char *) &insize, sizeof(int))) {
- return BASIC_ERROR;
- }
- return ALL_OK;
-}
-
-/**
-* This function will try and set the socket up for active open to a specified
-* address and port provided by the input parameter
-*/
-bool Socket_TCP_SSL::
-ActiveOpen(const Socket_Address &theaddress) {
- _socket = DO_NEWTCP(theaddress.get_family());
- if (_socket == BAD_SOCKET) {
- return false;
- }
-
- if (DO_CONNECT(_socket, &theaddress.GetAddressInfo()) != 0) {
- return ErrorClose();
- }
-
- _ssl = SSL_new(global_ssl_ctx);
- if (_ssl == nullptr) {
- return false;
- }
- SSL_set_fd(_ssl, (int)GetSocket());
- if (SSL_connect(_ssl) == -1) {
- return false;
- }
- return true;
-
- // return SetSslUp();
-}
-
-/**
- * Ok Lets Send the Data - if error 0 if socket closed for write or lengh is 0
- * + bytes writen ( May be smaller than requested)
- */
-inline int Socket_TCP_SSL::
-SendData(const char *data, int size) {
- if (_ssl == nullptr) {
- return -1;
- }
-
-// ERR_clear_error();
-
- return SSL_write(_ssl, data, size);
-}
-
-/**
- * Read the data from the connection - if error 0 if socket closed for read or
- * length is 0 + bytes read ( May be smaller than requested)
- */
-inline int Socket_TCP_SSL::
-RecvData(char *data, int len) {
- if (_ssl == nullptr) {
- return -1;
- }
-
- ERR_clear_error();
-
- return SSL_read(_ssl, data, len);
-}
-
-/**
- * Is last error a blocking error ?? True is last error was a blocking error
- */
-inline bool Socket_TCP_SSL::
-ErrorIs_WouldBlocking(int err) {
- if (_ssl == nullptr || err >= 0) {
- nativenet_cat.warning()
- << "Socket_TCP_SSL::ErrorIs_WouldBlocking->Called With Error number "
- << err << " or _ssl is NULL\n";
- return false;
- }
-
- int ssl_error_code = SSL_get_error(_ssl,err);
- bool answer = false;
-
- switch(ssl_error_code) {
- case SSL_ERROR_WANT_READ:
- case SSL_ERROR_WANT_WRITE:
- case SSL_ERROR_WANT_CONNECT:
-// case SSL_ERROR_WANT_ACCEPT:
- answer = true;
- break;
-// hmm not sure we need this .. hmmmm
- case SSL_ERROR_SYSCALL:
- if(GETERROR() == LOCAL_BLOCKING_ERROR) {
- answer = true;
- } else {
- DetailErrorFormat();
-// LOGWARNING("Socket_TCP_SSL::ErrorIs_WouldBlocking-> Not A blocking Error1
-// SSl_CODe=[%d] OS=[%d]",ssl_error_code,GETERROR());
- }
- break;
- default:
- DetailErrorFormat();
-// LOGWARNING("Socket_TCP_SSL::ErrorIs_WouldBlocking-> Not A blocking Error2
-// SSl_CODe=[%d] OS=[%d]",ssl_error_code,GETERROR());
- answer = false;
- break;
- }
-
-// ERR_clear_error();
- return answer;
-}
-
-inline void Socket_TCP_SSL::
-DetailErrorFormat(void) {
- return; // turn on for debuging
-
- uint32_t l;
- char buf[256];
- char buf2[4096];
- const char *file,*data;
- int line,flags;
- uint32_t es;
-
- es = CRYPTO_thread_id();
- while ((l = ERR_get_error_line_data(&file, &line, &data, &flags)) != 0) {
- ERR_error_string_n(l, buf, sizeof(buf));
- BIO_snprintf(buf2, sizeof(buf2), "***%lu:%s:%s:%d:%s\n", (unsigned long) es, buf, file, line, (flags & ERR_TXT_STRING) ? data : "NoText");
- nativenet_cat.warning()
- << "Socket_TCP_SSL::DetailErrorFormat->[" << buf2 << "]\n";
- }
-}
-
-#endif // HAVE_OPENSSL
-
-#endif //__SOCKET_TCP_SSL_H__
diff --git a/panda/src/nativenet/time_base.h b/panda/src/nativenet/time_base.h
index 8b7ea108f7..0aa12baf58 100644
--- a/panda/src/nativenet/time_base.h
+++ b/panda/src/nativenet/time_base.h
@@ -14,7 +14,7 @@
* returning the current system time ?? So use time functions that grab the
* current system time sparingly ??
*/
-#ifdef WIN32
+#ifdef _WIN32
#include
#include
#include
@@ -64,7 +64,7 @@ inline void TimeAdd(const struct timeval &start, const struct timeval &delta, st
NormalizeTime(answer);
}
-#ifdef WIN32
+#ifdef _WIN32
// Lets make Windows think it is a unix machine :)
/**
diff --git a/panda/src/net/CMakeLists.txt b/panda/src/net/CMakeLists.txt
new file mode 100644
index 0000000000..d811b806e8
--- /dev/null
+++ b/panda/src/net/CMakeLists.txt
@@ -0,0 +1,51 @@
+if(NOT HAVE_NET OR NOT WANT_NATIVE_NET)
+ return()
+endif()
+
+set(P3NET_HEADERS
+ config_net.h connection.h connectionListener.h
+ connectionManager.N connectionManager.h
+ connectionReader.I connectionReader.h
+ connectionWriter.h datagramQueue.h
+ datagramTCPHeader.I datagramTCPHeader.h
+ datagramUDPHeader.I datagramUDPHeader.h
+ netAddress.h netDatagram.I netDatagram.h
+ datagramGeneratorNet.I datagramGeneratorNet.h
+ datagramSinkNet.I datagramSinkNet.h
+ queuedConnectionListener.I
+ queuedConnectionListener.h queuedConnectionManager.h
+ queuedConnectionReader.h recentConnectionReader.h
+ queuedReturn.h queuedReturn.I
+)
+
+set(P3NET_SOURCES
+ config_net.cxx connection.cxx connectionListener.cxx
+ connectionManager.cxx connectionReader.cxx
+ connectionWriter.cxx datagramQueue.cxx datagramTCPHeader.cxx
+ datagramUDPHeader.cxx netAddress.cxx netDatagram.cxx
+ datagramGeneratorNet.cxx
+ datagramSinkNet.cxx
+ queuedConnectionListener.cxx
+ queuedConnectionManager.cxx queuedConnectionReader.cxx
+ recentConnectionReader.cxx
+)
+
+composite_sources(p3net P3NET_SOURCES)
+add_component_library(p3net SYMBOL BUILDING_PANDA_NET
+ ${P3NET_HEADERS} ${P3NET_SOURCES})
+target_link_libraries(p3net p3nativenet p3pipeline p3pandabase pandaexpress)
+target_interrogate(p3net ALL)
+
+if(WIN32)
+ target_link_libraries(p3net iphlpapi.lib)
+endif()
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3net
+ EXPORT Core COMPONENT Core
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT CoreDevel)
+endif()
+install(FILES ${P3NET_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/panda/src/net/connectionManager.cxx b/panda/src/net/connectionManager.cxx
index 6ad6063a8b..1af31a8f78 100644
--- a/panda/src/net/connectionManager.cxx
+++ b/panda/src/net/connectionManager.cxx
@@ -25,7 +25,7 @@
#if defined(CPPPARSER)
#elif defined(_WIN32)
#include // For gethostname()
-#include // For GetAdaptersAddresses()
+#include // For GetAdaptersAddresses()
#elif defined(__ANDROID__)
#include
#else
@@ -478,7 +478,7 @@ scan_interfaces() {
_interfaces.clear();
_interfaces_scanned = true;
-#ifdef WIN32_VC
+#ifdef _WIN32
int flags = GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_SKIP_UNICAST | GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER;
ULONG family = support_ipv6 ? AF_UNSPEC : AF_INET;
ULONG buffer_size = 0;
@@ -544,7 +544,7 @@ scan_interfaces() {
#elif defined(__ANDROID__)
// TODO: implementation using netlink_socket?
-#else // WIN32_VC
+#else // _WIN32
struct ifaddrs *ifa;
if (getifaddrs(&ifa) != 0) {
// Failure.
@@ -578,7 +578,7 @@ scan_interfaces() {
freeifaddrs(ifa);
-#endif // WIN32_VC
+#endif // _WIN32
}
/**
diff --git a/panda/src/ode/CMakeLists.txt b/panda/src/ode/CMakeLists.txt
new file mode 100644
index 0000000000..13bc422c74
--- /dev/null
+++ b/panda/src/ode/CMakeLists.txt
@@ -0,0 +1,103 @@
+if(NOT HAVE_ODE)
+ return()
+endif()
+
+set(P3ODE_HEADERS
+ ode_includes.h config_ode.h
+ odeWorld.I odeWorld.h
+ odeMass.I odeMass.h
+ odeBody.I odeBody.h
+ odeJointGroup.I odeJointGroup.h
+ odeJoint.I odeJoint.h
+ odeUtil.h
+ odeSpace.I odeSpace.h
+ odeGeom.I odeGeom.h
+ odeSurfaceParameters.I odeSurfaceParameters.h
+ odeContactGeom.I odeContactGeom.h
+ odeContact.I odeContact.h
+ odeAMotorJoint.I odeAMotorJoint.h
+ odeBallJoint.I odeBallJoint.h
+ odeContactJoint.I odeContactJoint.h
+ odeFixedJoint.I odeFixedJoint.h
+ odeHingeJoint.I odeHingeJoint.h
+ odeHinge2Joint.I odeHinge2Joint.h
+ odeLMotorJoint.I odeLMotorJoint.h
+ odeNullJoint.I odeNullJoint.h
+ odePlane2dJoint.I odePlane2dJoint.h
+ odeSliderJoint.I odeSliderJoint.h
+ odeUniversalJoint.I odeUniversalJoint.h
+ odeJointCollection.I odeJointCollection.h
+ odeSimpleSpace.I odeSimpleSpace.h
+ odeHashSpace.I odeHashSpace.h
+ odeQuadTreeSpace.I odeQuadTreeSpace.h
+ odeSphereGeom.I odeSphereGeom.h
+ odeBoxGeom.I odeBoxGeom.h
+ odePlaneGeom.I odePlaneGeom.h
+ odeCappedCylinderGeom.I odeCappedCylinderGeom.h
+ odeCylinderGeom.I odeCylinderGeom.h
+ odeRayGeom.I odeRayGeom.h
+ odeTriMeshData.I odeTriMeshData.h
+ odeTriMeshGeom.I odeTriMeshGeom.h
+ odeCollisionEntry.I odeCollisionEntry.h
+ odeHelperStructs.h
+)
+
+set(P3ODE_SOURCES
+ config_ode.cxx
+ odeWorld.cxx odeMass.cxx odeBody.cxx
+ odeJointGroup.cxx odeJoint.cxx
+ odeUtil.cxx
+ odeSpace.cxx
+ odeGeom.cxx
+ odeSurfaceParameters.cxx
+ odeContactGeom.cxx odeContact.cxx
+ odeAMotorJoint.cxx odeBallJoint.cxx
+ odeContactJoint.cxx odeFixedJoint.cxx
+ odeHingeJoint.cxx odeHinge2Joint.cxx
+ odeLMotorJoint.cxx odeNullJoint.cxx
+ odePlane2dJoint.cxx odeSliderJoint.cxx
+ odeUniversalJoint.cxx odeJointCollection.cxx
+ odeSimpleSpace.cxx
+ odeHashSpace.cxx odeQuadTreeSpace.cxx
+ odeSphereGeom.cxx odeBoxGeom.cxx
+ odePlaneGeom.cxx odeCappedCylinderGeom.cxx
+ odeCylinderGeom.cxx odeRayGeom.cxx
+ odeTriMeshData.cxx odeTriMeshGeom.cxx
+ odeCollisionEntry.cxx
+)
+
+set(P3ODE_IGATEEXT
+ odeBody_ext.cxx
+ odeBody_ext.h
+ odeBody_ext.I
+ odeGeom_ext.cxx
+ odeGeom_ext.h
+ odeGeom_ext.I
+ odeJoint_ext.cxx
+ odeJoint_ext.h
+ odeSpace_ext.cxx
+ odeSpace_ext.h
+ odeSpace_ext.I
+ odeUtil_ext.cxx
+ odeUtil_ext.h
+)
+
+set(P3ODE_IGATE_SOURCES "${P3ODE_HEADERS};${P3ODE_SOURCES}")
+list(REMOVE_ITEM P3ODE_IGATE_SOURCES "odeHelperStructs.h")
+
+composite_sources(p3ode P3ODE_SOURCES)
+add_library(p3ode ${P3ODE_SOURCES} ${P3ODE_HEADERS})
+set_target_properties(p3ode PROPERTIES DEFINE_SYMBOL BUILDING_PANDAODE)
+target_link_libraries(p3ode panda
+ PKG::ODE)
+target_interrogate(p3ode ${P3ODE_IGATE_SOURCES} EXTENSIONS ${P3ODE_IGATEEXT})
+
+install(TARGETS p3ode
+ EXPORT ODE COMPONENT ODE
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT ODEDevel)
+install(FILES ${P3ODE_HEADERS} COMPONENT ODEDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
+
+export_targets(ODE COMPONENT ODEDevel)
diff --git a/panda/src/pandabase/CMakeLists.txt b/panda/src/pandabase/CMakeLists.txt
new file mode 100644
index 0000000000..73633927c1
--- /dev/null
+++ b/panda/src/pandabase/CMakeLists.txt
@@ -0,0 +1,14 @@
+set(P3PANDABASE_HEADERS
+ pandabase.h pandasymbols.h
+)
+
+set(P3PANDABASE_SOURCES
+ pandabase.cxx
+)
+
+# Yes, INTERFACE: don't build it, there's no code!
+add_library(p3pandabase INTERFACE)
+target_link_libraries(p3pandabase INTERFACE p3dtool)
+
+install(FILES ${P3PANDABASE_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
+install(TARGETS p3pandabase EXPORT Core COMPONENT Core)
diff --git a/panda/src/pandabase/pandasymbols.h b/panda/src/pandabase/pandasymbols.h
index 1d4d487edd..3cabc46e8b 100644
--- a/panda/src/pandabase/pandasymbols.h
+++ b/panda/src/pandabase/pandasymbols.h
@@ -587,7 +587,7 @@
#define EXPTP_VRPN IMPORT_TEMPL
#endif
-#if (defined(WIN32_VC) || defined(WIN64_VC)) && !defined(CPPPARSER)
+#if defined(_MSC_VER) && !defined(CPPPARSER)
#define INLINE_LINMATH __forceinline
#define INLINE_MATHUTIL __forceinline
diff --git a/panda/src/parametrics/CMakeLists.txt b/panda/src/parametrics/CMakeLists.txt
new file mode 100644
index 0000000000..5f1a96593f
--- /dev/null
+++ b/panda/src/parametrics/CMakeLists.txt
@@ -0,0 +1,51 @@
+set(P3PARAMETRICS_HEADERS
+ config_parametrics.h
+ cubicCurveseg.h curveFitter.I curveFitter.h
+ hermiteCurve.h
+ nurbsCurve.I nurbsCurve.h
+ nurbsCurveEvaluator.I nurbsCurveEvaluator.h
+ nurbsCurveInterface.I nurbsCurveInterface.h
+ nurbsCurveResult.I nurbsCurveResult.h
+ nurbsBasisVector.I nurbsBasisVector.h
+ nurbsSurfaceEvaluator.I nurbsSurfaceEvaluator.h
+ nurbsSurfaceResult.I nurbsSurfaceResult.h
+ nurbsVertex.h nurbsVertex.I
+ parametricCurve.h
+ parametricCurveCollection.I parametricCurveCollection.h
+ piecewiseCurve.h
+ ropeNode.I ropeNode.h
+ sheetNode.I sheetNode.h
+)
+
+set(P3PARAMETRICS_SOURCES
+ config_parametrics.cxx cubicCurveseg.cxx
+ curveFitter.cxx hermiteCurve.cxx
+ nurbsCurve.cxx
+ nurbsCurveEvaluator.cxx
+ nurbsCurveInterface.cxx
+ nurbsCurveResult.cxx
+ nurbsBasisVector.cxx
+ nurbsSurfaceEvaluator.cxx
+ nurbsSurfaceResult.cxx
+ nurbsVertex.cxx
+ parametricCurve.cxx parametricCurveCollection.cxx
+ piecewiseCurve.cxx
+ ropeNode.cxx
+ sheetNode.cxx
+)
+
+composite_sources(p3parametrics P3PARAMETRICS_SOURCES)
+add_component_library(p3parametrics NOINIT SYMBOL BUILDING_PANDA_PARAMETRICS
+ ${P3PARAMETRICS_HEADERS} ${P3PARAMETRICS_SOURCES})
+target_link_libraries(p3parametrics p3pgraph)
+target_interrogate(p3parametrics ALL)
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3parametrics
+ EXPORT Core COMPONENT Core
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT CoreDevel)
+endif()
+install(FILES ${P3PARAMETRICS_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/panda/src/particlesystem/CMakeLists.txt b/panda/src/particlesystem/CMakeLists.txt
new file mode 100644
index 0000000000..7a227f7dc6
--- /dev/null
+++ b/panda/src/particlesystem/CMakeLists.txt
@@ -0,0 +1,64 @@
+set(P3PARTICLESYSTEM_HEADERS
+ baseParticle.I baseParticle.h baseParticleEmitter.I
+ baseParticleEmitter.h baseParticleFactory.I
+ baseParticleFactory.h baseParticleRenderer.I
+ baseParticleRenderer.h arcEmitter.I arcEmitter.h
+ boxEmitter.I boxEmitter.h
+ config_particlesystem.h discEmitter.I discEmitter.h
+ emitters.h
+ geomParticleRenderer.I geomParticleRenderer.h lineEmitter.I
+ lineEmitter.h lineParticleRenderer.I lineParticleRenderer.h
+ particlefactories.h
+ particles.h
+ particleSystem.I particleSystem.h particleSystemManager.I
+ particleSystemManager.h pointEmitter.I pointEmitter.h
+ pointParticle.h pointParticleFactory.h
+ pointParticleRenderer.I pointParticleRenderer.h
+ rectangleEmitter.I rectangleEmitter.h ringEmitter.I
+ ringEmitter.h sparkleParticleRenderer.I
+ sparkleParticleRenderer.h sphereSurfaceEmitter.I
+ sphereSurfaceEmitter.h sphereVolumeEmitter.I
+ sphereVolumeEmitter.h spriteParticleRenderer.I
+ spriteParticleRenderer.h tangentRingEmitter.I
+ tangentRingEmitter.h zSpinParticle.I zSpinParticle.h
+ zSpinParticleFactory.I zSpinParticleFactory.h
+ particleCommonFuncs.h colorInterpolationManager.I
+ colorInterpolationManager.h
+)
+
+set(P3PARTICLESYSTEM_SOURCES
+ baseParticle.cxx baseParticleEmitter.cxx baseParticleFactory.cxx
+ baseParticleRenderer.cxx boxEmitter.cxx arcEmitter.cxx
+ config_particlesystem.cxx discEmitter.cxx
+ geomParticleRenderer.cxx lineEmitter.cxx
+ lineParticleRenderer.cxx particleSystem.cxx
+ particleSystemManager.cxx pointEmitter.cxx pointParticle.cxx
+ pointParticleFactory.cxx pointParticleRenderer.cxx
+ rectangleEmitter.cxx ringEmitter.cxx
+ sparkleParticleRenderer.cxx sphereSurfaceEmitter.cxx
+ sphereVolumeEmitter.cxx spriteParticleRenderer.cxx
+ tangentRingEmitter.cxx zSpinParticle.cxx
+ zSpinParticleFactory.cxx colorInterpolationManager.cxx
+)
+
+set(P3PARTICLESYSTEM_IGATE_SOURCES
+ ${P3PARTICLESYSTEM_HEADERS} ${P3PARTICLESYSTEM_SOURCES})
+list(REMOVE_ITEM P3PARTICLESYSTEM_IGATE_SOURCES "emitters.h")
+list(REMOVE_ITEM P3PARTICLESYSTEM_IGATE_SOURCES "particlefactories.h")
+list(REMOVE_ITEM P3PARTICLESYSTEM_IGATE_SOURCES "particles.h")
+
+composite_sources(p3particlesystem P3PARTICLESYSTEM_SOURCES)
+add_component_library(p3particlesystem SYMBOL BUILDING_PANDA_PARTICLESYSTEM
+ ${P3PARTICLESYSTEM_HEADERS} ${P3PARTICLESYSTEM_SOURCES})
+target_link_libraries(p3particlesystem p3physics panda)
+target_interrogate(p3particlesystem ${P3PARTICLESYSTEM_IGATE_SOURCES})
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3particlesystem
+ EXPORT Core COMPONENT Core
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT CoreDevel)
+endif()
+install(FILES ${P3PARTICLESYSTEM_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/panda/src/particlesystem/particleSystem.h b/panda/src/particlesystem/particleSystem.h
index 7518bbfd9a..6d77d520dc 100644
--- a/panda/src/particlesystem/particleSystem.h
+++ b/panda/src/particlesystem/particleSystem.h
@@ -104,6 +104,8 @@ PUBLISHED:
virtual void write_spawn_templates(std::ostream &out, int indent=0) const;
virtual void write(std::ostream &out, int indent=0) const;
+ void birth_litter();
+
private:
#ifdef PSSANITYCHECK
int sanity_check();
@@ -111,7 +113,6 @@ private:
bool birth_particle();
void kill_particle(int pool_index);
- void birth_litter();
void resize_pool(int size);
pdeque< int > _free_particle_fifo;
diff --git a/panda/src/pgraph/CMakeLists.txt b/panda/src/pgraph/CMakeLists.txt
new file mode 100644
index 0000000000..80559490c8
--- /dev/null
+++ b/panda/src/pgraph/CMakeLists.txt
@@ -0,0 +1,246 @@
+set(P3PGRAPH_HEADERS
+ accumulatedAttribs.I accumulatedAttribs.h
+ alphaTestAttrib.I alphaTestAttrib.h
+ antialiasAttrib.I antialiasAttrib.h
+ attribNodeRegistry.I attribNodeRegistry.h
+ audioVolumeAttrib.I audioVolumeAttrib.h
+ auxSceneData.I auxSceneData.h
+ auxBitplaneAttrib.I auxBitplaneAttrib.h
+ bamFile.I bamFile.h
+ billboardEffect.I billboardEffect.h
+ cacheStats.I cacheStats.h
+ camera.I camera.h
+ clipPlaneAttrib.I clipPlaneAttrib.h
+ colorAttrib.I colorAttrib.h
+ colorBlendAttrib.I colorBlendAttrib.h
+ colorScaleAttrib.I colorScaleAttrib.h
+ colorWriteAttrib.I colorWriteAttrib.h
+ compassEffect.I compassEffect.h
+ config_pgraph.h
+ cullBin.I cullBin.h
+ cullBinEnums.h
+ cullBinAttrib.I cullBinAttrib.h
+ cullBinManager.I cullBinManager.h
+ cullFaceAttrib.I cullFaceAttrib.h
+ cullHandler.I cullHandler.h
+ cullPlanes.I cullPlanes.h
+ cullResult.I cullResult.h
+ cullTraverser.I cullTraverser.h
+ cullTraverserData.I cullTraverserData.h
+ cullableObject.I cullableObject.h
+ decalEffect.I decalEffect.h
+ depthOffsetAttrib.I depthOffsetAttrib.h
+ depthTestAttrib.I depthTestAttrib.h
+ depthWriteAttrib.I depthWriteAttrib.h
+ findApproxLevelEntry.I findApproxLevelEntry.h
+ findApproxPath.I findApproxPath.h
+ fog.I fog.h
+ fogAttrib.I fogAttrib.h
+ geomDrawCallbackData.I geomDrawCallbackData.h
+ geomNode.I geomNode.h
+ geomTransformer.I geomTransformer.h
+ internalNameCollection.I internalNameCollection.h
+ lensNode.I lensNode.h
+ light.I light.h
+ lightAttrib.I lightAttrib.h
+ lightRampAttrib.I lightRampAttrib.h
+ loader.I loader.h
+ loaderFileType.h
+ loaderFileTypeBam.h
+ loaderFileTypeRegistry.h
+ logicOpAttrib.I logicOpAttrib.h
+ materialAttrib.I materialAttrib.h
+ materialCollection.I materialCollection.h
+ modelFlattenRequest.I modelFlattenRequest.h
+ modelLoadRequest.I modelLoadRequest.h
+ modelSaveRequest.I modelSaveRequest.h
+ modelNode.I modelNode.h
+ modelPool.I modelPool.h
+ modelRoot.I modelRoot.h
+ nodePath.I nodePath.h
+ nodePathCollection.I nodePathCollection.h
+ nodePathComponent.I nodePathComponent.h
+ occluderEffect.I occluderEffect.h
+ occluderNode.I occluderNode.h
+ pandaNode.I pandaNode.h
+ pandaNodeChain.I pandaNodeChain.h
+ planeNode.I planeNode.h
+ paramNodePath.I paramNodePath.h
+ polylightEffect.I polylightEffect.h
+ polylightNode.I polylightNode.h
+ portalNode.I portalNode.h
+ portalClipper.I portalClipper.h
+ renderAttrib.I renderAttrib.h
+ renderAttribRegistry.I renderAttribRegistry.h
+ renderEffect.I renderEffect.h
+ renderEffects.I renderEffects.h
+ renderModeAttrib.I renderModeAttrib.h
+ renderState.I renderState.h
+ rescaleNormalAttrib.I rescaleNormalAttrib.h
+ sceneGraphReducer.I sceneGraphReducer.h
+ sceneSetup.I sceneSetup.h
+ scissorAttrib.I scissorAttrib.h
+ scissorEffect.I scissorEffect.h
+ shadeModelAttrib.I shadeModelAttrib.h
+ shaderAttrib.I shaderAttrib.h
+ shaderInput.I shaderInput.h
+ shaderPool.I shaderPool.h
+ showBoundsEffect.I showBoundsEffect.h
+ stateMunger.I stateMunger.h
+ stencilAttrib.I stencilAttrib.h
+ texMatrixAttrib.I texMatrixAttrib.h
+ texProjectorEffect.I texProjectorEffect.h
+ textureAttrib.I textureAttrib.h
+ texGenAttrib.I texGenAttrib.h
+ textureStageCollection.I textureStageCollection.h
+ transformState.I transformState.h
+ transparencyAttrib.I transparencyAttrib.h
+ weakNodePath.I weakNodePath.h
+ workingNodePath.I workingNodePath.h
+)
+
+set(P3PGRAPH_SOURCES
+ accumulatedAttribs.cxx
+ alphaTestAttrib.cxx
+ antialiasAttrib.cxx
+ attribNodeRegistry.cxx
+ audioVolumeAttrib.cxx
+ auxBitplaneAttrib.cxx
+ auxSceneData.cxx
+ bamFile.cxx
+ billboardEffect.cxx
+ cacheStats.cxx
+ camera.cxx
+ clipPlaneAttrib.cxx
+ colorAttrib.cxx
+ colorBlendAttrib.cxx
+ colorScaleAttrib.cxx
+ colorWriteAttrib.cxx
+ compassEffect.cxx
+ config_pgraph.cxx
+ cullBin.cxx
+ cullBinAttrib.cxx
+ cullBinManager.cxx
+ cullFaceAttrib.cxx
+ cullHandler.cxx
+ cullPlanes.cxx
+ cullResult.cxx
+ cullTraverser.cxx
+ cullTraverserData.cxx
+ cullableObject.cxx
+ decalEffect.cxx
+ depthOffsetAttrib.cxx
+ depthTestAttrib.cxx
+ depthWriteAttrib.cxx
+ findApproxLevelEntry.cxx
+ findApproxPath.cxx
+ fog.cxx
+ fogAttrib.cxx
+ geomDrawCallbackData.cxx
+ geomNode.cxx
+ geomTransformer.cxx
+ internalNameCollection.cxx
+ lensNode.cxx
+ light.cxx
+ lightAttrib.cxx
+ lightRampAttrib.cxx
+ loader.cxx
+ loaderFileType.cxx
+ loaderFileTypeBam.cxx
+ loaderFileTypeRegistry.cxx
+ logicOpAttrib.cxx
+ materialAttrib.cxx
+ materialCollection.cxx
+ modelFlattenRequest.cxx
+ modelLoadRequest.cxx
+ modelSaveRequest.cxx
+ modelNode.cxx
+ modelPool.cxx
+ modelRoot.cxx
+ nodePath.cxx
+ nodePathCollection.cxx
+ nodePathComponent.cxx
+ occluderEffect.cxx
+ occluderNode.cxx
+ pandaNode.cxx
+ pandaNodeChain.cxx
+ planeNode.cxx
+ paramNodePath.cxx
+ polylightEffect.cxx
+ polylightNode.cxx
+ portalNode.cxx
+ portalClipper.cxx
+ renderAttrib.cxx
+ renderAttribRegistry.cxx
+ renderEffect.cxx
+ renderEffects.cxx
+ renderModeAttrib.cxx
+ renderState.cxx
+ rescaleNormalAttrib.cxx
+ sceneGraphReducer.cxx
+ sceneSetup.cxx
+ scissorAttrib.cxx
+ scissorEffect.cxx
+ shadeModelAttrib.cxx
+ shaderAttrib.cxx
+ shaderInput.cxx
+ shaderPool.cxx
+ showBoundsEffect.cxx
+ stateMunger.cxx
+ stencilAttrib.cxx
+ texMatrixAttrib.cxx
+ texProjectorEffect.cxx
+ textureAttrib.cxx
+ texGenAttrib.cxx
+ textureStageCollection.cxx
+ transformState.cxx
+ transparencyAttrib.cxx
+ weakNodePath.cxx
+ workingNodePath.cxx
+)
+
+set(P3PGRAPH_IGATEEXT
+ loaderFileTypeRegistry_ext.cxx
+ loaderFileTypeRegistry_ext.h
+ nodePathCollection_ext.cxx
+ nodePathCollection_ext.h
+ nodePath_ext.cxx
+ nodePath_ext.h
+ nodePath_ext.I
+ pandaNode_ext.cxx
+ pandaNode_ext.h
+ pythonLoaderFileType.cxx
+ pythonLoaderFileType.h
+ renderState_ext.cxx
+ renderState_ext.h
+ shaderAttrib_ext.cxx
+ shaderAttrib_ext.h
+ shaderInput_ext.cxx
+ shaderInput_ext.h
+ transformState_ext.cxx
+ transformState_ext.h
+)
+
+# This is a large file; let's build it separately
+set_source_files_properties(nodePath.cxx PROPERTIES SKIP_UNITY_BUILD_INCLUSION YES)
+
+composite_sources(p3pgraph P3PGRAPH_SOURCES)
+add_component_library(p3pgraph SYMBOL BUILDING_PANDA_PGRAPH
+ ${P3PGRAPH_HEADERS} ${P3PGRAPH_SOURCES})
+target_link_libraries(p3pgraph p3gobj p3event p3gsgbase p3putil p3linmath pandaexpress)
+target_interrogate(p3pgraph ALL EXTENSIONS ${P3PGRAPH_IGATEEXT})
+
+if(HAVE_EIGEN)
+ # Eigen puts this over the threshold where bigobj is needed on MSVC
+ set_target_properties(p3pgraph PROPERTIES MSVC_BIGOBJ ON)
+endif()
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3pgraph
+ EXPORT Core COMPONENT Core
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT CoreDevel)
+endif()
+install(FILES ${P3PGRAPH_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/panda/src/pgraph/cullableObject.cxx b/panda/src/pgraph/cullableObject.cxx
index 920e524659..38f35f7024 100644
--- a/panda/src/pgraph/cullableObject.cxx
+++ b/panda/src/pgraph/cullableObject.cxx
@@ -223,29 +223,23 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
return false;
}
+ GeomVertexDataPipelineReader reader(source_data, current_thread);
+ reader.check_array_readers();
+
PStatTimer timer(_munge_sprites_pcollector, current_thread);
- _sw_sprites_pcollector.add_level(source_data->get_num_rows());
+ _sw_sprites_pcollector.add_level(reader.get_num_rows());
GraphicsStateGuardianBase *gsg = traverser->get_gsg();
- GeomVertexReader vertex(source_data, InternalName::get_vertex(),
- current_thread);
- GeomVertexReader normal(source_data, InternalName::get_normal(),
- current_thread);
- GeomVertexReader color(source_data, InternalName::get_color(),
- current_thread);
- GeomVertexReader texcoord(source_data, InternalName::get_texcoord(),
- current_thread);
- GeomVertexReader rotate(source_data, InternalName::get_rotate(),
- current_thread);
- GeomVertexReader size(source_data, InternalName::get_size(),
- current_thread);
- GeomVertexReader aspect_ratio(source_data, InternalName::get_aspect_ratio(),
- current_thread);
+ GeomVertexReader vertex(&reader, InternalName::get_vertex());
+ GeomVertexReader normal(&reader, InternalName::get_normal());
+ GeomVertexReader rotate(&reader, InternalName::get_rotate());
+ GeomVertexReader size(&reader, InternalName::get_size());
+ GeomVertexReader aspect_ratio(&reader, InternalName::get_aspect_ratio());
bool has_normal = (normal.has_column());
- bool has_color = (color.has_column());
- bool has_texcoord = (texcoord.has_column());
+ bool has_color = (reader.has_column(InternalName::get_color()));
+ bool has_texcoord = (reader.has_column(InternalName::get_texcoord()));
bool has_rotate = (rotate.has_column());
bool has_size = (size.has_column());
bool has_aspect_ratio = (aspect_ratio.has_column());
@@ -280,7 +274,7 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
{
LightMutexHolder holder(_format_lock);
- SourceFormat sformat(source_data->get_format(), sprite_texcoord);
+ SourceFormat sformat(reader.get_format(), sprite_texcoord);
FormatMap::iterator fmi = _format_map.find(sformat);
if (fmi != _format_map.end()) {
new_format = (*fmi).second;
@@ -304,13 +298,13 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
Geom::C_clip_point);
}
if (has_normal) {
- const GeomVertexColumn *c = normal.get_column();
+ const GeomVertexColumn *c = reader.get_format()->get_normal_column();
new_array_format->add_column
(InternalName::get_normal(), c->get_num_components(),
c->get_numeric_type(), c->get_contents());
}
if (has_color) {
- const GeomVertexColumn *c = color.get_column();
+ const GeomVertexColumn *c = reader.get_format()->get_color_column();
new_array_format->add_column
(InternalName::get_color(), c->get_num_components(),
c->get_numeric_type(), c->get_contents());
@@ -322,12 +316,34 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
Geom::C_texcoord);
} else if (has_texcoord) {
- const GeomVertexColumn *c = texcoord.get_column();
+ const GeomVertexColumn *c = reader.get_format()->get_column(InternalName::get_texcoord());
new_array_format->add_column
(InternalName::get_texcoord(), c->get_num_components(),
c->get_numeric_type(), c->get_contents());
}
+ // Go through the other columns and copy them from the original.
+ for (size_t ai = 0; ai < sformat._format->get_num_arrays(); ++ai) {
+ const GeomVertexArrayFormat *aformat = sformat._format->get_array(ai);
+
+ for (size_t ci = 0; ci < aformat->get_num_columns(); ++ci) {
+ const GeomVertexColumn *column = aformat->get_column(ci);
+ const InternalName *name = column->get_name();
+ if (name != InternalName::get_vertex() &&
+ name != InternalName::get_normal() &&
+ name != InternalName::get_color() &&
+ name != InternalName::get_texcoord() &&
+ name != InternalName::get_rotate() &&
+ name != InternalName::get_size() &&
+ name != InternalName::get_aspect_ratio()) {
+
+ new_array_format->add_column(name,
+ column->get_num_components(), column->get_numeric_type(),
+ column->get_contents());
+ }
+ }
+ }
+
new_format = GeomVertexFormat::register_format(new_array_format);
_format_map[sformat] = new_format;
}
@@ -362,7 +378,7 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
// Now convert all of the vertices in the GeomVertexData to quads. We
// always convert all the vertices, assuming all the vertices are referenced
// by GeomPrimitives, because we want to optimize for the most common case.
- int orig_verts = source_data->get_num_rows();
+ int orig_verts = reader.get_num_rows();
int new_verts = 4 * orig_verts; // each vertex becomes four.
PT(GeomVertexData) new_data = new GeomVertexData
@@ -371,9 +387,50 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
GeomVertexWriter new_vertex(new_data, InternalName::get_vertex());
GeomVertexWriter new_normal(new_data, InternalName::get_normal());
- GeomVertexWriter new_color(new_data, InternalName::get_color());
GeomVertexWriter new_texcoord(new_data, InternalName::get_texcoord());
+ nassertr(new_vertex.has_column(), false);
+ unsigned char *write_ptr = new_vertex.get_array_handle()->get_write_pointer();
+
+ // Collect all other columns that we just need to copy the data of.
+ struct CopyOp {
+ unsigned char *_to_pointer;
+ const unsigned char *_from_pointer;
+ size_t _num_bytes;
+ size_t _from_stride;
+ };
+ pvector copies;
+
+ const GeomVertexArrayFormat *aformat = new_format->get_array(0);
+ for (size_t ci = 0; ci < aformat->get_num_columns(); ++ci) {
+ const GeomVertexColumn *column = aformat->get_column(ci);
+ const InternalName *name = column->get_name();
+ if (name != InternalName::get_vertex() &&
+ (retransform_sprites || name != InternalName::get_normal()) &&
+ (!sprite_texcoord || name != InternalName::get_texcoord())) {
+
+ int source_array;
+ const GeomVertexColumn *source_column;
+ if (reader.get_format()->get_array_info(name, source_array, source_column)) {
+ CopyOp copy;
+ copy._to_pointer = write_ptr + (size_t)column->get_start();
+ copy._from_pointer = reader.get_array_reader(source_array)->get_read_pointer(true) + (size_t)source_column->get_start();
+ copy._num_bytes = (size_t)column->get_total_bytes();
+ copy._from_stride = reader.get_format()->get_array(source_array)->get_stride();
+
+ if (!copies.empty() &&
+ (copy._to_pointer == copies.back()._to_pointer + copies.back()._num_bytes) &&
+ (copy._from_pointer == copies.back()._from_pointer + copies.back()._num_bytes)) {
+ // Merge with previous.
+ copies.back()._num_bytes += copy._num_bytes;
+ } else {
+ copies.push_back(copy);
+ }
+ }
+ }
+ }
+ size_t to_stride = aformat->get_stride();
+
// We'll keep an array of all of the points' eye-space coordinates, and
// their distance from the camera, so we can sort the points for each
// primitive, below.
@@ -447,14 +504,6 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
new_vertex.set_data4(inv_render_transform.xform(LPoint4(p4[0] - c1[0], p4[1] - c1[1], p4[2], p4[3])));
new_vertex.set_data4(inv_render_transform.xform(LPoint4(p4[0] - c0[0], p4[1] - c0[1], p4[2], p4[3])));
- if (has_normal) {
- const LNormal &c = normal.get_data3();
- new_normal.set_data3(c);
- new_normal.set_data3(c);
- new_normal.set_data3(c);
- new_normal.set_data3(c);
- }
-
} else {
// Without retransform_sprites, we can simply load the clip-space
// coordinates.
@@ -464,6 +513,7 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
new_vertex.set_data4(p4[0] - c0[0], p4[1] - c0[1], p4[2], p4[3]);
if (has_normal) {
+ // We need to transform the normals to clip-space too, then.
LNormal c = render_transform.xform_vec(normal.get_data3());
new_normal.set_data3(c);
new_normal.set_data3(c);
@@ -471,24 +521,24 @@ munge_points_to_quads(const CullTraverser *traverser, bool force) {
new_normal.set_data3(c);
}
}
- if (has_color) {
- const LColor &c = color.get_data4();
- new_color.set_data4(c);
- new_color.set_data4(c);
- new_color.set_data4(c);
- new_color.set_data4(c);
- }
if (sprite_texcoord) {
new_texcoord.set_data2(1.0f, 0.0f);
new_texcoord.set_data2(0.0f, 0.0f);
new_texcoord.set_data2(1.0f, 1.0f);
new_texcoord.set_data2(0.0f, 1.0f);
- } else if (has_texcoord) {
- const LVecBase4 &c = texcoord.get_data4();
- new_texcoord.set_data4(c);
- new_texcoord.set_data4(c);
- new_texcoord.set_data4(c);
- new_texcoord.set_data4(c);
+ }
+
+ // Other columns are simply duplicated for each vertex.
+ for (CopyOp © : copies) {
+ memcpy(copy._to_pointer, copy._from_pointer, copy._num_bytes);
+ copy._to_pointer += to_stride;
+ memcpy(copy._to_pointer, copy._from_pointer, copy._num_bytes);
+ copy._to_pointer += to_stride;
+ memcpy(copy._to_pointer, copy._from_pointer, copy._num_bytes);
+ copy._to_pointer += to_stride;
+ memcpy(copy._to_pointer, copy._from_pointer, copy._num_bytes);
+ copy._to_pointer += to_stride;
+ copy._from_pointer += copy._from_stride;
}
++vi;
diff --git a/panda/src/pgraph/findApproxPath.h b/panda/src/pgraph/findApproxPath.h
index fe3ac5d765..a9a7ba8827 100644
--- a/panda/src/pgraph/findApproxPath.h
+++ b/panda/src/pgraph/findApproxPath.h
@@ -59,7 +59,7 @@ public:
void output(std::ostream &out) const;
INLINE void output_component(std::ostream &out, int index) const;
-#if !defined(WIN32_VC) && !defined(WIN64_VC)
+#ifndef _MSC_VER
// Visual C++ won't let us define the ostream operator functions for these
// guys if they're private--even though we declare them friends.
private:
diff --git a/panda/src/pgraph/pandaNode.h b/panda/src/pgraph/pandaNode.h
index cec5e220a2..b008a4f850 100644
--- a/panda/src/pgraph/pandaNode.h
+++ b/panda/src/pgraph/pandaNode.h
@@ -566,11 +566,6 @@ private:
INLINE void set_fancy_bit(int bits, bool value);
-#ifdef HAVE_PYTHON
- void inc_py_refs();
- void dec_py_refs();
-#endif
-
CPT(RenderEffects) _effects;
TagData _tag_data;
diff --git a/panda/src/pgraph/shaderAttrib.cxx b/panda/src/pgraph/shaderAttrib.cxx
index 7647945291..fde1a99a3d 100644
--- a/panda/src/pgraph/shaderAttrib.cxx
+++ b/panda/src/pgraph/shaderAttrib.cxx
@@ -530,7 +530,8 @@ get_shader_input_matrix(const InternalName *id, LMatrix4 &matrix) const {
if (p.get_value_type() == ShaderInput::M_nodepath) {
const NodePath &np = p.get_nodepath();
nassertr(!np.is_empty(), LMatrix4::ident_mat());
- return np.get_transform()->get_mat();
+ matrix = np.get_transform()->get_mat();
+ return matrix;
} else if (p.get_value_type() == ShaderInput::M_numeric &&
p.get_ptr()._size >= 16 && (p.get_ptr()._size & 15) == 0) {
diff --git a/panda/src/pgraphnodes/CMakeLists.txt b/panda/src/pgraphnodes/CMakeLists.txt
new file mode 100644
index 0000000000..7b25e2b5bf
--- /dev/null
+++ b/panda/src/pgraphnodes/CMakeLists.txt
@@ -0,0 +1,61 @@
+set(P3PGRAPHNODES_HEADERS
+ ambientLight.h ambientLight.I
+ callbackNode.h callbackNode.I
+ computeNode.h computeNode.I
+ config_pgraphnodes.h
+ directionalLight.h directionalLight.I
+ fadeLodNode.I fadeLodNode.h fadeLodNodeData.h
+ lightLensNode.h lightLensNode.I
+ lightNode.h lightNode.I
+ lodNode.I lodNode.h lodNodeType.h
+ nodeCullCallbackData.h nodeCullCallbackData.I
+ pointLight.h pointLight.I
+ rectangleLight.h rectangleLight.I
+ sceneGraphAnalyzer.h sceneGraphAnalyzer.I
+ selectiveChildNode.h selectiveChildNode.I
+ sequenceNode.h sequenceNode.I
+ shaderGenerator.h shaderGenerator.I
+ sphereLight.h sphereLight.I
+ spotlight.h spotlight.I
+ switchNode.h switchNode.I
+ uvScrollNode.I uvScrollNode.h
+)
+
+set(P3PGRAPHNODES_SOURCES
+ ambientLight.cxx
+ callbackNode.cxx
+ computeNode.cxx
+ config_pgraphnodes.cxx
+ directionalLight.cxx
+ fadeLodNode.cxx fadeLodNodeData.cxx
+ lightLensNode.cxx
+ lightNode.cxx
+ lodNode.cxx lodNodeType.cxx
+ nodeCullCallbackData.cxx
+ pointLight.cxx
+ rectangleLight.cxx
+ sceneGraphAnalyzer.cxx
+ selectiveChildNode.cxx
+ sequenceNode.cxx
+ shaderGenerator.cxx
+ sphereLight.cxx
+ spotlight.cxx
+ switchNode.cxx
+ uvScrollNode.cxx
+)
+
+composite_sources(p3pgraphnodes P3PGRAPHNODES_SOURCES)
+add_component_library(p3pgraphnodes SYMBOL BUILDING_PANDA_PGRAPHNODES
+ ${P3PGRAPHNODES_HEADERS} ${P3PGRAPHNODES_SOURCES})
+target_link_libraries(p3pgraphnodes p3pgraph)
+target_interrogate(p3pgraphnodes ALL)
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3pgraphnodes
+ EXPORT Core COMPONENT Core
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT CoreDevel)
+endif()
+install(FILES ${P3PGRAPHNODES_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/panda/src/pgui/CMakeLists.txt b/panda/src/pgui/CMakeLists.txt
new file mode 100644
index 0000000000..0b68d56653
--- /dev/null
+++ b/panda/src/pgui/CMakeLists.txt
@@ -0,0 +1,57 @@
+set(P3PGUI_HEADERS
+ config_pgui.h
+ pgButton.I pgButton.h
+ pgButtonNotify.I pgButtonNotify.h
+ pgCullTraverser.I pgCullTraverser.h
+ pgEntry.I pgEntry.h
+ pgMouseWatcherGroup.I pgMouseWatcherGroup.h
+ pgMouseWatcherParameter.I pgMouseWatcherParameter.h
+ pgFrameStyle.I pgFrameStyle.h
+ pgItem.I pgItem.h
+ pgItemNotify.I pgItemNotify.h
+ pgMouseWatcherBackground.h
+ pgMouseWatcherRegion.I pgMouseWatcherRegion.h
+ pgScrollFrame.I pgScrollFrame.h
+ pgSliderBar.I pgSliderBar.h
+ pgSliderBarNotify.I pgSliderBarNotify.h
+ pgTop.I pgTop.h
+ pgVirtualFrame.I pgVirtualFrame.h
+ pgWaitBar.I pgWaitBar.h
+)
+
+set(P3PGUI_SOURCES
+ config_pgui.cxx
+ pgButton.cxx
+ pgButtonNotify.cxx
+ pgCullTraverser.cxx
+ pgEntry.cxx
+ pgMouseWatcherGroup.cxx
+ pgMouseWatcherParameter.cxx
+ pgFrameStyle.cxx
+ pgItem.cxx
+ pgItemNotify.cxx
+ pgMouseWatcherBackground.cxx
+ pgMouseWatcherRegion.cxx
+ pgScrollFrame.cxx
+ pgSliderBar.cxx
+ pgSliderBarNotify.cxx
+ pgTop.cxx
+ pgVirtualFrame.cxx
+ pgWaitBar.cxx
+)
+
+composite_sources(p3pgui P3PGUI_SOURCES)
+add_component_library(p3pgui SYMBOL BUILDING_PANDA_PGUI
+ ${P3PGUI_HEADERS} ${P3PGUI_SOURCES})
+target_link_libraries(p3pgui p3tform)
+target_interrogate(p3pgui ALL)
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3pgui
+ EXPORT Core COMPONENT Core
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT CoreDevel)
+endif()
+install(FILES ${P3PGUI_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/panda/src/physics/CMakeLists.txt b/panda/src/physics/CMakeLists.txt
new file mode 100644
index 0000000000..9b0b9456b6
--- /dev/null
+++ b/panda/src/physics/CMakeLists.txt
@@ -0,0 +1,55 @@
+set(P3PHYSICS_HEADERS
+ actorNode.I actorNode.h angularEulerIntegrator.h angularForce.h
+ angularIntegrator.h angularVectorForce.I
+ angularVectorForce.h baseForce.I baseForce.h
+ baseIntegrator.I baseIntegrator.h config_physics.h
+ forces.h
+ forceNode.I forceNode.h
+ linearControlForce.I linearControlForce.h
+ linearCylinderVortexForce.I linearCylinderVortexForce.h
+ linearDistanceForce.I
+ linearDistanceForce.h linearEulerIntegrator.h linearForce.I
+ linearForce.h linearFrictionForce.I linearFrictionForce.h
+ linearIntegrator.h linearJitterForce.h linearNoiseForce.I
+ linearNoiseForce.h linearRandomForce.I linearRandomForce.h
+ linearSinkForce.h linearSourceForce.h
+ linearUserDefinedForce.I linearUserDefinedForce.h
+ linearVectorForce.I linearVectorForce.h physical.I
+ physical.h physicalNode.I physicalNode.h
+ physicsCollisionHandler.I physicsCollisionHandler.h
+ physicsManager.I physicsManager.h
+ physicsObject.I physicsObject.h
+ physicsObjectCollection.I physicsObjectCollection.h
+)
+
+set(P3PHYSICS_SOURCES
+ actorNode.cxx angularEulerIntegrator.cxx angularForce.cxx
+ angularIntegrator.cxx angularVectorForce.cxx baseForce.cxx
+ baseIntegrator.cxx config_physics.cxx forceNode.cxx
+ linearControlForce.cxx
+ linearCylinderVortexForce.cxx linearDistanceForce.cxx
+ linearEulerIntegrator.cxx linearForce.cxx
+ linearFrictionForce.cxx linearIntegrator.cxx
+ linearJitterForce.cxx linearNoiseForce.cxx
+ linearRandomForce.cxx linearSinkForce.cxx
+ linearSourceForce.cxx linearUserDefinedForce.cxx
+ linearVectorForce.cxx physical.cxx physicalNode.cxx
+ physicsCollisionHandler.cxx physicsManager.cxx physicsObject.cxx
+ physicsObjectCollection.cxx
+)
+
+composite_sources(p3physics P3PHYSICS_SOURCES)
+add_component_library(p3physics SYMBOL BUILDING_PANDA_PHYSICS
+ ${P3PHYSICS_HEADERS} ${P3PHYSICS_SOURCES})
+target_link_libraries(p3physics panda)
+target_interrogate(p3physics ALL)
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3physics
+ EXPORT Core COMPONENT Core
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT CoreDevel)
+endif()
+install(FILES ${P3PHYSICS_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/panda/src/pipeline/CMakeLists.txt b/panda/src/pipeline/CMakeLists.txt
new file mode 100644
index 0000000000..aa7852623b
--- /dev/null
+++ b/panda/src/pipeline/CMakeLists.txt
@@ -0,0 +1,148 @@
+set(P3PIPELINE_HEADERS
+ contextSwitch.h
+ blockerSimple.h blockerSimple.I
+ conditionVar.h conditionVar.I
+ conditionVarDebug.h conditionVarDebug.I
+ conditionVarDirect.h conditionVarDirect.I
+ conditionVarDummyImpl.h conditionVarDummyImpl.I
+ conditionVarFull.h
+ conditionVarImpl.h
+ conditionVarSimpleImpl.h conditionVarSimpleImpl.I
+ conditionVarSpinlockImpl.h conditionVarSpinlockImpl.I
+ conditionVarPosixImpl.h conditionVarPosixImpl.I
+ config_pipeline.h
+ cycleData.h cycleData.I
+ cycleDataLockedReader.h cycleDataLockedReader.I
+ cycleDataLockedStageReader.h cycleDataLockedStageReader.I
+ cycleDataReader.h cycleDataReader.I
+ cycleDataStageReader.h cycleDataStageReader.I
+ cycleDataStageWriter.h cycleDataStageWriter.I
+ cycleDataWriter.h cycleDataWriter.I
+ cyclerHolder.h cyclerHolder.I
+ externalThread.h
+ genericThread.h genericThread.I
+ lightMutex.I lightMutex.h
+ lightMutexDirect.h lightMutexDirect.I
+ lightMutexHolder.I lightMutexHolder.h
+ lightReMutex.I lightReMutex.h
+ lightReMutexDirect.h lightReMutexDirect.I
+ lightReMutexHolder.I lightReMutexHolder.h
+ mainThread.h
+ mutexDebug.h mutexDebug.I
+ mutexDirect.h mutexDirect.I
+ mutexHolder.h mutexHolder.I
+ mutexSimpleImpl.h mutexSimpleImpl.I
+ mutexTrueImpl.h
+ pipeline.h pipeline.I
+ pipelineCycler.h pipelineCycler.I
+ pipelineCyclerLinks.h pipelineCyclerLinks.I
+ pipelineCyclerBase.h
+ pipelineCyclerDummyImpl.h pipelineCyclerDummyImpl.I
+ pipelineCyclerTrivialImpl.h pipelineCyclerTrivialImpl.I
+ pipelineCyclerTrueImpl.h pipelineCyclerTrueImpl.I
+ pmutex.h pmutex.I
+ reMutex.I reMutex.h
+ reMutexDirect.h reMutexDirect.I
+ reMutexHolder.h reMutexHolder.I
+ reMutexSpinlockImpl.h reMutexSpinlockImpl.I
+ psemaphore.h psemaphore.I
+ thread.h thread.I threadImpl.h
+ threadDummyImpl.h threadDummyImpl.I
+ threadSimpleImpl.h threadSimpleImpl.I
+ threadPosixImpl.h threadPosixImpl.I
+ threadSimpleManager.h threadSimpleManager.I
+ threadPriority.h
+)
+
+set(P3PIPELINE_SOURCES
+ contextSwitch.c
+ conditionVar.cxx
+ conditionVarDebug.cxx
+ conditionVarDirect.cxx
+ conditionVarDummyImpl.cxx
+ conditionVarSimpleImpl.cxx
+ conditionVarSpinlockImpl.cxx
+ conditionVarPosixImpl.cxx
+ config_pipeline.cxx
+ cycleData.cxx
+ cycleDataLockedReader.cxx
+ cycleDataLockedStageReader.cxx
+ cycleDataReader.cxx
+ cycleDataStageReader.cxx
+ cycleDataStageWriter.cxx
+ cycleDataWriter.cxx
+ cyclerHolder.cxx
+ externalThread.cxx
+ genericThread.cxx
+ lightMutex.cxx
+ lightMutexDirect.cxx
+ lightMutexHolder.cxx
+ lightReMutex.cxx
+ lightReMutexDirect.cxx
+ lightReMutexHolder.cxx
+ mainThread.cxx
+ mutexDebug.cxx
+ mutexDirect.cxx
+ mutexHolder.cxx
+ mutexSimpleImpl.cxx
+ pipeline.cxx
+ pipelineCycler.cxx
+ pipelineCyclerDummyImpl.cxx
+ pipelineCyclerTrivialImpl.cxx
+ pipelineCyclerTrueImpl.cxx
+ pmutex.cxx
+ reMutex.cxx
+ reMutexDirect.cxx
+ reMutexHolder.cxx
+ reMutexSpinlockImpl.cxx
+ psemaphore.cxx
+ thread.cxx
+ threadDummyImpl.cxx
+ threadPosixImpl.cxx
+ threadSimpleImpl.cxx
+ threadSimpleManager.cxx
+ threadPriority.cxx
+)
+
+if(WIN32)
+ list(APPEND P3PIPELINE_HEADERS
+ conditionVarWin32Impl.h conditionVarWin32Impl.I
+ threadWin32Impl.h threadWin32Impl.I)
+ list(APPEND P3PIPELINE_SOURCES
+ conditionVarWin32Impl.cxx
+ threadWin32Impl.cxx)
+endif()
+
+set(P3PIPELINE_IGATEEXT
+ pmutex_ext.h
+ pmutex_ext.I
+ pythonThread.cxx
+ pythonThread.h
+ reMutex_ext.h
+ reMutex_ext.I
+)
+
+composite_sources(p3pipeline P3PIPELINE_SOURCES)
+add_component_library(p3pipeline SYMBOL BUILDING_PANDA_PIPELINE
+ ${P3PIPELINE_HEADERS} ${P3PIPELINE_SOURCES})
+target_link_libraries(p3pipeline pandaexpress
+ PKG::THREADS)
+target_interrogate(p3pipeline ALL EXTENSIONS ${P3PIPELINE_IGATEEXT})
+
+if(PHAVE_UCONTEXT_H)
+ target_compile_definitions(p3pipeline PRIVATE PHAVE_UCONTEXT_H)
+endif()
+
+if(OS_SIMPLE_THREADS)
+ target_compile_definitions(p3pipeline PRIVATE OS_SIMPLE_THREADS)
+endif()
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3pipeline
+ EXPORT Core COMPONENT Core
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT CoreDevel)
+endif()
+install(FILES ${P3PIPELINE_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/panda/src/pipeline/conditionVarImpl.h b/panda/src/pipeline/conditionVarImpl.h
index 774ab72753..880573340b 100644
--- a/panda/src/pipeline/conditionVarImpl.h
+++ b/panda/src/pipeline/conditionVarImpl.h
@@ -46,7 +46,7 @@ typedef ConditionVarPosixImpl ConditionVarImpl;
typedef ConditionVarImpl ConditionVarFullImpl;
-#if defined(WIN32_VC)
+#ifdef _WIN32
#include "conditionVarWin32Impl.h"
typedef ConditionVarWin32Impl TrueConditionVarImpl;
diff --git a/panda/src/pipeline/conditionVarWin32Impl.cxx b/panda/src/pipeline/conditionVarWin32Impl.cxx
index 9d3a95e0b1..5ba4165a0c 100644
--- a/panda/src/pipeline/conditionVarWin32Impl.cxx
+++ b/panda/src/pipeline/conditionVarWin32Impl.cxx
@@ -13,8 +13,8 @@
#include "selectThreadImpl.h"
-#if defined(WIN32_VC) || defined(WIN64_VC)
+#ifdef _WIN32
#include "conditionVarWin32Impl.h"
-#endif // WIN32_VC
+#endif // _WIN32
diff --git a/panda/src/pipeline/conditionVarWin32Impl.h b/panda/src/pipeline/conditionVarWin32Impl.h
index b7daa767bd..5c8d4a91d3 100644
--- a/panda/src/pipeline/conditionVarWin32Impl.h
+++ b/panda/src/pipeline/conditionVarWin32Impl.h
@@ -17,7 +17,7 @@
#include "pandabase.h"
#include "selectThreadImpl.h"
-#if defined(WIN32_VC)
+#ifdef _WIN32
#include "mutexWin32Impl.h"
#include "pnotify.h"
@@ -44,6 +44,6 @@ private:
#include "conditionVarWin32Impl.I"
-#endif // WIN32_VC
+#endif // _WIN32
#endif
diff --git a/panda/src/pipeline/test_delete.cxx b/panda/src/pipeline/test_delete.cxx
index 3ea431f77b..af0c168ee7 100644
--- a/panda/src/pipeline/test_delete.cxx
+++ b/panda/src/pipeline/test_delete.cxx
@@ -29,7 +29,7 @@ static const int max_doobers_per_chunk = 1000;
// The number of threads to spawn.
static const int number_of_threads = 4;
-#if defined(WIN32_VC) || defined(WIN64_VC)
+#ifdef _WIN32
static int last_rand = 0;
#endif /* __WIN32__ */
@@ -39,7 +39,7 @@ static double
random_f(double max) {
MutexHolder l(rand_mutex);
int i = rand();
-#if defined(WIN32_VC) || defined(WIN64_VC)
+#ifdef _WIN32
last_rand = i;
#endif /* __WIN32__ */
return max * (double)i / (double)RAND_MAX;
@@ -88,7 +88,7 @@ public:
thread_main() {
OUTPUT(nout << *this << " beginning.\n");
-#if defined(WIN32_VC) || defined(WIN64_VC)
+#ifdef _WIN32
rand_mutex.acquire();
srand(last_rand);
rand_mutex.release();
diff --git a/panda/src/pipeline/test_diners.cxx b/panda/src/pipeline/test_diners.cxx
index a5ff82e446..24631078e9 100644
--- a/panda/src/pipeline/test_diners.cxx
+++ b/panda/src/pipeline/test_diners.cxx
@@ -26,7 +26,7 @@
using std::cerr;
-#ifdef WIN32_VC
+#ifdef _WIN32
// Under Windows, the rand() function seems to return a sequence per-thread,
// so we use this trick to set each thread to a different seed.
static int last_rand = 0;
@@ -38,7 +38,7 @@ static double random_f(double max)
{
MutexHolder l(rand_mutex);
int i = rand();
-#ifdef WIN32_VC
+#ifdef _WIN32
last_rand = i;
#endif /* __WIN32__ */
return max * (double)i / (double)RAND_MAX;
@@ -76,7 +76,7 @@ class philosopher : public Thread {
private:
int _id;
void thread_main() {
-#ifdef WIN32_VC
+#ifdef _WIN32
rand_mutex.acquire();
srand(last_rand);
rand_mutex.release();
diff --git a/panda/src/pipeline/threadDummyImpl.I b/panda/src/pipeline/threadDummyImpl.I
index 0bd2f7747a..7bab1ae408 100644
--- a/panda/src/pipeline/threadDummyImpl.I
+++ b/panda/src/pipeline/threadDummyImpl.I
@@ -101,14 +101,14 @@ is_simple_threads() {
*/
INLINE void ThreadDummyImpl::
sleep(double seconds) {
-#ifdef WIN32
+#ifdef _WIN32
Sleep((int)(seconds * 1000));
#else
struct timespec rqtp;
rqtp.tv_sec = time_t(seconds);
rqtp.tv_nsec = long((seconds - (double)rqtp.tv_sec) * 1000000000.0);
nanosleep(&rqtp, nullptr);
-#endif // WIN32
+#endif // _WIN32
}
/**
diff --git a/panda/src/pipeline/threadDummyImpl.cxx b/panda/src/pipeline/threadDummyImpl.cxx
index 2d30630d98..e5d0d0642c 100644
--- a/panda/src/pipeline/threadDummyImpl.cxx
+++ b/panda/src/pipeline/threadDummyImpl.cxx
@@ -32,7 +32,7 @@ std::string ThreadDummyImpl::
get_unique_id() const {
// In a single-threaded application, this is just the unique process ID.
std::ostringstream strm;
-#ifdef WIN32
+#ifdef _WIN32
strm << GetCurrentProcessId();
#else
strm << getpid();
diff --git a/panda/src/pipeline/threadDummyImpl.h b/panda/src/pipeline/threadDummyImpl.h
index 7721ca2d6c..c7cea7a3ca 100644
--- a/panda/src/pipeline/threadDummyImpl.h
+++ b/panda/src/pipeline/threadDummyImpl.h
@@ -24,7 +24,7 @@
class Thread;
-#ifdef WIN32
+#ifdef _WIN32
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1
#endif
diff --git a/panda/src/pnmimage/CMakeLists.txt b/panda/src/pnmimage/CMakeLists.txt
new file mode 100644
index 0000000000..8c6e17abac
--- /dev/null
+++ b/panda/src/pnmimage/CMakeLists.txt
@@ -0,0 +1,56 @@
+set(P3PNMIMAGE_HEADERS
+ config_pnmimage.h
+ convert_srgb.h convert_srgb.I
+ pfmFile.I pfmFile.h
+ pnmbitio.h
+ pnmBrush.h pnmBrush.I
+ pnmFileType.h pnmFileTypeRegistry.h pnmImage.I
+ pnmImage.h pnmImageHeader.I pnmImageHeader.h
+ pnmPainter.h pnmPainter.I
+ pnmReader.I
+ pnmReader.h pnmWriter.I pnmWriter.h pnmimage_base.h
+ ppmcmap.h
+)
+
+set(P3PNMIMAGE_SOURCES
+ config_pnmimage.cxx
+ convert_srgb.cxx
+ convert_srgb_sse2.cxx
+ pfmFile.cxx
+ pnm-image-filter.cxx
+ pnmbitio.cxx
+ pnmBrush.cxx
+ pnmFileType.cxx
+ pnmFileTypeRegistry.cxx pnmImage.cxx pnmImageHeader.cxx
+ pnmPainter.cxx
+ pnmReader.cxx pnmWriter.cxx pnmimage_base.cxx
+ ppmcmap.cxx
+)
+
+set(P3PNMIMAGE_IGATEEXT
+ pfmFile_ext.cxx
+ pfmFile_ext.h
+)
+
+if(HAVE_SSE2 AND CMAKE_SIZEOF_VOID_P EQUAL 4 AND CMAKE_SYSTEM_PROCESSOR MATCHES "86")
+ # It's only necessary to do this on 32-bit x86; 64-bit makes SSE2 builtin.
+ set_source_files_properties(convert_srgb_sse2.cxx PROPERTIES
+ SKIP_UNITY_BUILD_INCLUSION YES
+ COMPILE_FLAGS -msse2)
+endif()
+
+composite_sources(p3pnmimage P3PNMIMAGE_SOURCES)
+add_component_library(p3pnmimage SYMBOL BUILDING_PANDA_PNMIMAGE
+ ${P3PNMIMAGE_HEADERS} ${P3PNMIMAGE_SOURCES})
+target_link_libraries(p3pnmimage p3mathutil)
+target_interrogate(p3pnmimage ALL EXTENSIONS ${P3PNMIMAGE_IGATEEXT})
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3pnmimage
+ EXPORT Core COMPONENT Core
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT CoreDevel)
+endif()
+install(FILES ${P3PNMIMAGE_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/panda/src/pnmimage/pnmimage_base.cxx b/panda/src/pnmimage/pnmimage_base.cxx
index d5ef09e415..f30939575d 100644
--- a/panda/src/pnmimage/pnmimage_base.cxx
+++ b/panda/src/pnmimage/pnmimage_base.cxx
@@ -33,12 +33,8 @@ pm_message(const char *format, ...) {
static const size_t buffer_size = 1024;
char buffer[buffer_size];
-#if defined(WIN32_VC) || defined(WIN64_VC)
- // Windows doesn't define vsnprintf(). Hope we don't overflow.
- vsprintf(buffer, format, ap);
-#else
+
vsnprintf(buffer, buffer_size, format, ap);
-#endif
nassertv(strlen(buffer) < buffer_size);
pnmimage_cat.info() << buffer << "\n";
@@ -57,12 +53,8 @@ pm_error(const char *format, ...) {
static const size_t buffer_size = 1024;
char buffer[buffer_size];
-#if defined(WIN32_VC) || defined(WIN64_VC)
- // Windows doesn't define vsnprintf(). Hope we don't overflow.
- vsprintf(buffer, format, ap);
-#else
+
vsnprintf(buffer, buffer_size, format, ap);
-#endif
nassertv(strlen(buffer) < buffer_size);
pnmimage_cat.error() << buffer << "\n";
diff --git a/panda/src/pnmimagetypes/CMakeLists.txt b/panda/src/pnmimagetypes/CMakeLists.txt
new file mode 100644
index 0000000000..84c8ceeab7
--- /dev/null
+++ b/panda/src/pnmimagetypes/CMakeLists.txt
@@ -0,0 +1,48 @@
+set(P3PNMIMAGETYPES_HEADERS
+ config_pnmimagetypes.h
+ pnmFileTypeBMP.h
+ pnmFileTypeEXR.h
+ pnmFileTypeIMG.h
+ pnmFileTypePNG.h
+ pnmFileTypePNM.h
+ pnmFileTypePfm.h
+ pnmFileTypeSGI.h pnmFileTypeSoftImage.h
+ pnmFileTypeStbImage.h
+ pnmFileTypeTGA.h
+ pnmFileTypeTIFF.h
+ pnmFileTypeJPG.h
+ sgi.h
+)
+
+set(P3PNMIMAGETYPES_SOURCES
+ config_pnmimagetypes.cxx
+ pnmFileTypeBMPReader.cxx pnmFileTypeBMPWriter.cxx
+ pnmFileTypeBMP.cxx
+ pnmFileTypeEXR.cxx
+ pnmFileTypeIMG.cxx
+ pnmFileTypeJPG.cxx pnmFileTypeJPGReader.cxx pnmFileTypeJPGWriter.cxx
+ pnmFileTypePNG.cxx
+ pnmFileTypePNM.cxx
+ pnmFileTypePfm.cxx
+ pnmFileTypeSGI.cxx
+ pnmFileTypeSGIReader.cxx pnmFileTypeSGIWriter.cxx
+ pnmFileTypeSoftImage.cxx
+ pnmFileTypeStbImage.cxx
+ pnmFileTypeTIFF.cxx
+ pnmFileTypeTGA.cxx
+)
+
+composite_sources(p3pnmimagetypes P3PNMIMAGETYPES_SOURCES)
+add_component_library(p3pnmimagetypes SYMBOL BUILDING_PANDA_PNMIMAGETYPES
+ ${P3PNMIMAGETYPES_HEADERS} ${P3PNMIMAGETYPES_SOURCES})
+target_link_libraries(p3pnmimagetypes p3pnmimage
+ PKG::JPEG PKG::TIFF PKG::PNG PKG::OPENEXR)
+set_target_properties(p3pnmimagetypes PROPERTIES CXX_EXCEPTIONS ON)
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3pnmimagetypes
+ EXPORT Core COMPONENT Core
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ ARCHIVE COMPONENT CoreDevel)
+endif()
diff --git a/panda/src/pnmimagetypes/colrops.c b/panda/src/pnmimagetypes/colrops.c
index a82bf85399..51608dcbfe 100644
--- a/panda/src/pnmimagetypes/colrops.c
+++ b/panda/src/pnmimagetypes/colrops.c
@@ -1,5 +1,5 @@
/* Filename: colrops.c
- * Created by:
+ * Created by:
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
@@ -23,7 +23,7 @@
#endif
#define bmalloc malloc
-#if !defined(WIN32_VC) && !defined(WIN64_VC)
+#ifndef _WIN32
extern char *bmalloc(int);
#else
#include
@@ -37,7 +37,7 @@ static BYTE *g_mant = NULL, *g_nexp = NULL;
static BYTE (*g_bval)[256] = NULL;
#ifndef pow
-#if !defined(WIN32_VC) && !defined(WIN64_VC)
+#ifndef _WIN32
extern double pow(double, double);
#endif
#endif
diff --git a/panda/src/pnmimagetypes/pnmFileTypeBMP.h b/panda/src/pnmimagetypes/pnmFileTypeBMP.h
index 6cd3e8e32f..1777699bcd 100644
--- a/panda/src/pnmimagetypes/pnmFileTypeBMP.h
+++ b/panda/src/pnmimagetypes/pnmFileTypeBMP.h
@@ -25,7 +25,7 @@
/**
* For reading and writing Windows BMP files.
*/
-class EXPCL_PANDA_PNMIMAGETYPES PNMFileTypeBMP : public PNMFileType {
+class PNMFileTypeBMP : public PNMFileType {
public:
PNMFileTypeBMP();
diff --git a/panda/src/pnmimagetypes/pnmFileTypeEXR.h b/panda/src/pnmimagetypes/pnmFileTypeEXR.h
index 75a2b000e9..23e211ee98 100644
--- a/panda/src/pnmimagetypes/pnmFileTypeEXR.h
+++ b/panda/src/pnmimagetypes/pnmFileTypeEXR.h
@@ -36,7 +36,7 @@ class ImfStdIstream;
/**
* For reading and writing EXR floating-point or integer files.
*/
-class EXPCL_PANDA_PNMIMAGETYPES PNMFileTypeEXR : public PNMFileType {
+class PNMFileTypeEXR : public PNMFileType {
public:
PNMFileTypeEXR();
diff --git a/panda/src/pnmimagetypes/pnmFileTypeIMG.h b/panda/src/pnmimagetypes/pnmFileTypeIMG.h
index 2c406dfa68..e75aaeb972 100644
--- a/panda/src/pnmimagetypes/pnmFileTypeIMG.h
+++ b/panda/src/pnmimagetypes/pnmFileTypeIMG.h
@@ -25,7 +25,7 @@
/**
* For reading and writing headerless R,G,B files.
*/
-class EXPCL_PANDA_PNMIMAGETYPES PNMFileTypeIMG : public PNMFileType {
+class PNMFileTypeIMG : public PNMFileType {
public:
PNMFileTypeIMG();
diff --git a/panda/src/pnmimagetypes/pnmFileTypeJPG.h b/panda/src/pnmimagetypes/pnmFileTypeJPG.h
index f851c6d226..d577e52bf6 100644
--- a/panda/src/pnmimagetypes/pnmFileTypeJPG.h
+++ b/panda/src/pnmimagetypes/pnmFileTypeJPG.h
@@ -55,7 +55,7 @@ extern "C" {
/**
* For reading and writing Jpeg files.
*/
-class EXPCL_PANDA_PNMIMAGETYPES PNMFileTypeJPG : public PNMFileType {
+class PNMFileTypeJPG : public PNMFileType {
public:
PNMFileTypeJPG();
diff --git a/panda/src/pnmimagetypes/pnmFileTypePNG.h b/panda/src/pnmimagetypes/pnmFileTypePNG.h
index 3c1df88cbc..535a5b2f43 100644
--- a/panda/src/pnmimagetypes/pnmFileTypePNG.h
+++ b/panda/src/pnmimagetypes/pnmFileTypePNG.h
@@ -28,7 +28,7 @@
/**
* For reading and writing PNG files.
*/
-class EXPCL_PANDA_PNMIMAGETYPES PNMFileTypePNG : public PNMFileType {
+class PNMFileTypePNG : public PNMFileType {
public:
PNMFileTypePNG();
diff --git a/panda/src/pnmimagetypes/pnmFileTypePNM.h b/panda/src/pnmimagetypes/pnmFileTypePNM.h
index 1c65c19109..811661b1fa 100644
--- a/panda/src/pnmimagetypes/pnmFileTypePNM.h
+++ b/panda/src/pnmimagetypes/pnmFileTypePNM.h
@@ -25,7 +25,7 @@
/**
* For reading and writing basic PNM files--*.pbm, *.ppm, *.pnm.
*/
-class EXPCL_PANDA_PNMIMAGETYPES PNMFileTypePNM : public PNMFileType {
+class PNMFileTypePNM : public PNMFileType {
public:
PNMFileTypePNM();
diff --git a/panda/src/pnmimagetypes/pnmFileTypePfm.h b/panda/src/pnmimagetypes/pnmFileTypePfm.h
index ab18685084..c97ec46eb6 100644
--- a/panda/src/pnmimagetypes/pnmFileTypePfm.h
+++ b/panda/src/pnmimagetypes/pnmFileTypePfm.h
@@ -25,7 +25,7 @@
* For reading and writing PFM files using the basic PNMImage interface, as if
* they were basic RGB files.
*/
-class EXPCL_PANDA_PNMIMAGETYPES PNMFileTypePfm : public PNMFileType {
+class PNMFileTypePfm : public PNMFileType {
public:
PNMFileTypePfm();
diff --git a/panda/src/pnmimagetypes/pnmFileTypeSGI.h b/panda/src/pnmimagetypes/pnmFileTypeSGI.h
index ff026a3740..dbced028e2 100644
--- a/panda/src/pnmimagetypes/pnmFileTypeSGI.h
+++ b/panda/src/pnmimagetypes/pnmFileTypeSGI.h
@@ -25,7 +25,7 @@
/**
* For reading and writing SGI RGB files.
*/
-class EXPCL_PANDA_PNMIMAGETYPES PNMFileTypeSGI : public PNMFileType {
+class PNMFileTypeSGI : public PNMFileType {
public:
PNMFileTypeSGI();
diff --git a/panda/src/pnmimagetypes/pnmFileTypeSoftImage.h b/panda/src/pnmimagetypes/pnmFileTypeSoftImage.h
index c6e6860621..55457bbfca 100644
--- a/panda/src/pnmimagetypes/pnmFileTypeSoftImage.h
+++ b/panda/src/pnmimagetypes/pnmFileTypeSoftImage.h
@@ -25,7 +25,7 @@
/**
* For reading and SoftImage native image files.
*/
-class EXPCL_PANDA_PNMIMAGETYPES PNMFileTypeSoftImage : public PNMFileType {
+class PNMFileTypeSoftImage : public PNMFileType {
public:
PNMFileTypeSoftImage();
diff --git a/panda/src/pnmimagetypes/pnmFileTypeStbImage.h b/panda/src/pnmimagetypes/pnmFileTypeStbImage.h
index ce7d2d55ea..260d6dc61c 100644
--- a/panda/src/pnmimagetypes/pnmFileTypeStbImage.h
+++ b/panda/src/pnmimagetypes/pnmFileTypeStbImage.h
@@ -27,7 +27,7 @@
* when compiling without support for more specific libraries that are more
* full-featured, such as libpng or libjpeg.
*/
-class EXPCL_PANDA_PNMIMAGETYPES PNMFileTypeStbImage : public PNMFileType {
+class PNMFileTypeStbImage : public PNMFileType {
public:
PNMFileTypeStbImage();
diff --git a/panda/src/pnmimagetypes/pnmFileTypeTGA.h b/panda/src/pnmimagetypes/pnmFileTypeTGA.h
index c50a09ed47..d4ce1426cd 100644
--- a/panda/src/pnmimagetypes/pnmFileTypeTGA.h
+++ b/panda/src/pnmimagetypes/pnmFileTypeTGA.h
@@ -26,11 +26,10 @@
struct ImageHeader;
-
/**
* For reading and writing Targa image files.
*/
-class EXPCL_PANDA_PNMIMAGETYPES PNMFileTypeTGA : public PNMFileType {
+class PNMFileTypeTGA : public PNMFileType {
public:
PNMFileTypeTGA();
diff --git a/panda/src/pnmimagetypes/pnmFileTypeTIFF.cxx b/panda/src/pnmimagetypes/pnmFileTypeTIFF.cxx
index 3c4634055d..b90f416f9a 100644
--- a/panda/src/pnmimagetypes/pnmFileTypeTIFF.cxx
+++ b/panda/src/pnmimagetypes/pnmFileTypeTIFF.cxx
@@ -1215,11 +1215,7 @@ void PNMFileTypeTIFF::
tiff_warning(const char *, const char *format, va_list ap) {
static const int buffer_size = 1024;
char buffer[buffer_size];
-#if defined(WIN32_VC) || defined(WIN64_VC)
- vsprintf(buffer, format, ap);
-#else
vsnprintf(buffer, buffer_size, format, ap);
-#endif
// We ignore the module. It seems generally useless to us.
pnmimage_tiff_cat.warning()
@@ -1234,11 +1230,7 @@ void PNMFileTypeTIFF::
tiff_error(const char *module, const char *format, va_list ap) {
static const int buffer_size = 1024;
char buffer[buffer_size];
-#if defined(WIN32_VC) || defined(WIN64_VC)
- vsprintf(buffer, format, ap);
-#else
vsnprintf(buffer, buffer_size, format, ap);
-#endif
// We ignore the module. It seems generally useless to us.
pnmimage_tiff_cat.error()
diff --git a/panda/src/pnmimagetypes/pnmFileTypeTIFF.h b/panda/src/pnmimagetypes/pnmFileTypeTIFF.h
index c61e4f53f1..36148a082e 100644
--- a/panda/src/pnmimagetypes/pnmFileTypeTIFF.h
+++ b/panda/src/pnmimagetypes/pnmFileTypeTIFF.h
@@ -30,7 +30,7 @@
/**
* For reading and writing TIFF files.
*/
-class EXPCL_PANDA_PNMIMAGETYPES PNMFileTypeTIFF : public PNMFileType {
+class PNMFileTypeTIFF : public PNMFileType {
public:
PNMFileTypeTIFF();
diff --git a/panda/src/pnmtext/CMakeLists.txt b/panda/src/pnmtext/CMakeLists.txt
new file mode 100644
index 0000000000..6acc9bd910
--- /dev/null
+++ b/panda/src/pnmtext/CMakeLists.txt
@@ -0,0 +1,35 @@
+if(NOT HAVE_FREETYPE)
+ return()
+endif()
+
+set(P3PNMTEXT_HEADERS
+ config_pnmtext.h
+ freetypeFace.h freetypeFace.I
+ freetypeFont.h freetypeFont.I
+ pnmTextGlyph.h pnmTextGlyph.I
+ pnmTextMaker.h pnmTextMaker.I
+)
+
+set(P3PNMTEXT_SOURCES
+ config_pnmtext.cxx
+ freetypeFace.cxx
+ freetypeFont.cxx
+ pnmTextGlyph.cxx
+ pnmTextMaker.cxx
+)
+
+composite_sources(p3pnmtext P3PNMTEXT_SOURCES)
+add_component_library(p3pnmtext SYMBOL BUILDING_PANDA_PNMTEXT
+ ${P3PNMTEXT_HEADERS} ${P3PNMTEXT_SOURCES})
+target_link_libraries(p3pnmtext p3parametrics p3pnmimage PKG::FREETYPE)
+target_interrogate(p3pnmtext ALL)
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3pnmtext
+ EXPORT Core COMPONENT Core
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT CoreDevel)
+endif()
+install(FILES ${P3PNMTEXT_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/panda/src/pstatclient/CMakeLists.txt b/panda/src/pstatclient/CMakeLists.txt
new file mode 100644
index 0000000000..2aa8e37f77
--- /dev/null
+++ b/panda/src/pstatclient/CMakeLists.txt
@@ -0,0 +1,45 @@
+set(P3PSTATCLIENT_HEADERS
+ config_pstatclient.h pStatClient.I pStatClient.h
+ pStatClientImpl.I pStatClientImpl.h
+ pStatClientVersion.I
+ pStatClientVersion.h pStatClientControlMessage.h
+ pStatCollector.I pStatCollector.h pStatCollectorDef.h
+ pStatCollectorForward.I pStatCollectorForward.h
+ pStatFrameData.I pStatFrameData.h pStatProperties.h
+ pStatServerControlMessage.h pStatThread.I pStatThread.h
+ pStatTimer.I pStatTimer.h
+)
+
+set(P3PSTATCLIENT_SOURCES
+ config_pstatclient.cxx pStatClient.cxx pStatClientImpl.cxx
+ pStatClientVersion.cxx
+ pStatClientControlMessage.cxx
+ pStatCollector.cxx
+ pStatCollectorDef.cxx
+ pStatCollectorForward.cxx
+ pStatFrameData.cxx pStatProperties.cxx
+ pStatServerControlMessage.cxx
+ pStatThread.cxx
+)
+
+composite_sources(p3pstatclient P3PSTATCLIENT_SOURCES)
+add_component_library(p3pstatclient SYMBOL BUILDING_PANDA_PSTATCLIENT
+ ${P3PSTATCLIENT_HEADERS} ${P3PSTATCLIENT_SOURCES})
+target_link_libraries(p3pstatclient p3putil pandaexpress)
+
+if(HAVE_NET AND WANT_NATIVE_NET)
+ target_link_libraries(p3pstatclient p3net)
+endif()
+
+target_interrogate(p3pstatclient ALL)
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3pstatclient
+ EXPORT Core COMPONENT Core
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT CoreDevel)
+endif()
+install(FILES ${P3PSTATCLIENT_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
+install(FILES config_pstats.h COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/panda/src/pstatclient/pStatClientImpl.cxx b/panda/src/pstatclient/pStatClientImpl.cxx
index d607a53bd9..f25b863b97 100644
--- a/panda/src/pstatclient/pStatClientImpl.cxx
+++ b/panda/src/pstatclient/pStatClientImpl.cxx
@@ -27,8 +27,8 @@
#include
-#if defined(WIN32_VC) || defined(WIN64_VC)
-#include
+#ifdef _WIN32
+#include
#include
#endif
diff --git a/panda/src/putil/CMakeLists.txt b/panda/src/putil/CMakeLists.txt
new file mode 100644
index 0000000000..5b5d841f19
--- /dev/null
+++ b/panda/src/putil/CMakeLists.txt
@@ -0,0 +1,150 @@
+set(P3PUTIL_HEADERS
+ animInterface.h animInterface.I
+ autoTextureScale.h
+ bam.h
+ bamCache.h bamCache.I
+ bamCacheIndex.h bamCacheIndex.I
+ bamCacheRecord.h bamCacheRecord.I
+ bamEnums.h
+ bamReader.I bamReader.h bamReaderParam.I
+ bamReaderParam.h
+ bamWriter.I bamWriter.h
+ bitArray.I bitArray.h
+ bitMask.I bitMask.h
+ buttonHandle.I buttonHandle.h
+ buttonMap.I buttonMap.h
+ buttonRegistry.I buttonRegistry.h
+ cachedTypedWritableReferenceCount.h cachedTypedWritableReferenceCount.I
+ callbackData.h callbackData.I
+ callbackObject.h callbackObject.I
+ clockObject.h clockObject.I
+ collideMask.h
+ colorSpace.h
+ copyOnWriteObject.h copyOnWriteObject.I
+ copyOnWritePointer.h copyOnWritePointer.I
+ compareTo.I compareTo.h
+ config_putil.N config_putil.h configurable.h
+ cPointerCallbackObject.h cPointerCallbackObject.I
+ datagramBuffer.I datagramBuffer.h
+ datagramInputFile.I datagramInputFile.h
+ datagramOutputFile.I datagramOutputFile.h
+ doubleBitMask.I doubleBitMask.h
+ drawMask.h
+ factory.I factory.h
+ factoryBase.I factoryBase.h
+ factoryParam.I factoryParam.h factoryParams.I
+ factoryParams.h
+ firstOfPairCompare.I firstOfPairCompare.h
+ firstOfPairLess.I firstOfPairLess.h
+ gamepadButton.h
+ globalPointerRegistry.I globalPointerRegistry.h
+ indirectCompareNames.I indirectCompareNames.h
+ indirectCompareSort.I indirectCompareSort.h
+ indirectCompareTo.I indirectCompareTo.h
+ ioPtaDatagramFloat.h ioPtaDatagramInt.h
+ ioPtaDatagramShort.h keyboardButton.h
+ iterator_types.h
+ linkedListNode.I linkedListNode.h
+ load_prc_file.h
+ loaderOptions.I loaderOptions.h
+ modifierButtons.I modifierButtons.h
+ mouseButton.h mouseData.h
+ nameUniquifier.I nameUniquifier.h
+ nodeCachedReferenceCount.h nodeCachedReferenceCount.I
+ paramValue.I paramValue.h
+ pbitops.I pbitops.h
+ pointerData.h pointerData.I
+ portalMask.h
+ pta_ushort.h
+ simpleHashMap.I simpleHashMap.h
+ sparseArray.I sparseArray.h
+ timedCycle.I timedCycle.h typedWritable.I
+ typedWritable.h typedWritableReferenceCount.I
+ typedWritableReferenceCount.h updateSeq.I updateSeq.h
+ uniqueIdAllocator.h
+ vector_typedWritable.h
+ vector_ulong.h
+ vector_ushort.h vector_writable.h
+ writableConfigurable.h
+ writableParam.I writableParam.h
+)
+
+set(P3PUTIL_SOURCES
+ animInterface.cxx
+ autoTextureScale.cxx
+ bamCache.cxx
+ bamCacheIndex.cxx
+ bamCacheRecord.cxx
+ bamEnums.cxx
+ bamReader.cxx bamReaderParam.cxx
+ bamWriter.cxx
+ bitArray.cxx
+ bitMask.cxx
+ buttonHandle.cxx buttonMap.cxx buttonRegistry.cxx
+ cachedTypedWritableReferenceCount.cxx
+ callbackData.cxx
+ callbackObject.cxx
+ clockObject.cxx
+ colorSpace.cxx
+ copyOnWriteObject.cxx
+ copyOnWritePointer.cxx
+ config_putil.cxx configurable.cxx
+ cPointerCallbackObject.cxx
+ datagramBuffer.cxx
+ datagramInputFile.cxx datagramOutputFile.cxx
+ doubleBitMask.cxx
+ factoryBase.cxx
+ factoryParam.cxx factoryParams.cxx
+ gamepadButton.cxx
+ globalPointerRegistry.cxx
+ ioPtaDatagramFloat.cxx
+ ioPtaDatagramInt.cxx ioPtaDatagramShort.cxx
+ keyboardButton.cxx
+ linkedListNode.cxx
+ load_prc_file.cxx
+ loaderOptions.cxx
+ modifierButtons.cxx
+ mouseButton.cxx
+ nameUniquifier.cxx
+ nodeCachedReferenceCount.cxx
+ paramValue.cxx
+ pbitops.cxx
+ pointerData.cxx
+ pta_ushort.cxx
+ simpleHashMap.cxx
+ sparseArray.cxx
+ timedCycle.cxx typedWritable.cxx
+ typedWritableReferenceCount.cxx updateSeq.cxx
+ uniqueIdAllocator.cxx
+ vector_typedWritable.cxx
+ vector_ulong.cxx
+ vector_ushort.cxx vector_writable.cxx
+ writableConfigurable.cxx writableParam.cxx
+)
+
+set(P3PUTIL_IGATEEXT
+ bamReader_ext.cxx
+ bamReader_ext.h
+ callbackObject_ext.h
+ pythonCallbackObject.cxx
+ pythonCallbackObject.h
+ typedWritable_ext.cxx
+ typedWritable_ext.h
+)
+
+composite_sources(p3putil P3PUTIL_SOURCES)
+add_component_library(p3putil SYMBOL BUILDING_PANDA_PUTIL
+ ${P3PUTIL_HEADERS} ${P3PUTIL_SOURCES})
+target_link_libraries(p3putil p3linmath p3pipeline)
+target_interrogate(p3putil ALL EXTENSIONS ${P3PUTIL_IGATEEXT})
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3putil
+ EXPORT Core COMPONENT Core
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT CoreDevel)
+endif()
+install(FILES ${P3PUTIL_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
+install(FILES config_util.h COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/panda/src/recorder/CMakeLists.txt b/panda/src/recorder/CMakeLists.txt
new file mode 100644
index 0000000000..b65627db79
--- /dev/null
+++ b/panda/src/recorder/CMakeLists.txt
@@ -0,0 +1,34 @@
+set(P3RECORDER_HEADERS
+ config_recorder.h
+ mouseRecorder.h
+ recorderBase.h recorderBase.I
+ recorderController.h recorderController.I
+ recorderFrame.h recorderFrame.I
+ recorderHeader.h recorderHeader.I
+ recorderTable.h recorderTable.I
+ socketStreamRecorder.h socketStreamRecorder.I
+)
+
+set(P3RECORDER_SOURCES
+ config_recorder.cxx
+ mouseRecorder.cxx
+ recorderBase.cxx recorderController.cxx
+ recorderFrame.cxx recorderHeader.cxx recorderTable.cxx
+ socketStreamRecorder.cxx
+)
+
+composite_sources(p3recorder P3RECORDER_SOURCES)
+add_component_library(p3recorder NOINIT SYMBOL BUILDING_PANDA_RECORDER
+ ${P3RECORDER_HEADERS} ${P3RECORDER_SOURCES})
+target_link_libraries(p3recorder p3dgraph pandaexpress)
+target_interrogate(p3recorder ALL)
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3recorder
+ EXPORT Core COMPONENT Core
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT CoreDevel)
+endif()
+install(FILES ${P3RECORDER_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/panda/src/speedtree/speedTreeNode.cxx b/panda/src/speedtree/speedTreeNode.cxx
index b00af199bb..eed5399fc4 100644
--- a/panda/src/speedtree/speedTreeNode.cxx
+++ b/panda/src/speedtree/speedTreeNode.cxx
@@ -108,7 +108,7 @@ SpeedTreeNode(const string &name) :
_os_shaders_dir = shaders_dir.to_os_specific();
// Ensure the path ends with a terminal slash; SpeedTree requires this.
-#if defined(WIN32) || defined(WIN64)
+#ifdef _WIN32
if (!_os_shaders_dir.empty() && _os_shaders_dir[_os_shaders_dir.length() - 1] != '\\') {
_os_shaders_dir += "\\";
}
@@ -1560,7 +1560,7 @@ setup_for_render(GraphicsStateGuardian *gsg) {
os_textures_dir = speedtree_textures_dir.get_value().to_os_specific();
// Ensure the path ends with a terminal slash; SpeedTree requires
// this.
-#if defined(WIN32) || defined(WIN64)
+#ifdef _WIN32
if (!os_textures_dir.empty() && os_textures_dir[os_textures_dir.length() - 1] != '\\') {
os_textures_dir += "\\";
}
diff --git a/panda/src/testbed/CMakeLists.txt b/panda/src/testbed/CMakeLists.txt
new file mode 100644
index 0000000000..3c497f42ac
--- /dev/null
+++ b/panda/src/testbed/CMakeLists.txt
@@ -0,0 +1,9 @@
+if(NOT BUILD_PANDATOOL)
+ # It's safe to say, if the user doesn't want pandatool, they don't want pview
+ # either.
+ return()
+endif()
+
+add_executable(pview pview.cxx)
+target_link_libraries(pview p3framework)
+install(TARGETS pview EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
diff --git a/panda/src/text/CMakeLists.txt b/panda/src/text/CMakeLists.txt
new file mode 100644
index 0000000000..b7cbaee022
--- /dev/null
+++ b/panda/src/text/CMakeLists.txt
@@ -0,0 +1,58 @@
+set(P3TEXT_HEADERS
+ config_text.h
+ default_font.h
+ dynamicTextFont.I dynamicTextFont.h
+ dynamicTextGlyph.I dynamicTextGlyph.h
+ dynamicTextPage.I dynamicTextPage.h
+ fontPool.I fontPool.h
+ geomTextGlyph.I geomTextGlyph.h
+ staticTextFont.I staticTextFont.h
+ textAssembler.I textAssembler.h
+ textFont.I textFont.h
+ textGlyph.I textGlyph.h
+ textGraphic.I textGraphic.h
+ textNode.I textNode.h
+ textProperties.I textProperties.h
+ textPropertiesManager.I textPropertiesManager.h
+)
+
+set(P3TEXT_SOURCES
+ config_text.cxx
+ default_font.cxx
+ dynamicTextFont.cxx
+ dynamicTextGlyph.cxx
+ dynamicTextPage.cxx
+ fontPool.cxx
+ geomTextGlyph.cxx
+ staticTextFont.cxx
+ textAssembler.cxx
+ textFont.cxx textGlyph.cxx
+ textGraphic.cxx
+ textNode.cxx
+ textProperties.cxx
+ textPropertiesManager.cxx
+)
+
+composite_sources(p3text P3TEXT_SOURCES)
+add_component_library(p3text SYMBOL BUILDING_PANDA_TEXT
+ ${P3TEXT_HEADERS} ${P3TEXT_SOURCES})
+target_link_libraries(p3text p3parametrics
+ PKG::HARFBUZZ)
+if(HAVE_FREETYPE)
+ target_link_libraries(p3text p3pnmtext)
+endif()
+target_interrogate(p3text ALL)
+
+if(HAVE_HARFBUZZ)
+ target_compile_definitions(p3text PRIVATE HAVE_HARFBUZZ)
+endif()
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3text
+ EXPORT Core COMPONENT Core
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT CoreDevel)
+endif()
+install(FILES ${P3TEXT_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/panda/src/tform/CMakeLists.txt b/panda/src/tform/CMakeLists.txt
new file mode 100644
index 0000000000..c8da2e176c
--- /dev/null
+++ b/panda/src/tform/CMakeLists.txt
@@ -0,0 +1,45 @@
+set(P3TFORM_HEADERS
+ buttonThrower.I buttonThrower.h
+ config_tform.h
+ driveInterface.I driveInterface.h
+ mouseInterfaceNode.I mouseInterfaceNode.h
+ mouseSubregion.I mouseSubregion.h
+ mouseWatcher.h mouseWatcher.I
+ mouseWatcherBase.h mouseWatcherBase.I
+ mouseWatcherGroup.h
+ mouseWatcherParameter.I mouseWatcherParameter.h
+ mouseWatcherRegion.I mouseWatcherRegion.h
+ trackball.h
+ transform2sg.h
+)
+
+set(P3TFORM_SOURCES
+ buttonThrower.cxx
+ config_tform.cxx
+ driveInterface.cxx
+ mouseInterfaceNode.cxx
+ mouseSubregion.cxx
+ mouseWatcher.cxx
+ mouseWatcherBase.cxx
+ mouseWatcherGroup.cxx
+ mouseWatcherParameter.cxx
+ mouseWatcherRegion.cxx
+ trackball.cxx
+ transform2sg.cxx
+)
+
+composite_sources(p3tform P3TFORM_SOURCES)
+add_component_library(p3tform NOINIT SYMBOL BUILDING_PANDA_TFORM
+ ${P3TFORM_HEADERS} ${P3TFORM_SOURCES})
+target_link_libraries(p3tform p3device p3grutil)
+target_interrogate(p3tform ALL)
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3tform
+ EXPORT Core COMPONENT Core
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT CoreDevel)
+endif()
+install(FILES ${P3TFORM_HEADERS} COMPONENT CoreDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/panda/src/tinydisplay/config_tinydisplay.cxx b/panda/src/tinydisplay/config_tinydisplay.cxx
index 9b69b9bd00..b843f2e85d 100644
--- a/panda/src/tinydisplay/config_tinydisplay.cxx
+++ b/panda/src/tinydisplay/config_tinydisplay.cxx
@@ -87,7 +87,7 @@ init_libtinydisplay() {
ps->set_system_tag("TinyPanda", "native_window_system", "X11");
#endif
-#ifdef WIN32
+#ifdef _WIN32
TinyWinGraphicsPipe::init_type();
TinyWinGraphicsWindow::init_type();
selection->add_pipe_type(TinyWinGraphicsPipe::get_class_type(),
@@ -116,7 +116,7 @@ init_libtinydisplay() {
int
get_pipe_type_p3tinydisplay() {
-#ifdef WIN32
+#ifdef _WIN32
return TinyWinGraphicsPipe::get_class_type().get_index();
#endif
diff --git a/panda/src/tinydisplay/tinyWinGraphicsPipe.cxx b/panda/src/tinydisplay/tinyWinGraphicsPipe.cxx
index adc51e6c9f..1347d406aa 100644
--- a/panda/src/tinydisplay/tinyWinGraphicsPipe.cxx
+++ b/panda/src/tinydisplay/tinyWinGraphicsPipe.cxx
@@ -13,7 +13,7 @@
#include "pandabase.h"
-#ifdef WIN32
+#ifdef _WIN32
#include "tinyWinGraphicsPipe.h"
#include "config_tinydisplay.h"
diff --git a/panda/src/tinydisplay/tinyWinGraphicsPipe.h b/panda/src/tinydisplay/tinyWinGraphicsPipe.h
index 8626a9d675..72d6e875a5 100644
--- a/panda/src/tinydisplay/tinyWinGraphicsPipe.h
+++ b/panda/src/tinydisplay/tinyWinGraphicsPipe.h
@@ -16,7 +16,7 @@
#include "pandabase.h"
-#ifdef WIN32
+#ifdef _WIN32
#include "winGraphicsPipe.h"
#include "tinyGraphicsStateGuardian.h"
diff --git a/panda/src/tinydisplay/tinyWinGraphicsWindow.cxx b/panda/src/tinydisplay/tinyWinGraphicsWindow.cxx
index ac16d45bf2..9f39a20723 100644
--- a/panda/src/tinydisplay/tinyWinGraphicsWindow.cxx
+++ b/panda/src/tinydisplay/tinyWinGraphicsWindow.cxx
@@ -13,7 +13,7 @@
#include "pandabase.h"
-#ifdef WIN32
+#ifdef _WIN32
#include "tinyWinGraphicsWindow.h"
#include "config_tinydisplay.h"
diff --git a/panda/src/tinydisplay/tinyWinGraphicsWindow.h b/panda/src/tinydisplay/tinyWinGraphicsWindow.h
index ecc1365a0b..b234001540 100644
--- a/panda/src/tinydisplay/tinyWinGraphicsWindow.h
+++ b/panda/src/tinydisplay/tinyWinGraphicsWindow.h
@@ -16,7 +16,7 @@
#include "pandabase.h"
-#ifdef WIN32
+#ifdef _WIN32
#include "winGraphicsWindow.h"
#include "tinyWinGraphicsPipe.h"
diff --git a/panda/src/tinydisplay/zfeatures.h b/panda/src/tinydisplay/zfeatures.h
index 73a61d95c5..aab61bfa34 100644
--- a/panda/src/tinydisplay/zfeatures.h
+++ b/panda/src/tinydisplay/zfeatures.h
@@ -7,7 +7,7 @@
#define BIG_ENDIAN 4321
#if (defined(__i386__) || defined(__i386)) || \
- defined(__ia64__) || defined(WIN32) || \
+ defined(__ia64__) || defined(_WIN32) || \
(defined(__alpha__) || defined(__alpha)) || \
defined(__arm__) || \
(defined(__mips__) && defined(__MIPSEL__)) || \
diff --git a/panda/src/vision/CMakeLists.txt b/panda/src/vision/CMakeLists.txt
new file mode 100644
index 0000000000..284e764807
--- /dev/null
+++ b/panda/src/vision/CMakeLists.txt
@@ -0,0 +1,54 @@
+if(NOT HAVE_OPENCV AND NOT HAVE_ARTOOLKIT)
+ return()
+endif()
+
+set(P3VISION_HEADERS
+ arToolKit.h arToolKit.I
+ config_vision.h
+ openCVTexture.h openCVTexture.I
+ webcamVideoCursorOpenCV.h
+ webcamVideoCursorV4L.h
+ webcamVideo.h webcamVideo.I
+ webcamVideoOpenCV.h
+ webcamVideoV4L.h
+)
+
+set(P3VISION_SOURCES
+ arToolKit.cxx
+ config_vision.cxx
+ openCVTexture.cxx
+ webcamVideoCursorOpenCV.cxx
+ webcamVideoCursorV4L.cxx
+ webcamVideo.cxx
+ webcamVideoDS.cxx
+ webcamVideoOpenCV.cxx
+ webcamVideoV4L.cxx
+)
+
+composite_sources(p3vision P3VISION_SOURCES)
+add_library(p3vision ${P3VISION_HEADERS} ${P3VISION_SOURCES})
+set_target_properties(p3vision PROPERTIES DEFINE_SYMBOL BUILDING_VISION)
+target_link_libraries(p3vision panda
+ PKG::OPENCV PKG::ARTOOLKIT)
+set_target_properties(p3vision PROPERTIES CXX_EXCEPTIONS ON)
+target_interrogate(p3vision ALL)
+
+if(OPENCV_VER_3)
+ set_target_properties(p3vision PROPERTIES COMPILE_DEFINITIONS "OPENCV_VER_3")
+elseif(OPENCV_VER_23)
+ set_target_properties(p3vision PROPERTIES COMPILE_DEFINITIONS "OPENCV_VER_23")
+endif()
+
+if(HAVE_FFMPEG)
+ target_compile_definitions(p3vision PRIVATE HAVE_FFMPEG)
+endif()
+
+install(TARGETS p3vision
+ EXPORT Vision COMPONENT Vision
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT VisionDevel)
+install(FILES ${P3VISION_HEADERS} COMPONENT VisionDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
+
+export_targets(Vision COMPONENT VisionDevel)
diff --git a/panda/src/vrpn/CMakeLists.txt b/panda/src/vrpn/CMakeLists.txt
new file mode 100644
index 0000000000..11e5a5fc61
--- /dev/null
+++ b/panda/src/vrpn/CMakeLists.txt
@@ -0,0 +1,48 @@
+if(NOT HAVE_VRPN)
+ return()
+endif()
+
+set(P3VRPN_HEADERS
+ config_vrpn.h
+ vrpnAnalogDevice.h vrpnAnalogDevice.I
+ vrpnAnalog.h vrpnAnalog.I
+ vrpnButtonDevice.h vrpnButtonDevice.I
+ vrpnButton.h vrpnButton.I
+ vrpnClient.h vrpnClient.I
+ vrpnDialDevice.h vrpnDialDevice.I
+ vrpnDial.h vrpnDial.I
+ vrpn_interface.h
+ vrpnTrackerDevice.h vrpnTrackerDevice.I
+ vrpnTracker.h vrpnTracker.I
+)
+
+set(P3VRPN_SOURCES
+ config_vrpn.cxx
+ vrpnAnalog.cxx
+ vrpnAnalogDevice.cxx
+ vrpnButton.cxx
+ vrpnButtonDevice.cxx
+ vrpnClient.cxx
+ vrpnDial.cxx
+ vrpnDialDevice.cxx
+ vrpnTracker.cxx
+ vrpnTrackerDevice.cxx
+)
+
+composite_sources(p3vrpn P3VRPN_SOURCES)
+add_library(p3vrpn ${P3VRPN_HEADERS} ${P3VRPN_SOURCES})
+set_target_properties(p3vrpn PROPERTIES DEFINE_SYMBOL BUILDING_VRPN)
+target_link_libraries(p3vrpn panda PKG::VRPN)
+target_interrogate(p3vrpn ALL)
+
+set_target_properties(p3vrpn PROPERTIES CXX_EXCEPTIONS ON)
+
+install(TARGETS p3vrpn
+ EXPORT VRPN COMPONENT VRPN
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT VRPNDevel)
+install(FILES ${P3VRPN_HEADERS} COMPONENT VRPNDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
+
+export_targets(VRPN COMPONENT VRPNDevel)
diff --git a/panda/src/vrpn/vrpnAnalog.I b/panda/src/vrpn/vrpnAnalog.I
index afd951e417..234e6b4616 100644
--- a/panda/src/vrpn/vrpnAnalog.I
+++ b/panda/src/vrpn/vrpnAnalog.I
@@ -28,12 +28,3 @@ INLINE bool VrpnAnalog::
is_empty() const {
return _devices.empty();
}
-
-/**
- * Polls the connected device. Normally you should not call this directly;
- * this will be called by the VrpnClient.
- */
-INLINE void VrpnAnalog::
-poll() {
- _analog->mainloop();
-}
diff --git a/panda/src/vrpn/vrpnAnalog.cxx b/panda/src/vrpn/vrpnAnalog.cxx
index 2745aab75e..b0b81c8867 100644
--- a/panda/src/vrpn/vrpnAnalog.cxx
+++ b/panda/src/vrpn/vrpnAnalog.cxx
@@ -70,6 +70,15 @@ unmark(VrpnAnalogDevice *device) {
}
}
+/**
+ * Polls the connected device. Normally you should not call this directly;
+ * this will be called by the VrpnClient.
+ */
+void VrpnAnalog::
+poll() {
+ _analog->mainloop();
+}
+
/**
*
*/
diff --git a/panda/src/vrpn/vrpnAnalog.h b/panda/src/vrpn/vrpnAnalog.h
index 07f3c84b21..34bc51f277 100644
--- a/panda/src/vrpn/vrpnAnalog.h
+++ b/panda/src/vrpn/vrpnAnalog.h
@@ -46,7 +46,7 @@ public:
void mark(VrpnAnalogDevice *device);
void unmark(VrpnAnalogDevice *device);
- INLINE void poll();
+ void poll();
void output(std::ostream &out) const;
void write(std::ostream &out, int indent_level = 0) const;
diff --git a/panda/src/vrpn/vrpnButton.I b/panda/src/vrpn/vrpnButton.I
index ed10b89fae..e083d0325b 100644
--- a/panda/src/vrpn/vrpnButton.I
+++ b/panda/src/vrpn/vrpnButton.I
@@ -28,12 +28,3 @@ INLINE bool VrpnButton::
is_empty() const {
return _devices.empty();
}
-
-/**
- * Polls the connected device. Normally you should not call this directly;
- * this will be called by the VrpnClient.
- */
-INLINE void VrpnButton::
-poll() {
- _button->mainloop();
-}
diff --git a/panda/src/vrpn/vrpnButton.cxx b/panda/src/vrpn/vrpnButton.cxx
index 3312afa31d..eefbcf1015 100644
--- a/panda/src/vrpn/vrpnButton.cxx
+++ b/panda/src/vrpn/vrpnButton.cxx
@@ -70,6 +70,15 @@ unmark(VrpnButtonDevice *device) {
}
}
+/**
+ * Polls the connected device. Normally you should not call this directly;
+ * this will be called by the VrpnClient.
+ */
+void VrpnButton::
+poll() {
+ _button->mainloop();
+}
+
/**
*
*/
diff --git a/panda/src/vrpn/vrpnButton.h b/panda/src/vrpn/vrpnButton.h
index 1b9fc14cf4..3b151b5130 100644
--- a/panda/src/vrpn/vrpnButton.h
+++ b/panda/src/vrpn/vrpnButton.h
@@ -45,7 +45,7 @@ public:
void mark(VrpnButtonDevice *device);
void unmark(VrpnButtonDevice *device);
- INLINE void poll();
+ void poll();
void output(std::ostream &out) const;
void write(std::ostream &out, int indent_level = 0) const;
diff --git a/panda/src/vrpn/vrpnClient.I b/panda/src/vrpn/vrpnClient.I
index 486a4e29f6..908c77a0c9 100644
--- a/panda/src/vrpn/vrpnClient.I
+++ b/panda/src/vrpn/vrpnClient.I
@@ -19,25 +19,6 @@ get_server_name() const {
return _server_name;
}
-/**
- * Returns true if everything seems to be kosher with the server (even if
- * there is no connection), or false otherwise.
- */
-INLINE bool VrpnClient::
-is_valid() const {
- return (_connection->doing_okay() != 0);
-}
-
-/**
- * Returns true if the connection is established successfully, false
- * otherwise.
- */
-INLINE bool VrpnClient::
-is_connected() const {
- return (_connection->connected() != 0);
-}
-
-
/**
* Little inline function to convert a struct timeval to only seconds
*/
diff --git a/panda/src/vrpn/vrpnClient.cxx b/panda/src/vrpn/vrpnClient.cxx
index 1fb7fcb4ff..9bf4ea2795 100644
--- a/panda/src/vrpn/vrpnClient.cxx
+++ b/panda/src/vrpn/vrpnClient.cxx
@@ -60,6 +60,24 @@ VrpnClient::
delete _connection;
}
+/**
+ * Returns true if everything seems to be kosher with the server (even if
+ * there is no connection), or false otherwise.
+ */
+bool VrpnClient::
+is_valid() const {
+ return (_connection->doing_okay() != 0);
+}
+
+/**
+ * Returns true if the connection is established successfully, false
+ * otherwise.
+ */
+bool VrpnClient::
+is_connected() const {
+ return (_connection->connected() != 0);
+}
+
/**
* Writes a list of the active devices that the VrpnClient is currently
* polling each frame.
diff --git a/panda/src/vrpn/vrpnClient.h b/panda/src/vrpn/vrpnClient.h
index 127492d9cf..979351eac9 100644
--- a/panda/src/vrpn/vrpnClient.h
+++ b/panda/src/vrpn/vrpnClient.h
@@ -38,8 +38,8 @@ PUBLISHED:
~VrpnClient();
INLINE const std::string &get_server_name() const;
- INLINE bool is_valid() const;
- INLINE bool is_connected() const;
+ bool is_valid() const;
+ bool is_connected() const;
void write(std::ostream &out, int indent_level = 0) const;
diff --git a/panda/src/vrpn/vrpnDial.I b/panda/src/vrpn/vrpnDial.I
index 2cb9981826..3813aa02be 100644
--- a/panda/src/vrpn/vrpnDial.I
+++ b/panda/src/vrpn/vrpnDial.I
@@ -27,12 +27,3 @@ INLINE bool VrpnDial::
is_empty() const {
return _devices.empty();
}
-
-/**
- * Polls the connected device. Normally you should not call this directly;
- * this will be called by the VrpnClient.
- */
-INLINE void VrpnDial::
-poll() {
- _dial->mainloop();
-}
diff --git a/panda/src/vrpn/vrpnDial.cxx b/panda/src/vrpn/vrpnDial.cxx
index 62b1fe73df..04f19762df 100644
--- a/panda/src/vrpn/vrpnDial.cxx
+++ b/panda/src/vrpn/vrpnDial.cxx
@@ -70,6 +70,15 @@ unmark(VrpnDialDevice *device) {
}
}
+/**
+ * Polls the connected device. Normally you should not call this directly;
+ * this will be called by the VrpnClient.
+ */
+void VrpnDial::
+poll() {
+ _dial->mainloop();
+}
+
/**
*
*/
diff --git a/panda/src/vrpn/vrpnDial.h b/panda/src/vrpn/vrpnDial.h
index e98fd7d99d..e7be9c8aa1 100644
--- a/panda/src/vrpn/vrpnDial.h
+++ b/panda/src/vrpn/vrpnDial.h
@@ -45,7 +45,7 @@ public:
void mark(VrpnDialDevice *device);
void unmark(VrpnDialDevice *device);
- INLINE void poll();
+ void poll();
void output(std::ostream &out) const;
void write(std::ostream &out, int indent_level = 0) const;
diff --git a/panda/src/vrpn/vrpnTracker.I b/panda/src/vrpn/vrpnTracker.I
index b651121923..89c91084b5 100644
--- a/panda/src/vrpn/vrpnTracker.I
+++ b/panda/src/vrpn/vrpnTracker.I
@@ -28,12 +28,3 @@ INLINE bool VrpnTracker::
is_empty() const {
return _devices.empty();
}
-
-/**
- * Polls the connected device. Normally you should not call this directly;
- * this will be called by the VrpnClient.
- */
-INLINE void VrpnTracker::
-poll() {
- _tracker->mainloop();
-}
diff --git a/panda/src/vrpn/vrpnTracker.cxx b/panda/src/vrpn/vrpnTracker.cxx
index e1b08e2a72..046eaf1d69 100644
--- a/panda/src/vrpn/vrpnTracker.cxx
+++ b/panda/src/vrpn/vrpnTracker.cxx
@@ -72,6 +72,15 @@ unmark(VrpnTrackerDevice *device) {
}
}
+/**
+ * Polls the connected device. Normally you should not call this directly;
+ * this will be called by the VrpnClient.
+ */
+void VrpnTracker::
+poll() {
+ _tracker->mainloop();
+}
+
/**
*
*/
diff --git a/panda/src/vrpn/vrpnTracker.h b/panda/src/vrpn/vrpnTracker.h
index 1b6c30347d..bb6651cff7 100644
--- a/panda/src/vrpn/vrpnTracker.h
+++ b/panda/src/vrpn/vrpnTracker.h
@@ -45,7 +45,7 @@ public:
void mark(VrpnTrackerDevice *device);
void unmark(VrpnTrackerDevice *device);
- INLINE void poll();
+ void poll();
void output(std::ostream &out) const;
void write(std::ostream &out, int indent_level = 0) const;
diff --git a/panda/src/wgldisplay/CMakeLists.txt b/panda/src/wgldisplay/CMakeLists.txt
new file mode 100644
index 0000000000..77c5e75db5
--- /dev/null
+++ b/panda/src/wgldisplay/CMakeLists.txt
@@ -0,0 +1,35 @@
+if(NOT HAVE_WGL)
+ return()
+endif()
+
+set(P3WGLDISPLAY_HEADERS
+ config_wgldisplay.h
+ wglGraphicsBuffer.I wglGraphicsBuffer.h
+ wglGraphicsPipe.I wglGraphicsPipe.h
+ wglGraphicsStateGuardian.I wglGraphicsStateGuardian.h
+ wglGraphicsWindow.I wglGraphicsWindow.h
+ wglext.h
+)
+
+set(P3WGLDISPLAY_SOURCES
+ config_wgldisplay.cxx
+ wglGraphicsBuffer.cxx
+ wglGraphicsPipe.cxx
+ wglGraphicsStateGuardian.cxx
+ wglGraphicsWindow.cxx
+)
+
+composite_sources(p3wgldisplay P3WGLDISPLAY_SOURCES)
+add_component_library(p3wgldisplay SYMBOL BUILDING_PANDA_WGLDISPLAY
+ ${P3WGLDISPLAY_HEADERS} ${P3WGLDISPLAY_SOURCES})
+target_link_libraries(p3wgldisplay p3glgsg p3windisplay)
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3wgldisplay
+ EXPORT OpenGL COMPONENT OpenGL
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d
+ ARCHIVE COMPONENT OpenGLDevel)
+endif()
+install(FILES ${P3WGLDISPLAY_HEADERS} COMPONENT OpenGLDevel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/panda3d)
diff --git a/panda/src/windisplay/CMakeLists.txt b/panda/src/windisplay/CMakeLists.txt
new file mode 100644
index 0000000000..a966134957
--- /dev/null
+++ b/panda/src/windisplay/CMakeLists.txt
@@ -0,0 +1,33 @@
+if(NOT WIN32)
+ return()
+endif()
+
+set(P3WINDISPLAY_HEADERS
+ config_windisplay.h
+ winGraphicsPipe.I winGraphicsPipe.h
+ winGraphicsWindow.I winGraphicsWindow.h
+ winDetectDx.h
+)
+
+set(P3WINDISPLAY_SOURCES
+ config_windisplay.cxx winGraphicsPipe.cxx
+ winGraphicsWindow.cxx
+ winDetectDx9.cxx
+)
+
+composite_sources(p3windisplay P3WINDISPLAY_SOURCES)
+add_component_library(p3windisplay SYMBOL BUILDING_PANDAWIN
+ ${P3WINDISPLAY_HEADERS} ${P3WINDISPLAY_SOURCES})
+target_link_libraries(p3windisplay panda user32.lib imm32.lib)
+
+if(HAVE_DX9)
+ target_compile_definitions(p3windisplay PRIVATE HAVE_DX9)
+endif()
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3windisplay
+ EXPORT Core COMPONENT Core
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ ARCHIVE COMPONENT CoreDevel)
+endif()
diff --git a/panda/src/x11display/CMakeLists.txt b/panda/src/x11display/CMakeLists.txt
new file mode 100644
index 0000000000..d3a3ebbe12
--- /dev/null
+++ b/panda/src/x11display/CMakeLists.txt
@@ -0,0 +1,21 @@
+if(NOT HAVE_X11)
+ return()
+endif()
+
+set(P3X11DISPLAY_HEADERS
+ config_x11display.h x11GraphicsPipe.I x11GraphicsPipe.h
+ x11GraphicsWindow.h x11GraphicsWindow.I
+)
+
+set(P3X11DISPLAY_SOURCES
+ config_x11display.cxx x11GraphicsPipe.cxx x11GraphicsWindow.cxx
+)
+
+composite_sources(p3x11display P3X11DISPLAY_SOURCES)
+add_component_library(p3x11display SYMBOL BUILDING_PANDAX11
+ ${P3X11DISPLAY_HEADERS} ${P3X11DISPLAY_SOURCES})
+target_link_libraries(p3x11display panda PKG::X11)
+
+if(NOT BUILD_METALIBS)
+ install(TARGETS p3x11display EXPORT Core COMPONENT Core DESTINATION ${CMAKE_INSTALL_LIBDIR})
+endif()
diff --git a/panda/src/x11display/x11GraphicsPipe.I b/panda/src/x11display/x11GraphicsPipe.I
index a516b2e6a2..3f608bad5b 100644
--- a/panda/src/x11display/x11GraphicsPipe.I
+++ b/panda/src/x11display/x11GraphicsPipe.I
@@ -58,18 +58,18 @@ get_hidden_cursor() {
}
/**
- * Returns true if relative mouse mode is supported on this display.
+ * Returns true if a form of relative mouse mode is supported on this display.
*/
INLINE bool x11GraphicsPipe::
supports_relative_mouse() const {
- return (_XF86DGADirectVideo != nullptr);
+ return (_XF86DGADirectVideo != nullptr) || (_XISelectEvents != nullptr);
}
/**
* Enables relative mouse mode for this display. Returns false if unsupported.
*/
INLINE bool x11GraphicsPipe::
-enable_relative_mouse() {
+enable_dga_mouse() {
if (_XF86DGADirectVideo != nullptr) {
x11display_cat.info() << "Enabling relative mouse using XF86DGA extension\n";
_XF86DGADirectVideo(_display, _screen, XF86DGADirectMouse);
@@ -82,7 +82,7 @@ enable_relative_mouse() {
* Disables relative mouse mode for this display.
*/
INLINE void x11GraphicsPipe::
-disable_relative_mouse() {
+disable_dga_mouse() {
if (_XF86DGADirectVideo != nullptr) {
x11display_cat.info() << "Disabling relative mouse using XF86DGA extension\n";
_XF86DGADirectVideo(_display, _screen, 0);
diff --git a/panda/src/x11display/x11GraphicsPipe.cxx b/panda/src/x11display/x11GraphicsPipe.cxx
index 8f87b57609..e2f3da7d9d 100644
--- a/panda/src/x11display/x11GraphicsPipe.cxx
+++ b/panda/src/x11display/x11GraphicsPipe.cxx
@@ -107,7 +107,7 @@ x11GraphicsPipe(const std::string &display) :
int major_ver, minor_ver;
if (_XF86DGAQueryVersion == nullptr || _XF86DGADirectVideo == nullptr) {
x11display_cat.warning()
- << "libXxf86dga.so.1 does not provide required functions; relative mouse mode will not work.\n";
+ << "libXxf86dga.so.1 does not provide required functions; relative mouse mode may not work.\n";
} else if (!_XF86DGAQueryVersion(_display, &major_ver, &minor_ver)) {
_XF86DGADirectVideo = nullptr;
@@ -116,7 +116,7 @@ x11GraphicsPipe(const std::string &display) :
_XF86DGADirectVideo = nullptr;
if (x11display_cat.is_debug()) {
x11display_cat.debug()
- << "cannot dlopen libXxf86dga.so.1; cursor changing will not work.\n";
+ << "cannot dlopen libXxf86dga.so.1; relative mouse mode may not work.\n";
}
}
@@ -214,6 +214,44 @@ x11GraphicsPipe(const std::string &display) :
}
}
+ // Dynamically load the XInput2 extension.
+ int ev, err;
+ if (XQueryExtension(_display, "XInputExtension", &_xi_opcode, &ev, &err)) {
+ void *xi = dlopen("libXi.so.6", RTLD_NOW | RTLD_LOCAL);
+ if (xi != nullptr) {
+ pfn_XIQueryVersion _XIQueryVersion = (pfn_XIQueryVersion)dlsym(xi, "XIQueryVersion");
+ _XISelectEvents = (pfn_XISelectEvents)dlsym(xi, "XISelectEvents");
+
+ int major_ver = 2, minor_ver = 0;
+ if (_XIQueryVersion == nullptr || _XISelectEvents == nullptr) {
+ x11display_cat.warning()
+ << "libXi.so.6 does not provide required functions; relative mouse mode will not work.\n";
+ _XISelectEvents = nullptr;
+ dlclose(xi);
+
+ } else if (_XIQueryVersion(_display, &major_ver, &minor_ver) == Success) {
+ if (x11display_cat.is_debug()) {
+ x11display_cat.debug()
+ << "Found XInput extension " << major_ver << "." << minor_ver << "\n";
+ }
+
+ } else {
+ if (x11display_cat.is_debug()) {
+ x11display_cat.debug()
+ << "XInput2 extension not supported; relative mouse mode will not work.\n";
+ }
+ _XISelectEvents = nullptr;
+ dlclose(xi);
+ }
+ } else {
+ _XISelectEvents = nullptr;
+ if (x11display_cat.is_debug()) {
+ x11display_cat.debug()
+ << "cannot dlopen libXi.so.1; relative mouse mode will not work.\n";
+ }
+ }
+ }
+
// Use Xrandr to fill in the supported resolution list.
if (_have_xrandr) {
// If we have XRRGetScreenResources, we prefer that. It seems to be more
@@ -324,6 +362,59 @@ x11GraphicsPipe::
}
}
+/**
+ * Enables raw mouse mode for this display. Returns false if unsupported.
+ */
+INLINE bool x11GraphicsPipe::
+enable_raw_mouse() {
+ if (_num_raw_mouse_windows > 0) {
+ // Already enabled by another window.
+ ++_num_raw_mouse_windows;
+ return true;
+ }
+ if (_XISelectEvents != nullptr) {
+ XIEventMask event_mask;
+ unsigned char mask[XIMaskLen(XI_RawMotion)] = {0};
+
+ event_mask.deviceid = XIAllMasterDevices;
+ event_mask.mask_len = sizeof(mask);
+ event_mask.mask = mask;
+ XISetMask(mask, XI_RawMotion);
+
+ if (_XISelectEvents(_display, _root, &event_mask, 1) == Success) {
+ if (x11display_cat.info()) {
+ x11display_cat.info()
+ << "Enabled raw mouse events using XInput2 extension\n";
+ }
+ ++_num_raw_mouse_windows;
+ return true;
+ }
+ }
+ return false;
+}
+
+/**
+ * Disables raw mouse mode for this display.
+ */
+void x11GraphicsPipe::
+disable_raw_mouse() {
+ if (--_num_raw_mouse_windows == 0) {
+ if (x11display_cat.is_debug()) {
+ x11display_cat.debug()
+ << "Disabling raw mouse events using XInput2 extension\n";
+ }
+
+ XIEventMask event_mask;
+ unsigned char mask[] = {0};
+
+ event_mask.deviceid = XIAllMasterDevices;
+ event_mask.mask_len = sizeof(mask);
+ event_mask.mask = mask;
+
+ _XISelectEvents(_display, _root, &event_mask, 1);
+ }
+}
+
/**
* Returns an XRRScreenResources object, or null if RandR 1.2 is not supported.
*/
diff --git a/panda/src/x11display/x11GraphicsPipe.h b/panda/src/x11display/x11GraphicsPipe.h
index e1abf80b00..260ec941d6 100644
--- a/panda/src/x11display/x11GraphicsPipe.h
+++ b/panda/src/x11display/x11GraphicsPipe.h
@@ -87,6 +87,45 @@ typedef struct _XRRCrtcInfo {
typedef void (*pfn_XRRFreeScreenResources)(XRRScreenResources *resources);
typedef void (*pfn_XRRFreeCrtcInfo)(XRRCrtcInfo *crtcInfo);
+typedef struct {
+ int deviceid;
+ int mask_len;
+ unsigned char *mask;
+} XIEventMask;
+
+typedef struct {
+ int mask_len;
+ unsigned char *mask;
+ double *values;
+} XIValuatorState;
+
+typedef struct {
+ int type;
+ unsigned long serial;
+ Bool send_event;
+ X11_Display *display;
+ int extension;
+ int evtype;
+ Time time;
+ int deviceid;
+ int sourceid;
+ int detail;
+ int flags;
+ XIValuatorState valuators;
+ double *raw_values;
+} XIRawEvent;
+
+#define XI_RawMotion 17
+#define XI_RawMotionMask (1 << XI_RawMotion)
+
+#define XISetMask(ptr, event) (((unsigned char*)(ptr))[(event)>>3] |= (1 << ((event) & 7)))
+#define XIClearMask(ptr, event) (((unsigned char*)(ptr))[(event)>>3] &= ~(1 << ((event) & 7)))
+#define XIMaskIsSet(ptr, event) (((unsigned char*)(ptr))[(event)>>3] & (1 << ((event) & 7)))
+#define XIMaskLen(event) (((event) >> 3) + 1)
+
+#define XIAllDevices 0
+#define XIAllMasterDevices 1
+
class FrameBufferProperties;
/**
@@ -106,8 +145,10 @@ public:
INLINE X11_Cursor get_hidden_cursor();
INLINE bool supports_relative_mouse() const;
- INLINE bool enable_relative_mouse();
- INLINE void disable_relative_mouse();
+ INLINE bool enable_dga_mouse();
+ INLINE void disable_dga_mouse();
+ INLINE bool enable_raw_mouse();
+ INLINE void disable_raw_mouse();
static INLINE int disable_x_error_messages();
static INLINE int enable_x_error_messages();
@@ -170,6 +211,8 @@ public:
pfn_XRRConfigCurrentConfiguration _XRRConfigCurrentConfiguration;
pfn_XRRSetScreenConfig _XRRSetScreenConfig;
+ int _xi_opcode;
+
protected:
X11_Display *_display;
int _screen;
@@ -190,6 +233,11 @@ protected:
pfn_XRRGetCrtcInfo _XRRGetCrtcInfo;
pfn_XRRFreeCrtcInfo _XRRFreeCrtcInfo;
+ typedef Status (*pfn_XIQueryVersion)(X11_Display *, int*, int*);
+ typedef Status (*pfn_XISelectEvents)(X11_Display *, X11_Window, XIEventMask *, int);
+ pfn_XISelectEvents _XISelectEvents = nullptr;
+ int _num_raw_mouse_windows = 0;
+
private:
void make_hidden_cursor();
void release_hidden_cursor();
diff --git a/panda/src/x11display/x11GraphicsWindow.cxx b/panda/src/x11display/x11GraphicsWindow.cxx
index de58cd1028..c7d3455164 100644
--- a/panda/src/x11display/x11GraphicsWindow.cxx
+++ b/panda/src/x11display/x11GraphicsWindow.cxx
@@ -117,6 +117,7 @@ x11GraphicsWindow(GraphicsEngine *engine, GraphicsPipe *pipe,
_awaiting_configure = false;
_dga_mouse_enabled = false;
+ _raw_mouse_enabled = false;
_override_redirect = False;
_wm_delete_window = x11_pipe->_wm_delete_window;
@@ -154,8 +155,8 @@ get_pointer(int device) const {
// We recheck this immediately to get the most up-to-date value, but we
// won't bother waiting for the lock if we can't.
- if (device == 0 && !_dga_mouse_enabled && result._in_window &&
- x11GraphicsPipe::_x_mutex.try_lock()) {
+ if (device == 0 && !_dga_mouse_enabled && !_raw_mouse_enabled &&
+ result._in_window && x11GraphicsPipe::_x_mutex.try_lock()) {
XEvent event;
if (_xwindow != None &&
XQueryPointer(_display, _xwindow, &event.xbutton.root,
@@ -355,7 +356,7 @@ process_events() {
case ButtonPress:
// This refers to the mouse buttons.
button = get_mouse_button(event.xbutton);
- if (!_dga_mouse_enabled) {
+ if (_properties.get_mouse_mode() != WindowProperties::M_relative) {
_input->set_pointer_in_window(event.xbutton.x, event.xbutton.y);
}
_input->button_down(button);
@@ -363,18 +364,49 @@ process_events() {
case ButtonRelease:
button = get_mouse_button(event.xbutton);
- if (!_dga_mouse_enabled) {
+ if (_properties.get_mouse_mode() != WindowProperties::M_relative) {
_input->set_pointer_in_window(event.xbutton.x, event.xbutton.y);
}
_input->button_up(button);
break;
case MotionNotify:
- if (_dga_mouse_enabled) {
- PointerData md = _input->get_pointer();
- _input->set_pointer_in_window(md.get_x() + event.xmotion.x_root, md.get_y() + event.xmotion.y_root);
- } else {
- _input->set_pointer_in_window(event.xmotion.x, event.xmotion.y);
+ if (!_raw_mouse_enabled) {
+ if (_dga_mouse_enabled) {
+ PointerData md = _input->get_pointer();
+ _input->set_pointer_in_window(md.get_x() + event.xmotion.x_root, md.get_y() + event.xmotion.y_root);
+ } else {
+ _input->set_pointer_in_window(event.xmotion.x, event.xmotion.y);
+ }
+ }
+ break;
+
+ case GenericEvent:
+ if (_raw_mouse_enabled) {
+ XGenericEventCookie *cookie = &event.xcookie;
+ XGetEventData(_display, cookie);
+
+ x11GraphicsPipe *x11_pipe;
+ DCAST_INTO_V(x11_pipe, _pipe);
+
+ if (cookie->evtype == XI_RawMotion &&
+ cookie->extension == x11_pipe->_xi_opcode) {
+ const XIRawEvent *raw_event = (const XIRawEvent *)cookie->data;
+ const double *values = raw_event->raw_values;
+
+ double x = 0, y = 0;
+ if (XIMaskIsSet(raw_event->valuators.mask, 0)) {
+ x = values[0];
+ }
+ if (XIMaskIsSet(raw_event->valuators.mask, 1)) {
+ y = values[1];
+ }
+
+ PointerData md = _input->get_pointer();
+ _input->set_pointer_in_window(md.get_x() + x, md.get_y() + y);
+ }
+
+ XFreeEventData(_display, cookie);
}
break;
@@ -392,7 +424,7 @@ process_events() {
break;
case EnterNotify:
- if (_dga_mouse_enabled) {
+ if (_properties.get_mouse_mode() == WindowProperties::M_relative) {
PointerData md = _input->get_pointer();
_input->set_pointer_in_window(md.get_x(), md.get_y());
} else {
@@ -508,9 +540,8 @@ process_events() {
changed_properties = true;
}
- if (properties.has_foreground() && (
- _properties.get_mouse_mode() == WindowProperties::M_confined ||
- _dga_mouse_enabled)) {
+ if (properties.has_foreground() &&
+ (_properties.get_mouse_mode() != WindowProperties::M_absolute)) {
x11GraphicsPipe *x11_pipe;
DCAST_INTO_V(x11_pipe, _pipe);
@@ -525,13 +556,13 @@ process_events() {
XGrabPointer(_display, _xwindow, True, 0, GrabModeAsync, GrabModeAsync,
_xwindow, cursor, CurrentTime);
if (_dga_mouse_enabled) {
- x11_pipe->enable_relative_mouse();
+ x11_pipe->enable_dga_mouse();
}
}
else {
// window is leaving the foreground, ungrab the pointer
if (_dga_mouse_enabled) {
- x11_pipe->disable_relative_mouse();
+ x11_pipe->disable_dga_mouse();
} else if (_properties.get_mouse_mode() == WindowProperties::M_confined) {
XUngrabPointer(_display, CurrentTime);
}
@@ -850,9 +881,13 @@ set_properties_now(WindowProperties &properties) {
case WindowProperties::M_absolute:
XUngrabPointer(_display, CurrentTime);
if (_dga_mouse_enabled) {
- x11_pipe->disable_relative_mouse();
+ x11_pipe->disable_dga_mouse();
_dga_mouse_enabled = false;
}
+ if (_raw_mouse_enabled) {
+ x11_pipe->disable_raw_mouse();
+ _raw_mouse_enabled = false;
+ }
_properties.set_mouse_mode(WindowProperties::M_absolute);
properties.clear_mouse_mode();
break;
@@ -871,13 +906,16 @@ set_properties_now(WindowProperties &properties) {
GrabModeAsync, _xwindow, cursor, CurrentTime) != GrabSuccess) {
x11display_cat.error() << "Failed to grab pointer!\n";
} else {
- x11_pipe->enable_relative_mouse();
+ if (x11_pipe->enable_dga_mouse()) {
+ _dga_mouse_enabled = true;
+ } else {
+ _raw_mouse_enabled = _raw_mouse_enabled || x11_pipe->enable_raw_mouse();
+ }
_properties.set_mouse_mode(WindowProperties::M_relative);
properties.clear_mouse_mode();
- _dga_mouse_enabled = true;
- // Get the real mouse position, so we can addsubtract our relative
+ // Get the real mouse position, so we can add/subtract our relative
// coordinates later.
XEvent event;
XQueryPointer(_display, _xwindow, &event.xbutton.root,
@@ -885,10 +923,6 @@ set_properties_now(WindowProperties &properties) {
&event.xbutton.x, &event.xbutton.y, &event.xbutton.state);
_input->set_pointer_in_window(event.xbutton.x, event.xbutton.y);
}
- } else {
- x11display_cat.warning()
- << "XF86DGA extension not available, cannot enable relative mouse mode\n";
- _dga_mouse_enabled = false;
}
}
break;
@@ -899,9 +933,13 @@ set_properties_now(WindowProperties &properties) {
DCAST_INTO_V(x11_pipe, _pipe);
if (_dga_mouse_enabled) {
- x11_pipe->disable_relative_mouse();
+ x11_pipe->disable_dga_mouse();
_dga_mouse_enabled = false;
}
+ if (_raw_mouse_enabled) {
+ x11_pipe->disable_raw_mouse();
+ _raw_mouse_enabled = false;
+ }
X11_Cursor cursor = None;
if (_properties.get_cursor_hidden()) {
cursor = x11_pipe->get_hidden_cursor();
@@ -1436,7 +1474,7 @@ open_raw_mice() {
*/
void x11GraphicsWindow::
handle_keystroke(XKeyEvent &event) {
- if (!_dga_mouse_enabled) {
+ if (_properties.get_mouse_mode() != WindowProperties::M_relative) {
_input->set_pointer_in_window(event.x, event.y);
}
@@ -1471,7 +1509,7 @@ handle_keystroke(XKeyEvent &event) {
*/
void x11GraphicsWindow::
handle_keypress(XKeyEvent &event) {
- if (!_dga_mouse_enabled) {
+ if (_properties.get_mouse_mode() != WindowProperties::M_relative) {
_input->set_pointer_in_window(event.x, event.y);
}
@@ -1506,7 +1544,7 @@ handle_keypress(XKeyEvent &event) {
*/
void x11GraphicsWindow::
handle_keyrelease(XKeyEvent &event) {
- if (!_dga_mouse_enabled) {
+ if (_properties.get_mouse_mode() != WindowProperties::M_relative) {
_input->set_pointer_in_window(event.x, event.y);
}
@@ -2000,6 +2038,13 @@ get_keyboard_map() const {
LightReMutexHolder holder(x11GraphicsPipe::_x_mutex);
for (int k = 9; k <= 135; ++k) {
+ if (k >= 78 && k <= 91) {
+ // Ignore numpad keys for now. These are not mapped to separate button
+ // handles in Panda, so we don't want their mappings to conflict with
+ // the regular numeric keys.
+ continue;
+ }
+
ButtonHandle raw_button = map_raw_button(k);
if (raw_button == ButtonHandle::none()) {
continue;
@@ -2007,11 +2052,31 @@ get_keyboard_map() const {
KeySym sym = XkbKeycodeToKeysym(_display, k, 0, 0);
ButtonHandle button = map_button(sym);
- if (button == ButtonHandle::none()) {
+ std::string label;
+
+ // Compose a label for some keys; I have not yet been able to find an API
+ // that does this effectively.
+ if (sym >= XK_a && sym <= XK_z) {
+ label = toupper((char)sym);
+ }
+ else if (sym >= XK_F1 && sym <= XK_F35) {
+ label = "F" + format_string(sym - XK_F1 + 1);
+ }
+ else if (sym >= XK_exclamdown && sym <= XK_ydiaeresis) {
+ // A latin-1 symbol. Translate this to the label.
+ char buffer[255];
+ int nbytes = XkbTranslateKeySym(_display, &sym, 0, buffer, 255, 0);
+ if (nbytes > 0) {
+ label.assign(buffer, nbytes);
+ }
+ }
+
+ if (button == ButtonHandle::none() && label.empty()) {
+ // No label and no mapping; this is useless.
continue;
}
- map->map_button(raw_button, button);
+ map->map_button(raw_button, button, label);
}
return map;
@@ -2025,8 +2090,10 @@ Bool x11GraphicsWindow::
check_event(X11_Display *display, XEvent *event, char *arg) {
const x11GraphicsWindow *self = (x11GraphicsWindow *)arg;
- // We accept any event that is sent to our window.
- return (event->xany.window == self->_xwindow);
+ // We accept any event that is sent to our window. However, we have to let
+ // raw mouse events through, since they're not associated with any window.
+ return (event->xany.window == self->_xwindow ||
+ (event->type == GenericEvent && self->_raw_mouse_enabled));
}
/**
diff --git a/panda/src/x11display/x11GraphicsWindow.h b/panda/src/x11display/x11GraphicsWindow.h
index f512b16a19..e3d4a86382 100644
--- a/panda/src/x11display/x11GraphicsWindow.h
+++ b/panda/src/x11display/x11GraphicsWindow.h
@@ -92,6 +92,7 @@ protected:
long _event_mask;
bool _awaiting_configure;
bool _dga_mouse_enabled;
+ bool _raw_mouse_enabled;
Bool _override_redirect;
Atom _wm_delete_window;
diff --git a/pandatool/CMakeLists.txt b/pandatool/CMakeLists.txt
new file mode 100644
index 0000000000..8f26fb2d9a
--- /dev/null
+++ b/pandatool/CMakeLists.txt
@@ -0,0 +1,48 @@
+if(NOT BUILD_PANDA)
+ message(FATAL_ERROR "Cannot build pandatool without panda! Please enable the BUILD_PANDA option.")
+endif()
+
+# Include pandatool source directories
+add_subdirectory(src/assimp)
+add_subdirectory(src/bam)
+add_subdirectory(src/converter)
+add_subdirectory(src/daeegg)
+add_subdirectory(src/daeprogs)
+add_subdirectory(src/dxf)
+add_subdirectory(src/dxfegg)
+add_subdirectory(src/dxfprogs)
+add_subdirectory(src/eggbase)
+add_subdirectory(src/eggcharbase)
+add_subdirectory(src/eggprogs)
+add_subdirectory(src/egg-mkfont)
+add_subdirectory(src/egg-optchar)
+add_subdirectory(src/egg-palettize)
+add_subdirectory(src/egg-qtess)
+add_subdirectory(src/flt)
+add_subdirectory(src/fltegg)
+add_subdirectory(src/fltprogs)
+add_subdirectory(src/gtk-stats)
+add_subdirectory(src/imagebase)
+add_subdirectory(src/imageprogs)
+add_subdirectory(src/lwo)
+add_subdirectory(src/lwoegg)
+add_subdirectory(src/lwoprogs)
+add_subdirectory(src/miscprogs)
+add_subdirectory(src/objegg)
+add_subdirectory(src/objprogs)
+add_subdirectory(src/palettizer)
+add_subdirectory(src/pandatoolbase)
+add_subdirectory(src/pfmprogs)
+add_subdirectory(src/progbase)
+add_subdirectory(src/pstatserver)
+add_subdirectory(src/ptloader)
+add_subdirectory(src/text-stats)
+add_subdirectory(src/vrml)
+add_subdirectory(src/vrmlegg)
+add_subdirectory(src/vrmlprogs)
+add_subdirectory(src/win-stats)
+add_subdirectory(src/xfile)
+add_subdirectory(src/xfileegg)
+add_subdirectory(src/xfileprogs)
+
+export_targets(Tools)
diff --git a/pandatool/src/assimp/CMakeLists.txt b/pandatool/src/assimp/CMakeLists.txt
new file mode 100644
index 0000000000..536d15ec39
--- /dev/null
+++ b/pandatool/src/assimp/CMakeLists.txt
@@ -0,0 +1,33 @@
+if(NOT HAVE_ASSIMP)
+ return()
+endif()
+
+set(P3ASSIMP_HEADERS
+ assimpLoader.h assimpLoader.I
+ config_assimp.h
+ loaderFileTypeAssimp.h
+ pandaIOStream.h
+ pandaIOSystem.h
+ pandaLogger.h
+)
+
+set(P3ASSIMP_SOURCES
+ assimpLoader.cxx
+ config_assimp.cxx
+ loaderFileTypeAssimp.cxx
+ pandaIOStream.cxx
+ pandaIOSystem.cxx
+ pandaLogger.cxx
+)
+
+composite_sources(p3assimp P3ASSIMP_SOURCES)
+add_library(p3assimp ${MODULE_TYPE} ${P3ASSIMP_HEADERS} ${P3ASSIMP_SOURCES})
+set_target_properties(p3assimp PROPERTIES DEFINE_SYMBOL BUILDING_ASSIMP)
+target_link_libraries(p3assimp PRIVATE p3pandatoolbase)
+target_link_libraries(p3assimp PUBLIC PKG::ASSIMP)
+
+if(BUILD_SHARED_LIBS)
+ # We can't install this if we're doing a static build, because it depends on
+ # a static library that isn't installed.
+ install(TARGETS p3assimp EXPORT Assimp COMPONENT Assimp DESTINATION ${MODULE_DESTINATION})
+endif()
diff --git a/pandatool/src/bam/CMakeLists.txt b/pandatool/src/bam/CMakeLists.txt
new file mode 100644
index 0000000000..79389b92ff
--- /dev/null
+++ b/pandatool/src/bam/CMakeLists.txt
@@ -0,0 +1,23 @@
+add_executable(bam-info bamInfo.cxx bamInfo.h)
+target_link_libraries(bam-info p3progbase panda)
+install(TARGETS bam-info EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+if(HAVE_EGG)
+
+ add_executable(egg2bam eggToBam.cxx eggToBam.h)
+ target_link_libraries(egg2bam p3eggbase p3progbase panda)
+ install(TARGETS egg2bam EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+ if(HAVE_SQUISH)
+ target_compile_definitions(egg2bam PRIVATE HAVE_SQUISH)
+ endif()
+
+ add_executable(bam2egg bamToEgg.cxx bamToEgg.h)
+ target_link_libraries(bam2egg p3converter p3eggbase p3progbase panda)
+ install(TARGETS bam2egg EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+ add_executable(pts2bam ptsToBam.cxx ptsToBam.h)
+ target_link_libraries(pts2bam p3progbase pandaegg panda)
+ install(TARGETS pts2bam EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+endif()
diff --git a/pandatool/src/converter/CMakeLists.txt b/pandatool/src/converter/CMakeLists.txt
new file mode 100644
index 0000000000..2e75fed9f2
--- /dev/null
+++ b/pandatool/src/converter/CMakeLists.txt
@@ -0,0 +1,18 @@
+if(NOT HAVE_EGG)
+ return()
+endif()
+
+set(P3CONVERTER_HEADERS
+ somethingToEggConverter.h somethingToEggConverter.I
+ eggToSomethingConverter.h eggToSomethingConverter.I
+)
+
+set(P3CONVERTER_SOURCES
+ somethingToEggConverter.cxx eggToSomethingConverter.cxx
+)
+
+add_library(p3converter STATIC ${P3CONVERTER_HEADERS} ${P3CONVERTER_SOURCES})
+target_link_libraries(p3converter p3pandatoolbase pandaegg)
+
+# This is only needed for binaries in the pandatool package. It is not useful
+# for user applications, so it is not installed.
diff --git a/pandatool/src/daeegg/CMakeLists.txt b/pandatool/src/daeegg/CMakeLists.txt
new file mode 100644
index 0000000000..07b6320d14
--- /dev/null
+++ b/pandatool/src/daeegg/CMakeLists.txt
@@ -0,0 +1,26 @@
+if(NOT HAVE_EGG OR NOT HAVE_FCOLLADA)
+ return()
+endif()
+
+set(P3DAEEGG_HEADERS
+ config_daeegg.h
+ daeCharacter.h
+ daeMaterials.h
+ daeToEggConverter.h
+ fcollada_utils.h
+ pre_fcollada_include.h
+)
+
+set(P3DAEEGG_SOURCES
+ config_daeegg.cxx
+ daeCharacter.cxx
+ daeMaterials.cxx
+ daeToEggConverter.cxx
+)
+
+add_library(p3daeegg STATIC ${P3DAEEGG_HEADERS} ${P3DAEEGG_SOURCES})
+target_link_libraries(p3daeegg p3eggbase
+ PKG::FCOLLADA)
+
+# This is only needed for binaries in the pandatool package. It is not useful
+# for user applications, so it is not installed.
diff --git a/pandatool/src/daeprogs/CMakeLists.txt b/pandatool/src/daeprogs/CMakeLists.txt
new file mode 100644
index 0000000000..67ffc386c4
--- /dev/null
+++ b/pandatool/src/daeprogs/CMakeLists.txt
@@ -0,0 +1,11 @@
+if(HAVE_EGG AND HAVE_FCOLLADA)
+
+ add_executable(egg2dae eggToDAE.cxx eggToDAE.h)
+ target_link_libraries(egg2dae p3daeegg p3eggbase p3progbase)
+ install(TARGETS egg2dae EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+ add_executable(dae2egg daeToEgg.cxx daeToEgg.h)
+ target_link_libraries(dae2egg p3daeegg p3eggbase p3progbase)
+ install(TARGETS dae2egg EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+endif()
diff --git a/pandatool/src/dxf/CMakeLists.txt b/pandatool/src/dxf/CMakeLists.txt
new file mode 100644
index 0000000000..c8095a327f
--- /dev/null
+++ b/pandatool/src/dxf/CMakeLists.txt
@@ -0,0 +1,20 @@
+set(P3DXF_HEADERS
+ dxfFile.h
+ dxfLayer.h
+ dxfLayerMap.h
+ dxfVertex.h
+)
+
+set(P3DXF_SOURCES
+ dxfFile.cxx
+ dxfLayer.cxx
+ dxfLayerMap.cxx
+ dxfVertex.cxx
+)
+
+composite_sources(p3dxf P3DXF_SOURCES)
+add_library(p3dxf STATIC ${P3DXF_HEADERS} ${P3DXF_SOURCES})
+target_link_libraries(p3dxf p3pandatoolbase)
+
+# This is only needed for binaries in the pandatool package. It is not useful
+# for user applications, so it is not installed.
diff --git a/pandatool/src/dxfegg/CMakeLists.txt b/pandatool/src/dxfegg/CMakeLists.txt
new file mode 100644
index 0000000000..74684b1c1f
--- /dev/null
+++ b/pandatool/src/dxfegg/CMakeLists.txt
@@ -0,0 +1,19 @@
+if(NOT HAVE_EGG)
+ return()
+endif()
+
+set(P3DXFEGG_HEADERS
+ dxfToEggConverter.h
+ dxfToEggLayer.h
+)
+
+set(P3DXFEGG_SOURCES
+ dxfToEggConverter.cxx
+ dxfToEggLayer.cxx
+)
+
+add_library(p3dxfegg STATIC ${P3DXFEGG_HEADERS} ${P3DXFEGG_SOURCES})
+target_link_libraries(p3dxfegg p3dxf p3eggbase)
+
+# This is only needed for binaries in the pandatool package. It is not useful
+# for user applications, so it is not installed.
diff --git a/pandatool/src/dxfprogs/CMakeLists.txt b/pandatool/src/dxfprogs/CMakeLists.txt
new file mode 100644
index 0000000000..3cd39a0baa
--- /dev/null
+++ b/pandatool/src/dxfprogs/CMakeLists.txt
@@ -0,0 +1,15 @@
+add_executable(dxf-points dxfPoints.cxx dxfPoints.h)
+target_link_libraries(dxf-points p3progbase p3dxf)
+install(TARGETS dxf-points EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+if(HAVE_EGG)
+
+ add_executable(egg2dxf eggToDXF.cxx eggToDXF.h eggToDXFLayer.cxx eggToDXFLayer.h)
+ target_link_libraries(egg2dxf p3dxfegg p3eggbase p3progbase)
+ install(TARGETS egg2dxf EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+ add_executable(dxf2egg dxfToEgg.cxx dxfToEgg.h)
+ target_link_libraries(dxf2egg p3dxfegg p3eggbase p3progbase)
+ install(TARGETS dxf2egg EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+endif()
diff --git a/pandatool/src/egg-mkfont/CMakeLists.txt b/pandatool/src/egg-mkfont/CMakeLists.txt
new file mode 100644
index 0000000000..8b548e2e91
--- /dev/null
+++ b/pandatool/src/egg-mkfont/CMakeLists.txt
@@ -0,0 +1,21 @@
+if(NOT HAVE_EGG OR NOT HAVE_FREETYPE)
+ return()
+endif()
+
+set(P3EGG_MKFONT_HEADERS
+ eggMakeFont.h
+ rangeDescription.h rangeDescription.I
+ rangeIterator.h rangeIterator.I
+)
+
+set(P3EGG_MKFONT_SOURCES
+ eggMakeFont.cxx
+ rangeDescription.cxx
+ rangeIterator.cxx
+)
+
+composite_sources(egg-mkfont P3EGG_MKFONT_SOURCES)
+add_executable(egg-mkfont ${P3EGG_MKFONT_HEADERS} ${P3EGG_MKFONT_SOURCES})
+target_link_libraries(egg-mkfont p3palettizer p3eggbase p3pandatoolbase)
+
+install(TARGETS egg-mkfont EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
diff --git a/pandatool/src/egg-optchar/CMakeLists.txt b/pandatool/src/egg-optchar/CMakeLists.txt
new file mode 100644
index 0000000000..b30a070224
--- /dev/null
+++ b/pandatool/src/egg-optchar/CMakeLists.txt
@@ -0,0 +1,23 @@
+if(NOT HAVE_EGG)
+ return()
+endif()
+
+set(P3EGG_OPTCHAR_HEADERS
+ config_egg_optchar.h
+ eggOptchar.h
+ eggOptcharUserData.h eggOptcharUserData.I
+ vertexMembership.h vertexMembership.I
+)
+
+set(P3EGG_OPTCHAR_SOURCES
+ config_egg_optchar.cxx
+ eggOptchar.cxx
+ eggOptcharUserData.cxx
+ vertexMembership.cxx
+)
+
+composite_sources(egg-optchar P3EGG_OPTCHAR_SOURCES)
+add_executable(egg-optchar ${P3EGG_OPTCHAR_HEADERS} ${P3EGG_OPTCHAR_SOURCES})
+target_link_libraries(egg-optchar p3eggcharbase)
+
+install(TARGETS egg-optchar EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
diff --git a/pandatool/src/egg-palettize/CMakeLists.txt b/pandatool/src/egg-palettize/CMakeLists.txt
new file mode 100644
index 0000000000..18576f25d6
--- /dev/null
+++ b/pandatool/src/egg-palettize/CMakeLists.txt
@@ -0,0 +1,16 @@
+if(NOT HAVE_EGG)
+ return()
+endif()
+
+add_executable(egg-palettize eggPalettize.cxx eggPalettize.h)
+target_link_libraries(egg-palettize p3palettizer p3eggbase p3progbase)
+install(TARGETS egg-palettize EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+add_library(p3txafile txaFileFilter.cxx txaFileFilter.h txaFileFilter.I)
+set_target_properties(p3txafile PROPERTIES DEFINE_SYMBOL BUILDING_MISC)
+target_link_libraries(p3txafile PRIVATE p3palettizer)
+if(BUILD_SHARED_LIBS)
+ # We can't install this if we're doing a static build, because it depends on
+ # a static library that isn't installed.
+ install(TARGETS p3txafile EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
+endif()
diff --git a/pandatool/src/egg-qtess/CMakeLists.txt b/pandatool/src/egg-qtess/CMakeLists.txt
new file mode 100644
index 0000000000..c8f4244c8a
--- /dev/null
+++ b/pandatool/src/egg-qtess/CMakeLists.txt
@@ -0,0 +1,31 @@
+if(NOT HAVE_EGG)
+ return()
+endif()
+
+set(P3EGG_QTESS_HEADERS
+ config_egg_qtess.h
+ eggQtess.h
+ isoPlacer.h isoPlacer.I
+ qtessGlobals.h
+ qtessInputEntry.h qtessInputEntry.I
+ qtessInputFile.h qtessInputFile.I
+ qtessSurface.h qtessSurface.I
+ subdivSegment.h subdivSegment.I
+)
+
+set(P3EGG_QTESS_SOURCES
+ config_egg_qtess.cxx
+ eggQtess.cxx
+ isoPlacer.cxx
+ qtessGlobals.cxx
+ qtessInputEntry.cxx
+ qtessInputFile.cxx
+ qtessSurface.cxx
+ subdivSegment.cxx
+)
+
+composite_sources(egg-qtess P3EGG_QTESS_SOURCES)
+add_executable(egg-qtess ${P3EGG_QTESS_HEADERS} ${P3EGG_QTESS_SOURCES})
+target_link_libraries(egg-qtess p3eggbase)
+
+install(TARGETS egg-qtess EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
diff --git a/pandatool/src/eggbase/CMakeLists.txt b/pandatool/src/eggbase/CMakeLists.txt
new file mode 100644
index 0000000000..115ac0882c
--- /dev/null
+++ b/pandatool/src/eggbase/CMakeLists.txt
@@ -0,0 +1,28 @@
+if(NOT HAVE_EGG)
+ return()
+endif()
+
+set(P3EGGBASE_HEADERS
+ eggBase.h eggConverter.h eggFilter.h
+ eggMakeSomething.h
+ eggMultiBase.h eggMultiFilter.h
+ eggReader.h eggSingleBase.h
+ eggToSomething.h eggWriter.h
+ somethingToEgg.h
+)
+
+set(P3EGGBASE_SOURCES
+ eggBase.cxx eggConverter.cxx eggFilter.cxx
+ eggMakeSomething.cxx
+ eggMultiBase.cxx
+ eggMultiFilter.cxx eggReader.cxx eggSingleBase.cxx
+ eggToSomething.cxx
+ eggWriter.cxx somethingToEgg.cxx
+)
+
+composite_sources(p3eggbase P3EGGBASE_SOURCES)
+add_library(p3eggbase STATIC ${P3EGGBASE_HEADERS} ${P3EGGBASE_SOURCES})
+target_link_libraries(p3eggbase p3progbase p3converter)
+
+# This is only needed for binaries in the pandatool package. It is not useful
+# for user applications, so it is not installed.
diff --git a/pandatool/src/eggcharbase/CMakeLists.txt b/pandatool/src/eggcharbase/CMakeLists.txt
new file mode 100644
index 0000000000..384bebe032
--- /dev/null
+++ b/pandatool/src/eggcharbase/CMakeLists.txt
@@ -0,0 +1,46 @@
+if(NOT HAVE_EGG)
+ return()
+endif()
+
+set(P3EGGCHARBASE_HEADERS
+ config_eggcharbase.h
+ eggBackPointer.h
+ eggCharacterCollection.h eggCharacterCollection.I
+ eggCharacterData.h eggCharacterData.I
+ eggCharacterDb.h eggCharacterDb.I
+ eggCharacterFilter.h
+ eggComponentData.h eggComponentData.I
+ eggJointData.h eggJointData.I
+ eggJointNodePointer.h
+ eggJointPointer.h eggJointPointer.I
+ eggMatrixTablePointer.h
+ eggScalarTablePointer.h
+ eggSliderData.h eggSliderData.I
+ eggSliderPointer.h
+ eggVertexPointer.h
+)
+
+set(P3EGGCHARBASE_SOURCES
+ config_eggcharbase.cxx
+ eggBackPointer.cxx
+ eggCharacterCollection.cxx
+ eggCharacterData.cxx
+ eggCharacterDb.cxx
+ eggCharacterFilter.cxx
+ eggComponentData.cxx
+ eggJointData.cxx
+ eggJointNodePointer.cxx
+ eggJointPointer.cxx
+ eggMatrixTablePointer.cxx
+ eggScalarTablePointer.cxx
+ eggSliderData.cxx
+ eggSliderPointer.cxx
+ eggVertexPointer.cxx
+)
+
+composite_sources(p3eggcharbase P3EGGCHARBASE_SOURCES)
+add_library(p3eggcharbase STATIC ${P3EGGCHARBASE_HEADERS} ${P3EGGCHARBASE_SOURCES})
+target_link_libraries(p3eggcharbase p3eggbase)
+
+# This is only needed for binaries in the pandatool package. It is not useful
+# for user applications, so it is not installed.
diff --git a/pandatool/src/eggprogs/CMakeLists.txt b/pandatool/src/eggprogs/CMakeLists.txt
new file mode 100644
index 0000000000..a14d33ab80
--- /dev/null
+++ b/pandatool/src/eggprogs/CMakeLists.txt
@@ -0,0 +1,39 @@
+if(NOT HAVE_EGG)
+ return()
+endif()
+
+add_executable(egg-crop eggCrop.cxx eggCrop.h)
+target_link_libraries(egg-crop p3eggbase)
+install(TARGETS egg-crop EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+add_executable(egg-list-textures eggListTextures.cxx eggListTextures.h)
+target_link_libraries(egg-list-textures p3eggbase)
+install(TARGETS egg-list-textures EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+add_executable(egg-make-tube eggMakeTube.cxx eggMakeTube.h)
+target_link_libraries(egg-make-tube p3eggbase)
+install(TARGETS egg-make-tube EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+add_executable(egg-rename eggRename.cxx eggRename.h)
+target_link_libraries(egg-rename p3eggbase)
+install(TARGETS egg-rename EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+add_executable(egg-retarget-anim eggRetargetAnim.cxx eggRetargetAnim.h)
+target_link_libraries(egg-retarget-anim p3eggcharbase)
+install(TARGETS egg-retarget-anim EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+add_executable(egg-texture-cards eggTextureCards.cxx eggTextureCards.h)
+target_link_libraries(egg-texture-cards p3eggbase)
+install(TARGETS egg-texture-cards EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+add_executable(egg2c eggToC.cxx eggToC.h)
+target_link_libraries(egg2c p3eggbase)
+install(TARGETS egg2c EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+add_executable(egg-topstrip eggTopstrip.cxx eggTopstrip.h)
+target_link_libraries(egg-topstrip p3eggcharbase)
+install(TARGETS egg-topstrip EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+add_executable(egg-trans eggTrans.cxx eggTrans.h)
+target_link_libraries(egg-trans p3eggbase)
+install(TARGETS egg-trans EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
diff --git a/pandatool/src/flt/CMakeLists.txt b/pandatool/src/flt/CMakeLists.txt
new file mode 100644
index 0000000000..02f096b81b
--- /dev/null
+++ b/pandatool/src/flt/CMakeLists.txt
@@ -0,0 +1,90 @@
+set(P3FLT_HEADERS
+ config_flt.h
+ fltBead.h
+ fltBeadID.h
+ fltCurve.h fltCurve.I
+ fltError.h
+ fltExternalReference.h
+ fltEyepoint.h
+ fltFace.h fltFace.I
+ fltGeometry.h fltGeometry.I
+ fltGroup.h
+ fltHeader.h
+ fltInstanceDefinition.h
+ fltInstanceRef.h
+ fltLightSourceDefinition.h
+ fltLocalVertexPool.h fltLocalVertexPool.I
+ fltLOD.h
+ fltMaterial.h
+ fltMesh.h fltMesh.I
+ fltMeshPrimitive.h fltMeshPrimitive.I
+ fltObject.h
+ fltOpcode.h
+ fltPackedColor.h fltPackedColor.I
+ fltRecord.h fltRecord.I
+ fltRecordReader.h
+ fltRecordWriter.h
+ fltTexture.h
+ fltTrackplane.h
+ fltTransformGeneralMatrix.h
+ fltTransformPut.h
+ fltTransformRecord.h
+ fltTransformRotateAboutEdge.h
+ fltTransformRotateAboutPoint.h
+ fltTransformRotateScale.h
+ fltTransformScale.h
+ fltTransformTranslate.h
+ fltUnsupportedRecord.h
+ fltVectorRecord.h
+ fltVertex.h fltVertex.I
+ fltVertexList.h
+)
+
+set(P3FLT_SOURCES
+ config_flt.cxx
+ fltBead.cxx
+ fltBeadID.cxx
+ fltCurve.cxx
+ fltError.cxx
+ fltExternalReference.cxx
+ fltEyepoint.cxx
+ fltFace.cxx
+ fltGeometry.cxx
+ fltGroup.cxx
+ fltHeader.cxx
+ fltInstanceDefinition.cxx
+ fltInstanceRef.cxx
+ fltLightSourceDefinition.cxx
+ fltLocalVertexPool.cxx
+ fltLOD.cxx
+ fltMaterial.cxx
+ fltMesh.cxx
+ fltMeshPrimitive.cxx
+ fltObject.cxx
+ fltOpcode.cxx
+ fltPackedColor.cxx
+ fltRecord.cxx
+ fltRecordReader.cxx
+ fltRecordWriter.cxx
+ fltTexture.cxx
+ fltTrackplane.cxx
+ fltTransformGeneralMatrix.cxx
+ fltTransformPut.cxx
+ fltTransformRecord.cxx
+ fltTransformRotateAboutEdge.cxx
+ fltTransformRotateAboutPoint.cxx
+ fltTransformRotateScale.cxx
+ fltTransformScale.cxx
+ fltTransformTranslate.cxx
+ fltUnsupportedRecord.cxx
+ fltVectorRecord.cxx
+ fltVertex.cxx
+ fltVertexList.cxx
+)
+
+composite_sources(p3flt P3FLT_SOURCES)
+add_library(p3flt STATIC ${P3FLT_HEADERS} ${P3FLT_SOURCES})
+target_link_libraries(p3flt p3pandatoolbase panda)
+
+# This is only needed for binaries in the pandatool package. It is not useful
+# for user applications, so it is not installed.
diff --git a/pandatool/src/fltegg/CMakeLists.txt b/pandatool/src/fltegg/CMakeLists.txt
new file mode 100644
index 0000000000..5a61e47ace
--- /dev/null
+++ b/pandatool/src/fltegg/CMakeLists.txt
@@ -0,0 +1,19 @@
+if(NOT HAVE_EGG)
+ return()
+endif()
+
+set(P3FLTEGG_HEADERS
+ fltToEggConverter.h fltToEggConverter.I
+ fltToEggLevelState.h fltToEggLevelState.I
+)
+
+set(P3FLTEGG_SOURCES
+ fltToEggConverter.cxx
+ fltToEggLevelState.cxx
+)
+
+add_library(p3fltegg STATIC ${P3FLTEGG_HEADERS} ${P3FLTEGG_SOURCES})
+target_link_libraries(p3fltegg p3flt p3eggbase)
+
+# This is only needed for binaries in the pandatool package. It is not useful
+# for user applications, so it is not installed.
diff --git a/pandatool/src/fltprogs/CMakeLists.txt b/pandatool/src/fltprogs/CMakeLists.txt
new file mode 100644
index 0000000000..29a04166b7
--- /dev/null
+++ b/pandatool/src/fltprogs/CMakeLists.txt
@@ -0,0 +1,19 @@
+add_executable(flt-info fltInfo.cxx fltInfo.h)
+target_link_libraries(flt-info p3progbase p3flt)
+install(TARGETS flt-info EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+add_executable(flt-trans fltTrans.cxx fltTrans.h)
+target_link_libraries(flt-trans p3progbase p3flt)
+install(TARGETS flt-trans EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+if(HAVE_EGG)
+
+ add_executable(egg2flt eggToFlt.cxx eggToFlt.h)
+ target_link_libraries(egg2flt p3fltegg p3eggbase p3progbase)
+ install(TARGETS egg2flt EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+ add_executable(flt2egg fltToEgg.cxx fltToEgg.h)
+ target_link_libraries(flt2egg p3fltegg p3eggbase p3progbase)
+ install(TARGETS flt2egg EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+endif()
diff --git a/pandatool/src/gtk-stats/CMakeLists.txt b/pandatool/src/gtk-stats/CMakeLists.txt
new file mode 100644
index 0000000000..b78ebf2e80
--- /dev/null
+++ b/pandatool/src/gtk-stats/CMakeLists.txt
@@ -0,0 +1,41 @@
+if(NOT HAVE_GTK2 OR NOT HAVE_NET)
+ return()
+endif()
+
+set(GTKSTATS_HEADERS
+ gtkStatsChartMenu.h
+ gtkStatsGraph.h
+ gtkStatsLabel.h
+ gtkStatsLabelStack.h
+ gtkStatsMenuId.h
+ gtkStatsMonitor.h gtkStatsMonitor.I
+ gtkStatsPianoRoll.h
+ gtkStatsServer.h
+ gtkStatsStripChart.h
+)
+
+set(GTKSTATS_SOURCES
+ gtkStats.cxx
+ gtkStatsChartMenu.cxx
+ gtkStatsGraph.cxx
+ gtkStatsLabel.cxx
+ gtkStatsLabelStack.cxx
+ gtkStatsMonitor.cxx
+ gtkStatsPianoRoll.cxx
+ gtkStatsServer.cxx
+ gtkStatsStripChart.cxx
+)
+
+composite_sources(gtk-stats GTKSTATS_SOURCES)
+add_executable(gtk-stats ${GTKSTATS_HEADERS} ${GTKSTATS_SOURCES})
+target_link_libraries(gtk-stats p3progbase p3pstatserver PKG::GTK2)
+
+# This program is NOT actually called gtk-stats. It's pstats-gtk on Win32 and
+# pstats everywhere else (as the Win32 GUI is not built).
+if(WIN32)
+ set_target_properties(gtk-stats PROPERTIES OUTPUT_NAME "pstats-gtk")
+else()
+ set_target_properties(gtk-stats PROPERTIES OUTPUT_NAME "pstats")
+endif()
+
+install(TARGETS gtk-stats EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
diff --git a/pandatool/src/imagebase/CMakeLists.txt b/pandatool/src/imagebase/CMakeLists.txt
new file mode 100644
index 0000000000..46ffce3d5c
--- /dev/null
+++ b/pandatool/src/imagebase/CMakeLists.txt
@@ -0,0 +1,20 @@
+set(P3IMAGEBASE_HEADERS
+ imageBase.h
+ imageFilter.h
+ imageReader.h
+ imageWriter.h imageWriter.I
+)
+
+set(P3IMAGEBASE_SOURCES
+ imageBase.cxx
+ imageFilter.cxx
+ imageReader.cxx
+ imageWriter.cxx
+)
+
+composite_sources(p3imagebase P3IMAGEBASE_SOURCES)
+add_library(p3imagebase STATIC ${P3IMAGEBASE_HEADERS} ${P3IMAGEBASE_SOURCES})
+target_link_libraries(p3imagebase p3progbase)
+
+# This is only needed for binaries in the pandatool package. It is not useful
+# for user applications, so it is not installed.
diff --git a/pandatool/src/imageprogs/CMakeLists.txt b/pandatool/src/imageprogs/CMakeLists.txt
new file mode 100644
index 0000000000..f39b4b90fb
--- /dev/null
+++ b/pandatool/src/imageprogs/CMakeLists.txt
@@ -0,0 +1,19 @@
+add_executable(image-fix-hidden-color imageFixHiddenColor.cxx imageFixHiddenColor.h)
+target_link_libraries(image-fix-hidden-color p3imagebase)
+install(TARGETS image-fix-hidden-color EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+add_executable(image-info imageInfo.cxx imageInfo.h)
+target_link_libraries(image-info p3imagebase)
+install(TARGETS image-info EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+add_executable(image-resize imageResize.cxx imageResize.h)
+target_link_libraries(image-resize p3imagebase)
+install(TARGETS image-resize EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+add_executable(image-transform-colors imageTransformColors.cxx imageTransformColors.h)
+target_link_libraries(image-transform-colors p3imagebase)
+install(TARGETS image-transform-colors EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+add_executable(image-trans imageTrans.cxx imageTrans.h)
+target_link_libraries(image-trans p3imagebase)
+install(TARGETS image-trans EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
diff --git a/pandatool/src/lwo/CMakeLists.txt b/pandatool/src/lwo/CMakeLists.txt
new file mode 100644
index 0000000000..c7c7f33c35
--- /dev/null
+++ b/pandatool/src/lwo/CMakeLists.txt
@@ -0,0 +1,69 @@
+set(P3LWO_HEADERS
+ config_lwo.h
+ iffChunk.h iffChunk.I
+ iffGenericChunk.h iffGenericChunk.I
+ iffId.h iffId.I
+ iffInputFile.h iffInputFile.I
+ lwoBoundingBox.h
+ lwoChunk.h
+ lwoClip.h
+ lwoDiscontinuousVertexMap.h
+ lwoGroupChunk.h
+ lwoHeader.h lwoHeader.I
+ lwoInputFile.h lwoInputFile.I
+ lwoLayer.h
+ lwoPoints.h
+ lwoPolygons.h lwoPolygonTags.h
+ lwoStillImage.h
+ lwoSurfaceBlockAxis.h lwoSurfaceBlockChannel.h lwoSurfaceBlockCoordSys.h
+ lwoSurfaceBlockEnabled.h lwoSurfaceBlock.h lwoSurfaceBlockHeader.h
+ lwoSurfaceBlockImage.h lwoSurfaceBlockOpacity.h lwoSurfaceBlockProjection.h
+ lwoSurfaceBlockRefObj.h lwoSurfaceBlockRepeat.h lwoSurfaceBlockTMap.h
+ lwoSurfaceBlockTransform.h lwoSurfaceBlockVMapName.h lwoSurfaceBlockWrap.h
+ lwoSurfaceColor.h
+ lwoSurface.h
+ lwoSurfaceParameter.h
+ lwoSurfaceSidedness.h
+ lwoSurfaceSmoothingAngle.h
+ lwoTags.h
+ lwoVertexMap.h
+)
+
+set(P3LWO_SOURCES
+ config_lwo.cxx
+ iffChunk.cxx
+ iffGenericChunk.cxx
+ iffId.cxx
+ iffInputFile.cxx
+ lwoBoundingBox.cxx
+ lwoChunk.cxx
+ lwoClip.cxx
+ lwoDiscontinuousVertexMap.cxx
+ lwoGroupChunk.cxx
+ lwoHeader.cxx
+ lwoInputFile.cxx
+ lwoLayer.cxx
+ lwoPoints.cxx
+ lwoPolygons.cxx
+ lwoPolygonTags.cxx
+ lwoStillImage.cxx
+ lwoSurfaceBlockAxis.cxx lwoSurfaceBlockChannel.cxx lwoSurfaceBlockCoordSys.cxx
+ lwoSurfaceBlock.cxx lwoSurfaceBlockEnabled.cxx lwoSurfaceBlockHeader.cxx
+ lwoSurfaceBlockImage.cxx lwoSurfaceBlockOpacity.cxx lwoSurfaceBlockProjection.cxx
+ lwoSurfaceBlockRefObj.cxx lwoSurfaceBlockRepeat.cxx lwoSurfaceBlockTMap.cxx
+ lwoSurfaceBlockTransform.cxx lwoSurfaceBlockVMapName.cxx lwoSurfaceBlockWrap.cxx
+ lwoSurfaceColor.cxx
+ lwoSurface.cxx
+ lwoSurfaceParameter.cxx
+ lwoSurfaceSidedness.cxx
+ lwoSurfaceSmoothingAngle.cxx
+ lwoTags.cxx
+ lwoVertexMap.cxx
+)
+
+composite_sources(p3lwo P3LWO_SOURCES)
+add_library(p3lwo STATIC ${P3LWO_HEADERS} ${P3LWO_SOURCES})
+target_link_libraries(p3lwo p3pandatoolbase)
+
+# This is only needed for binaries in the pandatool package. It is not useful
+# for user applications, so it is not installed.
diff --git a/pandatool/src/lwoegg/CMakeLists.txt b/pandatool/src/lwoegg/CMakeLists.txt
new file mode 100644
index 0000000000..dbd4cff02f
--- /dev/null
+++ b/pandatool/src/lwoegg/CMakeLists.txt
@@ -0,0 +1,31 @@
+if(NOT HAVE_EGG)
+ return()
+endif()
+
+set(P3LWOEGG_HEADERS
+ cLwoClip.h cLwoClip.I
+ cLwoLayer.h cLwoLayer.I
+ cLwoPoints.h cLwoPoints.I
+ cLwoPolygons.h cLwoPolygons.I
+ cLwoSurfaceBlock.h cLwoSurfaceBlock.I
+ cLwoSurfaceBlockTMap.h cLwoSurfaceBlockTMap.I
+ cLwoSurface.h cLwoSurface.I
+ lwoToEggConverter.h lwoToEggConverter.I
+)
+
+set(P3LWOEGG_SOURCES
+ cLwoClip.cxx
+ cLwoLayer.cxx
+ cLwoPoints.cxx
+ cLwoPolygons.cxx
+ cLwoSurfaceBlock.cxx
+ cLwoSurfaceBlockTMap.cxx
+ cLwoSurface.cxx
+ lwoToEggConverter.cxx
+)
+
+add_library(p3lwoegg STATIC ${P3LWOEGG_HEADERS} ${P3LWOEGG_SOURCES})
+target_link_libraries(p3lwoegg p3lwo p3eggbase)
+
+# This is only needed for binaries in the pandatool package. It is not useful
+# for user applications, so it is not installed.
diff --git a/pandatool/src/lwoprogs/CMakeLists.txt b/pandatool/src/lwoprogs/CMakeLists.txt
new file mode 100644
index 0000000000..0a3c1de2e5
--- /dev/null
+++ b/pandatool/src/lwoprogs/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_executable(lwo-scan lwoScan.cxx lwoScan.h)
+target_link_libraries(lwo-scan p3progbase p3lwo)
+install(TARGETS lwo-scan EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+if(HAVE_EGG)
+
+ add_executable(lwo2egg lwoToEgg.cxx lwoToEgg.h)
+ target_link_libraries(lwo2egg p3lwoegg p3eggbase p3progbase)
+ install(TARGETS lwo2egg EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+endif()
diff --git a/pandatool/src/maya/mayaApi.cxx b/pandatool/src/maya/mayaApi.cxx
index b045f45f32..d3324279ee 100644
--- a/pandatool/src/maya/mayaApi.cxx
+++ b/pandatool/src/maya/mayaApi.cxx
@@ -25,7 +25,7 @@
#include
#include "post_maya_include.h"
-#ifdef WIN32_VC
+#ifdef _WIN32
#include // for chdir()
#endif
@@ -226,7 +226,7 @@ is_valid() const {
return _is_valid;
}
-#ifdef WIN32
+#ifdef _WIN32
static string
back_to_front_slash(const string &str) {
string result = str;
diff --git a/pandatool/src/mayaprogs/mayaPview.cxx b/pandatool/src/mayaprogs/mayaPview.cxx
index 06fc171b14..1c956672b3 100644
--- a/pandatool/src/mayaprogs/mayaPview.cxx
+++ b/pandatool/src/mayaprogs/mayaPview.cxx
@@ -43,11 +43,11 @@
// On Windows, we have code to fork pview as a separate process, which seems
// to be better for Maya.
-#ifdef WIN32_VC
+#ifdef _WIN32
#include
#include
#define SEPARATE_PVIEW 1
-#endif // WIN32_VC
+#endif // _WIN32
/**
*
diff --git a/pandatool/src/mayaprogs/mayaSavePview.cxx b/pandatool/src/mayaprogs/mayaSavePview.cxx
index 1537d95ce8..65a29236f3 100644
--- a/pandatool/src/mayaprogs/mayaSavePview.cxx
+++ b/pandatool/src/mayaprogs/mayaSavePview.cxx
@@ -22,7 +22,7 @@
#include
-#ifdef WIN32_VC
+#ifdef _WIN32
#include
#endif
@@ -69,7 +69,7 @@ doIt(const MArgList &args) {
pview_args = "-cla";
}
-#ifdef WIN32_VC
+#ifdef _WIN32
// On Windows, we use the spawn function to run pview asynchronously.
MString quoted = MString("\"") + filename + MString("\"");
intptr_t retval = _spawnlp(_P_DETACH, "pview",
@@ -78,7 +78,7 @@ doIt(const MArgList &args) {
return MS::kFailure;
}
-#else // WIN32_VC
+#else // _WIN32
// On non-Windows (e.g. Unix), we just use the system function, which runs
// synchronously. We could fork a process, but no one's asked for this yet.
MString command = MString("pview " + pview_args + MString(" \"") + filename + MString("\""));
@@ -87,7 +87,7 @@ doIt(const MArgList &args) {
if (command_result != 0) {
return MS::kFailure;
}
-#endif // WIN32_VC
+#endif // _WIN32
return MS::kSuccess;
}
diff --git a/pandatool/src/mayaprogs/mayaSavePview.h b/pandatool/src/mayaprogs/mayaSavePview.h
index d8f31d6688..56a84bf14c 100644
--- a/pandatool/src/mayaprogs/mayaSavePview.h
+++ b/pandatool/src/mayaprogs/mayaSavePview.h
@@ -71,7 +71,7 @@ public:
// Since we don't include any of the Panda headers (other than
// dtool_config.h), we have to define this macro ourselves, to tell Windows to
// export the following functions from the DLL.
-#ifdef WIN32_VC
+#ifdef _WIN32
#define EXPCL_MISC __declspec(dllexport)
#else
#define EXPCL_MISC
diff --git a/pandatool/src/mayaprogs/mayaToEgg_server.cxx b/pandatool/src/mayaprogs/mayaToEgg_server.cxx
index e95118d33b..11b33a20d4 100644
--- a/pandatool/src/mayaprogs/mayaToEgg_server.cxx
+++ b/pandatool/src/mayaprogs/mayaToEgg_server.cxx
@@ -11,7 +11,7 @@
* @date 2009-11-09
*/
-#if defined(WIN32_VC) || defined(WIN64_VC)
+#ifdef _WIN32
#include // for chdir
#endif
#include "mayaToEgg_server.h"
@@ -424,7 +424,7 @@ poll() {
buffers.push_back(buffer);
}
// Change to the client's current dir
-#ifdef WIN64_VC
+#ifdef _WIN64
_chdir(cwd.c_str());
#else
chdir(cwd.c_str());
diff --git a/pandatool/src/mayaprogs/mayapath.cxx b/pandatool/src/mayaprogs/mayapath.cxx
index 255aa569cf..c98e38243b 100644
--- a/pandatool/src/mayaprogs/mayapath.cxx
+++ b/pandatool/src/mayaprogs/mayapath.cxx
@@ -347,7 +347,7 @@ main(int argc, char *argv[]) {
putenv(putenv_cstr);
}
-#ifdef WIN32
+#ifdef _WIN32
string sep = ";";
#else
string sep = ":";
diff --git a/pandatool/src/miscprogs/CMakeLists.txt b/pandatool/src/miscprogs/CMakeLists.txt
new file mode 100644
index 0000000000..169cecc774
--- /dev/null
+++ b/pandatool/src/miscprogs/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_executable(bin2c binToC.cxx binToC.h)
+target_link_libraries(bin2c p3progbase)
+install(TARGETS bin2c EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
diff --git a/pandatool/src/objegg/CMakeLists.txt b/pandatool/src/objegg/CMakeLists.txt
new file mode 100644
index 0000000000..c6106815b2
--- /dev/null
+++ b/pandatool/src/objegg/CMakeLists.txt
@@ -0,0 +1,23 @@
+if(NOT HAVE_EGG)
+ return()
+endif()
+
+set(P3OBJEGG_HEADERS
+ config_objegg.h
+ eggToObjConverter.h
+ objToEggConverter.h
+ objToEggConverter.I
+)
+
+set(P3OBJEGG_SOURCES
+ config_objegg.cxx
+ eggToObjConverter.cxx
+ objToEggConverter.cxx
+)
+
+composite_sources(p3objegg P3OBJEGG_SOURCES)
+add_library(p3objegg STATIC ${P3OBJEGG_HEADERS} ${P3OBJEGG_SOURCES})
+target_link_libraries(p3objegg p3eggbase)
+
+# This is only needed for binaries in the pandatool package. It is not useful
+# for user applications, so it is not installed.
diff --git a/pandatool/src/objprogs/CMakeLists.txt b/pandatool/src/objprogs/CMakeLists.txt
new file mode 100644
index 0000000000..adc398fab4
--- /dev/null
+++ b/pandatool/src/objprogs/CMakeLists.txt
@@ -0,0 +1,11 @@
+if(NOT HAVE_EGG)
+ return()
+endif()
+
+add_executable(egg2obj eggToObj.cxx eggToObj.h)
+target_link_libraries(egg2obj p3objegg p3eggbase)
+install(TARGETS egg2obj EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+add_executable(obj2egg objToEgg.cxx objToEgg.h)
+target_link_libraries(obj2egg p3objegg p3eggbase p3progbase)
+install(TARGETS obj2egg EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
diff --git a/pandatool/src/palettizer/CMakeLists.txt b/pandatool/src/palettizer/CMakeLists.txt
new file mode 100644
index 0000000000..f3cb281893
--- /dev/null
+++ b/pandatool/src/palettizer/CMakeLists.txt
@@ -0,0 +1,60 @@
+if(NOT HAVE_EGG)
+ return()
+endif()
+
+set(P3PALETTIZER_HEADERS
+ config_palettizer.h
+ destTextureImage.h
+ eggFile.h
+ filenameUnifier.h
+ imageFile.h
+ omitReason.h
+ paletteGroup.h
+ paletteGroups.h
+ paletteImage.h
+ palettePage.h
+ palettizer.h
+ pal_string_utils.h
+ sourceTextureImage.h
+ textureImage.h
+ textureMemoryCounter.h
+ texturePlacement.h
+ texturePosition.h
+ textureProperties.h
+ textureReference.h
+ textureRequest.h
+ txaFile.h
+ txaLine.h
+)
+
+set(P3PALETTIZER_SOURCES
+ config_palettizer.cxx
+ destTextureImage.cxx
+ eggFile.cxx
+ filenameUnifier.cxx
+ imageFile.cxx
+ omitReason.cxx
+ paletteGroup.cxx
+ paletteGroups.cxx
+ paletteImage.cxx
+ palettePage.cxx
+ palettizer.cxx
+ pal_string_utils.cxx
+ sourceTextureImage.cxx
+ textureImage.cxx
+ textureMemoryCounter.cxx
+ texturePlacement.cxx
+ texturePosition.cxx
+ textureProperties.cxx
+ textureReference.cxx
+ textureRequest.cxx
+ txaFile.cxx
+ txaLine.cxx
+)
+
+composite_sources(p3palettizer P3PALETTIZER_SOURCES)
+add_library(p3palettizer STATIC ${P3PALETTIZER_HEADERS} ${P3PALETTIZER_SOURCES})
+target_link_libraries(p3palettizer p3progbase p3converter)
+
+# This is only needed for binaries in the pandatool package. It is not useful
+# for user applications, so it is not installed.
diff --git a/pandatool/src/palettizer/paletteGroups.h b/pandatool/src/palettizer/paletteGroups.h
index 9a2cdd2b52..bdcfd248e1 100644
--- a/pandatool/src/palettizer/paletteGroups.h
+++ b/pandatool/src/palettizer/paletteGroups.h
@@ -30,7 +30,7 @@ private:
typedef pset Groups;
public:
-#ifndef WIN32_VC
+#ifndef _WIN32
typedef Groups::const_pointer pointer;
typedef Groups::const_pointer const_pointer;
#endif
diff --git a/pandatool/src/pandatoolbase/CMakeLists.txt b/pandatool/src/pandatoolbase/CMakeLists.txt
new file mode 100644
index 0000000000..93d9aae35e
--- /dev/null
+++ b/pandatool/src/pandatoolbase/CMakeLists.txt
@@ -0,0 +1,31 @@
+set(P3PANDATOOLBASE_HEADERS
+ animationConvert.h
+ config_pandatoolbase.h
+ distanceUnit.h
+ pandatoolbase.h pandatoolsymbols.h
+ pathReplace.h pathReplace.I
+ pathStore.h
+)
+
+set(P3PANDATOOLBASE_SOURCES
+ animationConvert.cxx
+ config_pandatoolbase.cxx
+ distanceUnit.cxx
+ pandatoolbase.cxx
+ pathReplace.cxx
+ pathStore.cxx
+)
+
+composite_sources(p3pandatoolbase P3PANDATOOLBASE_SOURCES)
+add_library(p3pandatoolbase STATIC ${P3PANDATOOLBASE_HEADERS} ${P3PANDATOOLBASE_SOURCES})
+target_link_libraries(p3pandatoolbase panda)
+
+# ptloader - a module - may need to link in libraries in this package, so:
+if(MODULE_TYPE STREQUAL "MODULE")
+ set_target_properties(p3pandatoolbase PROPERTIES
+ POSITION_INDEPENDENT_CODE ON
+ INTERFACE_POSITION_INDEPENDENT_CODE ON)
+endif()
+
+# This is only needed for binaries in the pandatool package. It is not useful
+# for user applications, so it is not installed.
diff --git a/pandatool/src/pfmprogs/CMakeLists.txt b/pandatool/src/pfmprogs/CMakeLists.txt
new file mode 100644
index 0000000000..13cb6af787
--- /dev/null
+++ b/pandatool/src/pfmprogs/CMakeLists.txt
@@ -0,0 +1,9 @@
+add_executable(pfm-bba
+ config_pfmprogs.cxx config_pfmprogs.h
+ pfmBba.cxx pfmBba.h)
+target_link_libraries(pfm-bba p3progbase)
+install(TARGETS pfm-bba EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+add_executable(pfm-trans pfmTrans.cxx pfmTrans.h)
+target_link_libraries(pfm-trans p3progbase)
+install(TARGETS pfm-trans EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
diff --git a/pandatool/src/progbase/CMakeLists.txt b/pandatool/src/progbase/CMakeLists.txt
new file mode 100644
index 0000000000..70e9212649
--- /dev/null
+++ b/pandatool/src/progbase/CMakeLists.txt
@@ -0,0 +1,22 @@
+set(P3PROGBASE_HEADERS
+ programBase.h programBase.I
+ withOutputFile.h withOutputFile.I
+ wordWrapStream.h wordWrapStreamBuf.I
+ wordWrapStreamBuf.h
+)
+
+set(P3PROGBASE_SOURCES
+ programBase.cxx withOutputFile.cxx wordWrapStream.cxx
+ wordWrapStreamBuf.cxx
+)
+
+composite_sources(p3progbase P3PROGBASE_SOURCES)
+add_library(p3progbase STATIC ${P3PROGBASE_HEADERS} ${P3PROGBASE_SOURCES})
+target_link_libraries(p3progbase p3pandatoolbase panda PKG::ZLIB)
+
+if(IOCTL_TERMINAL_WIDTH)
+ target_compile_definitions(p3progbase PRIVATE IOCTL_TERMINAL_WIDTH)
+endif()
+
+# This is only needed for binaries in the pandatool package. It is not useful
+# for user applications, so it is not installed.
diff --git a/pandatool/src/pstatserver/CMakeLists.txt b/pandatool/src/pstatserver/CMakeLists.txt
new file mode 100644
index 0000000000..359f529b18
--- /dev/null
+++ b/pandatool/src/pstatserver/CMakeLists.txt
@@ -0,0 +1,33 @@
+if(NOT HAVE_NET)
+ return()
+endif()
+
+set(P3PSTATSERVER_HEADERS
+ pStatClientData.h
+ pStatGraph.h pStatGraph.I
+ pStatListener.h
+ pStatMonitor.h pStatMonitor.I
+ pStatPianoRoll.h pStatPianoRoll.I
+ pStatReader.h
+ pStatServer.h
+ pStatStripChart.h pStatStripChart.I
+ pStatThreadData.h pStatThreadData.I
+ pStatView.h pStatView.I
+ pStatViewLevel.h pStatViewLevel.I
+)
+
+set(P3PSTATSERVER_SOURCES
+ pStatClientData.cxx pStatGraph.cxx
+ pStatListener.cxx
+ pStatMonitor.cxx pStatPianoRoll.cxx
+ pStatReader.cxx pStatServer.cxx
+ pStatStripChart.cxx pStatThreadData.cxx
+ pStatView.cxx pStatViewLevel.cxx
+)
+
+composite_sources(p3pstatserver P3PSTATSERVER_SOURCES)
+add_library(p3pstatserver STATIC ${P3PSTATSERVER_HEADERS} ${P3PSTATSERVER_SOURCES})
+target_link_libraries(p3pstatserver p3pandatoolbase panda)
+
+# This is only needed for binaries in the pandatool package. It is not useful
+# for user applications, so it is not installed.
diff --git a/pandatool/src/ptloader/CMakeLists.txt b/pandatool/src/ptloader/CMakeLists.txt
new file mode 100644
index 0000000000..0d98ee8377
--- /dev/null
+++ b/pandatool/src/ptloader/CMakeLists.txt
@@ -0,0 +1,31 @@
+if(NOT HAVE_EGG)
+ return()
+endif()
+
+set(P3PTLOADER_HEADERS
+ config_ptloader.h
+ loaderFileTypePandatool.h
+)
+
+set(P3PTLOADER_SOURCES
+ config_ptloader.cxx
+ loaderFileTypePandatool.cxx
+)
+
+composite_sources(p3ptloader P3PTLOADER_SOURCES)
+add_library(p3ptloader ${MODULE_TYPE} ${P3PTLOADER_HEADERS} ${P3PTLOADER_SOURCES})
+set_target_properties(p3ptloader PROPERTIES DEFINE_SYMBOL BUILDING_PTLOADER)
+target_link_libraries(p3ptloader PRIVATE
+ p3dxfegg p3fltegg p3lwoegg p3objegg p3vrmlegg p3xfileegg
+ p3converter)
+
+if(HAVE_FCOLLADA)
+ target_link_libraries(p3ptloader PRIVATE p3daeegg)
+ target_compile_definitions(p3ptloader PRIVATE HAVE_FCOLLADA)
+endif()
+
+if(BUILD_SHARED_LIBS)
+ # We can't install this if we're doing a static build, because it depends on
+ # a bunch of static libraries that aren't installed.
+ install(TARGETS p3ptloader EXPORT Tools COMPONENT Tools DESTINATION ${MODULE_DESTINATION})
+endif()
diff --git a/pandatool/src/text-stats/CMakeLists.txt b/pandatool/src/text-stats/CMakeLists.txt
new file mode 100644
index 0000000000..155b9013f3
--- /dev/null
+++ b/pandatool/src/text-stats/CMakeLists.txt
@@ -0,0 +1,19 @@
+if(NOT HAVE_NET)
+ return()
+endif()
+
+set(TEXTSTATS_HEADERS
+ textMonitor.h textMonitor.I
+ textStats.h
+)
+
+set(TEXTSTATS_SOURCES
+ textMonitor.cxx
+ textStats.cxx
+)
+
+composite_sources(text-stats TEXTSTATS_SOURCES)
+add_executable(text-stats ${TEXTSTATS_HEADERS} ${TEXTSTATS_SOURCES})
+target_link_libraries(text-stats p3progbase p3pstatserver)
+
+install(TARGETS text-stats EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
diff --git a/pandatool/src/vrml/CMakeLists.txt b/pandatool/src/vrml/CMakeLists.txt
new file mode 100644
index 0000000000..235ccbff4e
--- /dev/null
+++ b/pandatool/src/vrml/CMakeLists.txt
@@ -0,0 +1,30 @@
+set(P3VRML_HEADERS
+ parse_vrml.h
+ standard_nodes.h
+ vrmlLexerDefs.h
+ vrmlNode.h
+ vrmlNodeType.h
+ vrmlParserDefs.h
+)
+
+set(P3VRML_SOURCES
+ parse_vrml.cxx
+ standard_nodes.cxx
+ vrmlNode.cxx
+ vrmlNodeType.cxx
+)
+
+set(P3VRML_PARSER_SOURCES
+ vrmlParser.cxx
+ vrmlLexer.cxx
+)
+
+add_bison_target(vrmlParser.cxx vrmlParser.yxx DEFINES vrmlParser.h PREFIX vrmlyy)
+add_flex_target(vrmlLexer.cxx vrmlLexer.lxx CASE_INSENSITIVE PREFIX vrmlyy)
+
+composite_sources(p3vrml P3VRML_SOURCES)
+add_library(p3vrml STATIC ${P3VRML_HEADERS} ${P3VRML_SOURCES} ${P3VRML_PARSER_SOURCES})
+target_link_libraries(p3vrml p3pandatoolbase)
+
+# This is only needed for binaries in the pandatool package. It is not useful
+# for user applications, so it is not installed.
diff --git a/pandatool/src/vrmlegg/CMakeLists.txt b/pandatool/src/vrmlegg/CMakeLists.txt
new file mode 100644
index 0000000000..b2a38c840e
--- /dev/null
+++ b/pandatool/src/vrmlegg/CMakeLists.txt
@@ -0,0 +1,22 @@
+if(NOT HAVE_EGG)
+ return()
+endif()
+
+set(P3VRMLEGG_HEADERS
+ indexedFaceSet.h
+ vrmlAppearance.h
+ vrmlToEggConverter.h
+)
+
+set(P3VRMLEGG_SOURCES
+ indexedFaceSet.cxx
+ vrmlAppearance.cxx
+ vrmlToEggConverter.cxx
+)
+
+composite_sources(p3vrmlegg P3VRMLEGG_SOURCES)
+add_library(p3vrmlegg STATIC ${P3VRMLEGG_HEADERS} ${P3VRMLEGG_SOURCES})
+target_link_libraries(p3vrmlegg p3vrml p3eggbase)
+
+# This is only needed for binaries in the pandatool package. It is not useful
+# for user applications, so it is not installed.
diff --git a/pandatool/src/vrmlprogs/CMakeLists.txt b/pandatool/src/vrmlprogs/CMakeLists.txt
new file mode 100644
index 0000000000..82a5e78bd3
--- /dev/null
+++ b/pandatool/src/vrmlprogs/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_executable(vrml-trans vrmlTrans.cxx vrmlTrans.h)
+target_link_libraries(vrml-trans p3progbase p3vrml)
+install(TARGETS vrml-trans EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+if(HAVE_EGG)
+
+ add_executable(vrml2egg vrmlToEgg.cxx vrmlToEgg.h)
+ target_link_libraries(vrml2egg p3vrmlegg p3eggbase p3progbase)
+ install(TARGETS vrml2egg EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+endif()
diff --git a/pandatool/src/win-stats/CMakeLists.txt b/pandatool/src/win-stats/CMakeLists.txt
new file mode 100644
index 0000000000..0cd7768c3a
--- /dev/null
+++ b/pandatool/src/win-stats/CMakeLists.txt
@@ -0,0 +1,37 @@
+if(NOT WIN32 OR NOT HAVE_NET)
+ return()
+endif()
+
+set(WINSTATS_HEADERS
+ winStatsChartMenu.h
+ winStatsGraph.h
+ winStats.h
+ winStatsLabel.h
+ winStatsLabelStack.h
+ winStatsMenuId.h
+ winStatsMonitor.h winStatsMonitor.I
+ winStatsPianoRoll.h
+ winStatsServer.h
+ winStatsStripChart.h
+)
+
+set(WINSTATS_SOURCES
+ winStatsChartMenu.cxx
+ winStats.cxx
+ winStatsGraph.cxx
+ winStatsLabel.cxx
+ winStatsLabelStack.cxx
+ winStatsMonitor.cxx
+ winStatsPianoRoll.cxx
+ winStatsServer.cxx
+ winStatsStripChart.cxx
+)
+
+composite_sources(win-stats WINSTATS_SOURCES)
+add_executable(win-stats ${WINSTATS_HEADERS} ${WINSTATS_SOURCES})
+target_link_libraries(win-stats p3progbase p3pstatserver)
+
+# This program is NOT actually called win-stats. It's just pstats.exe
+set_target_properties(win-stats PROPERTIES OUTPUT_NAME "pstats")
+
+install(TARGETS win-stats EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
diff --git a/pandatool/src/xfile/CMakeLists.txt b/pandatool/src/xfile/CMakeLists.txt
new file mode 100644
index 0000000000..1768ef35ed
--- /dev/null
+++ b/pandatool/src/xfile/CMakeLists.txt
@@ -0,0 +1,56 @@
+set(P3XFILE_HEADERS
+ config_xfile.h
+ standard_templates.h
+ windowsGuid.h windowsGuid.I
+ xFileArrayDef.h xFileArrayDef.I
+ xFileDataDef.h xFileDataDef.I
+ xFileDataNode.h xFileDataNode.I
+ xFileDataNodeReference.h xFileDataNodeReference.I
+ xFileDataNodeTemplate.h xFileDataNodeTemplate.I
+ xFileDataObjectArray.h xFileDataObjectArray.I
+ xFileDataObjectDouble.h xFileDataObjectDouble.I
+ xFileDataObject.h xFileDataObject.I
+ xFileDataObjectInteger.h xFileDataObjectInteger.I
+ xFileDataObjectString.h xFileDataObjectString.I
+ xFile.h xFile.I
+ xFileNode.h xFileNode.I
+ xFileParseData.h xFileParseData.I
+ xFileTemplate.h xFileTemplate.I
+ xLexerDefs.h
+ xParserDefs.h
+)
+
+set(P3XFILE_SOURCES
+ config_xfile.cxx
+ standard_templates.cxx
+ windowsGuid.cxx
+ xFileArrayDef.cxx
+ xFile.cxx
+ xFileDataDef.cxx
+ xFileDataNode.cxx
+ xFileDataNodeReference.cxx
+ xFileDataNodeTemplate.cxx
+ xFileDataObjectArray.cxx
+ xFileDataObject.cxx
+ xFileDataObjectDouble.cxx
+ xFileDataObjectInteger.cxx
+ xFileDataObjectString.cxx
+ xFileNode.cxx
+ xFileParseData.cxx
+ xFileTemplate.cxx
+)
+
+set(P3XFILE_PARSER_SOURCES
+ xParser.cxx
+ xLexer.cxx
+)
+
+add_bison_target(xParser.cxx xParser.yxx DEFINES xParser.h PREFIX xyy)
+add_flex_target(xLexer.cxx xLexer.lxx CASE_INSENSITIVE PREFIX xyy)
+
+composite_sources(p3xfile P3XFILE_SOURCES)
+add_library(p3xfile STATIC ${P3XFILE_HEADERS} ${P3XFILE_SOURCES} ${P3XFILE_PARSER_SOURCES})
+target_link_libraries(p3xfile p3pandatoolbase)
+
+# This is only needed for binaries in the pandatool package. It is not useful
+# for user applications, so it is not installed.
diff --git a/pandatool/src/xfileegg/CMakeLists.txt b/pandatool/src/xfileegg/CMakeLists.txt
new file mode 100644
index 0000000000..eb8bd12e57
--- /dev/null
+++ b/pandatool/src/xfileegg/CMakeLists.txt
@@ -0,0 +1,26 @@
+if(NOT HAVE_EGG)
+ return()
+endif()
+
+set(P3XFILEEGG_HEADERS
+ xFileAnimationSet.h xFileAnimationSet.I
+ xFileFace.h xFileMaker.h
+ xFileMaterial.h xFileMesh.h xFileNormal.h
+ xFileToEggConverter.h
+ xFileVertex.h xFileVertexPool.h
+)
+
+set(P3XFILEEGG_SOURCES
+ xFileAnimationSet.cxx
+ xFileFace.cxx xFileMaker.cxx
+ xFileMaterial.cxx xFileMesh.cxx xFileNormal.cxx
+ xFileToEggConverter.cxx
+ xFileVertex.cxx
+)
+
+composite_sources(p3xfileegg P3XFILEEGG_SOURCES)
+add_library(p3xfileegg STATIC ${P3XFILEEGG_HEADERS} ${P3XFILEEGG_SOURCES})
+target_link_libraries(p3xfileegg p3xfile p3eggbase)
+
+# This is only needed for binaries in the pandatool package. It is not useful
+# for user applications, so it is not installed.
diff --git a/pandatool/src/xfileprogs/CMakeLists.txt b/pandatool/src/xfileprogs/CMakeLists.txt
new file mode 100644
index 0000000000..29562db00d
--- /dev/null
+++ b/pandatool/src/xfileprogs/CMakeLists.txt
@@ -0,0 +1,15 @@
+add_executable(x-trans xFileTrans.cxx xFileTrans.h)
+target_link_libraries(x-trans p3progbase p3xfile)
+install(TARGETS x-trans EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+if(HAVE_EGG)
+
+ add_executable(egg2x eggToX.cxx eggToX.h)
+ target_link_libraries(egg2x p3xfileegg p3eggbase p3progbase)
+ install(TARGETS egg2x EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+ add_executable(x2egg xFileToEgg.cxx xFileToEgg.h)
+ target_link_libraries(x2egg p3xfileegg p3eggbase p3progbase)
+ install(TARGETS x2egg EXPORT Tools COMPONENT Tools DESTINATION ${CMAKE_INSTALL_BINDIR})
+
+endif()
diff --git a/tests/display/test_glsl_shader.py b/tests/display/test_glsl_shader.py
index a380f8ccfb..891410c3e7 100644
--- a/tests/display/test_glsl_shader.py
+++ b/tests/display/test_glsl_shader.py
@@ -261,6 +261,54 @@ def test_glsl_bool(gsg):
run_glsl_test(gsg, code, preamble, flags)
+def test_glsl_mat3(gsg):
+ param1 = core.LMatrix4(core.LMatrix3(1, 2, 3, 4, 5, 6, 7, 8, 9))
+
+ param2 = core.NodePath("param2")
+ param2.set_mat(core.LMatrix3(10, 11, 12, 13, 14, 15, 16, 17, 18))
+
+ preamble = """
+ uniform mat3 param1;
+ uniform mat3 param2;
+ """
+ code = """
+ assert(param1[0] == vec3(1, 2, 3));
+ assert(param1[1] == vec3(4, 5, 6));
+ assert(param1[2] == vec3(7, 8, 9));
+ assert(param2[0] == vec3(10, 11, 12));
+ assert(param2[1] == vec3(13, 14, 15));
+ assert(param2[2] == vec3(16, 17, 18));
+ """
+ run_glsl_test(gsg, code, preamble, {'param1': param1, 'param2': param2})
+
+
+def test_glsl_mat4(gsg):
+ param1 = core.LMatrix4(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)
+
+ param2 = core.NodePath("param2")
+ param2.set_mat(core.LMatrix4(
+ 17, 18, 19, 20,
+ 21, 22, 23, 24,
+ 25, 26, 27, 28,
+ 29, 30, 31, 32))
+
+ preamble = """
+ uniform mat4 param1;
+ uniform mat4 param2;
+ """
+ code = """
+ assert(param1[0] == vec4(1, 2, 3, 4));
+ assert(param1[1] == vec4(5, 6, 7, 8));
+ assert(param1[2] == vec4(9, 10, 11, 12));
+ assert(param1[3] == vec4(13, 14, 15, 16));
+ assert(param2[0] == vec4(17, 18, 19, 20));
+ assert(param2[1] == vec4(21, 22, 23, 24));
+ assert(param2[2] == vec4(25, 26, 27, 28));
+ assert(param2[3] == vec4(29, 30, 31, 32));
+ """
+ run_glsl_test(gsg, code, preamble, {'param1': param1, 'param2': param2})
+
+
def test_glsl_pta_int(gsg):
pta = core.PTA_int((0, 1, 2, 3))
diff --git a/tests/gui/test_DirectScrolledFrame.py b/tests/gui/test_DirectScrolledFrame.py
new file mode 100644
index 0000000000..85ad8a53d4
--- /dev/null
+++ b/tests/gui/test_DirectScrolledFrame.py
@@ -0,0 +1,36 @@
+from direct.gui.DirectScrolledFrame import DirectScrolledFrame
+import pytest
+
+
+def test_set_scrollbar_width():
+ w = 1
+
+ frm = DirectScrolledFrame(scrollBarWidth=w)
+
+ assert frm['scrollBarWidth'] == 1
+
+ assert frm.verticalScroll['frameSize'] == (-w / 2.0, w / 2.0, -1, 1)
+ assert frm.horizontalScroll['frameSize'] == (-1, 1, -w / 2.0, w / 2.0)
+
+ # manual changes to the framesize
+ frm.verticalScroll['frameSize'] = (-2, 2, -4, 4)
+ frm.horizontalScroll['frameSize'] = (-4, 4, -2, 2)
+ assert frm.verticalScroll['frameSize'] == (-2, 2, -4, 4)
+ assert frm.horizontalScroll['frameSize'] == (-4, 4, -2, 2)
+
+ # change scrollbar width to a new value
+ w = 2
+ frm['scrollBarWidth'] = w
+
+ # check, new value is set correct
+ assert frm['scrollBarWidth'] == 2
+
+ # check if new size is set correct
+ assert frm.verticalScroll['frameSize'] == (-w / 2.0, w / 2.0, -4, 4)
+ assert frm.horizontalScroll['frameSize'] == (-4, 4, -w / 2.0, w / 2.0)
+
+
+def test_set_scrollbar_width_on_init():
+ frm = DirectScrolledFrame(verticalScroll_frameSize=(-2, 2, -4, 4), horizontalScroll_frameSize=(-4, 4, -2, 2))
+ assert frm.verticalScroll['frameSize'] == (-2, 2, -4, 4)
+ assert frm.horizontalScroll['frameSize'] == (-4, 4, -2, 2)
diff --git a/tests/gui/test_DirectSlider.py b/tests/gui/test_DirectSlider.py
new file mode 100644
index 0000000000..5c740c6c98
--- /dev/null
+++ b/tests/gui/test_DirectSlider.py
@@ -0,0 +1,29 @@
+from direct.gui.DirectSlider import DirectSlider
+from direct.gui import DirectGuiGlobals as DGG
+import pytest
+
+def test_slider_orientation():
+ slider = DirectSlider()
+
+ # Horizontal orientation is the default
+ assert slider['orientation'] == DGG.HORIZONTAL
+ assert slider['frameSize'] == (-1, 1, -0.08, 0.08)
+ assert slider['frameVisibleScale'] == (1, 0.25)
+
+ # try change to vertical orientation
+ slider['orientation'] = DGG.VERTICAL
+ assert slider['orientation'] == DGG.VERTICAL
+ assert slider['frameSize'] == (-0.08, 0.08, -1, 1)
+ assert slider['frameVisibleScale'] == (0.25, 1)
+
+ # back to horizontal
+ slider['orientation'] = DGG.HORIZONTAL
+ assert slider['orientation'] == DGG.HORIZONTAL
+ assert slider['frameSize'] == (-1, 1, -0.08, 0.08)
+ assert slider['frameVisibleScale'] == (1, 0.25)
+
+ # finally change to inverted vertical orientation
+ slider['orientation'] = DGG.VERTICAL_INVERTED
+ assert slider['orientation'] == DGG.VERTICAL_INVERTED
+ assert slider['frameSize'] == (-0.08, 0.08, -1, 1)
+ assert slider['frameVisibleScale'] == (0.25, 1)
diff --git a/tests/interrogate/test_property.py b/tests/interrogate/test_property.py
index 4d521d03e5..fffcb78ac0 100755
--- a/tests/interrogate/test_property.py
+++ b/tests/interrogate/test_property.py
@@ -149,7 +149,7 @@ def test_seq_property_getitem():
prop[i]
# Make sure it preserves refcount of invalid indices
- i = "nonsense"
+ i = "nonsense195641"
with constant_refcount(i):
try:
prop[i]
@@ -250,7 +250,7 @@ def test_seq_property_index():
except ValueError:
pass
- nonsense = "nonsense"
+ nonsense = "nonsense854371"
with constant_refcount(nonsense):
try:
prop.index(nonsense)
@@ -271,7 +271,7 @@ def test_seq_property_count():
with constant_refcount(item_b):
prop.count(item_b)
- nonsense = "nonsense"
+ nonsense = "nonsense219449"
with constant_refcount(nonsense):
prop.count(nonsense)
@@ -447,8 +447,8 @@ def test_map_property_empty():
def test_map_property_getitem():
- key = 'key'
- value = 'value'
+ key = 'key162732'
+ value = 'value162732'
prop = map_property(**{key: value})
with constant_refcount(key):
@@ -462,8 +462,8 @@ def test_map_property_getitem():
def test_map_property_setitem():
- key = 'key'
- value = 'value'
+ key = 'key559075'
+ value = 'value559075'
prop = map_property()
# Setting new key
@@ -490,8 +490,8 @@ def test_map_property_setitem():
def test_map_property_delitem():
- key = 'key'
- value = 'value'
+ key = 'key731691'
+ value = 'value731691'
prop = map_property(**{key: value})
with constant_refcount(key):
@@ -519,11 +519,11 @@ def test_map_property_contains():
def test_map_property_get():
- key = 'key'
- value = 'value'
+ key = 'key861801'
+ value = 'value861801'
prop = map_property(**{key: value})
- default = 'default'
+ default = 'default861801'
with constant_refcount(key):
with constant_refcount(default):
assert prop.get(key) == value
diff --git a/tests/linmath/test_lvector2.py b/tests/linmath/test_lvector2.py
index d5aab7f96f..fe37409f3e 100644
--- a/tests/linmath/test_lvector2.py
+++ b/tests/linmath/test_lvector2.py
@@ -1,30 +1,90 @@
from math import floor, ceil
import sys
+from panda3d.core import Vec2, Vec3, Vec4, Vec2F, Vec2D
import pytest
-from panda3d.core import Vec2
-
-
-original_vector = Vec2(2.3, -2.6)
reason = '''Rounding in Python 2.7 expects to return a float value, since it returns a Vector it
does not work. When Python 2.7 gets deprecated, remove this check.'''
+
@pytest.mark.skipif(sys.version_info < (3, 5), reason=reason)
def test_round():
+ original_vector = Vec2(2.3, -2.6)
+
rounded_vector = round(original_vector)
assert rounded_vector.x == 2
assert rounded_vector.y == -3
+
@pytest.mark.skipif(sys.version_info < (3, 5), reason=reason)
def test_floor():
+ original_vector = Vec2(2.3, -2.6)
+
rounded_vector = floor(original_vector)
assert rounded_vector.x == 2
assert rounded_vector.y == -3
+
@pytest.mark.skipif(sys.version_info < (3, 5), reason=reason)
def test_ceil():
+ original_vector = Vec2(2.3, -2.6)
+
rounded_vector = ceil(original_vector)
assert rounded_vector.x == 3
assert rounded_vector.y == -2
+
+
+def test_vec2_creation():
+ assert Vec2(x=1, y=2) == Vec2(1, 2) == Vec2((1, 2))
+
+
+def test_vec2_getter_setter():
+ original_vector = Vec2(2, 3)
+
+ assert original_vector.x == 2
+ assert original_vector.y == 3
+
+ original_vector.x = 1
+ original_vector.y = 3
+
+ assert original_vector == Vec2(1, 3)
+
+ original_vector[0] = 3
+ original_vector[1] = 1
+
+ assert original_vector == Vec2(3, 1)
+
+ original_vector.set_x(-8)
+ original_vector.set_y(6)
+
+ assert original_vector.x == -8
+ assert original_vector.y == 6
+
+
+def test_vec2_sum():
+ original_vector = Vec2(2, 3)
+
+ assert original_vector + original_vector == Vec2(4, 6)
+ assert original_vector + 3 == Vec2(5, 6)
+
+
+def test_vec2_power():
+ assert Vec2(2, -3) ** 2 == Vec2(4, 9)
+
+
+def test_vec2_len():
+ assert len(Vec2(2, -3)) == 2
+
+
+def test_vec2_swizzle_mask():
+ original_vector = Vec2(3, 5)
+
+ assert original_vector.yx == Vec2(5, 3)
+ assert original_vector.xy == original_vector
+
+
+def test_vec2_str():
+ assert str(Vec2F(2, 3)) == "LVector2f(2, 3)"
+ assert str(Vec2D(2, 3)) == "LVector2d(2, 3)"
diff --git a/tests/linmath/test_lvector3.py b/tests/linmath/test_lvector3.py
index 7ddefa728c..cbc8c51e9a 100644
--- a/tests/linmath/test_lvector3.py
+++ b/tests/linmath/test_lvector3.py
@@ -1,18 +1,17 @@
from math import floor, ceil
import sys
+from panda3d.core import Vec2, Vec3, Vec3F, Vec3D
import pytest
-from panda3d.core import Vec3
-
-
-original_vector = Vec3(2.3, -2.6, 3.5)
reason = '''Rounding in Python 2.7 expects to return a float value, since it returns a Vector it
does not work. When Python 2.7 gets deprecated, remove this check.'''
@pytest.mark.skipif(sys.version_info < (3, 5), reason=reason)
def test_round():
+ original_vector = Vec3(2.3, -2.6, 3.5)
+
rounded_vector = round(original_vector)
assert rounded_vector.x == 2
assert rounded_vector.y == -3
@@ -21,6 +20,8 @@ def test_round():
@pytest.mark.skipif(sys.version_info < (3, 5), reason=reason)
def test_floor():
+ original_vector = Vec3(2.3, -2.6, 3.5)
+
rounded_vector = floor(original_vector)
assert rounded_vector.x == 2
assert rounded_vector.y == -3
@@ -29,7 +30,67 @@ def test_floor():
@pytest.mark.skipif(sys.version_info < (3, 5), reason=reason)
def test_ceil():
+ original_vector = Vec3(2.3, -2.6, 3.5)
+
rounded_vector = ceil(original_vector)
assert rounded_vector.x == 3
assert rounded_vector.y == -2
assert rounded_vector.z == 4
+
+
+def test_vec3_creation():
+ assert Vec3(x=1, y=2, z=1) == Vec3(1, 2, 1) == Vec3((1, 2, 1))
+
+
+def test_vec3_getter_setter():
+ original_vector = Vec3(2, 3, 7)
+
+ assert original_vector.x == 2
+ assert original_vector.y == 3
+ assert original_vector.z == 7
+
+ original_vector.x = 1
+ original_vector.y = 3
+ original_vector.z = 5
+
+ assert original_vector == Vec3(1, 3, 5)
+
+ original_vector[0] = 3
+ original_vector[1] = 1
+ original_vector[2] = 1
+
+ assert original_vector == Vec3(3, 1, 1)
+
+ original_vector.set_x(-8)
+ original_vector.set_y(6)
+ original_vector.set_z(10)
+
+ assert original_vector.x == -8
+ assert original_vector.y == 6
+ assert original_vector.z == 10
+
+
+def test_vec3_sum():
+ original_vector = Vec3(2, 3, -2)
+
+ assert original_vector + original_vector == Vec3(4, 6, -4)
+ assert original_vector + 3 == Vec3(5, 6, 1)
+
+
+def test_vec3_power():
+ assert Vec3(2, -3, 2) ** 2 == Vec3(4, 9, 4)
+
+
+def test_vec3_len():
+ assert len(Vec3(2, -3, 10)) == 3
+
+def test_vec3_swizzle_mask():
+ original_vector = Vec3(3, 5, 1)
+
+ assert original_vector.xy == Vec2(3, 5)
+ assert original_vector.zxy == Vec3(1, 3, 5)
+
+
+def test_vec3_str():
+ assert str(Vec3F(2, 3, 1)) == "LVector3f(2, 3, 1)"
+ assert str(Vec3D(2, 3, 1)) == "LVector3d(2, 3, 1)"
diff --git a/tests/linmath/test_lvector4.py b/tests/linmath/test_lvector4.py
index 61768f1434..a8ac1797c2 100644
--- a/tests/linmath/test_lvector4.py
+++ b/tests/linmath/test_lvector4.py
@@ -1,18 +1,17 @@
from math import floor, ceil
import sys
+from panda3d.core import Vec2, Vec3, Vec4, Vec4F, Vec4D
import pytest
-from panda3d.core import Vec4
-
-
-original_vector = Vec4(2.3, -2.6, 3.5, 1)
reason = '''Rounding in Python 2.7 expects to return a float value, since it returns a Vector it
does not work. When Python 2.7 gets deprecated, remove this check.'''
@pytest.mark.skipif(sys.version_info < (3, 5), reason=reason)
def test_round():
+ original_vector = Vec4(2.3, -2.6, 3.5, 1)
+
rounded_vector = round(original_vector)
assert rounded_vector.x == 2
assert rounded_vector.y == -3
@@ -22,6 +21,8 @@ def test_round():
@pytest.mark.skipif(sys.version_info < (3, 5), reason=reason)
def test_floor():
+ original_vector = Vec4(2.3, -2.6, 3.5, 1)
+
rounded_vector = floor(original_vector)
assert rounded_vector.x == 2
assert rounded_vector.y == -3
@@ -31,8 +32,75 @@ def test_floor():
@pytest.mark.skipif(sys.version_info < (3, 5), reason=reason)
def test_ceil():
+ original_vector = Vec4(2.3, -2.6, 3.5, 1)
+
rounded_vector = ceil(original_vector)
assert rounded_vector.x == 3
assert rounded_vector.y == -2
assert rounded_vector.z == 4
assert rounded_vector.w == 1
+
+
+def test_vec4_creation():
+ assert Vec4(x=1, y=2, z=1, w=7) == Vec4(1, 2, 1, 7) == Vec4((1, 2, 1, 7))
+
+
+def test_vec4_getter_setter():
+ original_vector = Vec4(2, 3, 7, 9)
+
+ assert original_vector.x == 2
+ assert original_vector.y == 3
+ assert original_vector.z == 7
+ assert original_vector.w == 9
+
+ original_vector.x = 1
+ original_vector.y = 3
+ original_vector.z = 5
+ original_vector.w = -8
+
+ assert original_vector == Vec4(1, 3, 5, -8)
+
+ original_vector[0] = 3
+ original_vector[1] = 1
+ original_vector[2] = 1
+ original_vector[3] = -2
+
+ assert original_vector == Vec4(3, 1, 1, -2)
+
+ original_vector.set_x(-8)
+ original_vector.set_y(6)
+ original_vector.set_z(10)
+ original_vector.set_w(30)
+
+ assert original_vector.x == -8
+ assert original_vector.y == 6
+ assert original_vector.z == 10
+ assert original_vector.w == 30
+
+
+def test_vec4_sum():
+ original_vector = Vec4(2, 3, -2, 1)
+
+ assert original_vector + original_vector == Vec4(4, 6, -4, 2)
+ assert original_vector + 3 == Vec4(5, 6, 1, 4)
+
+
+def test_vec4_power():
+ assert Vec4(2, -3, 2, -1) ** 2 == Vec4(4, 9, 4, 1)
+
+
+def test_vec4_len():
+ assert len(Vec4(2, -3, 10, 30)) == 4
+
+
+def test_vec4_swizzle_mask():
+ original_vector = Vec4(3, 5, 1, 0)
+
+ assert original_vector.xy == Vec2(3, 5)
+ assert original_vector.zxy == Vec3(1, 3, 5)
+ assert original_vector.zxyw == Vec4(1, 3, 5, 0)
+
+
+def test_vec4_str():
+ assert str(Vec4F(2, 3, 1, 9)) == "LVector4f(2, 3, 1, 9)"
+ assert str(Vec4D(2, 3, 1, 9)) == "LVector4d(2, 3, 1, 9)"
diff --git a/tests/particles/test_particlesystem.py b/tests/particles/test_particlesystem.py
index 9e2ff85c20..41dce1ccaf 100644
--- a/tests/particles/test_particlesystem.py
+++ b/tests/particles/test_particlesystem.py
@@ -101,3 +101,38 @@ def test_particle_soft_start():
system.update(1)
assert system.get_living_particles() == 1
+
+
+def test_particle_burst_emission():
+ effect = ParticleEffect()
+ system = Particles("testSystem", 10)
+ effect.add_particles(system)
+
+ # Setup some dummy nodes, since it seems to want them
+ # We might normally call "start", but that calls "enable", which
+ # seems to assume that "base" exists and has physics and particle managers...
+ system.setRenderParent(NodePath(PandaNode("test")))
+ system.setSpawnRenderNodePath(NodePath(PandaNode("test")))
+ # However, we don't want normal emission, so we now soft-stop it immediately,
+ # before the system has a chance to update and emit.
+ effect.softStop()
+
+ # Now, a sanity-check: assert that we have no particles,
+ # Then update the system, and assert again that we
+ # have no particles. If so, then we're (hopefully)
+ # not emitting normally!
+
+ assert system.getLivingParticles() == 0
+ system.update(1)
+ assert system.getLivingParticles() == 0
+
+ # Now, the real test: emit a particle-burst!
+ effect.birthLitter()
+
+ # And assert that a particle has, in fact, been emitted.
+ assert system.getLivingParticles() == 1
+
+ # Check the snake-case version, too.
+ effect.birth_litter()
+
+ assert system.getLivingParticles() == 2