Init
This commit is contained in:
119
physx/snippets/compiler/cmake/CMakeLists.txt
Normal file
119
physx/snippets/compiler/cmake/CMakeLists.txt
Normal file
@ -0,0 +1,119 @@
|
||||
##
|
||||
## Redistribution and use in source and binary forms, with or without
|
||||
## modification, are permitted provided that the following conditions
|
||||
## are met:
|
||||
## * Redistributions of source code must retain the above copyright
|
||||
## notice, this list of conditions and the following disclaimer.
|
||||
## * Redistributions in binary form must reproduce the above copyright
|
||||
## notice, this list of conditions and the following disclaimer in the
|
||||
## documentation and/or other materials provided with the distribution.
|
||||
## * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
## contributors may be used to endorse or promote products derived
|
||||
## from this software without specific prior written permission.
|
||||
##
|
||||
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
## EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
## PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
## OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
##
|
||||
## Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
cmake_minimum_required(VERSION 3.7)
|
||||
project(Snippets C CXX)
|
||||
|
||||
IF(NOT DEFINED CMAKEMODULES_VERSION)
|
||||
SET(CMAKEMODULES_PATH $ENV{PM_CMakeModules_PATH} CACHE INTERNAL "Path to CMakeModules")
|
||||
SET(CMAKEMODULES_NAME $ENV{PM_CMakeModules_NAME} CACHE INTERNAL "CMakeModules name")
|
||||
SET(CMAKEMODULES_VERSION $ENV{PM_CMakeModules_VERSION} CACHE INTERNAL "CMakeModules version from generation batch")
|
||||
|
||||
#TODO: More elegance
|
||||
IF(NOT EXISTS ${CMAKEMODULES_PATH})
|
||||
MESSAGE(FATAL_ERROR "Could not find ${CMAKEMODULES_PATH}")
|
||||
ENDIF()
|
||||
|
||||
ENDIF()
|
||||
|
||||
SET(CMAKE_MODULE_PATH ${CMAKEMODULES_PATH})
|
||||
|
||||
# This is required to be defined by external callers!
|
||||
IF(NOT DEFINED PHYSX_ROOT_DIR)
|
||||
MESSAGE(FATAL_ERROR "PHYSX_ROOT_DIR variable wasn't set.")
|
||||
ENDIF()
|
||||
|
||||
IF(NOT EXISTS ${PHYSX_ROOT_DIR})
|
||||
MESSAGE(FATAL_ERROR "PHYSX_ROOT_DIR variable was invalid.")
|
||||
ENDIF()
|
||||
|
||||
INCLUDE(NvidiaBuildOptions)
|
||||
|
||||
|
||||
IF(CMAKE_CONFIGURATION_TYPES)
|
||||
SET(CMAKE_CONFIGURATION_TYPES debug checked profile release)
|
||||
SET(CMAKE_CONFIGURATION_TYPES "${CMAKE_CONFIGURATION_TYPES}" CACHE STRING
|
||||
"Reset config to what we need"
|
||||
FORCE)
|
||||
|
||||
# Need to define these at least once.
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS_CHECKED "/DEBUG")
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS_PROFILE "/DEBUG")
|
||||
|
||||
SET(CMAKE_EXE_LINKER_FLAGS_PROFILE "/DEBUG")
|
||||
SET(CMAKE_EXE_LINKER_FLAGS_CHECKED "/DEBUG")
|
||||
ENDIF()
|
||||
|
||||
|
||||
SET(PROJECT_CMAKE_FILES_DIR compiler/cmake)
|
||||
SET(PLATFORM_CMAKELISTS ${PHYSX_ROOT_DIR}/snippets/${PROJECT_CMAKE_FILES_DIR}/${TARGET_BUILD_PLATFORM}/CMakeLists.txt)
|
||||
|
||||
IF(NOT EXISTS ${PLATFORM_CMAKELISTS})
|
||||
MESSAGE(FATAL_ERROR "Unable to find platform CMakeLists.txt for ${TARGET_BUILD_PLATFORM} at ${PLATFORM_CMAKELISTS}")
|
||||
ENDIF()
|
||||
|
||||
# Include the platform specific CMakeLists
|
||||
INCLUDE(${PHYSX_ROOT_DIR}/snippets/${PROJECT_CMAKE_FILES_DIR}/${TARGET_BUILD_PLATFORM}/CMakeLists.txt)
|
||||
|
||||
SET(SOURCE_DISTRO_FILE_LIST "")
|
||||
|
||||
# Include all of the projects
|
||||
SET(SNIPPETS_LIST Articulation BVHStructure ContactModification ContactReport ContactReportCCD ConvexMeshCreate
|
||||
CustomJoint CustomProfiler DeformableMesh HelloWorld ImmediateArticulation ImmediateMode Joint MBP MultiThreading
|
||||
PrunerSerialization RaycastCCD Serialization SplitFetchResults
|
||||
SplitSim Stepper ToleranceScale TriangleMeshCreate Triggers)
|
||||
|
||||
LIST(APPEND SNIPPETS_LIST ${PLATFORM_SNIPPETS_LIST})
|
||||
|
||||
SET(SNIPPETS_VEHICLE_LIST NestedScene Vehicle4W VehicleContactMod VehicleMultiThreading
|
||||
VehicleNoDrive VehicleScale VehicleTank)
|
||||
|
||||
LIST(APPEND SNIPPETS_VEHICLE_LIST ${PLATFORM_SNIPPETS_VEHICLE_LIST})
|
||||
|
||||
IF(SNIPPET_RENDER_ENABLED)
|
||||
INCLUDE(SnippetRender.cmake)
|
||||
SET_PROPERTY(TARGET SnippetRender PROPERTY FOLDER "Snippets/Libraries only")
|
||||
ENDIF()
|
||||
|
||||
INCLUDE(SnippetUtils.cmake)
|
||||
SET_PROPERTY(TARGET SnippetUtils PROPERTY FOLDER "Snippets/Libraries only")
|
||||
|
||||
FOREACH(SNIPPET_NAME ${SNIPPETS_LIST})
|
||||
INCLUDE(SnippetTemplate.cmake)
|
||||
SET_PROPERTY(TARGET Snippet${SNIPPET_NAME} PROPERTY FOLDER "Snippets")
|
||||
ENDFOREACH()
|
||||
|
||||
FOREACH(SNIPPET_NAME ${SNIPPETS_VEHICLE_LIST})
|
||||
INCLUDE(SnippetVehicleTemplate.cmake)
|
||||
SET_PROPERTY(TARGET Snippet${SNIPPET_NAME} PROPERTY FOLDER "Snippets")
|
||||
ENDFOREACH()
|
||||
|
||||
IF(PX_GENERATE_SOURCE_DISTRO)
|
||||
FOREACH(FILE_NAME ${SOURCE_DISTRO_FILE_LIST})
|
||||
FILE(APPEND "${CMAKE_CURRENT_BINARY_DIR}/source_distro_list.txt" "${FILE_NAME}\n")
|
||||
ENDFOREACH()
|
||||
ENDIF()
|
||||
87
physx/snippets/compiler/cmake/SnippetRender.cmake
Normal file
87
physx/snippets/compiler/cmake/SnippetRender.cmake
Normal file
@ -0,0 +1,87 @@
|
||||
##
|
||||
## Redistribution and use in source and binary forms, with or without
|
||||
## modification, are permitted provided that the following conditions
|
||||
## are met:
|
||||
## * Redistributions of source code must retain the above copyright
|
||||
## notice, this list of conditions and the following disclaimer.
|
||||
## * Redistributions in binary form must reproduce the above copyright
|
||||
## notice, this list of conditions and the following disclaimer in the
|
||||
## documentation and/or other materials provided with the distribution.
|
||||
## * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
## contributors may be used to endorse or promote products derived
|
||||
## from this software without specific prior written permission.
|
||||
##
|
||||
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
## EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
## PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
## OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
##
|
||||
## Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#
|
||||
# Build SnippetRender common
|
||||
#
|
||||
|
||||
# Include here after the directories are defined so that the platform specific file can use the variables.
|
||||
include(${PHYSX_ROOT_DIR}/snippets/${PROJECT_CMAKE_FILES_DIR}/${TARGET_BUILD_PLATFORM}/SnippetRender.cmake)
|
||||
|
||||
SET(SNIPPETRENDER_FILES
|
||||
${PHYSX_ROOT_DIR}/snippets/snippetrender/SnippetCamera.cpp
|
||||
${PHYSX_ROOT_DIR}/snippets/snippetrender/SnippetCamera.h
|
||||
${PHYSX_ROOT_DIR}/snippets/snippetrender/SnippetRender.cpp
|
||||
${PHYSX_ROOT_DIR}/snippets/snippetrender/SnippetRender.h
|
||||
)
|
||||
|
||||
ADD_LIBRARY(SnippetRender STATIC
|
||||
${SNIPPETRENDER_FILES}
|
||||
|
||||
${SNIPPETRENDER_PLATFORM_FILES}
|
||||
)
|
||||
|
||||
TARGET_INCLUDE_DIRECTORIES(SnippetRender
|
||||
PRIVATE ${PHYSX_ROOT_DIR}/include
|
||||
PUBLIC ${SNIPPETRENDER_PLATFORM_INCLUDES}
|
||||
)
|
||||
|
||||
TARGET_COMPILE_DEFINITIONS(SnippetRender
|
||||
PRIVATE ${SNIPPETRENDER_COMPILE_DEFS}
|
||||
)
|
||||
|
||||
|
||||
IF(NV_USE_GAMEWORKS_OUTPUT_DIRS)
|
||||
SET_TARGET_PROPERTIES(SnippetRender PROPERTIES
|
||||
COMPILE_PDB_NAME_DEBUG "SnippetRender_static_${CMAKE_DEBUG_POSTFIX}"
|
||||
COMPILE_PDB_NAME_CHECKED "SnippetRender_static_${CMAKE_CHECKED_POSTFIX}"
|
||||
COMPILE_PDB_NAME_PROFILE "SnippetRender_static_${CMAKE_PROFILE_POSTFIX}"
|
||||
COMPILE_PDB_NAME_RELEASE "SnippetRender_static_${CMAKE_RELEASE_POSTFIX}"
|
||||
|
||||
ARCHIVE_OUTPUT_NAME_DEBUG "SnippetRender_static"
|
||||
ARCHIVE_OUTPUT_NAME_CHECKED "SnippetRender_static"
|
||||
ARCHIVE_OUTPUT_NAME_PROFILE "SnippetRender_static"
|
||||
ARCHIVE_OUTPUT_NAME_RELEASE "SnippetRender_static"
|
||||
)
|
||||
ELSE()
|
||||
SET_TARGET_PROPERTIES(SnippetRender PROPERTIES
|
||||
COMPILE_PDB_NAME_DEBUG "SnippetRender${CMAKE_DEBUG_POSTFIX}"
|
||||
COMPILE_PDB_NAME_CHECKED "SnippetRender${CMAKE_CHECKED_POSTFIX}"
|
||||
COMPILE_PDB_NAME_PROFILE "SnippetRender${CMAKE_PROFILE_POSTFIX}"
|
||||
COMPILE_PDB_NAME_RELEASE "SnippetRender${CMAKE_RELEASE_POSTFIX}"
|
||||
)
|
||||
ENDIF()
|
||||
|
||||
|
||||
TARGET_LINK_LIBRARIES(SnippetRender
|
||||
PUBLIC PhysXFoundation
|
||||
PUBLIC ${SNIPPETRENDER_PLATFORM_LINKED_LIBS})
|
||||
|
||||
IF(PX_GENERATE_SOURCE_DISTRO)
|
||||
LIST(APPEND SOURCE_DISTRO_FILE_LIST ${SNIPPETRENDER_FILES})
|
||||
LIST(APPEND SOURCE_DISTRO_FILE_LIST ${SNIPPETRENDER_PLATFORM_FILES})
|
||||
ENDIF()
|
||||
91
physx/snippets/compiler/cmake/SnippetTemplate.cmake
Normal file
91
physx/snippets/compiler/cmake/SnippetTemplate.cmake
Normal file
@ -0,0 +1,91 @@
|
||||
##
|
||||
## Redistribution and use in source and binary forms, with or without
|
||||
## modification, are permitted provided that the following conditions
|
||||
## are met:
|
||||
## * Redistributions of source code must retain the above copyright
|
||||
## notice, this list of conditions and the following disclaimer.
|
||||
## * Redistributions in binary form must reproduce the above copyright
|
||||
## notice, this list of conditions and the following disclaimer in the
|
||||
## documentation and/or other materials provided with the distribution.
|
||||
## * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
## contributors may be used to endorse or promote products derived
|
||||
## from this software without specific prior written permission.
|
||||
##
|
||||
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
## EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
## PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
## OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
##
|
||||
## Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#
|
||||
# Build Snippet common template
|
||||
#
|
||||
|
||||
# Include here after the directories are defined so that the platform specific file can use the variables.
|
||||
INCLUDE(${PHYSX_ROOT_DIR}/snippets/${PROJECT_CMAKE_FILES_DIR}/${TARGET_BUILD_PLATFORM}/SnippetTemplate.cmake)
|
||||
|
||||
STRING(TOLOWER ${SNIPPET_NAME} SNIPPET_NAME_LOWER)
|
||||
FILE(GLOB SnippetSources ${PHYSX_ROOT_DIR}/snippets/snippet${SNIPPET_NAME_LOWER}/*.cpp)
|
||||
FILE(GLOB SnippetHeaders ${PHYSX_ROOT_DIR}/snippets/snippet${SNIPPET_NAME_LOWER}/*.h)
|
||||
|
||||
ADD_EXECUTABLE(Snippet${SNIPPET_NAME} ${SNIPPET_BUNDLE}
|
||||
${SNIPPET_PLATFORM_SOURCES}
|
||||
|
||||
${SnippetSources}
|
||||
${SnippetHeaders}
|
||||
)
|
||||
|
||||
TARGET_INCLUDE_DIRECTORIES(Snippet${SNIPPET_NAME}
|
||||
PRIVATE ${SNIPPET_PLATFORM_INCLUDES}
|
||||
|
||||
PRIVATE ${PHYSX_ROOT_DIR}/include/
|
||||
PRIVATE ${PHYSX_ROOT_DIR}/source/physxextensions/src
|
||||
)
|
||||
|
||||
TARGET_COMPILE_DEFINITIONS(Snippet${SNIPPET_NAME}
|
||||
PRIVATE ${SNIPPET_COMPILE_DEFS}
|
||||
)
|
||||
|
||||
IF(NV_USE_GAMEWORKS_OUTPUT_DIRS)
|
||||
SET_TARGET_PROPERTIES(Snippet${SNIPPET_NAME} PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY_DEBUG ${PX_EXE_OUTPUT_DIRECTORY_DEBUG}${EXE_PLATFORM_DIR}
|
||||
RUNTIME_OUTPUT_DIRECTORY_PROFILE ${PX_EXE_OUTPUT_DIRECTORY_PROFILE}${EXE_PLATFORM_DIR}
|
||||
RUNTIME_OUTPUT_DIRECTORY_CHECKED ${PX_EXE_OUTPUT_DIRECTORY_CHECKED}${EXE_PLATFORM_DIR}
|
||||
RUNTIME_OUTPUT_DIRECTORY_RELEASE ${PX_EXE_OUTPUT_DIRECTORY_RELEASE}${EXE_PLATFORM_DIR}
|
||||
|
||||
OUTPUT_NAME Snippet${SNIPPET_NAME}${EXE_SUFFIX}
|
||||
)
|
||||
ELSE()
|
||||
IF(APPEND_CONFIG_NAME)
|
||||
SET_TARGET_PROPERTIES(Snippet${SNIPPET_NAME} PROPERTIES
|
||||
DEBUG_OUTPUT_NAME Snippet${SNIPPET_NAME}DEBUG
|
||||
PROFILE_OUTPUT_NAME Snippet${SNIPPET_NAME}PROFILE
|
||||
CHECKED_OUTPUT_NAME Snippet${SNIPPET_NAME}CHECKED
|
||||
RELEASE_OUTPUT_NAME Snippet${SNIPPET_NAME}
|
||||
)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
TARGET_LINK_LIBRARIES(Snippet${SNIPPET_NAME}
|
||||
PUBLIC PhysXExtensions PhysX PhysXPvdSDK PhysXVehicle PhysXCharacterKinematic PhysXCooking PhysXCommon PhysXFoundation SnippetUtils
|
||||
PUBLIC ${SNIPPET_PLATFORM_LINKED_LIBS})
|
||||
|
||||
IF(CUSTOM_SNIPPET_TARGET_PROPERTIES)
|
||||
SET_TARGET_PROPERTIES(Snippet${SNIPPET_NAME} PROPERTIES
|
||||
${CUSTOM_SNIPPET_TARGET_PROPERTIES}
|
||||
)
|
||||
ENDIF()
|
||||
|
||||
IF(PX_GENERATE_SOURCE_DISTRO)
|
||||
LIST(APPEND SOURCE_DISTRO_FILE_LIST ${SNIPPET_PLATFORM_SOURCES})
|
||||
LIST(APPEND SOURCE_DISTRO_FILE_LIST ${SnippetSources})
|
||||
LIST(APPEND SOURCE_DISTRO_FILE_LIST ${SnippetHeaders})
|
||||
ENDIF()
|
||||
84
physx/snippets/compiler/cmake/SnippetUtils.cmake
Normal file
84
physx/snippets/compiler/cmake/SnippetUtils.cmake
Normal file
@ -0,0 +1,84 @@
|
||||
##
|
||||
## Redistribution and use in source and binary forms, with or without
|
||||
## modification, are permitted provided that the following conditions
|
||||
## are met:
|
||||
## * Redistributions of source code must retain the above copyright
|
||||
## notice, this list of conditions and the following disclaimer.
|
||||
## * Redistributions in binary form must reproduce the above copyright
|
||||
## notice, this list of conditions and the following disclaimer in the
|
||||
## documentation and/or other materials provided with the distribution.
|
||||
## * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
## contributors may be used to endorse or promote products derived
|
||||
## from this software without specific prior written permission.
|
||||
##
|
||||
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
## EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
## PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
## OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
##
|
||||
## Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#
|
||||
# Build SnippetUtils common
|
||||
#
|
||||
|
||||
# Include here after the directories are defined so that the platform specific file can use the variables.
|
||||
INCLUDE(${PHYSX_ROOT_DIR}/snippets/${PROJECT_CMAKE_FILES_DIR}/${TARGET_BUILD_PLATFORM}/SnippetUtils.cmake)
|
||||
|
||||
SET(SNIPPETUTILS_FILES
|
||||
${PHYSX_ROOT_DIR}/snippets/snippetutils/SnippetUtils.cpp
|
||||
${PHYSX_ROOT_DIR}/snippets/snippetutils/SnippetUtils.h
|
||||
)
|
||||
|
||||
ADD_LIBRARY(SnippetUtils STATIC
|
||||
${SNIPPETUTILS_FILES}
|
||||
)
|
||||
|
||||
TARGET_INCLUDE_DIRECTORIES(SnippetUtils
|
||||
PRIVATE ${SNIPPETUTILS_PLATFORM_INCLUDES}
|
||||
|
||||
PRIVATE ${PHYSX_ROOT_DIR}/include
|
||||
PRIVATE ${PHYSX_ROOT_DIR}/source/common/src
|
||||
)
|
||||
|
||||
TARGET_COMPILE_DEFINITIONS(SnippetUtils
|
||||
PRIVATE ${SNIPPETUTILS_COMPILE_DEFS}
|
||||
)
|
||||
|
||||
|
||||
IF(NV_USE_GAMEWORKS_OUTPUT_DIRS)
|
||||
SET_TARGET_PROPERTIES(SnippetUtils PROPERTIES
|
||||
COMPILE_PDB_NAME_DEBUG "SnippetUtils_static_${CMAKE_DEBUG_POSTFIX}"
|
||||
COMPILE_PDB_NAME_CHECKED "SnippetUtils_static_${CMAKE_CHECKED_POSTFIX}"
|
||||
COMPILE_PDB_NAME_PROFILE "SnippetUtils_static_${CMAKE_PROFILE_POSTFIX}"
|
||||
COMPILE_PDB_NAME_RELEASE "SnippetUtils_static_${CMAKE_RELEASE_POSTFIX}"
|
||||
|
||||
ARCHIVE_OUTPUT_NAME_DEBUG "SnippetUtils_static"
|
||||
ARCHIVE_OUTPUT_NAME_CHECKED "SnippetUtils_static"
|
||||
ARCHIVE_OUTPUT_NAME_PROFILE "SnippetUtils_static"
|
||||
ARCHIVE_OUTPUT_NAME_RELEASE "SnippetUtils_static"
|
||||
)
|
||||
ELSE()
|
||||
SET_TARGET_PROPERTIES(SnippetUtils PROPERTIES
|
||||
COMPILE_PDB_NAME_DEBUG "SnippetUtils${CMAKE_DEBUG_POSTFIX}"
|
||||
COMPILE_PDB_NAME_CHECKED "SnippetUtils${CMAKE_CHECKED_POSTFIX}"
|
||||
COMPILE_PDB_NAME_PROFILE "SnippetUtils${CMAKE_PROFILE_POSTFIX}"
|
||||
COMPILE_PDB_NAME_RELEASE "SnippetUtils${CMAKE_RELEASE_POSTFIX}"
|
||||
)
|
||||
ENDIF()
|
||||
|
||||
|
||||
TARGET_LINK_LIBRARIES(SnippetUtils
|
||||
PUBLIC PhysXFoundation
|
||||
)
|
||||
|
||||
IF(PX_GENERATE_SOURCE_DISTRO)
|
||||
LIST(APPEND SOURCE_DISTRO_FILE_LIST ${SNIPPETUTILS_FILES})
|
||||
ENDIF()
|
||||
96
physx/snippets/compiler/cmake/SnippetVehicleTemplate.cmake
Normal file
96
physx/snippets/compiler/cmake/SnippetVehicleTemplate.cmake
Normal file
@ -0,0 +1,96 @@
|
||||
##
|
||||
## Redistribution and use in source and binary forms, with or without
|
||||
## modification, are permitted provided that the following conditions
|
||||
## are met:
|
||||
## * Redistributions of source code must retain the above copyright
|
||||
## notice, this list of conditions and the following disclaimer.
|
||||
## * Redistributions in binary form must reproduce the above copyright
|
||||
## notice, this list of conditions and the following disclaimer in the
|
||||
## documentation and/or other materials provided with the distribution.
|
||||
## * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
## contributors may be used to endorse or promote products derived
|
||||
## from this software without specific prior written permission.
|
||||
##
|
||||
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
## EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
## PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
## OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
##
|
||||
## Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#
|
||||
# Build Snippetvehicle common template
|
||||
#
|
||||
|
||||
# Include here after the directories are defined so that the platform specific file can use the variables.
|
||||
INCLUDE(${PHYSX_ROOT_DIR}/snippets/${PROJECT_CMAKE_FILES_DIR}/${TARGET_BUILD_PLATFORM}/SnippetVehicleTemplate.cmake)
|
||||
|
||||
STRING(TOLOWER ${SNIPPET_NAME} SNIPPET_NAME_LOWER)
|
||||
FILE(GLOB SnippetSources ${PHYSX_ROOT_DIR}/snippets/snippet${SNIPPET_NAME_LOWER}/*.cpp)
|
||||
FILE(GLOB VehicleSources ${PHYSX_ROOT_DIR}/snippets/snippetvehiclecommon/*.cpp)
|
||||
FILE(GLOB SnippetHeaders ${PHYSX_ROOT_DIR}/snippets/snippet${SNIPPET_NAME_LOWER}/*.h)
|
||||
FILE(GLOB VehicleHeaders ${PHYSX_ROOT_DIR}/snippets/snippetvehiclecommon/*.h)
|
||||
|
||||
ADD_EXECUTABLE(Snippet${SNIPPET_NAME} ${SNIPPET_BUNDLE}
|
||||
${SNIPPET_PLATFORM_SOURCES}
|
||||
|
||||
${SnippetSources}
|
||||
${VehicleSources}
|
||||
${SnippetHeaders}
|
||||
${VehicleHeaders}
|
||||
)
|
||||
|
||||
TARGET_INCLUDE_DIRECTORIES(Snippet${SNIPPET_NAME}
|
||||
PRIVATE ${SNIPPET_PLATFORM_INCLUDES}
|
||||
|
||||
PRIVATE ${PHYSX_ROOT_DIR}/include/
|
||||
)
|
||||
|
||||
TARGET_COMPILE_DEFINITIONS(Snippet${SNIPPET_NAME}
|
||||
PRIVATE ${SNIPPET_COMPILE_DEFS}
|
||||
)
|
||||
|
||||
IF(NV_USE_GAMEWORKS_OUTPUT_DIRS)
|
||||
SET_TARGET_PROPERTIES(Snippet${SNIPPET_NAME} PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY_DEBUG ${PX_EXE_OUTPUT_DIRECTORY_DEBUG}${EXE_PLATFORM_DIR}
|
||||
RUNTIME_OUTPUT_DIRECTORY_PROFILE ${PX_EXE_OUTPUT_DIRECTORY_PROFILE}${EXE_PLATFORM_DIR}
|
||||
RUNTIME_OUTPUT_DIRECTORY_CHECKED ${PX_EXE_OUTPUT_DIRECTORY_CHECKED}${EXE_PLATFORM_DIR}
|
||||
RUNTIME_OUTPUT_DIRECTORY_RELEASE ${PX_EXE_OUTPUT_DIRECTORY_RELEASE}${EXE_PLATFORM_DIR}
|
||||
|
||||
OUTPUT_NAME Snippet${SNIPPET_NAME}${EXE_SUFFIX}
|
||||
)
|
||||
ELSE()
|
||||
IF(APPEND_CONFIG_NAME)
|
||||
SET_TARGET_PROPERTIES(Snippet${SNIPPET_NAME} PROPERTIES
|
||||
DEBUG_OUTPUT_NAME Snippet${SNIPPET_NAME}DEBUG
|
||||
PROFILE_OUTPUT_NAME Snippet${SNIPPET_NAME}PROFILE
|
||||
CHECKED_OUTPUT_NAME Snippet${SNIPPET_NAME}CHECKED
|
||||
RELEASE_OUTPUT_NAME Snippet${SNIPPET_NAME}
|
||||
)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
TARGET_LINK_LIBRARIES(Snippet${SNIPPET_NAME}
|
||||
PUBLIC PhysXExtensions PhysX PhysXPvdSDK PhysXVehicle PhysXCharacterKinematic PhysXCooking PhysXCommon PhysXFoundation SnippetUtils
|
||||
PUBLIC ${SNIPPET_PLATFORM_LINKED_LIBS})
|
||||
|
||||
IF(CUSTOM_SNIPPET_TARGET_PROPERTIES)
|
||||
SET_TARGET_PROPERTIES(Snippet${SNIPPET_NAME} PROPERTIES
|
||||
${CUSTOM_SNIPPET_TARGET_PROPERTIES}
|
||||
)
|
||||
ENDIF()
|
||||
|
||||
IF(PX_GENERATE_SOURCE_DISTRO)
|
||||
LIST(APPEND SOURCE_DISTRO_FILE_LIST ${SNIPPET_PLATFORM_SOURCES})
|
||||
LIST(APPEND SOURCE_DISTRO_FILE_LIST ${SnippetSources})
|
||||
LIST(APPEND SOURCE_DISTRO_FILE_LIST ${VehicleSources})
|
||||
LIST(APPEND SOURCE_DISTRO_FILE_LIST ${SnippetHeaders})
|
||||
LIST(APPEND SOURCE_DISTRO_FILE_LIST ${VehicleHeaders})
|
||||
ENDIF()
|
||||
53
physx/snippets/compiler/cmake/android/CMakeLists.txt
Normal file
53
physx/snippets/compiler/cmake/android/CMakeLists.txt
Normal file
@ -0,0 +1,53 @@
|
||||
##
|
||||
## Redistribution and use in source and binary forms, with or without
|
||||
## modification, are permitted provided that the following conditions
|
||||
## are met:
|
||||
## * Redistributions of source code must retain the above copyright
|
||||
## notice, this list of conditions and the following disclaimer.
|
||||
## * Redistributions in binary form must reproduce the above copyright
|
||||
## notice, this list of conditions and the following disclaimer in the
|
||||
## documentation and/or other materials provided with the distribution.
|
||||
## * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
## contributors may be used to endorse or promote products derived
|
||||
## from this software without specific prior written permission.
|
||||
##
|
||||
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
## EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
## PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
## OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
##
|
||||
## Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
IF(NOT DEFINED PHYSX_ANDROID_COMPILE_DEFS)
|
||||
MESSAGE(FATAL ERROR "Snippets uses the PhysX compile defs, and they're not defined when they need to be.")
|
||||
ENDIF()
|
||||
|
||||
IF (NOT DEFINED PHYSX_CXX_FLAGS)
|
||||
MESSAGE(FATAL ERROR "Snippets uses the PhysX CXX flags, and they're not defined when they need to be.")
|
||||
ENDIF()
|
||||
|
||||
STRING(TOLOWER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_LOWERCASE)
|
||||
|
||||
# Get the CXX Flags from the Cached variables set by the PhysX CMakeLists
|
||||
SET(CMAKE_CXX_FLAGS "${PHYSX_CXX_FLAGS}")
|
||||
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "${PHYSX_CXX_FLAGS_DEBUG}")
|
||||
SET(CMAKE_CXX_FLAGS_CHECKED ${PHYSX_CXX_FLAGS_CHECKED})
|
||||
SET(CMAKE_CXX_FLAGS_PROFILE ${PHYSX_CXX_FLAGS_PROFILE})
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE ${PHYSX_CXX_FLAGS_RELEASE})
|
||||
|
||||
# Build PDBs for all configurations
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS "/DEBUG")
|
||||
|
||||
SET(PHYSX_LIB_PATH "${PHYSX_ROOT_DIR}/lib/${COMPILER_AND_PLATFORM}")
|
||||
|
||||
|
||||
|
||||
|
||||
54
physx/snippets/compiler/cmake/android/SnippetTemplate.cmake
Normal file
54
physx/snippets/compiler/cmake/android/SnippetTemplate.cmake
Normal file
@ -0,0 +1,54 @@
|
||||
##
|
||||
## Redistribution and use in source and binary forms, with or without
|
||||
## modification, are permitted provided that the following conditions
|
||||
## are met:
|
||||
## * Redistributions of source code must retain the above copyright
|
||||
## notice, this list of conditions and the following disclaimer.
|
||||
## * Redistributions in binary form must reproduce the above copyright
|
||||
## notice, this list of conditions and the following disclaimer in the
|
||||
## documentation and/or other materials provided with the distribution.
|
||||
## * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
## contributors may be used to endorse or promote products derived
|
||||
## from this software without specific prior written permission.
|
||||
##
|
||||
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
## EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
## PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
## OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
##
|
||||
## Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#
|
||||
# Build Snippet android template
|
||||
#
|
||||
|
||||
SET(SNIPPET_COMPILE_DEFS
|
||||
# Common to all configurations
|
||||
|
||||
${PHYSX_ANDROID_COMPILE_DEFS};ANDROID;GLES2;
|
||||
|
||||
$<$<CONFIG:debug>:${PHYSX_ANDROID_DEBUG_COMPILE_DEFS};>
|
||||
$<$<CONFIG:checked>:${PHYSX_ANDROID_CHECKED_COMPILE_DEFS};>
|
||||
$<$<CONFIG:profile>:${PHYSX_ANDROID_PROFILE_COMPILE_DEFS};>
|
||||
$<$<CONFIG:release>:${PHYSX_ANDROID_RELEASE_COMPILE_DEFS};>
|
||||
)
|
||||
|
||||
SET(SNIPPET_PLATFORM_SOURCES
|
||||
${PHYSX_ROOT_DIR}/snippets/snippetcommon/ClassicMain.cpp
|
||||
)
|
||||
|
||||
SET(SNIPPET_PLATFORM_INCLUDES
|
||||
|
||||
)
|
||||
|
||||
SET(SNIPPET_PLATFORM_LINKED_LIBS
|
||||
|
||||
)
|
||||
|
||||
44
physx/snippets/compiler/cmake/android/SnippetUtils.cmake
Normal file
44
physx/snippets/compiler/cmake/android/SnippetUtils.cmake
Normal file
@ -0,0 +1,44 @@
|
||||
##
|
||||
## Redistribution and use in source and binary forms, with or without
|
||||
## modification, are permitted provided that the following conditions
|
||||
## are met:
|
||||
## * Redistributions of source code must retain the above copyright
|
||||
## notice, this list of conditions and the following disclaimer.
|
||||
## * Redistributions in binary form must reproduce the above copyright
|
||||
## notice, this list of conditions and the following disclaimer in the
|
||||
## documentation and/or other materials provided with the distribution.
|
||||
## * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
## contributors may be used to endorse or promote products derived
|
||||
## from this software without specific prior written permission.
|
||||
##
|
||||
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
## EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
## PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
## OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
##
|
||||
## Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#
|
||||
# Build SnippetUtils
|
||||
#
|
||||
|
||||
SET(SNIPPETUTILS_PLATFORM_INCLUDES
|
||||
)
|
||||
|
||||
SET(SNIPPETUTILS_COMPILE_DEFS
|
||||
# Common to all configurations
|
||||
${PHYSX_ANDROID_COMPILE_DEFS};PX_PHYSX_STATIC_LIB;ANDROID;GLES2
|
||||
|
||||
$<$<CONFIG:debug>:${PHYSX_ANDROID_DEBUG_COMPILE_DEFS};>
|
||||
$<$<CONFIG:checked>:${PHYSX_ANDROID_CHECKED_COMPILE_DEFS};>
|
||||
$<$<CONFIG:profile>:${PHYSX_ANDROID_PROFILE_COMPILE_DEFS};>
|
||||
$<$<CONFIG:release>:${PHYSX_ANDROID_RELEASE_COMPILE_DEFS};>
|
||||
)
|
||||
|
||||
@ -0,0 +1,54 @@
|
||||
##
|
||||
## Redistribution and use in source and binary forms, with or without
|
||||
## modification, are permitted provided that the following conditions
|
||||
## are met:
|
||||
## * Redistributions of source code must retain the above copyright
|
||||
## notice, this list of conditions and the following disclaimer.
|
||||
## * Redistributions in binary form must reproduce the above copyright
|
||||
## notice, this list of conditions and the following disclaimer in the
|
||||
## documentation and/or other materials provided with the distribution.
|
||||
## * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
## contributors may be used to endorse or promote products derived
|
||||
## from this software without specific prior written permission.
|
||||
##
|
||||
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
## EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
## PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
## OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
##
|
||||
## Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#
|
||||
# Build SnippetVehicle android template
|
||||
#
|
||||
|
||||
SET(SNIPPET_COMPILE_DEFS
|
||||
# Common to all configurations
|
||||
|
||||
${PHYSX_ANDROID_COMPILE_DEFS};ANDROID;GLES2;
|
||||
|
||||
$<$<CONFIG:debug>:${PHYSX_ANDROID_DEBUG_COMPILE_DEFS};>
|
||||
$<$<CONFIG:checked>:${PHYSX_ANDROID_CHECKED_COMPILE_DEFS};>
|
||||
$<$<CONFIG:profile>:${PHYSX_ANDROID_PROFILE_COMPILE_DEFS};>
|
||||
$<$<CONFIG:release>:${PHYSX_ANDROID_RELEASE_COMPILE_DEFS};>
|
||||
)
|
||||
|
||||
SET(SNIPPET_PLATFORM_SOURCES
|
||||
${PHYSX_ROOT_DIR}/snippets/snippetcommon/ClassicMain.cpp
|
||||
)
|
||||
|
||||
SET(SNIPPET_PLATFORM_INCLUDES
|
||||
|
||||
)
|
||||
|
||||
SET(SNIPPET_PLATFORM_LINKED_LIBS
|
||||
|
||||
)
|
||||
|
||||
62
physx/snippets/compiler/cmake/ios/CMakeLists.txt
Normal file
62
physx/snippets/compiler/cmake/ios/CMakeLists.txt
Normal file
@ -0,0 +1,62 @@
|
||||
##
|
||||
## Redistribution and use in source and binary forms, with or without
|
||||
## modification, are permitted provided that the following conditions
|
||||
## are met:
|
||||
## * Redistributions of source code must retain the above copyright
|
||||
## notice, this list of conditions and the following disclaimer.
|
||||
## * Redistributions in binary form must reproduce the above copyright
|
||||
## notice, this list of conditions and the following disclaimer in the
|
||||
## documentation and/or other materials provided with the distribution.
|
||||
## * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
## contributors may be used to endorse or promote products derived
|
||||
## from this software without specific prior written permission.
|
||||
##
|
||||
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
## EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
## PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
## OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
##
|
||||
## Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
IF(NOT DEFINED PHYSX_IOS_COMPILE_DEFS)
|
||||
MESSAGE(FATAL ERROR "Snippets uses the PhysX compile defs, and they're not defined when they need to be.")
|
||||
ENDIF()
|
||||
|
||||
IF (NOT DEFINED PHYSX_CXX_FLAGS)
|
||||
MESSAGE(FATAL ERROR "Snippets uses the PhysX CXX flags, and they're not defined when they need to be.")
|
||||
ENDIF()
|
||||
|
||||
# Get the CXX Flags from the Cached variables set by the PhysX CMakeLists
|
||||
SET(CMAKE_CXX_FLAGS "${PHYSX_CXX_FLAGS}")
|
||||
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "${PHYSX_CXX_FLAGS_DEBUG}")
|
||||
SET(CMAKE_CXX_FLAGS_CHECKED ${PHYSX_CXX_FLAGS_CHECKED})
|
||||
SET(CMAKE_CXX_FLAGS_PROFILE ${PHYSX_CXX_FLAGS_PROFILE})
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE ${PHYSX_CXX_FLAGS_RELEASE})
|
||||
|
||||
# Build PDBs for all configurations
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS "/DEBUG")
|
||||
|
||||
SET(PHYSX_LIB_PATH "${PHYSX_ROOT_DIR}/lib/${COMPILER_AND_PLATFORM}")
|
||||
|
||||
SET(SNIPPET_BUNDLE MACOSX_BUNDLE)
|
||||
|
||||
SET(CUSTOM_SNIPPET_TARGET_PROPERTIES
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "iPhone Developer"
|
||||
XCODE_ATTRIBUTE_INFOPLIST_FILE "${PHYSX_ROOT_DIR}/snippets/deployment/ios64/PhysXAppIos64-Info.plist"
|
||||
MACOSX_BUNDLE_INFO_PLIST "${PHYSX_ROOT_DIR}/snippets/deployment/ios64/PhysXAppIos64-Info.plist"
|
||||
XCODE_ATTRIBUTE_INFOPLIST_PREPROCESS YES
|
||||
CMAKE_XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET "7.0"
|
||||
XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH "YES"
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
53
physx/snippets/compiler/cmake/ios/SnippetTemplate.cmake
Normal file
53
physx/snippets/compiler/cmake/ios/SnippetTemplate.cmake
Normal file
@ -0,0 +1,53 @@
|
||||
##
|
||||
## Redistribution and use in source and binary forms, with or without
|
||||
## modification, are permitted provided that the following conditions
|
||||
## are met:
|
||||
## * Redistributions of source code must retain the above copyright
|
||||
## notice, this list of conditions and the following disclaimer.
|
||||
## * Redistributions in binary form must reproduce the above copyright
|
||||
## notice, this list of conditions and the following disclaimer in the
|
||||
## documentation and/or other materials provided with the distribution.
|
||||
## * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
## contributors may be used to endorse or promote products derived
|
||||
## from this software without specific prior written permission.
|
||||
##
|
||||
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
## EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
## PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
## OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
##
|
||||
## Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#
|
||||
# Build Snippet ios template
|
||||
#
|
||||
|
||||
SET(SNIPPET_COMPILE_DEFS
|
||||
# Common to all configurations
|
||||
|
||||
${PHYSX_IOS_COMPILE_DEFS};
|
||||
|
||||
$<$<CONFIG:debug>:${PHYSX_IOS_DEBUG_COMPILE_DEFS};>
|
||||
$<$<CONFIG:checked>:${PHYSX_IOS_CHECKED_COMPILE_DEFS};>
|
||||
$<$<CONFIG:profile>:${PHYSX_IOS_PROFILE_COMPILE_DEFS};>
|
||||
$<$<CONFIG:release>:${PHYSX_IOS_RELEASE_COMPILE_DEFS};>
|
||||
)
|
||||
|
||||
SET(SNIPPET_PLATFORM_SOURCES
|
||||
${PHYSX_ROOT_DIR}/snippets/snippetcommon/ClassicMain.cpp
|
||||
)
|
||||
|
||||
SET(SNIPPET_PLATFORM_INCLUDES
|
||||
|
||||
)
|
||||
|
||||
SET(SNIPPET_PLATFORM_LINKED_LIBS
|
||||
|
||||
)
|
||||
45
physx/snippets/compiler/cmake/ios/SnippetUtils.cmake
Normal file
45
physx/snippets/compiler/cmake/ios/SnippetUtils.cmake
Normal file
@ -0,0 +1,45 @@
|
||||
##
|
||||
## Redistribution and use in source and binary forms, with or without
|
||||
## modification, are permitted provided that the following conditions
|
||||
## are met:
|
||||
## * Redistributions of source code must retain the above copyright
|
||||
## notice, this list of conditions and the following disclaimer.
|
||||
## * Redistributions in binary form must reproduce the above copyright
|
||||
## notice, this list of conditions and the following disclaimer in the
|
||||
## documentation and/or other materials provided with the distribution.
|
||||
## * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
## contributors may be used to endorse or promote products derived
|
||||
## from this software without specific prior written permission.
|
||||
##
|
||||
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
## EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
## PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
## OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
##
|
||||
## Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#
|
||||
# Build SnippetUtils
|
||||
#
|
||||
|
||||
SET(SNIPPETUTILS_PLATFORM_INCLUDES
|
||||
)
|
||||
|
||||
SET(SNIPPETUTILS_COMPILE_DEFS
|
||||
# Common to all configurations
|
||||
${PHYSX_IOS_COMPILE_DEFS};
|
||||
|
||||
$<$<CONFIG:debug>:${PHYSX_IOS_DEBUG_COMPILE_DEFS};>
|
||||
$<$<CONFIG:checked>:${PHYSX_IOS_CHECKED_COMPILE_DEFS};>
|
||||
$<$<CONFIG:profile>:${PHYSX_IOS_PROFILE_COMPILE_DEFS};>
|
||||
$<$<CONFIG:release>:${PHYSX_IOS_RELEASE_COMPILE_DEFS};>
|
||||
)
|
||||
|
||||
|
||||
@ -0,0 +1,53 @@
|
||||
##
|
||||
## Redistribution and use in source and binary forms, with or without
|
||||
## modification, are permitted provided that the following conditions
|
||||
## are met:
|
||||
## * Redistributions of source code must retain the above copyright
|
||||
## notice, this list of conditions and the following disclaimer.
|
||||
## * Redistributions in binary form must reproduce the above copyright
|
||||
## notice, this list of conditions and the following disclaimer in the
|
||||
## documentation and/or other materials provided with the distribution.
|
||||
## * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
## contributors may be used to endorse or promote products derived
|
||||
## from this software without specific prior written permission.
|
||||
##
|
||||
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
## EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
## PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
## OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
##
|
||||
## Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#
|
||||
# Build SnippetVehicle ios template
|
||||
#
|
||||
|
||||
SET(SNIPPET_COMPILE_DEFS
|
||||
# Common to all configurations
|
||||
|
||||
${PHYSX_IOS_COMPILE_DEFS};
|
||||
|
||||
$<$<CONFIG:debug>:${PHYSX_IOS_DEBUG_COMPILE_DEFS};>
|
||||
$<$<CONFIG:checked>:${PHYSX_IOS_CHECKED_COMPILE_DEFS};>
|
||||
$<$<CONFIG:profile>:${PHYSX_IOS_PROFILE_COMPILE_DEFS};>
|
||||
$<$<CONFIG:release>:${PHYSX_IOS_RELEASE_COMPILE_DEFS};>
|
||||
)
|
||||
|
||||
SET(SNIPPET_PLATFORM_SOURCES
|
||||
${PHYSX_ROOT_DIR}/snippets/snippetcommon/ClassicMain.cpp
|
||||
)
|
||||
|
||||
SET(SNIPPET_PLATFORM_INCLUDES
|
||||
|
||||
)
|
||||
|
||||
SET(SNIPPET_PLATFORM_LINKED_LIBS
|
||||
|
||||
)
|
||||
61
physx/snippets/compiler/cmake/linux/CMakeLists.txt
Normal file
61
physx/snippets/compiler/cmake/linux/CMakeLists.txt
Normal file
@ -0,0 +1,61 @@
|
||||
##
|
||||
## Redistribution and use in source and binary forms, with or without
|
||||
## modification, are permitted provided that the following conditions
|
||||
## are met:
|
||||
## * Redistributions of source code must retain the above copyright
|
||||
## notice, this list of conditions and the following disclaimer.
|
||||
## * Redistributions in binary form must reproduce the above copyright
|
||||
## notice, this list of conditions and the following disclaimer in the
|
||||
## documentation and/or other materials provided with the distribution.
|
||||
## * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
## contributors may be used to endorse or promote products derived
|
||||
## from this software without specific prior written permission.
|
||||
##
|
||||
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
## EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
## PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
## OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
##
|
||||
## Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
IF(NOT DEFINED PHYSX_LINUX_COMPILE_DEFS)
|
||||
MESSAGE(FATAL ERROR "Snippets uses the PhysX compile defs, and they're not defined when they need to be.")
|
||||
ENDIF()
|
||||
|
||||
IF (NOT DEFINED PHYSX_CXX_FLAGS)
|
||||
MESSAGE(FATAL ERROR "Snippets uses the PhysX CXX flags, and they're not defined when they need to be.")
|
||||
ENDIF()
|
||||
|
||||
IF(NOT DEFINED TINYXML2_PATH)
|
||||
SET(TINYXML2_PATH $ENV{PM_tinyxml2_PATH} CACHE INTERNAL "Path to tinyxml2")
|
||||
ENDIF()
|
||||
|
||||
# Get the CXX Flags from the Cached variables set by the PhysX CMakeLists
|
||||
SET(CMAKE_CXX_FLAGS "${PHYSX_CXX_FLAGS}")
|
||||
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "${PHYSX_CXX_FLAGS_DEBUG}")
|
||||
SET(CMAKE_CXX_FLAGS_CHECKED ${PHYSX_CXX_FLAGS_CHECKED})
|
||||
SET(CMAKE_CXX_FLAGS_PROFILE ${PHYSX_CXX_FLAGS_PROFILE})
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE ${PHYSX_CXX_FLAGS_RELEASE})
|
||||
|
||||
# Build PDBs for all configurations
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS "/DEBUG")
|
||||
|
||||
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath='$ORIGIN'")
|
||||
|
||||
# Include all of the projects
|
||||
SET(PLATFORM_SNIPPETS_LIST Convert LoadCollection)
|
||||
|
||||
IF(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64")
|
||||
SET(SNIPPET_RENDER_ENABLED 0)
|
||||
ELSE()
|
||||
SET(SNIPPET_RENDER_ENABLED 1)
|
||||
LIST(APPEND PLATFORM_SNIPPETS_LIST HelloGRB)
|
||||
ENDIF()
|
||||
48
physx/snippets/compiler/cmake/linux/SnippetRender.cmake
Normal file
48
physx/snippets/compiler/cmake/linux/SnippetRender.cmake
Normal file
@ -0,0 +1,48 @@
|
||||
##
|
||||
## Redistribution and use in source and binary forms, with or without
|
||||
## modification, are permitted provided that the following conditions
|
||||
## are met:
|
||||
## * Redistributions of source code must retain the above copyright
|
||||
## notice, this list of conditions and the following disclaimer.
|
||||
## * Redistributions in binary form must reproduce the above copyright
|
||||
## notice, this list of conditions and the following disclaimer in the
|
||||
## documentation and/or other materials provided with the distribution.
|
||||
## * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
## contributors may be used to endorse or promote products derived
|
||||
## from this software without specific prior written permission.
|
||||
##
|
||||
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
## EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
## PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
## OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
##
|
||||
## Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#
|
||||
# Build SnippetRender
|
||||
#
|
||||
find_package(OpenGL $ENV{PM_OpenGL_VERSION} CONFIG REQUIRED) # Pull in OpenGL and GLUT
|
||||
|
||||
SET(SNIPPETRENDER_COMPILE_DEFS
|
||||
# Common to all configurations
|
||||
|
||||
${PHYSX_LINUX_COMPILE_DEFS};
|
||||
|
||||
$<$<CONFIG:debug>:${PHYSX_LINUX_DEBUG_COMPILE_DEFS};>
|
||||
$<$<CONFIG:checked>:${PHYSX_LINUX_CHECKED_COMPILE_DEFS};>
|
||||
$<$<CONFIG:profile>:${PHYSX_LINUX_PROFILE_COMPILE_DEFS};>
|
||||
$<$<CONFIG:release>:${PHYSX_LINUX_RELEASE_COMPILE_DEFS};>
|
||||
)
|
||||
|
||||
|
||||
SET(SNIPPETRENDER_PLATFORM_INCLUDES
|
||||
)
|
||||
|
||||
SET(SNIPPETRENDER_PLATFORM_LINKED_LIBS GL GLUT GLU)
|
||||
90
physx/snippets/compiler/cmake/linux/SnippetTemplate.cmake
Normal file
90
physx/snippets/compiler/cmake/linux/SnippetTemplate.cmake
Normal file
@ -0,0 +1,90 @@
|
||||
##
|
||||
## Redistribution and use in source and binary forms, with or without
|
||||
## modification, are permitted provided that the following conditions
|
||||
## are met:
|
||||
## * Redistributions of source code must retain the above copyright
|
||||
## notice, this list of conditions and the following disclaimer.
|
||||
## * Redistributions in binary form must reproduce the above copyright
|
||||
## notice, this list of conditions and the following disclaimer in the
|
||||
## documentation and/or other materials provided with the distribution.
|
||||
## * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
## contributors may be used to endorse or promote products derived
|
||||
## from this software without specific prior written permission.
|
||||
##
|
||||
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
## EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
## PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
## OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
##
|
||||
## Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#
|
||||
# Build Snippet linux template
|
||||
#
|
||||
|
||||
IF(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64")
|
||||
SET(SNIPPET_COMPILE_DEFS
|
||||
# Common to all configurations
|
||||
|
||||
${PHYSX_LINUX_COMPILE_DEFS};
|
||||
|
||||
$<$<CONFIG:debug>:${PHYSX_LINUX_DEBUG_COMPILE_DEFS};>
|
||||
$<$<CONFIG:checked>:${PHYSX_LINUX_CHECKED_COMPILE_DEFS};>
|
||||
$<$<CONFIG:profile>:${PHYSX_LINUX_PROFILE_COMPILE_DEFS};>
|
||||
$<$<CONFIG:release>:${PHYSX_LINUX_RELEASE_COMPILE_DEFS};>
|
||||
)
|
||||
ELSE()
|
||||
SET(SNIPPET_COMPILE_DEFS
|
||||
# Common to all configurations
|
||||
|
||||
${PHYSX_LINUX_COMPILE_DEFS};RENDER_SNIPPET;
|
||||
|
||||
$<$<CONFIG:debug>:${PHYSX_LINUX_DEBUG_COMPILE_DEFS};>
|
||||
$<$<CONFIG:checked>:${PHYSX_LINUX_CHECKED_COMPILE_DEFS};>
|
||||
$<$<CONFIG:profile>:${PHYSX_LINUX_PROFILE_COMPILE_DEFS};>
|
||||
$<$<CONFIG:release>:${PHYSX_LINUX_RELEASE_COMPILE_DEFS};>
|
||||
)
|
||||
ENDIF()
|
||||
|
||||
SET(SNIPPET_PLATFORM_SOURCES
|
||||
${PHYSX_ROOT_DIR}/snippets/snippetcommon/ClassicMain.cpp
|
||||
)
|
||||
|
||||
SET(SNIPPET_PLATFORM_INCLUDES
|
||||
|
||||
)
|
||||
|
||||
IF(${SNIPPET_NAME} STREQUAL "ArticulationLoader")
|
||||
LIST(APPEND SNIPPET_PLATFORM_SOURCES
|
||||
${TINYXML2_PATH}/tinyxml2.h
|
||||
${TINYXML2_PATH}/tinyxml2.cpp
|
||||
)
|
||||
LIST(APPEND SNIPPET_PLATFORM_INCLUDES
|
||||
${TINYXML2_PATH}
|
||||
)
|
||||
ENDIF()
|
||||
|
||||
IF(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64")
|
||||
SET(SNIPPET_PLATFORM_LINKED_LIBS
|
||||
rt pthread dl
|
||||
)
|
||||
ELSE()
|
||||
SET(SNIPPET_PLATFORM_LINKED_LIBS
|
||||
SnippetRender GL GLU GLUT X11 rt pthread dl -Wl,-rpath='${ORIGIN}'
|
||||
)
|
||||
ENDIF()
|
||||
|
||||
IF(PX_GENERATE_GPU_STATIC_LIBRARIES)
|
||||
IF(${SNIPPET_NAME} STREQUAL "ConvexDecomposition")
|
||||
LIST(APPEND SNIPPET_PLATFORM_LINKED_LIBS VHACD)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
|
||||
45
physx/snippets/compiler/cmake/linux/SnippetUtils.cmake
Normal file
45
physx/snippets/compiler/cmake/linux/SnippetUtils.cmake
Normal file
@ -0,0 +1,45 @@
|
||||
##
|
||||
## Redistribution and use in source and binary forms, with or without
|
||||
## modification, are permitted provided that the following conditions
|
||||
## are met:
|
||||
## * Redistributions of source code must retain the above copyright
|
||||
## notice, this list of conditions and the following disclaimer.
|
||||
## * Redistributions in binary form must reproduce the above copyright
|
||||
## notice, this list of conditions and the following disclaimer in the
|
||||
## documentation and/or other materials provided with the distribution.
|
||||
## * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
## contributors may be used to endorse or promote products derived
|
||||
## from this software without specific prior written permission.
|
||||
##
|
||||
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
## EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
## PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
## OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
##
|
||||
## Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#
|
||||
# Build SnippetUtils
|
||||
#
|
||||
|
||||
SET(SNIPPETUTILS_PLATFORM_INCLUDES
|
||||
)
|
||||
|
||||
|
||||
SET(SNIPPETUTILS_COMPILE_DEFS
|
||||
# Common to all configurations
|
||||
|
||||
${PHYSX_LINUX_COMPILE_DEFS};PX_PHYSX_STATIC_LIB;
|
||||
|
||||
$<$<CONFIG:debug>:${PHYSX_LINUX_DEBUG_COMPILE_DEFS};>
|
||||
$<$<CONFIG:checked>:${PHYSX_LINUX_CHECKED_COMPILE_DEFS};>
|
||||
$<$<CONFIG:profile>:${PHYSX_LINUX_PROFILE_COMPILE_DEFS};>
|
||||
$<$<CONFIG:release>:${PHYSX_LINUX_RELEASE_COMPILE_DEFS};>
|
||||
)
|
||||
@ -0,0 +1,72 @@
|
||||
##
|
||||
## Redistribution and use in source and binary forms, with or without
|
||||
## modification, are permitted provided that the following conditions
|
||||
## are met:
|
||||
## * Redistributions of source code must retain the above copyright
|
||||
## notice, this list of conditions and the following disclaimer.
|
||||
## * Redistributions in binary form must reproduce the above copyright
|
||||
## notice, this list of conditions and the following disclaimer in the
|
||||
## documentation and/or other materials provided with the distribution.
|
||||
## * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
## contributors may be used to endorse or promote products derived
|
||||
## from this software without specific prior written permission.
|
||||
##
|
||||
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
## EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
## PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
## OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
##
|
||||
## Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#
|
||||
# Build SnippetVehicle linux template
|
||||
#
|
||||
|
||||
IF(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64")
|
||||
SET(SNIPPET_COMPILE_DEFS
|
||||
# Common to all configurations
|
||||
|
||||
${PHYSX_LINUX_COMPILE_DEFS};
|
||||
|
||||
$<$<CONFIG:debug>:${PHYSX_LINUX_DEBUG_COMPILE_DEFS};>
|
||||
$<$<CONFIG:checked>:${PHYSX_LINUX_CHECKED_COMPILE_DEFS};>
|
||||
$<$<CONFIG:profile>:${PHYSX_LINUX_PROFILE_COMPILE_DEFS};>
|
||||
$<$<CONFIG:release>:${PHYSX_LINUX_RELEASE_COMPILE_DEFS};>
|
||||
)
|
||||
ELSE()
|
||||
SET(SNIPPET_COMPILE_DEFS
|
||||
# Common to all configurations
|
||||
|
||||
${PHYSX_LINUX_COMPILE_DEFS};RENDER_SNIPPET;
|
||||
|
||||
$<$<CONFIG:debug>:${PHYSX_LINUX_DEBUG_COMPILE_DEFS};>
|
||||
$<$<CONFIG:checked>:${PHYSX_LINUX_CHECKED_COMPILE_DEFS};>
|
||||
$<$<CONFIG:profile>:${PHYSX_LINUX_PROFILE_COMPILE_DEFS};>
|
||||
$<$<CONFIG:release>:${PHYSX_LINUX_RELEASE_COMPILE_DEFS};>
|
||||
)
|
||||
ENDIF()
|
||||
|
||||
SET(SNIPPET_PLATFORM_SOURCES
|
||||
${PHYSX_ROOT_DIR}/snippets/snippetcommon/ClassicMain.cpp
|
||||
)
|
||||
|
||||
SET(SNIPPET_PLATFORM_INCLUDES
|
||||
|
||||
)
|
||||
|
||||
IF(${CMAKE_SYSTEM_PROCESSOR} STREQUAL "aarch64")
|
||||
SET(SNIPPET_PLATFORM_LINKED_LIBS
|
||||
rt pthread dl
|
||||
)
|
||||
ELSE()
|
||||
SET(SNIPPET_PLATFORM_LINKED_LIBS
|
||||
SnippetRender GL GLU GLUT X11 rt pthread dl
|
||||
)
|
||||
ENDIF()
|
||||
57
physx/snippets/compiler/cmake/mac/CMakeLists.txt
Normal file
57
physx/snippets/compiler/cmake/mac/CMakeLists.txt
Normal file
@ -0,0 +1,57 @@
|
||||
##
|
||||
## Redistribution and use in source and binary forms, with or without
|
||||
## modification, are permitted provided that the following conditions
|
||||
## are met:
|
||||
## * Redistributions of source code must retain the above copyright
|
||||
## notice, this list of conditions and the following disclaimer.
|
||||
## * Redistributions in binary form must reproduce the above copyright
|
||||
## notice, this list of conditions and the following disclaimer in the
|
||||
## documentation and/or other materials provided with the distribution.
|
||||
## * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
## contributors may be used to endorse or promote products derived
|
||||
## from this software without specific prior written permission.
|
||||
##
|
||||
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
## EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
## PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
## OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
##
|
||||
## Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
IF(NOT DEFINED PHYSX_MAC_COMPILE_DEFS)
|
||||
MESSAGE(FATAL ERROR "Snippets uses the PhysX compile defs, and they're not defined when they need to be.")
|
||||
ENDIF()
|
||||
|
||||
IF (NOT DEFINED PHYSX_CXX_FLAGS)
|
||||
MESSAGE(FATAL ERROR "Snippets uses the PhysX CXX flags, and they're not defined when they need to be.")
|
||||
ENDIF()
|
||||
|
||||
# Get the CXX Flags from the Cached variables set by the PhysX CMakeLists
|
||||
SET(CMAKE_CXX_FLAGS "${PHYSX_CXX_FLAGS}")
|
||||
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "${PHYSX_CXX_FLAGS_DEBUG}")
|
||||
SET(CMAKE_CXX_FLAGS_CHECKED ${PHYSX_CXX_FLAGS_CHECKED})
|
||||
SET(CMAKE_CXX_FLAGS_PROFILE ${PHYSX_CXX_FLAGS_PROFILE})
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE ${PHYSX_CXX_FLAGS_RELEASE})
|
||||
|
||||
# Build PDBs for all configurations
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS "")
|
||||
SET(CMAKE_EXE_LINKER_FLAGS_PROFILE "")
|
||||
SET(CMAKE_EXE_LINKER_FLAGS_CHECKED "")
|
||||
|
||||
SET(PHYSX_LIB_PATH "${PHYSX_ROOT_DIR}/lib/${COMPILER_AND_PLATFORM}")
|
||||
|
||||
|
||||
SET(SNIPPET_RENDER_ENABLED 1)
|
||||
|
||||
# Include all of the projects
|
||||
SET(PLATFORM_SNIPPETS_LIST Convert LoadCollection)
|
||||
|
||||
|
||||
44
physx/snippets/compiler/cmake/mac/SnippetRender.cmake
Normal file
44
physx/snippets/compiler/cmake/mac/SnippetRender.cmake
Normal file
@ -0,0 +1,44 @@
|
||||
##
|
||||
## Redistribution and use in source and binary forms, with or without
|
||||
## modification, are permitted provided that the following conditions
|
||||
## are met:
|
||||
## * Redistributions of source code must retain the above copyright
|
||||
## notice, this list of conditions and the following disclaimer.
|
||||
## * Redistributions in binary form must reproduce the above copyright
|
||||
## notice, this list of conditions and the following disclaimer in the
|
||||
## documentation and/or other materials provided with the distribution.
|
||||
## * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
## contributors may be used to endorse or promote products derived
|
||||
## from this software without specific prior written permission.
|
||||
##
|
||||
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
## EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
## PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
## OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
##
|
||||
## Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#
|
||||
# Build SnippetRender
|
||||
#
|
||||
|
||||
SET(SNIPPETRENDER_PLATFORM_INCLUDES
|
||||
)
|
||||
|
||||
SET(SNIPPETRENDER_COMPILE_DEFS
|
||||
# Common to all configurations
|
||||
${PHYSX_MAC_COMPILE_DEFS};
|
||||
|
||||
$<$<CONFIG:debug>:${PHYSX_MAC_DEBUG_COMPILE_DEFS};>
|
||||
$<$<CONFIG:checked>:${PHYSX_MAC_CHECKED_COMPILE_DEFS};>
|
||||
$<$<CONFIG:profile>:${PHYSX_MAC_PROFILE_COMPILE_DEFS};>
|
||||
$<$<CONFIG:release>:${PHYSX_MAC_RELEASE_COMPILE_DEFS};>
|
||||
)
|
||||
|
||||
63
physx/snippets/compiler/cmake/mac/SnippetTemplate.cmake
Normal file
63
physx/snippets/compiler/cmake/mac/SnippetTemplate.cmake
Normal file
@ -0,0 +1,63 @@
|
||||
##
|
||||
## Redistribution and use in source and binary forms, with or without
|
||||
## modification, are permitted provided that the following conditions
|
||||
## are met:
|
||||
## * Redistributions of source code must retain the above copyright
|
||||
## notice, this list of conditions and the following disclaimer.
|
||||
## * Redistributions in binary form must reproduce the above copyright
|
||||
## notice, this list of conditions and the following disclaimer in the
|
||||
## documentation and/or other materials provided with the distribution.
|
||||
## * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
## contributors may be used to endorse or promote products derived
|
||||
## from this software without specific prior written permission.
|
||||
##
|
||||
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
## EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
## PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
## OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
##
|
||||
## Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#
|
||||
# Build Snippet mac template
|
||||
#
|
||||
|
||||
SET(SNIPPET_COMPILE_DEFS
|
||||
# Common to all configurations
|
||||
|
||||
${PHYSX_MAC_COMPILE_DEFS};RENDER_SNIPPET;
|
||||
|
||||
$<$<CONFIG:debug>:${PHYSX_MAC_DEBUG_COMPILE_DEFS};>
|
||||
$<$<CONFIG:checked>:${PHYSX_MAC_CHECKED_COMPILE_DEFS};>
|
||||
$<$<CONFIG:profile>:${PHYSX_MAC_PROFILE_COMPILE_DEFS};>
|
||||
$<$<CONFIG:release>:${PHYSX_MAC_RELEASE_COMPILE_DEFS};>
|
||||
)
|
||||
|
||||
SET(SNIPPET_PLATFORM_SOURCES
|
||||
${PHYSX_ROOT_DIR}/snippets/snippetcommon/ClassicMain.cpp
|
||||
)
|
||||
|
||||
SET(SNIPPET_PLATFORM_INCLUDES
|
||||
|
||||
)
|
||||
|
||||
FIND_PACKAGE(OpenGL REQUIRED)
|
||||
FIND_PACKAGE(GLUT REQUIRED)
|
||||
|
||||
SET(SNIPPET_PLATFORM_LINKED_LIBS
|
||||
SnippetRender ${OPENGL_LIBRARIES} ${GLUT_LIBRARY}
|
||||
)
|
||||
|
||||
IF(${SNIPPET_NAME} STREQUAL "ConvexDecomposition")
|
||||
LIST(APPEND SNIPPET_PLATFORM_LINKED_LIBS
|
||||
VHACD
|
||||
)
|
||||
ENDIF()
|
||||
|
||||
44
physx/snippets/compiler/cmake/mac/SnippetUtils.cmake
Normal file
44
physx/snippets/compiler/cmake/mac/SnippetUtils.cmake
Normal file
@ -0,0 +1,44 @@
|
||||
##
|
||||
## Redistribution and use in source and binary forms, with or without
|
||||
## modification, are permitted provided that the following conditions
|
||||
## are met:
|
||||
## * Redistributions of source code must retain the above copyright
|
||||
## notice, this list of conditions and the following disclaimer.
|
||||
## * Redistributions in binary form must reproduce the above copyright
|
||||
## notice, this list of conditions and the following disclaimer in the
|
||||
## documentation and/or other materials provided with the distribution.
|
||||
## * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
## contributors may be used to endorse or promote products derived
|
||||
## from this software without specific prior written permission.
|
||||
##
|
||||
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
## EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
## PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
## OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
##
|
||||
## Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#
|
||||
# Build SnippetUtils
|
||||
#
|
||||
|
||||
SET(SNIPPETUTILS_PLATFORM_INCLUDES
|
||||
)
|
||||
|
||||
SET(SNIPPETUTILS_COMPILE_DEFS
|
||||
# Common to all configurations
|
||||
${PHYSX_MAC_COMPILE_DEFS};
|
||||
|
||||
$<$<CONFIG:debug>:${PHYSX_MAC_DEBUG_COMPILE_DEFS};>
|
||||
$<$<CONFIG:checked>:${PHYSX_MAC_CHECKED_COMPILE_DEFS};>
|
||||
$<$<CONFIG:profile>:${PHYSX_MAC_PROFILE_COMPILE_DEFS};>
|
||||
$<$<CONFIG:release>:${PHYSX_MAC_RELEASE_COMPILE_DEFS};>
|
||||
)
|
||||
|
||||
@ -0,0 +1,57 @@
|
||||
##
|
||||
## Redistribution and use in source and binary forms, with or without
|
||||
## modification, are permitted provided that the following conditions
|
||||
## are met:
|
||||
## * Redistributions of source code must retain the above copyright
|
||||
## notice, this list of conditions and the following disclaimer.
|
||||
## * Redistributions in binary form must reproduce the above copyright
|
||||
## notice, this list of conditions and the following disclaimer in the
|
||||
## documentation and/or other materials provided with the distribution.
|
||||
## * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
## contributors may be used to endorse or promote products derived
|
||||
## from this software without specific prior written permission.
|
||||
##
|
||||
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
## EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
## PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
## OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
##
|
||||
## Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#
|
||||
# Build SnippetVehicle mac template
|
||||
#
|
||||
|
||||
SET(SNIPPET_COMPILE_DEFS
|
||||
# Common to all configurations
|
||||
|
||||
${PHYSX_MAC_COMPILE_DEFS};RENDER_SNIPPET;
|
||||
|
||||
$<$<CONFIG:debug>:${PHYSX_MAC_DEBUG_COMPILE_DEFS};>
|
||||
$<$<CONFIG:checked>:${PHYSX_MAC_CHECKED_COMPILE_DEFS};>
|
||||
$<$<CONFIG:profile>:${PHYSX_MAC_PROFILE_COMPILE_DEFS};>
|
||||
$<$<CONFIG:release>:${PHYSX_MAC_RELEASE_COMPILE_DEFS};>
|
||||
)
|
||||
|
||||
SET(SNIPPET_PLATFORM_SOURCES
|
||||
${PHYSX_ROOT_DIR}/snippets/snippetcommon/ClassicMain.cpp
|
||||
)
|
||||
|
||||
SET(SNIPPET_PLATFORM_INCLUDES
|
||||
|
||||
)
|
||||
|
||||
FIND_PACKAGE(OpenGL REQUIRED)
|
||||
FIND_PACKAGE(GLUT REQUIRED)
|
||||
|
||||
SET(SNIPPET_PLATFORM_LINKED_LIBS
|
||||
SnippetRender ${OPENGL_LIBRARIES} ${GLUT_LIBRARY}
|
||||
)
|
||||
|
||||
71
physx/snippets/compiler/cmake/windows/CMakeLists.txt
Normal file
71
physx/snippets/compiler/cmake/windows/CMakeLists.txt
Normal file
@ -0,0 +1,71 @@
|
||||
##
|
||||
## Redistribution and use in source and binary forms, with or without
|
||||
## modification, are permitted provided that the following conditions
|
||||
## are met:
|
||||
## * Redistributions of source code must retain the above copyright
|
||||
## notice, this list of conditions and the following disclaimer.
|
||||
## * Redistributions in binary form must reproduce the above copyright
|
||||
## notice, this list of conditions and the following disclaimer in the
|
||||
## documentation and/or other materials provided with the distribution.
|
||||
## * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
## contributors may be used to endorse or promote products derived
|
||||
## from this software without specific prior written permission.
|
||||
##
|
||||
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
## EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
## PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
## OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
##
|
||||
## Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
IF(NOT DEFINED PHYSX_WINDOWS_COMPILE_DEFS)
|
||||
MESSAGE(FATAL ERROR "Snippets uses the PhysX compile defs, and they're not defined when they need to be.")
|
||||
ENDIF()
|
||||
|
||||
IF (NOT DEFINED PHYSX_CXX_FLAGS)
|
||||
MESSAGE(FATAL ERROR "Snippets uses the PhysX CXX flags, and they're not defined when they need to be.")
|
||||
ENDIF()
|
||||
|
||||
IF(NOT DEFINED TINYXML2_PATH)
|
||||
SET(TINYXML2_PATH $ENV{PM_tinyxml2_PATH} CACHE INTERNAL "Path to tinyxml2")
|
||||
ENDIF()
|
||||
|
||||
# Get the CXX Flags from the Cached variables set by the PhysX CMakeLists
|
||||
SET(CMAKE_CXX_FLAGS "${PHYSX_CXX_FLAGS} /EHsc")
|
||||
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG ${PHYSX_CXX_FLAGS_DEBUG})
|
||||
SET(CMAKE_CXX_FLAGS_CHECKED ${PHYSX_CXX_FLAGS_CHECKED})
|
||||
SET(CMAKE_CXX_FLAGS_PROFILE ${PHYSX_CXX_FLAGS_PROFILE})
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE ${PHYSX_CXX_FLAGS_RELEASE})
|
||||
|
||||
# Build PDBs for all configurations
|
||||
SET(CMAKE_SHARED_LINKER_FLAGS "/DEBUG")
|
||||
|
||||
SET(SLN_PHYSXDEVICE_PATH "$ENV{PM_PhysXDevice_PATH}/bin/x86/")
|
||||
|
||||
# Include ConfigureFileMT to expose that function
|
||||
INCLUDE(ConfigureFileMt)
|
||||
|
||||
SET(SNIPPET_RENDER_ENABLED 1)
|
||||
|
||||
# Include all of the projects
|
||||
SET(PLATFORM_SNIPPETS_LIST Convert LoadCollection DelayLoadHook)
|
||||
|
||||
IF(PUBLIC_RELEASE)
|
||||
LIST(APPEND PLATFORM_SNIPPETS_LIST HelloGRB)
|
||||
ELSE()
|
||||
IF(PX_GENERATE_GPU_PROJECTS)
|
||||
LIST(APPEND PLATFORM_SNIPPETS_LIST HelloGRB)
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
IF(PX_BUILDVHACD)
|
||||
LIST(APPEND PLATFORM_SNIPPETS_LIST ConvexDecomposition)
|
||||
ENDIF()
|
||||
52
physx/snippets/compiler/cmake/windows/SnippetRender.cmake
Normal file
52
physx/snippets/compiler/cmake/windows/SnippetRender.cmake
Normal file
@ -0,0 +1,52 @@
|
||||
##
|
||||
## Redistribution and use in source and binary forms, with or without
|
||||
## modification, are permitted provided that the following conditions
|
||||
## are met:
|
||||
## * Redistributions of source code must retain the above copyright
|
||||
## notice, this list of conditions and the following disclaimer.
|
||||
## * Redistributions in binary form must reproduce the above copyright
|
||||
## notice, this list of conditions and the following disclaimer in the
|
||||
## documentation and/or other materials provided with the distribution.
|
||||
## * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
## contributors may be used to endorse or promote products derived
|
||||
## from this software without specific prior written permission.
|
||||
##
|
||||
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
## EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
## PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
## OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
##
|
||||
## Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#
|
||||
# Build SnippetRender
|
||||
#
|
||||
|
||||
SET(SNIPPETRENDER_COMPILE_DEFS
|
||||
# Common to all configurations
|
||||
|
||||
${PHYSX_WINDOWS_COMPILE_DEFS};PX_PHYSX_STATIC_LIB;GLUT_NO_LIB_PRAGMA;${PHYSX_LIBTYPE_DEFS};${PHYSXGPU_LIBTYPE_DEFS}
|
||||
|
||||
$<$<CONFIG:debug>:${PHYSX_WINDOWS_DEBUG_COMPILE_DEFS};>
|
||||
$<$<CONFIG:checked>:${PHYSX_WINDOWS_CHECKED_COMPILE_DEFS};>
|
||||
$<$<CONFIG:profile>:${PHYSX_WINDOWS_PROFILE_COMPILE_DEFS};>
|
||||
$<$<CONFIG:release>:${PHYSX_WINDOWS_RELEASE_COMPILE_DEFS};>
|
||||
)
|
||||
|
||||
SET(SNIPPETRENDER_PLATFORM_FILES
|
||||
${PHYSX_ROOT_DIR}/snippets/graphics/include/win32/GL/glut.h
|
||||
)
|
||||
|
||||
# Include OpenGL
|
||||
SET(SNIPPETRENDER_PLATFORM_INCLUDES
|
||||
${PHYSX_ROOT_DIR}/snippets/Graphics/include/win32/GL
|
||||
)
|
||||
|
||||
SET(SNIPPETRENDER_PLATFORM_LINKED_LIBS ${PHYSX_ROOT_DIR}/snippets/Graphics/lib/win${LIBPATH_SUFFIX}/glut/glut32.lib opengl32.lib glu32.lib)
|
||||
80
physx/snippets/compiler/cmake/windows/SnippetTemplate.cmake
Normal file
80
physx/snippets/compiler/cmake/windows/SnippetTemplate.cmake
Normal file
@ -0,0 +1,80 @@
|
||||
##
|
||||
## Redistribution and use in source and binary forms, with or without
|
||||
## modification, are permitted provided that the following conditions
|
||||
## are met:
|
||||
## * Redistributions of source code must retain the above copyright
|
||||
## notice, this list of conditions and the following disclaimer.
|
||||
## * Redistributions in binary form must reproduce the above copyright
|
||||
## notice, this list of conditions and the following disclaimer in the
|
||||
## documentation and/or other materials provided with the distribution.
|
||||
## * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
## contributors may be used to endorse or promote products derived
|
||||
## from this software without specific prior written permission.
|
||||
##
|
||||
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
## EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
## PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
## OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
##
|
||||
## Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#
|
||||
# Build Snippet win template
|
||||
#
|
||||
|
||||
SET(SNIPPET_COMPILE_DEFS
|
||||
# Common to all configurations
|
||||
|
||||
${PHYSX_WINDOWS_COMPILE_DEFS};RENDER_SNIPPET;${PHYSX_LIBTYPE_DEFS};${PHYSXGPU_LIBTYPE_DEFS}
|
||||
|
||||
$<$<CONFIG:debug>:${PHYSX_WINDOWS_DEBUG_COMPILE_DEFS};>
|
||||
$<$<CONFIG:checked>:${PHYSX_WINDOWS_CHECKED_COMPILE_DEFS};>
|
||||
$<$<CONFIG:profile>:${PHYSX_WINDOWS_PROFILE_COMPILE_DEFS};>
|
||||
$<$<CONFIG:release>:${PHYSX_WINDOWS_RELEASE_COMPILE_DEFS};>
|
||||
)
|
||||
|
||||
SET(SNIPPET_PLATFORM_SOURCES
|
||||
${PHYSX_ROOT_DIR}/snippets/snippetcommon/ClassicMain.cpp
|
||||
${PHYSX_ROOT_DIR}/snippets/snippetcommon/SnippetPrint.h
|
||||
${PHYSX_ROOT_DIR}/snippets/snippetcommon/SnippetPVD.h
|
||||
)
|
||||
|
||||
SET(SNIPPET_PLATFORM_INCLUDES
|
||||
|
||||
)
|
||||
|
||||
SET(SNIPPET_PLATFORM_INCLUDES
|
||||
|
||||
)
|
||||
|
||||
SET(SNIPPET_PLATFORM_LINKED_LIBS
|
||||
SnippetRender
|
||||
)
|
||||
|
||||
IF(${SNIPPET_NAME} STREQUAL "ArticulationLoader")
|
||||
LIST(APPEND SNIPPET_PLATFORM_SOURCES
|
||||
${TINYXML2_PATH}/tinyxml2.h
|
||||
${TINYXML2_PATH}/tinyxml2.cpp
|
||||
)
|
||||
LIST(APPEND SNIPPET_PLATFORM_INCLUDES
|
||||
${TINYXML2_PATH}
|
||||
)
|
||||
|
||||
ENDIF()
|
||||
|
||||
IF(${SNIPPET_NAME} STREQUAL "ConvexDecomposition")
|
||||
LIST(APPEND SNIPPET_PLATFORM_LINKED_LIBS
|
||||
VHACD
|
||||
)
|
||||
ENDIF()
|
||||
|
||||
IF(PX_GENERATE_GPU_STATIC_LIBRARIES)
|
||||
LIST(APPEND SNIPPET_PLATFORM_LINKED_LIBS PhysXGpu ${CUDA_CUDA_LIBRARY})
|
||||
ENDIF()
|
||||
44
physx/snippets/compiler/cmake/windows/SnippetUtils.cmake
Normal file
44
physx/snippets/compiler/cmake/windows/SnippetUtils.cmake
Normal file
@ -0,0 +1,44 @@
|
||||
##
|
||||
## Redistribution and use in source and binary forms, with or without
|
||||
## modification, are permitted provided that the following conditions
|
||||
## are met:
|
||||
## * Redistributions of source code must retain the above copyright
|
||||
## notice, this list of conditions and the following disclaimer.
|
||||
## * Redistributions in binary form must reproduce the above copyright
|
||||
## notice, this list of conditions and the following disclaimer in the
|
||||
## documentation and/or other materials provided with the distribution.
|
||||
## * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
## contributors may be used to endorse or promote products derived
|
||||
## from this software without specific prior written permission.
|
||||
##
|
||||
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
## EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
## PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
## OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
##
|
||||
## Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#
|
||||
# Build SnippetUtils
|
||||
#
|
||||
|
||||
SET(SNIPPETUTILS_PLATFORM_INCLUDES
|
||||
)
|
||||
|
||||
SET(SNIPPETUTILS_COMPILE_DEFS
|
||||
# Common to all configurations
|
||||
|
||||
${PHYSX_WINDOWS_COMPILE_DEFS};${PHYSX_LIBTYPE_DEFS};${PHYSXGPU_LIBTYPE_DEFS}
|
||||
|
||||
$<$<CONFIG:debug>:${PHYSX_WINDOWS_DEBUG_COMPILE_DEFS};>
|
||||
$<$<CONFIG:checked>:${PHYSX_WINDOWS_CHECKED_COMPILE_DEFS};>
|
||||
$<$<CONFIG:profile>:${PHYSX_WINDOWS_PROFILE_COMPILE_DEFS};>
|
||||
$<$<CONFIG:release>:${PHYSX_WINDOWS_RELEASE_COMPILE_DEFS};>
|
||||
)
|
||||
@ -0,0 +1,61 @@
|
||||
##
|
||||
## Redistribution and use in source and binary forms, with or without
|
||||
## modification, are permitted provided that the following conditions
|
||||
## are met:
|
||||
## * Redistributions of source code must retain the above copyright
|
||||
## notice, this list of conditions and the following disclaimer.
|
||||
## * Redistributions in binary form must reproduce the above copyright
|
||||
## notice, this list of conditions and the following disclaimer in the
|
||||
## documentation and/or other materials provided with the distribution.
|
||||
## * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
## contributors may be used to endorse or promote products derived
|
||||
## from this software without specific prior written permission.
|
||||
##
|
||||
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
## EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
## PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
## EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
## PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
## PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
## OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
##
|
||||
## Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#
|
||||
# Build Snippet win template
|
||||
#
|
||||
|
||||
SET(SNIPPET_COMPILE_DEFS
|
||||
# Common to all configurations
|
||||
|
||||
${PHYSX_WINDOWS_COMPILE_DEFS};RENDER_SNIPPET;${PHYSX_LIBTYPE_DEFS};${PHYSXGPU_LIBTYPE_DEFS}
|
||||
|
||||
$<$<CONFIG:debug>:${PHYSX_WINDOWS_DEBUG_COMPILE_DEFS};>
|
||||
$<$<CONFIG:checked>:${PHYSX_WINDOWS_CHECKED_COMPILE_DEFS};>
|
||||
$<$<CONFIG:profile>:${PHYSX_WINDOWS_PROFILE_COMPILE_DEFS};>
|
||||
$<$<CONFIG:release>:${PHYSX_WINDOWS_RELEASE_COMPILE_DEFS};>
|
||||
)
|
||||
|
||||
SET(SNIPPET_PLATFORM_SOURCES
|
||||
${PHYSX_ROOT_DIR}/snippets/snippetcommon/ClassicMain.cpp
|
||||
)
|
||||
|
||||
SET(SNIPPET_PLATFORM_INCLUDES
|
||||
|
||||
)
|
||||
|
||||
SET(SNIPPET_PLATFORM_LINKED_LIBS
|
||||
SnippetRender
|
||||
)
|
||||
|
||||
IF(PX_GENERATE_GPU_STATIC_LIBRARIES)
|
||||
LIST(APPEND SNIPPET_PLATFORM_LINKED_LIBS PhysXGpu)
|
||||
ENDIF()
|
||||
|
||||
IF(NOT PX_GENERATE_STATIC_LIBRARIES)
|
||||
LIST(APPEND SNIPPET_PLATFORM_LINKED_LIBS PhysXTask)
|
||||
ENDIF()
|
||||
38
physx/snippets/deployment/ios/PhysXAppIos-Info.plist
Normal file
38
physx/snippets/deployment/ios/PhysXAppIos-Info.plist
Normal file
@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>UIFileSharingEnabled</key>
|
||||
<true/>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string></string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.yourcompany.${PRODUCT_NAME}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<false/>
|
||||
<key>NSMainNibFile</key>
|
||||
<string>MainWindow</string>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UIInterfaceOrientation</key>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</dict>
|
||||
</plist>
|
||||
38
physx/snippets/deployment/ios64/PhysXAppIos64-Info.plist
Normal file
38
physx/snippets/deployment/ios64/PhysXAppIos64-Info.plist
Normal file
@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>UIFileSharingEnabled</key>
|
||||
<true/>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string></string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.yourcompany.${PRODUCT_NAME}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<false/>
|
||||
<key>NSMainNibFile</key>
|
||||
<string>MainWindow</string>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UIInterfaceOrientation</key>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</dict>
|
||||
</plist>
|
||||
34
physx/snippets/deployment/osx/PhysXAppOsx-Info.plist
Normal file
34
physx/snippets/deployment/osx/PhysXAppOsx-Info.plist
Normal file
@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string></string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>nvidia.${PRODUCT_NAME}</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2014 Simon Schirm. All rights reserved.</string>
|
||||
<key>NSMainNibFile</key>
|
||||
<string>MainMenu</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
</dict>
|
||||
</plist>
|
||||
786
physx/snippets/graphics/include/win32/GL/glut.h
Normal file
786
physx/snippets/graphics/include/win32/GL/glut.h
Normal file
@ -0,0 +1,786 @@
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#ifndef __glut_h__
|
||||
#define __glut_h__
|
||||
|
||||
/* Copyright (c) Mark J. Kilgard, 1994, 1995, 1996, 1998, 2000, 2006. */
|
||||
|
||||
/* This program is freely distributable without licensing fees and is
|
||||
provided without guarantee or warrantee expressed or implied. This
|
||||
program is -not- in the public domain. */
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
/* GLUT 3.7 now tries to avoid including <windows.h>
|
||||
to avoid name space pollution, but Win32's <GL/gl.h>
|
||||
needs APIENTRY and WINGDIAPI defined properly. */
|
||||
# if 0
|
||||
/* This would put tons of macros in our clean name space. */
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# include <windows.h>
|
||||
# else
|
||||
/* XXX This is from Win32's <windef.h> */
|
||||
# ifndef APIENTRY
|
||||
# define GLUT_APIENTRY_DEFINED
|
||||
/* Cygwin and MingW32 are two free GNU-based Open Source compilation
|
||||
environments for Win32. Note that __CYGWIN32__ is deprecated
|
||||
in favor of simply __CYGWIN__. */
|
||||
# if defined(__MINGW32__) || defined(__CYGWIN32__) || defined(__CYGWIN__)
|
||||
# ifdef i386
|
||||
# define APIENTRY __attribute__ ((stdcall))
|
||||
# else
|
||||
# define APIENTRY
|
||||
# endif
|
||||
# else
|
||||
# if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED)
|
||||
# define APIENTRY __stdcall
|
||||
# else
|
||||
# define APIENTRY
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
/* XXX This is from Win32's <winnt.h> */
|
||||
# ifndef CALLBACK
|
||||
# if defined(__MINGW32__) || defined(__CYGWIN32__) || defined(__CYGWIN__)
|
||||
# define CALLBACK __attribute__ ((stdcall))
|
||||
# else
|
||||
# if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED)
|
||||
# define CALLBACK __stdcall
|
||||
# else
|
||||
# define CALLBACK
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
/* XXX This is from Win32's <wingdi.h> and <winnt.h> */
|
||||
# ifndef WINGDIAPI
|
||||
# define GLUT_WINGDIAPI_DEFINED
|
||||
# if defined(__MINGW32__) || defined(__CYGWIN32__) || defined(__CYGWIN__)
|
||||
# define WINGDIAPI
|
||||
# else
|
||||
# define WINGDIAPI __declspec(dllimport)
|
||||
# endif
|
||||
# endif
|
||||
# if defined(__MINGW32__) || defined(__CYGWIN32__) || defined(__CYGWIN__)
|
||||
/* Rely on Cygwin32/MingW32 <stddef.h> to set wchar_t. */
|
||||
/* XXX Warning. The Cygwin32/MingW32 definition for wchar_t
|
||||
is an "int" instead of the "short" used by Windows. */
|
||||
# include <stddef.h>
|
||||
# else
|
||||
/* XXX This is from Win32's <ctype.h> */
|
||||
# ifndef _WCHAR_T_DEFINED
|
||||
typedef unsigned short wchar_t;
|
||||
# define _WCHAR_T_DEFINED
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
|
||||
/* To disable automatic library usage for GLUT, define GLUT_NO_LIB_PRAGMA
|
||||
in your compile preprocessor options. */
|
||||
# if !defined(GLUT_BUILDING_LIB) && !defined(GLUT_NO_LIB_PRAGMA)
|
||||
# pragma comment (lib, "winmm.lib") /* link with Windows MultiMedia lib */
|
||||
# pragma comment (lib, "user32.lib") /* link with Windows User lib */
|
||||
# pragma comment (lib, "gdi32.lib") /* link with Windows GDI lib */
|
||||
/* To enable automatic SGI OpenGL for Windows library usage for GLUT,
|
||||
define GLUT_USE_SGI_OPENGL in your compile preprocessor options. */
|
||||
# ifdef GLUT_USE_SGI_OPENGL
|
||||
# pragma comment (lib, "opengl.lib") /* link with SGI OpenGL for Windows lib */
|
||||
# pragma comment (lib, "glu.lib") /* link with SGI OpenGL Utility lib */
|
||||
# if defined(GLUT_STATIC_LIB)
|
||||
# pragma comment (lib, "glutstatic.lib") /* link with static Win32 GLUT lib */
|
||||
# else
|
||||
# pragma comment (lib, "glut.lib") /* link with Win32 GLUT lib */
|
||||
# endif
|
||||
# else
|
||||
# pragma comment (lib, "opengl32.lib") /* link with Microsoft OpenGL lib */
|
||||
# pragma comment (lib, "glu32.lib") /* link with Microsoft OpenGL Utility lib */
|
||||
# if defined(GLUT_STATIC_LIB)
|
||||
# pragma comment (lib, "glutstatic.lib") /* link with static Win32 GLUT lib */
|
||||
# else
|
||||
# pragma comment (lib, "glut32.lib") /* link with Win32 GLUT lib */
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
|
||||
/* To disable supression of annoying warnings about floats being promoted
|
||||
to doubles, define GLUT_NO_WARNING_DISABLE in your compile preprocessor
|
||||
options. */
|
||||
# if defined(_MSC_VER) && !defined(GLUT_NO_WARNING_DISABLE)
|
||||
# pragma warning (disable:4244) /* Disable bogus VC++ 4.2 conversion warnings. */
|
||||
# pragma warning (disable:4305) /* VC++ 5.0 version of above warning. */
|
||||
# endif
|
||||
|
||||
/* Win32 has an annoying issue where there are multiple C run-time
|
||||
libraries (CRTs). If the executable is linked with a different CRT
|
||||
from the GLUT DLL, the GLUT DLL will not share the same CRT static
|
||||
data seen by the executable. In particular, atexit callbacks registered
|
||||
in the executable will not be called if GLUT calls its (different)
|
||||
exit routine). GLUT is typically built with the
|
||||
"/MD" option (the CRT with multithreading DLL support), but the Visual
|
||||
C++ linker default is "/ML" (the single threaded CRT).
|
||||
|
||||
One workaround to this issue is requiring users to always link with
|
||||
the same CRT as GLUT is compiled with. That requires users supply a
|
||||
non-standard option. GLUT 3.7 has its own built-in workaround where
|
||||
the executable's "exit" function pointer is covertly passed to GLUT.
|
||||
GLUT then calls the executable's exit function pointer to ensure that
|
||||
any "atexit" calls registered by the application are called if GLUT
|
||||
needs to exit.
|
||||
|
||||
Note that the __glut*WithExit routines should NEVER be called directly.
|
||||
To avoid the atexit workaround, #define GLUT_DISABLE_ATEXIT_HACK. */
|
||||
|
||||
/* XXX This is from Win32's <process.h> */
|
||||
# if !defined(_MSC_VER) && !defined(__cdecl)
|
||||
/* Define __cdecl for non-Microsoft compilers. */
|
||||
# define __cdecl
|
||||
# define GLUT_DEFINED___CDECL
|
||||
# endif
|
||||
# ifndef _CRTIMP
|
||||
# ifdef _NTSDK
|
||||
/* Definition compatible with NT SDK */
|
||||
# define _CRTIMP
|
||||
# else
|
||||
/* Current definition */
|
||||
# ifdef _DLL
|
||||
# define _CRTIMP __declspec(dllimport)
|
||||
# else
|
||||
# define _CRTIMP
|
||||
# endif
|
||||
# endif
|
||||
# define GLUT_DEFINED__CRTIMP
|
||||
# endif
|
||||
|
||||
/* GLUT API entry point declarations for Win32. */
|
||||
# ifdef GLUT_BUILDING_LIB
|
||||
/* MSDN article 835326 says "When you build a DLL by using the 64-bit
|
||||
version of the Microsoft Visual C++ Compiler and Linker, you may
|
||||
receive Linker error number LNK4197 if a function has been declared
|
||||
for export more than one time." GLUT builds with glut.def that
|
||||
declares GLUT's EXPORTS list so do not use __declspec(dllexport)
|
||||
to keep 64-bit compiler happy. */
|
||||
# define GLUTAPI /*__declspec(dllexport)*/
|
||||
# else
|
||||
# ifdef _DLL
|
||||
# define GLUTAPI __declspec(dllimport)
|
||||
# else
|
||||
# define GLUTAPI extern
|
||||
# endif
|
||||
# endif
|
||||
|
||||
/* GLUT callback calling convention for Win32. */
|
||||
# define GLUTCALLBACK __cdecl
|
||||
|
||||
# if (_MSC_VER >= 800) || defined(__MINGW32__) || defined(_STDCALL_SUPPORTED) || defined(__CYGWIN32__)
|
||||
# define GLUTAPIENTRY __stdcall
|
||||
# else
|
||||
# define GLUTAPIENTRY
|
||||
# endif
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# ifndef GLUT_BUILDING_LIB
|
||||
# if __BORLANDC__
|
||||
# if defined(_BUILDRTLDLL)
|
||||
void __cdecl __export exit(int __status);
|
||||
# else
|
||||
void __cdecl exit(int __status);
|
||||
# endif
|
||||
# else
|
||||
# if _MSC_VER >= 1200
|
||||
extern _CRTIMP __declspec(noreturn) void __cdecl exit(int);
|
||||
# else
|
||||
extern _CRTIMP void __cdecl exit(int);
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#else
|
||||
/* non-Win32 case. */
|
||||
/* Define APIENTRY and CALLBACK to nothing if we aren't on Win32. */
|
||||
# define APIENTRY
|
||||
# define GLUT_APIENTRY_DEFINED
|
||||
# define CALLBACK
|
||||
/* Define GLUTAPI and GLUTCALLBACK as below if we aren't on Win32. */
|
||||
# define GLUTAPI extern
|
||||
# define GLUTAPIENTRY
|
||||
# define GLUTCALLBACK
|
||||
/* Prototype exit for the non-Win32 case (see above). */
|
||||
# ifdef __GNUC__
|
||||
extern void exit(int __status) __attribute__((__noreturn__));
|
||||
# else
|
||||
extern void exit(int);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
GLUT API revision history:
|
||||
|
||||
GLUT_API_VERSION is updated to reflect incompatible GLUT
|
||||
API changes (interface changes, semantic changes, deletions,
|
||||
or additions).
|
||||
|
||||
GLUT_API_VERSION=1 First public release of GLUT. 11/29/94
|
||||
|
||||
GLUT_API_VERSION=2 Added support for OpenGL/GLX multisampling,
|
||||
extension. Supports new input devices like tablet, dial and button
|
||||
box, and Spaceball. Easy to query OpenGL extensions.
|
||||
|
||||
GLUT_API_VERSION=3 glutMenuStatus added.
|
||||
|
||||
GLUT_API_VERSION=4 glutInitDisplayString, glutWarpPointer,
|
||||
glutBitmapLength, glutStrokeLength, glutWindowStatusFunc, dynamic
|
||||
video resize subAPI, glutPostWindowRedisplay, glutKeyboardUpFunc,
|
||||
glutSpecialUpFunc, glutIgnoreKeyRepeat, glutSetKeyRepeat,
|
||||
glutJoystickFunc, glutForceJoystickFunc, glutStrokeWidthf,
|
||||
glutStrokeLengthf (NOT FINALIZED!).
|
||||
**/
|
||||
#ifndef GLUT_API_VERSION /* allow this to be overriden */
|
||||
#define GLUT_API_VERSION 3
|
||||
#endif
|
||||
|
||||
/**
|
||||
GLUT implementation revision history:
|
||||
|
||||
GLUT_XLIB_IMPLEMENTATION is updated to reflect both GLUT
|
||||
API revisions and implementation revisions (ie, bug fixes).
|
||||
|
||||
GLUT_XLIB_IMPLEMENTATION=1 mjk's first public release of
|
||||
GLUT Xlib-based implementation. 11/29/94
|
||||
|
||||
GLUT_XLIB_IMPLEMENTATION=2 mjk's second public release of
|
||||
GLUT Xlib-based implementation providing GLUT version 2
|
||||
interfaces.
|
||||
|
||||
GLUT_XLIB_IMPLEMENTATION=3 mjk's GLUT 2.2 images. 4/17/95
|
||||
|
||||
GLUT_XLIB_IMPLEMENTATION=4 mjk's GLUT 2.3 images. 6/?/95
|
||||
|
||||
GLUT_XLIB_IMPLEMENTATION=5 mjk's GLUT 3.0 images. 10/?/95
|
||||
|
||||
GLUT_XLIB_IMPLEMENTATION=7 mjk's GLUT 3.1+ with glutWarpPoitner. 7/24/96
|
||||
|
||||
GLUT_XLIB_IMPLEMENTATION=8 mjk's GLUT 3.1+ with glutWarpPoitner
|
||||
and video resize. 1/3/97
|
||||
|
||||
GLUT_XLIB_IMPLEMENTATION=9 mjk's GLUT 3.4 release with early GLUT 4 routines.
|
||||
|
||||
GLUT_XLIB_IMPLEMENTATION=11 Mesa 2.5's GLUT 3.6 release.
|
||||
|
||||
GLUT_XLIB_IMPLEMENTATION=12 mjk's GLUT 3.6 release with early GLUT 4 routines + signal handling.
|
||||
|
||||
GLUT_XLIB_IMPLEMENTATION=13 mjk's GLUT 3.7 beta with GameGLUT support.
|
||||
|
||||
GLUT_XLIB_IMPLEMENTATION=14 mjk's GLUT 3.7 beta with f90gl friend interface.
|
||||
|
||||
GLUT_XLIB_IMPLEMENTATION=15 mjk's GLUT 3.7 beta sync'ed with Mesa <GL/glut.h>
|
||||
|
||||
GLUT_XLIB_IMPLEMENTATION=16 mjk's early GLUT 3.8
|
||||
|
||||
GLUT_XLIB_IMPLEMENTATION=17 mjk's GLUT 3.8 with glutStrokeWidthf and glutStrokeLengthf
|
||||
**/
|
||||
#ifndef GLUT_XLIB_IMPLEMENTATION /* Allow this to be overriden. */
|
||||
#define GLUT_XLIB_IMPLEMENTATION 17
|
||||
#endif
|
||||
|
||||
/* Display mode bit masks. */
|
||||
#define GLUT_RGB 0
|
||||
#define GLUT_RGBA GLUT_RGB
|
||||
#define GLUT_INDEX 1
|
||||
#define GLUT_SINGLE 0
|
||||
#define GLUT_DOUBLE 2
|
||||
#define GLUT_ACCUM 4
|
||||
#define GLUT_ALPHA 8
|
||||
#define GLUT_DEPTH 16
|
||||
#define GLUT_STENCIL 32
|
||||
#if (GLUT_API_VERSION >= 2)
|
||||
#define GLUT_MULTISAMPLE 128
|
||||
#define GLUT_STEREO 256
|
||||
#endif
|
||||
#if (GLUT_API_VERSION >= 3)
|
||||
#define GLUT_LUMINANCE 512
|
||||
#endif
|
||||
|
||||
/* Mouse buttons. */
|
||||
#define GLUT_LEFT_BUTTON 0
|
||||
#define GLUT_MIDDLE_BUTTON 1
|
||||
#define GLUT_RIGHT_BUTTON 2
|
||||
|
||||
/* Mouse button state. */
|
||||
#define GLUT_DOWN 0
|
||||
#define GLUT_UP 1
|
||||
|
||||
#if (GLUT_API_VERSION >= 2)
|
||||
/* function keys */
|
||||
#define GLUT_KEY_F1 1
|
||||
#define GLUT_KEY_F2 2
|
||||
#define GLUT_KEY_F3 3
|
||||
#define GLUT_KEY_F4 4
|
||||
#define GLUT_KEY_F5 5
|
||||
#define GLUT_KEY_F6 6
|
||||
#define GLUT_KEY_F7 7
|
||||
#define GLUT_KEY_F8 8
|
||||
#define GLUT_KEY_F9 9
|
||||
#define GLUT_KEY_F10 10
|
||||
#define GLUT_KEY_F11 11
|
||||
#define GLUT_KEY_F12 12
|
||||
/* directional keys */
|
||||
#define GLUT_KEY_LEFT 100
|
||||
#define GLUT_KEY_UP 101
|
||||
#define GLUT_KEY_RIGHT 102
|
||||
#define GLUT_KEY_DOWN 103
|
||||
#define GLUT_KEY_PAGE_UP 104
|
||||
#define GLUT_KEY_PAGE_DOWN 105
|
||||
#define GLUT_KEY_HOME 106
|
||||
#define GLUT_KEY_END 107
|
||||
#define GLUT_KEY_INSERT 108
|
||||
#endif
|
||||
|
||||
/* Entry/exit state. */
|
||||
#define GLUT_LEFT 0
|
||||
#define GLUT_ENTERED 1
|
||||
|
||||
/* Menu usage state. */
|
||||
#define GLUT_MENU_NOT_IN_USE 0
|
||||
#define GLUT_MENU_IN_USE 1
|
||||
|
||||
/* Visibility state. */
|
||||
#define GLUT_NOT_VISIBLE 0
|
||||
#define GLUT_VISIBLE 1
|
||||
|
||||
/* Window status state. */
|
||||
#define GLUT_HIDDEN 0
|
||||
#define GLUT_FULLY_RETAINED 1
|
||||
#define GLUT_PARTIALLY_RETAINED 2
|
||||
#define GLUT_FULLY_COVERED 3
|
||||
|
||||
/* Color index component selection values. */
|
||||
#define GLUT_RED 0
|
||||
#define GLUT_GREEN 1
|
||||
#define GLUT_BLUE 2
|
||||
|
||||
#ifdef _WIN32
|
||||
/* Stroke font constants (use these in GLUT program). */
|
||||
#define GLUT_STROKE_ROMAN ((void*)0)
|
||||
#define GLUT_STROKE_MONO_ROMAN ((void*)1)
|
||||
|
||||
/* Bitmap font constants (use these in GLUT program). */
|
||||
#define GLUT_BITMAP_9_BY_15 ((void*)2)
|
||||
#define GLUT_BITMAP_8_BY_13 ((void*)3)
|
||||
#define GLUT_BITMAP_TIMES_ROMAN_10 ((void*)4)
|
||||
#define GLUT_BITMAP_TIMES_ROMAN_24 ((void*)5)
|
||||
#if (GLUT_API_VERSION >= 3)
|
||||
#define GLUT_BITMAP_HELVETICA_10 ((void*)6)
|
||||
#define GLUT_BITMAP_HELVETICA_12 ((void*)7)
|
||||
#define GLUT_BITMAP_HELVETICA_18 ((void*)8)
|
||||
#endif
|
||||
#else
|
||||
/* Stroke font opaque addresses (use constants instead in source code). */
|
||||
GLUTAPI void *glutStrokeRoman;
|
||||
GLUTAPI void *glutStrokeMonoRoman;
|
||||
|
||||
/* Stroke font constants (use these in GLUT program). */
|
||||
#define GLUT_STROKE_ROMAN (&glutStrokeRoman)
|
||||
#define GLUT_STROKE_MONO_ROMAN (&glutStrokeMonoRoman)
|
||||
|
||||
/* Bitmap font opaque addresses (use constants instead in source code). */
|
||||
GLUTAPI void *glutBitmap9By15;
|
||||
GLUTAPI void *glutBitmap8By13;
|
||||
GLUTAPI void *glutBitmapTimesRoman10;
|
||||
GLUTAPI void *glutBitmapTimesRoman24;
|
||||
GLUTAPI void *glutBitmapHelvetica10;
|
||||
GLUTAPI void *glutBitmapHelvetica12;
|
||||
GLUTAPI void *glutBitmapHelvetica18;
|
||||
|
||||
/* Bitmap font constants (use these in GLUT program). */
|
||||
#define GLUT_BITMAP_9_BY_15 (&glutBitmap9By15)
|
||||
#define GLUT_BITMAP_8_BY_13 (&glutBitmap8By13)
|
||||
#define GLUT_BITMAP_TIMES_ROMAN_10 (&glutBitmapTimesRoman10)
|
||||
#define GLUT_BITMAP_TIMES_ROMAN_24 (&glutBitmapTimesRoman24)
|
||||
#if (GLUT_API_VERSION >= 3)
|
||||
#define GLUT_BITMAP_HELVETICA_10 (&glutBitmapHelvetica10)
|
||||
#define GLUT_BITMAP_HELVETICA_12 (&glutBitmapHelvetica12)
|
||||
#define GLUT_BITMAP_HELVETICA_18 (&glutBitmapHelvetica18)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* glutGet parameters. */
|
||||
#define GLUT_WINDOW_X ((GLenum) 100)
|
||||
#define GLUT_WINDOW_Y ((GLenum) 101)
|
||||
#define GLUT_WINDOW_WIDTH ((GLenum) 102)
|
||||
#define GLUT_WINDOW_HEIGHT ((GLenum) 103)
|
||||
#define GLUT_WINDOW_BUFFER_SIZE ((GLenum) 104)
|
||||
#define GLUT_WINDOW_STENCIL_SIZE ((GLenum) 105)
|
||||
#define GLUT_WINDOW_DEPTH_SIZE ((GLenum) 106)
|
||||
#define GLUT_WINDOW_RED_SIZE ((GLenum) 107)
|
||||
#define GLUT_WINDOW_GREEN_SIZE ((GLenum) 108)
|
||||
#define GLUT_WINDOW_BLUE_SIZE ((GLenum) 109)
|
||||
#define GLUT_WINDOW_ALPHA_SIZE ((GLenum) 110)
|
||||
#define GLUT_WINDOW_ACCUM_RED_SIZE ((GLenum) 111)
|
||||
#define GLUT_WINDOW_ACCUM_GREEN_SIZE ((GLenum) 112)
|
||||
#define GLUT_WINDOW_ACCUM_BLUE_SIZE ((GLenum) 113)
|
||||
#define GLUT_WINDOW_ACCUM_ALPHA_SIZE ((GLenum) 114)
|
||||
#define GLUT_WINDOW_DOUBLEBUFFER ((GLenum) 115)
|
||||
#define GLUT_WINDOW_RGBA ((GLenum) 116)
|
||||
#define GLUT_WINDOW_PARENT ((GLenum) 117)
|
||||
#define GLUT_WINDOW_NUM_CHILDREN ((GLenum) 118)
|
||||
#define GLUT_WINDOW_COLORMAP_SIZE ((GLenum) 119)
|
||||
#if (GLUT_API_VERSION >= 2)
|
||||
#define GLUT_WINDOW_NUM_SAMPLES ((GLenum) 120)
|
||||
#define GLUT_WINDOW_STEREO ((GLenum) 121)
|
||||
#endif
|
||||
#if (GLUT_API_VERSION >= 3)
|
||||
#define GLUT_WINDOW_CURSOR ((GLenum) 122)
|
||||
#endif
|
||||
#define GLUT_SCREEN_WIDTH ((GLenum) 200)
|
||||
#define GLUT_SCREEN_HEIGHT ((GLenum) 201)
|
||||
#define GLUT_SCREEN_WIDTH_MM ((GLenum) 202)
|
||||
#define GLUT_SCREEN_HEIGHT_MM ((GLenum) 203)
|
||||
#define GLUT_MENU_NUM_ITEMS ((GLenum) 300)
|
||||
#define GLUT_DISPLAY_MODE_POSSIBLE ((GLenum) 400)
|
||||
#define GLUT_INIT_WINDOW_X ((GLenum) 500)
|
||||
#define GLUT_INIT_WINDOW_Y ((GLenum) 501)
|
||||
#define GLUT_INIT_WINDOW_WIDTH ((GLenum) 502)
|
||||
#define GLUT_INIT_WINDOW_HEIGHT ((GLenum) 503)
|
||||
#define GLUT_INIT_DISPLAY_MODE ((GLenum) 504)
|
||||
#if (GLUT_API_VERSION >= 2)
|
||||
#define GLUT_ELAPSED_TIME ((GLenum) 700)
|
||||
#endif
|
||||
#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13)
|
||||
#define GLUT_WINDOW_FORMAT_ID ((GLenum) 123)
|
||||
#endif
|
||||
|
||||
#if (GLUT_API_VERSION >= 2)
|
||||
/* glutDeviceGet parameters. */
|
||||
#define GLUT_HAS_KEYBOARD ((GLenum) 600)
|
||||
#define GLUT_HAS_MOUSE ((GLenum) 601)
|
||||
#define GLUT_HAS_SPACEBALL ((GLenum) 602)
|
||||
#define GLUT_HAS_DIAL_AND_BUTTON_BOX ((GLenum) 603)
|
||||
#define GLUT_HAS_TABLET ((GLenum) 604)
|
||||
#define GLUT_NUM_MOUSE_BUTTONS ((GLenum) 605)
|
||||
#define GLUT_NUM_SPACEBALL_BUTTONS ((GLenum) 606)
|
||||
#define GLUT_NUM_BUTTON_BOX_BUTTONS ((GLenum) 607)
|
||||
#define GLUT_NUM_DIALS ((GLenum) 608)
|
||||
#define GLUT_NUM_TABLET_BUTTONS ((GLenum) 609)
|
||||
#endif
|
||||
#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13)
|
||||
#define GLUT_DEVICE_IGNORE_KEY_REPEAT ((GLenum) 610)
|
||||
#define GLUT_DEVICE_KEY_REPEAT ((GLenum) 611)
|
||||
#define GLUT_HAS_JOYSTICK ((GLenum) 612)
|
||||
#define GLUT_OWNS_JOYSTICK ((GLenum) 613)
|
||||
#define GLUT_JOYSTICK_BUTTONS ((GLenum) 614)
|
||||
#define GLUT_JOYSTICK_AXES ((GLenum) 615)
|
||||
#define GLUT_JOYSTICK_POLL_RATE ((GLenum) 616)
|
||||
#endif
|
||||
|
||||
#if (GLUT_API_VERSION >= 3)
|
||||
/* glutLayerGet parameters. */
|
||||
#define GLUT_OVERLAY_POSSIBLE ((GLenum) 800)
|
||||
#define GLUT_LAYER_IN_USE ((GLenum) 801)
|
||||
#define GLUT_HAS_OVERLAY ((GLenum) 802)
|
||||
#define GLUT_TRANSPARENT_INDEX ((GLenum) 803)
|
||||
#define GLUT_NORMAL_DAMAGED ((GLenum) 804)
|
||||
#define GLUT_OVERLAY_DAMAGED ((GLenum) 805)
|
||||
|
||||
#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9)
|
||||
/* glutVideoResizeGet parameters. */
|
||||
#define GLUT_VIDEO_RESIZE_POSSIBLE ((GLenum) 900)
|
||||
#define GLUT_VIDEO_RESIZE_IN_USE ((GLenum) 901)
|
||||
#define GLUT_VIDEO_RESIZE_X_DELTA ((GLenum) 902)
|
||||
#define GLUT_VIDEO_RESIZE_Y_DELTA ((GLenum) 903)
|
||||
#define GLUT_VIDEO_RESIZE_WIDTH_DELTA ((GLenum) 904)
|
||||
#define GLUT_VIDEO_RESIZE_HEIGHT_DELTA ((GLenum) 905)
|
||||
#define GLUT_VIDEO_RESIZE_X ((GLenum) 906)
|
||||
#define GLUT_VIDEO_RESIZE_Y ((GLenum) 907)
|
||||
#define GLUT_VIDEO_RESIZE_WIDTH ((GLenum) 908)
|
||||
#define GLUT_VIDEO_RESIZE_HEIGHT ((GLenum) 909)
|
||||
#endif
|
||||
|
||||
/* glutUseLayer parameters. */
|
||||
#define GLUT_NORMAL ((GLenum) 0)
|
||||
#define GLUT_OVERLAY ((GLenum) 1)
|
||||
|
||||
/* glutGetModifiers return mask. */
|
||||
#define GLUT_ACTIVE_SHIFT 1
|
||||
#define GLUT_ACTIVE_CTRL 2
|
||||
#define GLUT_ACTIVE_ALT 4
|
||||
|
||||
/* glutSetCursor parameters. */
|
||||
/* Basic arrows. */
|
||||
#define GLUT_CURSOR_RIGHT_ARROW 0
|
||||
#define GLUT_CURSOR_LEFT_ARROW 1
|
||||
/* Symbolic cursor shapes. */
|
||||
#define GLUT_CURSOR_INFO 2
|
||||
#define GLUT_CURSOR_DESTROY 3
|
||||
#define GLUT_CURSOR_HELP 4
|
||||
#define GLUT_CURSOR_CYCLE 5
|
||||
#define GLUT_CURSOR_SPRAY 6
|
||||
#define GLUT_CURSOR_WAIT 7
|
||||
#define GLUT_CURSOR_TEXT 8
|
||||
#define GLUT_CURSOR_CROSSHAIR 9
|
||||
/* Directional cursors. */
|
||||
#define GLUT_CURSOR_UP_DOWN 10
|
||||
#define GLUT_CURSOR_LEFT_RIGHT 11
|
||||
/* Sizing cursors. */
|
||||
#define GLUT_CURSOR_TOP_SIDE 12
|
||||
#define GLUT_CURSOR_BOTTOM_SIDE 13
|
||||
#define GLUT_CURSOR_LEFT_SIDE 14
|
||||
#define GLUT_CURSOR_RIGHT_SIDE 15
|
||||
#define GLUT_CURSOR_TOP_LEFT_CORNER 16
|
||||
#define GLUT_CURSOR_TOP_RIGHT_CORNER 17
|
||||
#define GLUT_CURSOR_BOTTOM_RIGHT_CORNER 18
|
||||
#define GLUT_CURSOR_BOTTOM_LEFT_CORNER 19
|
||||
/* Inherit from parent window. */
|
||||
#define GLUT_CURSOR_INHERIT 100
|
||||
/* Blank cursor. */
|
||||
#define GLUT_CURSOR_NONE 101
|
||||
/* Fullscreen crosshair (if available). */
|
||||
#define GLUT_CURSOR_FULL_CROSSHAIR 102
|
||||
#endif
|
||||
|
||||
/* GLUT initialization sub-API. */
|
||||
GLUTAPI void GLUTAPIENTRY glutInit(int *argcp, char **argv);
|
||||
#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK)
|
||||
GLUTAPI void GLUTAPIENTRY __glutInitWithExit(int *argcp, char **argv, void (__cdecl *exitfunc)(int));
|
||||
#ifndef GLUT_BUILDING_LIB
|
||||
static void GLUTAPIENTRY glutInit_ATEXIT_HACK(int *argcp, char **argv) { __glutInitWithExit(argcp, argv, exit); }
|
||||
#define glutInit glutInit_ATEXIT_HACK
|
||||
#endif
|
||||
#endif
|
||||
GLUTAPI void GLUTAPIENTRY glutInitDisplayMode(unsigned int mode);
|
||||
#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9)
|
||||
GLUTAPI void GLUTAPIENTRY glutInitDisplayString(const char *string);
|
||||
#endif
|
||||
GLUTAPI void GLUTAPIENTRY glutInitWindowPosition(int x, int y);
|
||||
GLUTAPI void GLUTAPIENTRY glutInitWindowSize(int width, int height);
|
||||
GLUTAPI void GLUTAPIENTRY glutMainLoop(void);
|
||||
|
||||
/* GLUT window sub-API. */
|
||||
GLUTAPI int GLUTAPIENTRY glutCreateWindow(const char *title);
|
||||
#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK)
|
||||
GLUTAPI int GLUTAPIENTRY __glutCreateWindowWithExit(const char *title, void (__cdecl *exitfunc)(int));
|
||||
#ifndef GLUT_BUILDING_LIB
|
||||
static int GLUTAPIENTRY glutCreateWindow_ATEXIT_HACK(const char *title) { return __glutCreateWindowWithExit(title, exit); }
|
||||
#define glutCreateWindow glutCreateWindow_ATEXIT_HACK
|
||||
#endif
|
||||
#endif
|
||||
GLUTAPI int GLUTAPIENTRY glutCreateSubWindow(int win, int x, int y, int width, int height);
|
||||
GLUTAPI void GLUTAPIENTRY glutDestroyWindow(int win);
|
||||
GLUTAPI void GLUTAPIENTRY glutPostRedisplay(void);
|
||||
#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 11)
|
||||
GLUTAPI void GLUTAPIENTRY glutPostWindowRedisplay(int win);
|
||||
#endif
|
||||
GLUTAPI void GLUTAPIENTRY glutSwapBuffers(void);
|
||||
GLUTAPI int GLUTAPIENTRY glutGetWindow(void);
|
||||
GLUTAPI void GLUTAPIENTRY glutSetWindow(int win);
|
||||
GLUTAPI void GLUTAPIENTRY glutSetWindowTitle(const char *title);
|
||||
GLUTAPI void GLUTAPIENTRY glutSetIconTitle(const char *title);
|
||||
GLUTAPI void GLUTAPIENTRY glutPositionWindow(int x, int y);
|
||||
GLUTAPI void GLUTAPIENTRY glutReshapeWindow(int width, int height);
|
||||
GLUTAPI void GLUTAPIENTRY glutPopWindow(void);
|
||||
GLUTAPI void GLUTAPIENTRY glutPushWindow(void);
|
||||
GLUTAPI void GLUTAPIENTRY glutIconifyWindow(void);
|
||||
GLUTAPI void GLUTAPIENTRY glutShowWindow(void);
|
||||
GLUTAPI void GLUTAPIENTRY glutHideWindow(void);
|
||||
#if (GLUT_API_VERSION >= 3)
|
||||
GLUTAPI void GLUTAPIENTRY glutFullScreen(void);
|
||||
GLUTAPI void GLUTAPIENTRY glutSetCursor(int cursor);
|
||||
#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9)
|
||||
GLUTAPI void GLUTAPIENTRY glutWarpPointer(int x, int y);
|
||||
#endif
|
||||
|
||||
/* GLUT overlay sub-API. */
|
||||
GLUTAPI void GLUTAPIENTRY glutEstablishOverlay(void);
|
||||
GLUTAPI void GLUTAPIENTRY glutRemoveOverlay(void);
|
||||
GLUTAPI void GLUTAPIENTRY glutUseLayer(GLenum layer);
|
||||
GLUTAPI void GLUTAPIENTRY glutPostOverlayRedisplay(void);
|
||||
#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 11)
|
||||
GLUTAPI void GLUTAPIENTRY glutPostWindowOverlayRedisplay(int win);
|
||||
#endif
|
||||
GLUTAPI void GLUTAPIENTRY glutShowOverlay(void);
|
||||
GLUTAPI void GLUTAPIENTRY glutHideOverlay(void);
|
||||
#endif
|
||||
|
||||
/* GLUT menu sub-API. */
|
||||
GLUTAPI int GLUTAPIENTRY glutCreateMenu(void (GLUTCALLBACK *func)(int));
|
||||
#if defined(_WIN32) && !defined(GLUT_DISABLE_ATEXIT_HACK)
|
||||
GLUTAPI int GLUTAPIENTRY __glutCreateMenuWithExit(void (GLUTCALLBACK *func)(int), void (__cdecl *exitfunc)(int));
|
||||
#ifndef GLUT_BUILDING_LIB
|
||||
static int GLUTAPIENTRY glutCreateMenu_ATEXIT_HACK(void (GLUTCALLBACK *func)(int)) { return __glutCreateMenuWithExit(func, exit); }
|
||||
#define glutCreateMenu glutCreateMenu_ATEXIT_HACK
|
||||
#endif
|
||||
#endif
|
||||
GLUTAPI void GLUTAPIENTRY glutDestroyMenu(int menu);
|
||||
GLUTAPI int GLUTAPIENTRY glutGetMenu(void);
|
||||
GLUTAPI void GLUTAPIENTRY glutSetMenu(int menu);
|
||||
GLUTAPI void GLUTAPIENTRY glutAddMenuEntry(const char *label, int value);
|
||||
GLUTAPI void GLUTAPIENTRY glutAddSubMenu(const char *label, int submenu);
|
||||
GLUTAPI void GLUTAPIENTRY glutChangeToMenuEntry(int item, const char *label, int value);
|
||||
GLUTAPI void GLUTAPIENTRY glutChangeToSubMenu(int item, const char *label, int submenu);
|
||||
GLUTAPI void GLUTAPIENTRY glutRemoveMenuItem(int item);
|
||||
GLUTAPI void GLUTAPIENTRY glutAttachMenu(int button);
|
||||
GLUTAPI void GLUTAPIENTRY glutDetachMenu(int button);
|
||||
|
||||
/* GLUT window callback sub-API. */
|
||||
GLUTAPI void GLUTAPIENTRY glutDisplayFunc(void (GLUTCALLBACK *func)(void));
|
||||
GLUTAPI void GLUTAPIENTRY glutReshapeFunc(void (GLUTCALLBACK *func)(int width, int height));
|
||||
GLUTAPI void GLUTAPIENTRY glutKeyboardFunc(void (GLUTCALLBACK *func)(unsigned char key, int x, int y));
|
||||
GLUTAPI void GLUTAPIENTRY glutMouseFunc(void (GLUTCALLBACK *func)(int button, int state, int x, int y));
|
||||
GLUTAPI void GLUTAPIENTRY glutMotionFunc(void (GLUTCALLBACK *func)(int x, int y));
|
||||
GLUTAPI void GLUTAPIENTRY glutPassiveMotionFunc(void (GLUTCALLBACK *func)(int x, int y));
|
||||
GLUTAPI void GLUTAPIENTRY glutEntryFunc(void (GLUTCALLBACK *func)(int state));
|
||||
GLUTAPI void GLUTAPIENTRY glutVisibilityFunc(void (GLUTCALLBACK *func)(int state));
|
||||
GLUTAPI void GLUTAPIENTRY glutIdleFunc(void (GLUTCALLBACK *func)(void));
|
||||
GLUTAPI void GLUTAPIENTRY glutTimerFunc(unsigned int millis, void (GLUTCALLBACK *func)(int value), int value);
|
||||
GLUTAPI void GLUTAPIENTRY glutMenuStateFunc(void (GLUTCALLBACK *func)(int state));
|
||||
#if (GLUT_API_VERSION >= 2)
|
||||
GLUTAPI void GLUTAPIENTRY glutSpecialFunc(void (GLUTCALLBACK *func)(int key, int x, int y));
|
||||
GLUTAPI void GLUTAPIENTRY glutSpaceballMotionFunc(void (GLUTCALLBACK *func)(int x, int y, int z));
|
||||
GLUTAPI void GLUTAPIENTRY glutSpaceballRotateFunc(void (GLUTCALLBACK *func)(int x, int y, int z));
|
||||
GLUTAPI void GLUTAPIENTRY glutSpaceballButtonFunc(void (GLUTCALLBACK *func)(int button, int state));
|
||||
GLUTAPI void GLUTAPIENTRY glutButtonBoxFunc(void (GLUTCALLBACK *func)(int button, int state));
|
||||
GLUTAPI void GLUTAPIENTRY glutDialsFunc(void (GLUTCALLBACK *func)(int dial, int value));
|
||||
GLUTAPI void GLUTAPIENTRY glutTabletMotionFunc(void (GLUTCALLBACK *func)(int x, int y));
|
||||
GLUTAPI void GLUTAPIENTRY glutTabletButtonFunc(void (GLUTCALLBACK *func)(int button, int state, int x, int y));
|
||||
#if (GLUT_API_VERSION >= 3)
|
||||
GLUTAPI void GLUTAPIENTRY glutMenuStatusFunc(void (GLUTCALLBACK *func)(int status, int x, int y));
|
||||
GLUTAPI void GLUTAPIENTRY glutOverlayDisplayFunc(void (GLUTCALLBACK *func)(void));
|
||||
#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9)
|
||||
GLUTAPI void GLUTAPIENTRY glutWindowStatusFunc(void (GLUTCALLBACK *func)(int state));
|
||||
#endif
|
||||
#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13)
|
||||
GLUTAPI void GLUTAPIENTRY glutKeyboardUpFunc(void (GLUTCALLBACK *func)(unsigned char key, int x, int y));
|
||||
GLUTAPI void GLUTAPIENTRY glutSpecialUpFunc(void (GLUTCALLBACK *func)(int key, int x, int y));
|
||||
GLUTAPI void GLUTAPIENTRY glutJoystickFunc(void (GLUTCALLBACK *func)(unsigned int buttonMask, int x, int y, int z), int pollInterval);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* GLUT color index sub-API. */
|
||||
GLUTAPI void GLUTAPIENTRY glutSetColor(int, GLfloat red, GLfloat green, GLfloat blue);
|
||||
GLUTAPI GLfloat GLUTAPIENTRY glutGetColor(int ndx, int component);
|
||||
GLUTAPI void GLUTAPIENTRY glutCopyColormap(int win);
|
||||
|
||||
/* GLUT state retrieval sub-API. */
|
||||
GLUTAPI int GLUTAPIENTRY glutGet(GLenum type);
|
||||
GLUTAPI int GLUTAPIENTRY glutDeviceGet(GLenum type);
|
||||
#if (GLUT_API_VERSION >= 2)
|
||||
/* GLUT extension support sub-API */
|
||||
GLUTAPI int GLUTAPIENTRY glutExtensionSupported(const char *name);
|
||||
#endif
|
||||
#if (GLUT_API_VERSION >= 3)
|
||||
GLUTAPI int GLUTAPIENTRY glutGetModifiers(void);
|
||||
GLUTAPI int GLUTAPIENTRY glutLayerGet(GLenum type);
|
||||
#endif
|
||||
|
||||
/* GLUT font sub-API */
|
||||
GLUTAPI void GLUTAPIENTRY glutBitmapCharacter(void *font, int character);
|
||||
GLUTAPI int GLUTAPIENTRY glutBitmapWidth(void *font, int character);
|
||||
GLUTAPI void GLUTAPIENTRY glutStrokeCharacter(void *font, int character);
|
||||
GLUTAPI int GLUTAPIENTRY glutStrokeWidth(void *font, int character);
|
||||
#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9)
|
||||
GLUTAPI int GLUTAPIENTRY glutBitmapLength(void *font, const unsigned char *string);
|
||||
GLUTAPI int GLUTAPIENTRY glutStrokeLength(void *font, const unsigned char *string);
|
||||
#endif
|
||||
#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 17)
|
||||
GLUTAPI float GLUTAPIENTRY glutStrokeWidthf(void *font, int character);
|
||||
GLUTAPI float GLUTAPIENTRY glutStrokeLengthf(void *font, const unsigned char *string);
|
||||
#endif
|
||||
|
||||
/* GLUT pre-built models sub-API */
|
||||
GLUTAPI void GLUTAPIENTRY glutWireSphere(GLdouble radius, GLint slices, GLint stacks);
|
||||
GLUTAPI void GLUTAPIENTRY glutSolidSphere(GLdouble radius, GLint slices, GLint stacks);
|
||||
GLUTAPI void GLUTAPIENTRY glutWireCone(GLdouble base, GLdouble height, GLint slices, GLint stacks);
|
||||
GLUTAPI void GLUTAPIENTRY glutSolidCone(GLdouble base, GLdouble height, GLint slices, GLint stacks);
|
||||
GLUTAPI void GLUTAPIENTRY glutWireCube(GLdouble size);
|
||||
GLUTAPI void GLUTAPIENTRY glutSolidCube(GLdouble size);
|
||||
GLUTAPI void GLUTAPIENTRY glutWireTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings);
|
||||
GLUTAPI void GLUTAPIENTRY glutSolidTorus(GLdouble innerRadius, GLdouble outerRadius, GLint sides, GLint rings);
|
||||
GLUTAPI void GLUTAPIENTRY glutWireDodecahedron(void);
|
||||
GLUTAPI void GLUTAPIENTRY glutSolidDodecahedron(void);
|
||||
GLUTAPI void GLUTAPIENTRY glutWireTeapot(GLdouble size);
|
||||
GLUTAPI void GLUTAPIENTRY glutSolidTeapot(GLdouble size);
|
||||
GLUTAPI void GLUTAPIENTRY glutWireOctahedron(void);
|
||||
GLUTAPI void GLUTAPIENTRY glutSolidOctahedron(void);
|
||||
GLUTAPI void GLUTAPIENTRY glutWireTetrahedron(void);
|
||||
GLUTAPI void GLUTAPIENTRY glutSolidTetrahedron(void);
|
||||
GLUTAPI void GLUTAPIENTRY glutWireIcosahedron(void);
|
||||
GLUTAPI void GLUTAPIENTRY glutSolidIcosahedron(void);
|
||||
|
||||
#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 9)
|
||||
/* GLUT video resize sub-API. */
|
||||
GLUTAPI int GLUTAPIENTRY glutVideoResizeGet(GLenum param);
|
||||
GLUTAPI void GLUTAPIENTRY glutSetupVideoResizing(void);
|
||||
GLUTAPI void GLUTAPIENTRY glutStopVideoResizing(void);
|
||||
GLUTAPI void GLUTAPIENTRY glutVideoResize(int x, int y, int width, int height);
|
||||
GLUTAPI void GLUTAPIENTRY glutVideoPan(int x, int y, int width, int height);
|
||||
|
||||
/* GLUT debugging sub-API. */
|
||||
GLUTAPI void GLUTAPIENTRY glutReportErrors(void);
|
||||
#endif
|
||||
|
||||
#if (GLUT_API_VERSION >= 4 || GLUT_XLIB_IMPLEMENTATION >= 13)
|
||||
/* GLUT device control sub-API. */
|
||||
/* glutSetKeyRepeat modes. */
|
||||
#define GLUT_KEY_REPEAT_OFF 0
|
||||
#define GLUT_KEY_REPEAT_ON 1
|
||||
#define GLUT_KEY_REPEAT_DEFAULT 2
|
||||
|
||||
/* Joystick button masks. */
|
||||
#define GLUT_JOYSTICK_BUTTON_A 1
|
||||
#define GLUT_JOYSTICK_BUTTON_B 2
|
||||
#define GLUT_JOYSTICK_BUTTON_C 4
|
||||
#define GLUT_JOYSTICK_BUTTON_D 8
|
||||
|
||||
GLUTAPI void GLUTAPIENTRY glutIgnoreKeyRepeat(int ignore);
|
||||
GLUTAPI void GLUTAPIENTRY glutSetKeyRepeat(int repeatMode);
|
||||
GLUTAPI void GLUTAPIENTRY glutForceJoystickFunc(void);
|
||||
|
||||
/* GLUT game mode sub-API. */
|
||||
/* glutGameModeGet. */
|
||||
#define GLUT_GAME_MODE_ACTIVE ((GLenum) 0)
|
||||
#define GLUT_GAME_MODE_POSSIBLE ((GLenum) 1)
|
||||
#define GLUT_GAME_MODE_WIDTH ((GLenum) 2)
|
||||
#define GLUT_GAME_MODE_HEIGHT ((GLenum) 3)
|
||||
#define GLUT_GAME_MODE_PIXEL_DEPTH ((GLenum) 4)
|
||||
#define GLUT_GAME_MODE_REFRESH_RATE ((GLenum) 5)
|
||||
#define GLUT_GAME_MODE_DISPLAY_CHANGED ((GLenum) 6)
|
||||
|
||||
GLUTAPI void GLUTAPIENTRY glutGameModeString(const char *string);
|
||||
GLUTAPI int GLUTAPIENTRY glutEnterGameMode(void);
|
||||
GLUTAPI void GLUTAPIENTRY glutLeaveGameMode(void);
|
||||
GLUTAPI int GLUTAPIENTRY glutGameModeGet(GLenum mode);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef GLUT_APIENTRY_DEFINED
|
||||
# undef GLUT_APIENTRY_DEFINED
|
||||
# undef APIENTRY
|
||||
#endif
|
||||
|
||||
#ifdef GLUT_WINGDIAPI_DEFINED
|
||||
# undef GLUT_WINGDIAPI_DEFINED
|
||||
# undef WINGDIAPI
|
||||
#endif
|
||||
|
||||
#ifdef GLUT_DEFINED___CDECL
|
||||
# undef GLUT_DEFINED___CDECL
|
||||
# undef __cdecl
|
||||
#endif
|
||||
|
||||
#ifdef GLUT_DEFINED__CRTIMP
|
||||
# undef GLUT_DEFINED__CRTIMP
|
||||
# undef _CRTIMP
|
||||
#endif
|
||||
|
||||
#endif /* __glut_h__ */
|
||||
BIN
physx/snippets/graphics/lib/win32/glut/glut32.lib
Normal file
BIN
physx/snippets/graphics/lib/win32/glut/glut32.lib
Normal file
Binary file not shown.
BIN
physx/snippets/graphics/lib/win64/glut/glut32.lib
Normal file
BIN
physx/snippets/graphics/lib/win64/glut/glut32.lib
Normal file
Binary file not shown.
610
physx/snippets/snippetarticulation/SnippetArticulation.cpp
Normal file
610
physx/snippets/snippetarticulation/SnippetArticulation.cpp
Normal file
@ -0,0 +1,610 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
// ****************************************************************************
|
||||
// This snippet demonstrates the use of articulations.
|
||||
// ****************************************************************************
|
||||
|
||||
#include <ctype.h>
|
||||
#include <vector>
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
|
||||
#include "../snippetutils/SnippetUtils.h"
|
||||
#include "../snippetcommon/SnippetPrint.h"
|
||||
#include "../snippetcommon/SnippetPVD.h"
|
||||
|
||||
#define USE_REDUCED_COORDINATE_ARTICULATION 1
|
||||
#define CREATE_SCISSOR_LIFT 1
|
||||
|
||||
#if CREATE_SCISSOR_LIFT
|
||||
bool gCreateLiftScene = true;
|
||||
#else
|
||||
bool gCreateLiftScene = false;
|
||||
#endif
|
||||
|
||||
using namespace physx;
|
||||
|
||||
PxDefaultAllocator gAllocator;
|
||||
PxDefaultErrorCallback gErrorCallback;
|
||||
|
||||
PxFoundation* gFoundation = NULL;
|
||||
PxPhysics* gPhysics = NULL;
|
||||
|
||||
PxDefaultCpuDispatcher* gDispatcher = NULL;
|
||||
PxScene* gScene = NULL;
|
||||
|
||||
PxMaterial* gMaterial = NULL;
|
||||
|
||||
PxPvd* gPvd = NULL;
|
||||
|
||||
#if USE_REDUCED_COORDINATE_ARTICULATION
|
||||
PxArticulationReducedCoordinate* gArticulation = NULL;
|
||||
PxArticulationJointReducedCoordinate* gDriveJoint = NULL;
|
||||
#else
|
||||
PxArticulation* gArticulation = NULL;
|
||||
#endif
|
||||
|
||||
#if USE_REDUCED_COORDINATE_ARTICULATION
|
||||
PxFilterFlags scissorFilter(PxFilterObjectAttributes attributes0, PxFilterData filterData0,
|
||||
PxFilterObjectAttributes attributes1, PxFilterData filterData1,
|
||||
PxPairFlags& pairFlags, const void* constantBlock, PxU32 constantBlockSize)
|
||||
{
|
||||
PX_UNUSED(attributes0);
|
||||
PX_UNUSED(attributes1);
|
||||
PX_UNUSED(constantBlock);
|
||||
PX_UNUSED(constantBlockSize);
|
||||
if (filterData0.word2 != 0 && filterData0.word2 == filterData1.word2)
|
||||
return PxFilterFlag::eKILL;
|
||||
pairFlags |= PxPairFlag::eCONTACT_DEFAULT;
|
||||
return PxFilterFlag::eDEFAULT;
|
||||
}
|
||||
|
||||
void createScissorLift()
|
||||
{
|
||||
const PxReal runnerLength = 2.f;
|
||||
const PxReal placementDistance = 1.8f;
|
||||
|
||||
const PxReal cosAng = (placementDistance) / (runnerLength);
|
||||
|
||||
const PxReal angle = PxAcos(cosAng);
|
||||
|
||||
const PxReal sinAng = PxSin(angle);
|
||||
|
||||
const PxQuat leftRot(-angle, PxVec3(1.f, 0.f, 0.f));
|
||||
const PxQuat rightRot(angle, PxVec3(1.f, 0.f, 0.f));
|
||||
|
||||
//(1) Create base...
|
||||
PxArticulationLink* base = gArticulation->createLink(NULL, PxTransform(PxVec3(0.f, 0.25f, 0.f)));
|
||||
PxRigidActorExt::createExclusiveShape(*base, PxBoxGeometry(0.5f, 0.25f, 1.5f), *gMaterial);
|
||||
PxRigidBodyExt::updateMassAndInertia(*base, 3.f);
|
||||
|
||||
//Now create the slider and fixed joints...
|
||||
|
||||
gArticulation->setSolverIterationCounts(32);
|
||||
|
||||
PxArticulationLink* leftRoot = gArticulation->createLink(base, PxTransform(PxVec3(0.f, 0.55f, -0.9f)));
|
||||
PxRigidActorExt::createExclusiveShape(*leftRoot, PxBoxGeometry(0.5f, 0.05f, 0.05f), *gMaterial);
|
||||
PxRigidBodyExt::updateMassAndInertia(*leftRoot, 1.f);
|
||||
|
||||
PxArticulationLink* rightRoot = gArticulation->createLink(base, PxTransform(PxVec3(0.f, 0.55f, 0.9f)));
|
||||
PxRigidActorExt::createExclusiveShape(*rightRoot, PxBoxGeometry(0.5f, 0.05f, 0.05f), *gMaterial);
|
||||
PxRigidBodyExt::updateMassAndInertia(*rightRoot, 1.f);
|
||||
|
||||
PxArticulationJointReducedCoordinate* joint = static_cast<PxArticulationJointReducedCoordinate*>(leftRoot->getInboundJoint());
|
||||
joint->setJointType(PxArticulationJointType::eFIX);
|
||||
joint->setParentPose(PxTransform(PxVec3(0.f, 0.25f, -0.9f)));
|
||||
joint->setChildPose(PxTransform(PxVec3(0.f, -0.05f, 0.f)));
|
||||
|
||||
//Set up the drive joint...
|
||||
gDriveJoint = static_cast<PxArticulationJointReducedCoordinate*>(rightRoot->getInboundJoint());
|
||||
gDriveJoint->setJointType(PxArticulationJointType::ePRISMATIC);
|
||||
gDriveJoint->setMotion(PxArticulationAxis::eZ, PxArticulationMotion::eLIMITED);
|
||||
gDriveJoint->setLimit(PxArticulationAxis::eZ, -1.4f, 0.2f);
|
||||
gDriveJoint->setDrive(PxArticulationAxis::eZ, 100000.f, 0.f, PX_MAX_F32);
|
||||
|
||||
gDriveJoint->setParentPose(PxTransform(PxVec3(0.f, 0.25f, 0.9f)));
|
||||
gDriveJoint->setChildPose(PxTransform(PxVec3(0.f, -0.05f, 0.f)));
|
||||
|
||||
|
||||
const PxU32 linkHeight = 3;
|
||||
PxArticulationLink* currLeft = leftRoot, *currRight = rightRoot;
|
||||
|
||||
PxQuat rightParentRot(PxIdentity);
|
||||
PxQuat leftParentRot(PxIdentity);
|
||||
for (PxU32 i = 0; i < linkHeight; ++i)
|
||||
{
|
||||
const PxVec3 pos(0.5f, 0.55f + 0.1f*(1 + i), 0.f);
|
||||
PxArticulationLink* leftLink = gArticulation->createLink(currLeft, PxTransform(pos + PxVec3(0.f, sinAng*(2 * i + 1), 0.f), leftRot));
|
||||
PxRigidActorExt::createExclusiveShape(*leftLink, PxBoxGeometry(0.05f, 0.05f, 1.f), *gMaterial);
|
||||
PxRigidBodyExt::updateMassAndInertia(*leftLink, 1.f);
|
||||
|
||||
const PxVec3 leftAnchorLocation = pos + PxVec3(0.f, sinAng*(2 * i), -0.9f);
|
||||
|
||||
joint = static_cast<PxArticulationJointReducedCoordinate*>(leftLink->getInboundJoint());
|
||||
joint->setParentPose(PxTransform(currLeft->getGlobalPose().transformInv(leftAnchorLocation), leftParentRot));
|
||||
joint->setChildPose(PxTransform(PxVec3(0.f, 0.f, -1.f), rightRot));
|
||||
joint->setJointType(PxArticulationJointType::eREVOLUTE);
|
||||
|
||||
leftParentRot = leftRot;
|
||||
|
||||
joint->setMotion(PxArticulationAxis::eTWIST, PxArticulationMotion::eLIMITED);
|
||||
joint->setLimit(PxArticulationAxis::eTWIST, -PxPi, angle);
|
||||
|
||||
|
||||
PxArticulationLink* rightLink = gArticulation->createLink(currRight, PxTransform(pos + PxVec3(0.f, sinAng*(2 * i + 1), 0.f), rightRot));
|
||||
PxRigidActorExt::createExclusiveShape(*rightLink, PxBoxGeometry(0.05f, 0.05f, 1.f), *gMaterial);
|
||||
PxRigidBodyExt::updateMassAndInertia(*rightLink, 1.f);
|
||||
|
||||
const PxVec3 rightAnchorLocation = pos + PxVec3(0.f, sinAng*(2 * i), 0.9f);
|
||||
|
||||
joint = static_cast<PxArticulationJointReducedCoordinate*>(rightLink->getInboundJoint());
|
||||
joint->setJointType(PxArticulationJointType::eREVOLUTE);
|
||||
joint->setParentPose(PxTransform(currRight->getGlobalPose().transformInv(rightAnchorLocation), rightParentRot));
|
||||
joint->setChildPose(PxTransform(PxVec3(0.f, 0.f, 1.f), leftRot));
|
||||
joint->setMotion(PxArticulationAxis::eTWIST, PxArticulationMotion::eLIMITED);
|
||||
joint->setLimit(PxArticulationAxis::eTWIST, -angle, PxPi);
|
||||
|
||||
rightParentRot = rightRot;
|
||||
|
||||
PxD6Joint* d6joint = PxD6JointCreate(*gPhysics, leftLink, PxTransform(PxIdentity), rightLink, PxTransform(PxIdentity));
|
||||
|
||||
d6joint->setMotion(PxD6Axis::eTWIST, PxD6Motion::eFREE);
|
||||
d6joint->setMotion(PxD6Axis::eSWING1, PxD6Motion::eFREE);
|
||||
d6joint->setMotion(PxD6Axis::eSWING2, PxD6Motion::eFREE);
|
||||
|
||||
currLeft = rightLink;
|
||||
currRight = leftLink;
|
||||
}
|
||||
|
||||
|
||||
PxArticulationLink* leftTop = gArticulation->createLink(currLeft, currLeft->getGlobalPose().transform(PxTransform(PxVec3(-0.5f, 0.f, -1.0f), leftParentRot)));
|
||||
PxRigidActorExt::createExclusiveShape(*leftTop, PxBoxGeometry(0.5f, 0.05f, 0.05f), *gMaterial);
|
||||
PxRigidBodyExt::updateMassAndInertia(*leftTop, 1.f);
|
||||
|
||||
PxArticulationLink* rightTop = gArticulation->createLink(currRight, currRight->getGlobalPose().transform(PxTransform(PxVec3(-0.5f, 0.f, 1.0f), rightParentRot)));
|
||||
PxRigidActorExt::createExclusiveShape(*rightTop, PxCapsuleGeometry(0.05f, 0.8f), *gMaterial);
|
||||
//PxRigidActorExt::createExclusiveShape(*rightTop, PxBoxGeometry(0.5f, 0.05f, 0.05f), *gMaterial);
|
||||
PxRigidBodyExt::updateMassAndInertia(*rightTop, 1.f);
|
||||
|
||||
joint = static_cast<PxArticulationJointReducedCoordinate*>(leftTop->getInboundJoint());
|
||||
joint->setParentPose(PxTransform(PxVec3(0.f, 0.f, -1.f), currLeft->getGlobalPose().q.getConjugate()));
|
||||
joint->setChildPose(PxTransform(PxVec3(0.5f, 0.f, 0.f), leftTop->getGlobalPose().q.getConjugate()));
|
||||
joint->setJointType(PxArticulationJointType::eREVOLUTE);
|
||||
joint->setMotion(PxArticulationAxis::eTWIST, PxArticulationMotion::eFREE);
|
||||
//joint->setDrive(PxArticulationAxis::eTWIST, 0.f, 10.f, PX_MAX_F32);
|
||||
|
||||
joint = static_cast<PxArticulationJointReducedCoordinate*>(rightTop->getInboundJoint());
|
||||
joint->setParentPose(PxTransform(PxVec3(0.f, 0.f, 1.f), currRight->getGlobalPose().q.getConjugate()));
|
||||
joint->setChildPose(PxTransform(PxVec3(0.5f, 0.f, 0.f), rightTop->getGlobalPose().q.getConjugate()));
|
||||
joint->setJointType(PxArticulationJointType::eREVOLUTE);
|
||||
joint->setMotion(PxArticulationAxis::eTWIST, PxArticulationMotion::eFREE);
|
||||
//joint->setDrive(PxArticulationAxis::eTWIST, 0.f, 10.f, PX_MAX_F32);
|
||||
|
||||
|
||||
currLeft = leftRoot;
|
||||
currRight = rightRoot;
|
||||
|
||||
rightParentRot = PxQuat(PxIdentity);
|
||||
leftParentRot = PxQuat(PxIdentity);
|
||||
|
||||
for (PxU32 i = 0; i < linkHeight; ++i)
|
||||
{
|
||||
const PxVec3 pos(-0.5f, 0.55f + 0.1f*(1 + i), 0.f);
|
||||
PxArticulationLink* leftLink = gArticulation->createLink(currLeft, PxTransform(pos + PxVec3(0.f, sinAng*(2 * i + 1), 0.f), leftRot));
|
||||
PxRigidActorExt::createExclusiveShape(*leftLink, PxBoxGeometry(0.05f, 0.05f, 1.f), *gMaterial);
|
||||
PxRigidBodyExt::updateMassAndInertia(*leftLink, 1.f);
|
||||
|
||||
const PxVec3 leftAnchorLocation = pos + PxVec3(0.f, sinAng*(2 * i), -0.9f);
|
||||
|
||||
joint = static_cast<PxArticulationJointReducedCoordinate*>(leftLink->getInboundJoint());
|
||||
joint->setJointType(PxArticulationJointType::eREVOLUTE);
|
||||
joint->setParentPose(PxTransform(currLeft->getGlobalPose().transformInv(leftAnchorLocation), leftParentRot));
|
||||
joint->setChildPose(PxTransform(PxVec3(0.f, 0.f, -1.f), rightRot));
|
||||
|
||||
leftParentRot = leftRot;
|
||||
|
||||
joint->setMotion(PxArticulationAxis::eTWIST, PxArticulationMotion::eLIMITED);
|
||||
joint->setLimit(PxArticulationAxis::eTWIST, -PxPi, angle);
|
||||
|
||||
PxArticulationLink* rightLink = gArticulation->createLink(currRight, PxTransform(pos + PxVec3(0.f, sinAng*(2 * i + 1), 0.f), rightRot));
|
||||
PxRigidActorExt::createExclusiveShape(*rightLink, PxBoxGeometry(0.05f, 0.05f, 1.f), *gMaterial);
|
||||
PxRigidBodyExt::updateMassAndInertia(*rightLink, 1.f);
|
||||
|
||||
const PxVec3 rightAnchorLocation = pos + PxVec3(0.f, sinAng*(2 * i), 0.9f);
|
||||
|
||||
/*joint = PxD6JointCreate(getPhysics(), currRight, PxTransform(currRight->getGlobalPose().transformInv(rightAnchorLocation)),
|
||||
rightLink, PxTransform(PxVec3(0.f, 0.f, 1.f)));*/
|
||||
|
||||
joint = static_cast<PxArticulationJointReducedCoordinate*>(rightLink->getInboundJoint());
|
||||
joint->setParentPose(PxTransform(currRight->getGlobalPose().transformInv(rightAnchorLocation), rightParentRot));
|
||||
joint->setJointType(PxArticulationJointType::eREVOLUTE);
|
||||
joint->setChildPose(PxTransform(PxVec3(0.f, 0.f, 1.f), leftRot));
|
||||
joint->setMotion(PxArticulationAxis::eTWIST, PxArticulationMotion::eLIMITED);
|
||||
joint->setLimit(PxArticulationAxis::eTWIST, -angle, PxPi);
|
||||
|
||||
rightParentRot = rightRot;
|
||||
|
||||
PxD6Joint* d6joint = PxD6JointCreate(*gPhysics, leftLink, PxTransform(PxIdentity), rightLink, PxTransform(PxIdentity));
|
||||
|
||||
d6joint->setMotion(PxD6Axis::eTWIST, PxD6Motion::eFREE);
|
||||
d6joint->setMotion(PxD6Axis::eSWING1, PxD6Motion::eFREE);
|
||||
d6joint->setMotion(PxD6Axis::eSWING2, PxD6Motion::eFREE);
|
||||
|
||||
currLeft = rightLink;
|
||||
currRight = leftLink;
|
||||
}
|
||||
|
||||
PxD6Joint* d6joint = PxD6JointCreate(*gPhysics, currLeft, PxTransform(PxVec3(0.f, 0.f, -1.f)), leftTop, PxTransform(PxVec3(-0.5f, 0.f, 0.f)));
|
||||
|
||||
d6joint->setMotion(PxD6Axis::eTWIST, PxD6Motion::eFREE);
|
||||
d6joint->setMotion(PxD6Axis::eSWING1, PxD6Motion::eFREE);
|
||||
d6joint->setMotion(PxD6Axis::eSWING2, PxD6Motion::eFREE);
|
||||
|
||||
d6joint = PxD6JointCreate(*gPhysics, currRight, PxTransform(PxVec3(0.f, 0.f, 1.f)), rightTop, PxTransform(PxVec3(-0.5f, 0.f, 0.f)));
|
||||
|
||||
d6joint->setMotion(PxD6Axis::eTWIST, PxD6Motion::eFREE);
|
||||
d6joint->setMotion(PxD6Axis::eSWING1, PxD6Motion::eFREE);
|
||||
d6joint->setMotion(PxD6Axis::eSWING2, PxD6Motion::eFREE);
|
||||
|
||||
|
||||
const PxTransform topPose(PxVec3(0.f, leftTop->getGlobalPose().p.y + 0.15f, 0.f));
|
||||
|
||||
PxArticulationLink* top = gArticulation->createLink(leftTop, topPose);
|
||||
PxRigidActorExt::createExclusiveShape(*top, PxBoxGeometry(0.5f, 0.1f, 1.5f), *gMaterial);
|
||||
PxRigidBodyExt::updateMassAndInertia(*top, 1.f);
|
||||
|
||||
joint = static_cast<PxArticulationJointReducedCoordinate*>(top->getInboundJoint());
|
||||
joint->setJointType(PxArticulationJointType::eFIX);
|
||||
joint->setParentPose(PxTransform(PxVec3(0.f, 0.0f, 0.f)));
|
||||
joint->setChildPose(PxTransform(PxVec3(0.f, -0.15f, -0.9f)));
|
||||
|
||||
gScene->addArticulation(*gArticulation);
|
||||
|
||||
for (PxU32 i = 0; i < gArticulation->getNbLinks(); ++i)
|
||||
{
|
||||
PxArticulationLink* link;
|
||||
gArticulation->getLinks(&link, 1, i);
|
||||
|
||||
link->setLinearDamping(0.2f);
|
||||
link->setAngularDamping(0.2f);
|
||||
|
||||
link->setMaxAngularVelocity(20.f);
|
||||
link->setMaxLinearVelocity(100.f);
|
||||
|
||||
if (link != top)
|
||||
{
|
||||
for (PxU32 b = 0; b < link->getNbShapes(); ++b)
|
||||
{
|
||||
PxShape* shape;
|
||||
link->getShapes(&shape, 1, b);
|
||||
|
||||
shape->setSimulationFilterData(PxFilterData(0, 0, 1, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const PxVec3 halfExt(0.25f);
|
||||
const PxReal density(0.5f);
|
||||
|
||||
PxRigidDynamic* box0 = gPhysics->createRigidDynamic(PxTransform(PxVec3(-0.25f, 5.f, 0.5f)));
|
||||
PxRigidActorExt::createExclusiveShape(*box0, PxBoxGeometry(halfExt), *gMaterial);
|
||||
PxRigidBodyExt::updateMassAndInertia(*box0, density);
|
||||
|
||||
gScene->addActor(*box0);
|
||||
|
||||
PxRigidDynamic* box1 = gPhysics->createRigidDynamic(PxTransform(PxVec3(0.25f, 5.f, 0.5f)));
|
||||
PxRigidActorExt::createExclusiveShape(*box1, PxBoxGeometry(halfExt), *gMaterial);
|
||||
PxRigidBodyExt::updateMassAndInertia(*box1, density);
|
||||
|
||||
gScene->addActor(*box1);
|
||||
|
||||
PxRigidDynamic* box2 = gPhysics->createRigidDynamic(PxTransform(PxVec3(-0.25f, 4.5f, 0.5f)));
|
||||
PxRigidActorExt::createExclusiveShape(*box2, PxBoxGeometry(halfExt), *gMaterial);
|
||||
PxRigidBodyExt::updateMassAndInertia(*box2, density);
|
||||
|
||||
gScene->addActor(*box2);
|
||||
|
||||
PxRigidDynamic* box3 = gPhysics->createRigidDynamic(PxTransform(PxVec3(0.25f, 4.5f, 0.5f)));
|
||||
PxRigidActorExt::createExclusiveShape(*box3, PxBoxGeometry(halfExt), *gMaterial);
|
||||
PxRigidBodyExt::updateMassAndInertia(*box3, density);
|
||||
|
||||
gScene->addActor(*box3);
|
||||
|
||||
PxRigidDynamic* box4 = gPhysics->createRigidDynamic(PxTransform(PxVec3(-0.25f, 5.f, 0.f)));
|
||||
PxRigidActorExt::createExclusiveShape(*box4, PxBoxGeometry(halfExt), *gMaterial);
|
||||
PxRigidBodyExt::updateMassAndInertia(*box4, density);
|
||||
|
||||
gScene->addActor(*box4);
|
||||
|
||||
PxRigidDynamic* box5 = gPhysics->createRigidDynamic(PxTransform(PxVec3(0.25f, 5.f, 0.f)));
|
||||
PxRigidActorExt::createExclusiveShape(*box5, PxBoxGeometry(halfExt), *gMaterial);
|
||||
PxRigidBodyExt::updateMassAndInertia(*box5, density);
|
||||
|
||||
gScene->addActor(*box5);
|
||||
|
||||
PxRigidDynamic* box6 = gPhysics->createRigidDynamic(PxTransform(PxVec3(-0.25f, 4.5f, 0.f)));
|
||||
PxRigidActorExt::createExclusiveShape(*box6, PxBoxGeometry(halfExt), *gMaterial);
|
||||
PxRigidBodyExt::updateMassAndInertia(*box6, density);
|
||||
|
||||
gScene->addActor(*box6);
|
||||
|
||||
PxRigidDynamic* box7 = gPhysics->createRigidDynamic(PxTransform(PxVec3(0.25f, 4.5f, 0.f)));
|
||||
PxRigidActorExt::createExclusiveShape(*box7, PxBoxGeometry(halfExt), *gMaterial);
|
||||
PxRigidBodyExt::updateMassAndInertia(*box7, density);
|
||||
|
||||
gScene->addActor(*box7);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void createLongChain()
|
||||
{
|
||||
const float scale = 0.25f;
|
||||
const float radius = 0.5f*scale;
|
||||
const float halfHeight = 1.0f*scale;
|
||||
const PxU32 nbCapsules = 40;
|
||||
const float capsuleMass = 1.0f;
|
||||
|
||||
const PxVec3 initPos(0.0f, 24.0f, 0.0f);
|
||||
PxVec3 pos = initPos;
|
||||
PxShape* capsuleShape = gPhysics->createShape(PxCapsuleGeometry(radius, halfHeight), *gMaterial);
|
||||
PxArticulationLink* firstLink = NULL;
|
||||
PxArticulationLink* parent = NULL;
|
||||
|
||||
const bool overlappingLinks = true; // Change this for another kind of rope
|
||||
|
||||
gArticulation->setSolverIterationCounts(16);
|
||||
|
||||
// Create rope
|
||||
for (PxU32 i = 0; i<nbCapsules; i++)
|
||||
{
|
||||
PxArticulationLink* link = gArticulation->createLink(parent, PxTransform(pos));
|
||||
if (!firstLink)
|
||||
firstLink = link;
|
||||
|
||||
link->attachShape(*capsuleShape);
|
||||
PxRigidBodyExt::setMassAndUpdateInertia(*link, capsuleMass);
|
||||
|
||||
link->setLinearDamping(0.1f);
|
||||
link->setAngularDamping(0.1f);
|
||||
|
||||
link->setMaxAngularVelocity(30.f);
|
||||
link->setMaxLinearVelocity(100.f);
|
||||
|
||||
PxArticulationJointBase* joint = link->getInboundJoint();
|
||||
|
||||
if (joint) // Will be null for root link
|
||||
{
|
||||
#if USE_REDUCED_COORDINATE_ARTICULATION
|
||||
PxArticulationJointReducedCoordinate* rcJoint = static_cast<PxArticulationJointReducedCoordinate*>(joint);
|
||||
rcJoint->setJointType(PxArticulationJointType::eSPHERICAL);
|
||||
rcJoint->setMotion(PxArticulationAxis::eSWING2, PxArticulationMotion::eFREE);
|
||||
rcJoint->setMotion(PxArticulationAxis::eSWING1, PxArticulationMotion::eFREE);
|
||||
rcJoint->setMotion(PxArticulationAxis::eTWIST, PxArticulationMotion::eFREE);
|
||||
rcJoint->setFrictionCoefficient(1.f);
|
||||
rcJoint->setMaxJointVelocity(1000000.f);
|
||||
#endif
|
||||
if (overlappingLinks)
|
||||
{
|
||||
joint->setParentPose(PxTransform(PxVec3(halfHeight, 0.0f, 0.0f)));
|
||||
joint->setChildPose(PxTransform(PxVec3(-halfHeight, 0.0f, 0.0f)));
|
||||
}
|
||||
else
|
||||
{
|
||||
joint->setParentPose(PxTransform(PxVec3(radius + halfHeight, 0.0f, 0.0f)));
|
||||
joint->setChildPose(PxTransform(PxVec3(-radius - halfHeight, 0.0f, 0.0f)));
|
||||
}
|
||||
}
|
||||
|
||||
if (overlappingLinks)
|
||||
pos.x += (radius + halfHeight*2.0f);
|
||||
else
|
||||
pos.x += (radius + halfHeight) * 2.0f;
|
||||
parent = link;
|
||||
}
|
||||
|
||||
//Attach large & heavy box at the end of the rope
|
||||
{
|
||||
const float boxMass = 50.0f;
|
||||
const float boxSize = 1.0f;
|
||||
PxShape* boxShape = gPhysics->createShape(PxBoxGeometry(boxSize, boxSize, boxSize), *gMaterial);
|
||||
|
||||
pos.x -= (radius + halfHeight) * 2.0f;
|
||||
pos.x += (radius + halfHeight) + boxSize;
|
||||
|
||||
PxArticulationLink* link = gArticulation->createLink(parent, PxTransform(pos));
|
||||
|
||||
link->setLinearDamping(0.1f);
|
||||
link->setAngularDamping(0.1f);
|
||||
link->setMaxAngularVelocity(30.f);
|
||||
link->setMaxLinearVelocity(100.f);
|
||||
|
||||
link->attachShape(*boxShape);
|
||||
PxRigidBodyExt::setMassAndUpdateInertia(*link, boxMass);
|
||||
|
||||
PxArticulationJointBase* joint = link->getInboundJoint();
|
||||
#if USE_REDUCED_COORDINATE_ARTICULATION
|
||||
PxArticulationJointReducedCoordinate* rcJoint = static_cast<PxArticulationJointReducedCoordinate*>(joint);
|
||||
rcJoint->setJointType(PxArticulationJointType::eSPHERICAL);
|
||||
rcJoint->setMotion(PxArticulationAxis::eSWING2, PxArticulationMotion::eFREE);
|
||||
rcJoint->setMotion(PxArticulationAxis::eSWING1, PxArticulationMotion::eFREE);
|
||||
rcJoint->setMotion(PxArticulationAxis::eTWIST, PxArticulationMotion::eFREE);
|
||||
rcJoint->setFrictionCoefficient(1.f);
|
||||
rcJoint->setMaxJointVelocity(1000000.f);
|
||||
#endif
|
||||
if (joint) // Will be null for root link
|
||||
{
|
||||
joint->setParentPose(PxTransform(PxVec3(radius + halfHeight, 0.0f, 0.0f)));
|
||||
joint->setChildPose(PxTransform(PxVec3(-boxSize, 0.0f, 0.0f)));
|
||||
}
|
||||
}
|
||||
gScene->addArticulation(*gArticulation);
|
||||
|
||||
#if USE_REDUCED_COORDINATE_ARTICULATION
|
||||
gArticulation->setArticulationFlags(PxArticulationFlag::eFIX_BASE);
|
||||
#else
|
||||
// Attach articulation to static world
|
||||
{
|
||||
PxShape* anchorShape = gPhysics->createShape(PxSphereGeometry(0.05f), *gMaterial);
|
||||
PxRigidStatic* anchor = PxCreateStatic(*gPhysics, PxTransform(initPos), *anchorShape);
|
||||
gScene->addActor(*anchor);
|
||||
PxSphericalJoint* j = PxSphericalJointCreate(*gPhysics, anchor, PxTransform(PxVec3(0.0f)), firstLink, PxTransform(PxVec3(0.0f)));
|
||||
PX_UNUSED(j);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Create obstacle
|
||||
{
|
||||
PxShape* boxShape = gPhysics->createShape(PxBoxGeometry(1.0f, 0.1f, 2.0f), *gMaterial);
|
||||
PxRigidStatic* obstacle = PxCreateStatic(*gPhysics, PxTransform(initPos + PxVec3(10.0f, -3.0f, 0.0f)), *boxShape);
|
||||
gScene->addActor(*obstacle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void initPhysics(bool /*interactive*/)
|
||||
{
|
||||
gFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gAllocator, gErrorCallback);
|
||||
gPvd = PxCreatePvd(*gFoundation);
|
||||
PxPvdTransport* transport = PxDefaultPvdSocketTransportCreate(PVD_HOST, 5425, 10);
|
||||
gPvd->connect(*transport,PxPvdInstrumentationFlag::eALL);
|
||||
|
||||
gPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, PxTolerancesScale(), true, gPvd);
|
||||
PxInitExtensions(*gPhysics, gPvd);
|
||||
|
||||
PxSceneDesc sceneDesc(gPhysics->getTolerancesScale());
|
||||
sceneDesc.gravity = PxVec3(0.0f, -9.81f, 0.0f);
|
||||
|
||||
PxU32 numCores = SnippetUtils::getNbPhysicalCores();
|
||||
gDispatcher = PxDefaultCpuDispatcherCreate(numCores == 0 ? 0 : numCores - 1);
|
||||
sceneDesc.cpuDispatcher = gDispatcher;
|
||||
sceneDesc.filterShader = PxDefaultSimulationFilterShader;
|
||||
|
||||
#if USE_REDUCED_COORDINATE_ARTICULATION
|
||||
sceneDesc.solverType = PxSolverType::eTGS;
|
||||
#if CREATE_SCISSOR_LIFT
|
||||
sceneDesc.filterShader = scissorFilter;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
gScene = gPhysics->createScene(sceneDesc);
|
||||
PxPvdSceneClient* pvdClient = gScene->getScenePvdClient();
|
||||
if(pvdClient)
|
||||
{
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONSTRAINTS, true);
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONTACTS, true);
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_SCENEQUERIES, true);
|
||||
}
|
||||
|
||||
gMaterial = gPhysics->createMaterial(0.5f, 0.5f, 0.f);
|
||||
|
||||
PxRigidStatic* groundPlane = PxCreatePlane(*gPhysics, PxPlane(0,1,0,0), *gMaterial);
|
||||
gScene->addActor(*groundPlane);
|
||||
|
||||
#if USE_REDUCED_COORDINATE_ARTICULATION
|
||||
gArticulation = gPhysics->createArticulationReducedCoordinate();
|
||||
#else
|
||||
gArticulation = gPhysics->createArticulation();
|
||||
|
||||
// Stabilization can create artefacts on jointed objects so we just disable it
|
||||
gArticulation->setStabilizationThreshold(0.0f);
|
||||
|
||||
gArticulation->setMaxProjectionIterations(16);
|
||||
gArticulation->setSeparationTolerance(0.001f);
|
||||
#endif
|
||||
|
||||
#if USE_REDUCED_COORDINATE_ARTICULATION & CREATE_SCISSOR_LIFT
|
||||
createScissorLift();
|
||||
#else
|
||||
createLongChain();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if USE_REDUCED_COORDINATE_ARTICULATION
|
||||
static bool gClosing = true;
|
||||
#endif
|
||||
|
||||
void stepPhysics(bool /*interactive*/)
|
||||
{
|
||||
const PxReal dt = 1.0f / 60.f;
|
||||
#if USE_REDUCED_COORDINATE_ARTICULATION & CREATE_SCISSOR_LIFT
|
||||
PxReal driveValue = gDriveJoint->getDriveTarget(PxArticulationAxis::eZ);
|
||||
|
||||
if (gClosing && driveValue < -1.2f)
|
||||
gClosing = false;
|
||||
else if (!gClosing && driveValue > 0.f)
|
||||
gClosing = true;
|
||||
|
||||
if (gClosing)
|
||||
driveValue -= dt*0.25f;
|
||||
else
|
||||
driveValue += dt*0.25f;
|
||||
gDriveJoint->setDriveTarget(PxArticulationAxis::eZ, driveValue);
|
||||
#endif
|
||||
|
||||
gScene->simulate(dt);
|
||||
gScene->fetchResults(true);
|
||||
}
|
||||
|
||||
void cleanupPhysics(bool /*interactive*/)
|
||||
{
|
||||
gArticulation->release();
|
||||
gScene->release();
|
||||
gDispatcher->release();
|
||||
gPhysics->release();
|
||||
PxPvdTransport* transport = gPvd->getTransport();
|
||||
gPvd->release();
|
||||
transport->release();
|
||||
PxCloseExtensions();
|
||||
gFoundation->release();
|
||||
|
||||
printf("SnippetArticulation done.\n");
|
||||
}
|
||||
|
||||
void keyPress(unsigned char /*key*/, const PxTransform& /*camera*/)
|
||||
{
|
||||
}
|
||||
|
||||
int snippetMain(int, const char*const*)
|
||||
{
|
||||
#ifdef RENDER_SNIPPET
|
||||
extern void renderLoop();
|
||||
renderLoop();
|
||||
#else
|
||||
static const PxU32 frameCount = 100;
|
||||
initPhysics(false);
|
||||
for(PxU32 i=0; i<frameCount; i++)
|
||||
stepPhysics(false);
|
||||
cleanupPhysics(false);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
145
physx/snippets/snippetarticulation/SnippetArticulationRender.cpp
Normal file
145
physx/snippets/snippetarticulation/SnippetArticulationRender.cpp
Normal file
@ -0,0 +1,145 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifdef RENDER_SNIPPET
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
|
||||
#include "../snippetrender/SnippetRender.h"
|
||||
#include "../snippetrender/SnippetCamera.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
extern void initPhysics(bool interactive);
|
||||
extern void stepPhysics(bool interactive);
|
||||
extern void cleanupPhysics(bool interactive);
|
||||
extern void keyPress(unsigned char key, const PxTransform& camera);
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
Snippets::Camera* sCamera;
|
||||
|
||||
void motionCallback(int x, int y)
|
||||
{
|
||||
sCamera->handleMotion(x, y);
|
||||
}
|
||||
|
||||
void keyboardCallback(unsigned char key, int x, int y)
|
||||
{
|
||||
if(key==27)
|
||||
exit(0);
|
||||
|
||||
if(!sCamera->handleKey(key, x, y))
|
||||
keyPress(key, sCamera->getTransform());
|
||||
}
|
||||
|
||||
void mouseCallback(int button, int state, int x, int y)
|
||||
{
|
||||
sCamera->handleMouse(button, state, x, y);
|
||||
}
|
||||
|
||||
void idleCallback()
|
||||
{
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
void renderCallback()
|
||||
{
|
||||
stepPhysics(true);
|
||||
|
||||
Snippets::startRender(sCamera->getEye(), sCamera->getDir());
|
||||
|
||||
PxScene* scene;
|
||||
PxGetPhysics().getScenes(&scene,1);
|
||||
PxU32 nbActors = scene->getNbActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC);
|
||||
if(nbActors)
|
||||
{
|
||||
std::vector<PxRigidActor*> actors(nbActors);
|
||||
scene->getActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC, reinterpret_cast<PxActor**>(&actors[0]), nbActors);
|
||||
Snippets::renderActors(&actors[0], static_cast<PxU32>(actors.size()), true);
|
||||
}
|
||||
|
||||
PxU32 nbArticulations = scene->getNbArticulations();
|
||||
for(PxU32 i=0;i<nbArticulations;i++)
|
||||
{
|
||||
PxArticulationBase* articulation;
|
||||
scene->getArticulations(&articulation, 1, i);
|
||||
|
||||
const PxU32 nbLinks = articulation->getNbLinks();
|
||||
std::vector<PxArticulationLink*> links(nbLinks);
|
||||
articulation->getLinks(&links[0], nbLinks);
|
||||
|
||||
Snippets::renderActors(reinterpret_cast<PxRigidActor**>(&links[0]), static_cast<PxU32>(links.size()), true);
|
||||
}
|
||||
|
||||
Snippets::finishRender();
|
||||
}
|
||||
|
||||
void exitCallback(void)
|
||||
{
|
||||
delete sCamera;
|
||||
cleanupPhysics(true);
|
||||
}
|
||||
}
|
||||
|
||||
const PxVec3 gCamEyeChain(9.621917f, 24.677629f, 16.127209f);
|
||||
const PxVec3 gCamDirChain(-0.138525f, -0.468482f, -0.872546f);
|
||||
|
||||
const PxVec3 gCamEyeLift(8.605188f, 4.050591f, 0.145860f);
|
||||
const PxVec3 gCamDirLift(-0.999581f, -0.026449f, 0.011790f);
|
||||
|
||||
extern bool gCreateLiftScene;
|
||||
|
||||
void renderLoop()
|
||||
{
|
||||
if(gCreateLiftScene)
|
||||
sCamera = new Snippets::Camera(gCamEyeLift, gCamDirLift);
|
||||
else
|
||||
sCamera = new Snippets::Camera(gCamEyeChain, gCamDirChain);
|
||||
|
||||
Snippets::setupDefaultWindow("PhysX Snippet Articulation");
|
||||
Snippets::setupDefaultRenderState();
|
||||
|
||||
glutIdleFunc(idleCallback);
|
||||
glutDisplayFunc(renderCallback);
|
||||
glutKeyboardFunc(keyboardCallback);
|
||||
glutMouseFunc(mouseCallback);
|
||||
glutMotionFunc(motionCallback);
|
||||
motionCallback(0,0);
|
||||
|
||||
atexit(exitCallback);
|
||||
|
||||
initPhysics(true);
|
||||
glutMainLoop();
|
||||
}
|
||||
|
||||
#endif
|
||||
201
physx/snippets/snippetbvhstructure/SnippetBVHStructure.cpp
Normal file
201
physx/snippets/snippetbvhstructure/SnippetBVHStructure.cpp
Normal file
@ -0,0 +1,201 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
// ****************************************************************************
|
||||
// This snippet illustrates the usage of PxBVHStructure
|
||||
//
|
||||
// It creates a large number of small sphere shapes forming a large sphere. Large sphere
|
||||
// represents an actor and the actor is inserted into the scene with BVHStructure
|
||||
// that is precomputed from all the small spheres. When an actor is insterted this
|
||||
// way the scene queries against this object behave actor centric rather than shape
|
||||
// centric.
|
||||
// Each actor that is added with a BVHSctructure does not update any of its shape bounds
|
||||
// within a pruning structure. It does update just the actor bounds and the query then
|
||||
// goes into actors bounds pruner, then a local query is done against the shapes in the
|
||||
// actor.
|
||||
// For a dynamic actor consisting of a large amound of shapes there can be a significant
|
||||
// performance benefits. During fetch results, there is no need to synchronize all
|
||||
// shape bounds into scene query system. Also when a new AABB tree is build inside
|
||||
// scene query system these actors shapes are not contained there.
|
||||
// ****************************************************************************
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
|
||||
#include "../snippetcommon/SnippetPrint.h"
|
||||
#include "../snippetcommon/SnippetPVD.h"
|
||||
#include "../snippetutils/SnippetUtils.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
PxDefaultAllocator gAllocator;
|
||||
PxDefaultErrorCallback gErrorCallback;
|
||||
|
||||
PxFoundation* gFoundation = NULL;
|
||||
PxPhysics* gPhysics = NULL;
|
||||
PxCooking* gCooking = NULL;
|
||||
|
||||
PxDefaultCpuDispatcher* gDispatcher = NULL;
|
||||
PxScene* gScene = NULL;
|
||||
|
||||
PxMaterial* gMaterial = NULL;
|
||||
|
||||
PxPvd* gPvd = NULL;
|
||||
|
||||
void createLargeSphere(const PxTransform& t, PxU32 density, PxReal largeRadius, PxReal radius, bool useAggregate)
|
||||
{
|
||||
PxRigidDynamic* body = gPhysics->createRigidDynamic(t);
|
||||
|
||||
// generate the sphere shapes
|
||||
const float gStep = PxPi/float(density);
|
||||
const float tStep = 2.0f*PxPi/float(density);
|
||||
for(PxU32 i=0; i<density;i++)
|
||||
{
|
||||
for(PxU32 j=0;j<density;j++)
|
||||
{
|
||||
const float sinG = PxSin(gStep * i);
|
||||
const float cosG = PxCos(gStep * i);
|
||||
const float sinT = PxSin(tStep * j);
|
||||
const float cosT = PxCos(tStep * j);
|
||||
|
||||
PxTransform localTm(PxVec3(largeRadius*sinG*cosT, largeRadius*sinG*sinT, largeRadius*cosG));
|
||||
PxShape* shape = gPhysics->createShape(PxSphereGeometry(radius), *gMaterial);
|
||||
shape->setLocalPose(localTm);
|
||||
body->attachShape(*shape);
|
||||
shape->release();
|
||||
}
|
||||
}
|
||||
PxRigidBodyExt::updateMassAndInertia(*body, 10.0f);
|
||||
|
||||
// get the bounds from the actor, this can be done through a helper function in PhysX extensions
|
||||
PxU32 numBounds = 0;
|
||||
PxBounds3* bounds = PxRigidActorExt::getRigidActorShapeLocalBoundsList(*body, numBounds);
|
||||
|
||||
// setup the PxBVHStructureDesc, it does contain only the PxBounds3 data
|
||||
PxBVHStructureDesc bvhDesc;
|
||||
bvhDesc.bounds.count = numBounds;
|
||||
bvhDesc.bounds.data = bounds;
|
||||
bvhDesc.bounds.stride = sizeof(PxBounds3);
|
||||
|
||||
// cook the bvh structure
|
||||
PxBVHStructure* bvh = gCooking->createBVHStructure(bvhDesc, gPhysics->getPhysicsInsertionCallback());
|
||||
|
||||
// release the memory allocated within extensions, the bounds are not required anymore
|
||||
gAllocator.deallocate(bounds);
|
||||
|
||||
// add the actor to the scene and provide the bvh structure (regular path without aggregate usage)
|
||||
if(!useAggregate)
|
||||
gScene->addActor(*body, bvh);
|
||||
|
||||
// Note that when objects with large amound of shapes are created it is also
|
||||
// recommended to create an aggregate from them, see the code below that would replace
|
||||
// the gScene->addActor(*body, bvh)
|
||||
if(useAggregate)
|
||||
{
|
||||
PxAggregate* aggregate = gPhysics->createAggregate(1, false);
|
||||
aggregate->addActor(*body, bvh);
|
||||
gScene->addAggregate(*aggregate);
|
||||
}
|
||||
|
||||
|
||||
// bvh can be released at this point, the precomputed BVH structure was copied to the SDK pruners.
|
||||
bvh->release();
|
||||
}
|
||||
|
||||
void initPhysics(bool /*interactive*/)
|
||||
{
|
||||
gFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gAllocator, gErrorCallback);
|
||||
|
||||
gPvd = PxCreatePvd(*gFoundation);
|
||||
PxPvdTransport* transport = PxDefaultPvdSocketTransportCreate(PVD_HOST, 5425, 10);
|
||||
gPvd->connect(*transport,PxPvdInstrumentationFlag::eALL);
|
||||
|
||||
gPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, PxTolerancesScale(),true,gPvd);
|
||||
gCooking = PxCreateCooking(PX_PHYSICS_VERSION, *gFoundation, PxCookingParams(PxTolerancesScale()));
|
||||
|
||||
PxSceneDesc sceneDesc(gPhysics->getTolerancesScale());
|
||||
sceneDesc.gravity = PxVec3(0.0f, -9.81f, 0.0f);
|
||||
gDispatcher = PxDefaultCpuDispatcherCreate(2);
|
||||
sceneDesc.cpuDispatcher = gDispatcher;
|
||||
sceneDesc.filterShader = PxDefaultSimulationFilterShader;
|
||||
gScene = gPhysics->createScene(sceneDesc);
|
||||
|
||||
PxPvdSceneClient* pvdClient = gScene->getScenePvdClient();
|
||||
if(pvdClient)
|
||||
{
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONSTRAINTS, true);
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONTACTS, true);
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_SCENEQUERIES, true);
|
||||
}
|
||||
gMaterial = gPhysics->createMaterial(0.5f, 0.5f, 0.6f);
|
||||
|
||||
PxRigidStatic* groundPlane = PxCreatePlane(*gPhysics, PxPlane(0,1,0,0), *gMaterial);
|
||||
gScene->addActor(*groundPlane);
|
||||
|
||||
for(PxU32 i = 0; i < 10; i++)
|
||||
createLargeSphere(PxTransform(PxVec3(200.0f*i, .0f, 100.0f)), 50, 30.0f, 1.0f, false);
|
||||
}
|
||||
|
||||
void stepPhysics(bool /*interactive*/)
|
||||
{
|
||||
gScene->simulate(1.0f/60.0f);
|
||||
gScene->fetchResults(true);
|
||||
}
|
||||
|
||||
void cleanupPhysics(bool /*interactive*/)
|
||||
{
|
||||
PX_RELEASE(gScene);
|
||||
PX_RELEASE(gDispatcher);
|
||||
PX_RELEASE(gPhysics);
|
||||
PX_RELEASE(gCooking);
|
||||
if(gPvd)
|
||||
{
|
||||
PxPvdTransport* transport = gPvd->getTransport();
|
||||
gPvd->release(); gPvd = NULL;
|
||||
PX_RELEASE(transport);
|
||||
}
|
||||
PX_RELEASE(gFoundation);
|
||||
|
||||
printf("SnippetBVHStructure done.\n");
|
||||
}
|
||||
|
||||
void keyPress(unsigned char , const PxTransform& )
|
||||
{
|
||||
}
|
||||
|
||||
int snippetMain(int, const char*const*)
|
||||
{
|
||||
static const PxU32 frameCount = 50;
|
||||
initPhysics(false);
|
||||
for(PxU32 i=0; i<frameCount; i++)
|
||||
stepPhysics(false);
|
||||
cleanupPhysics(false);
|
||||
return 0;
|
||||
}
|
||||
35
physx/snippets/snippetcommon/ClassicMain.cpp
Normal file
35
physx/snippets/snippetcommon/ClassicMain.cpp
Normal file
@ -0,0 +1,35 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
extern int snippetMain(int, const char*const*);
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
return snippetMain(argc, argv);
|
||||
}
|
||||
36
physx/snippets/snippetcommon/SnippetPVD.h
Normal file
36
physx/snippets/snippetcommon/SnippetPVD.h
Normal file
@ -0,0 +1,36 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
|
||||
#ifndef PHYSX_SNIPPET_PVD_H
|
||||
#define PHYSX_SNIPPET_PVD_H
|
||||
|
||||
#define PVD_HOST "127.0.0.1" //Set this to the IP address of the system running the PhysX Visual Debugger that you want to connect to.
|
||||
|
||||
#endif //PHYSX_SNIPPET_PVD_H
|
||||
45
physx/snippets/snippetcommon/SnippetPrint.h
Normal file
45
physx/snippets/snippetcommon/SnippetPrint.h
Normal file
@ -0,0 +1,45 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifndef PHYSX_SNIPPET_PRINT_H
|
||||
#define PHYSX_SNIPPET_PRINT_H
|
||||
|
||||
#include "foundation/PxPreprocessor.h"
|
||||
|
||||
#if PX_XBOXONE
|
||||
void OutputDebugPrint(const char*, ...);
|
||||
#define printf OutputDebugPrint
|
||||
#elif PX_XBOX_SERIES_X
|
||||
#include "PsString.h"
|
||||
#define printf shdfnd::printFormatted
|
||||
#elif PX_SWITCH
|
||||
#include "../SnippetCommon/Switch/SwitchSnippetPrint.h"
|
||||
#endif
|
||||
|
||||
#endif // PHYSX_SNIPPET_PRINT_H
|
||||
@ -0,0 +1,347 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
// ****************************************************************************
|
||||
// This snippet illustrates the use of simple contact reports and contact modification.
|
||||
//
|
||||
// It defines a filter shader function that requests contact modification and
|
||||
// touch reports for all pairs, and a contact callback function that saves
|
||||
// the contact points. It configures the scene to use this filter and callback,
|
||||
// and prints the number of contact reports each frame. If rendering, it renders
|
||||
// each contact as a line whose length and direction are defined by the contact
|
||||
// impulse.
|
||||
// This test sets up a situation that would be unstable without contact modification
|
||||
// due to very large mass ratios. This test uses local mass modification to make
|
||||
// the configuration stable. It also demonstrates how to interpret contact impulses
|
||||
// when local mass modification is used.
|
||||
// Local mass modification can be disabled with the MODIFY_MASS_PROPERTIES #define
|
||||
// to demonstrate the instability if it was not used.
|
||||
//
|
||||
// ****************************************************************************
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
|
||||
#include "../snippetutils/SnippetUtils.h"
|
||||
#include "../snippetcommon/SnippetPrint.h"
|
||||
#include "../snippetcommon/SnippetPVD.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
#define MODIFY_MASS_PROPERTIES 1
|
||||
|
||||
PxDefaultAllocator gAllocator;
|
||||
PxDefaultErrorCallback gErrorCallback;
|
||||
|
||||
PxFoundation* gFoundation = NULL;
|
||||
PxPhysics* gPhysics = NULL;
|
||||
|
||||
PxDefaultCpuDispatcher* gDispatcher = NULL;
|
||||
PxScene* gScene = NULL;
|
||||
PxMaterial* gMaterial = NULL;
|
||||
PxPvd* gPvd = NULL;
|
||||
|
||||
std::vector<PxVec3> gContactPositions;
|
||||
std::vector<PxVec3> gContactImpulses;
|
||||
std::vector<PxVec3> gContactLinearImpulses[2];
|
||||
std::vector<PxVec3> gContactAngularImpulses[2];
|
||||
|
||||
|
||||
PxFilterFlags contactReportFilterShader(PxFilterObjectAttributes attributes0, PxFilterData filterData0,
|
||||
PxFilterObjectAttributes attributes1, PxFilterData filterData1,
|
||||
PxPairFlags& pairFlags, const void* constantBlock, PxU32 constantBlockSize)
|
||||
{
|
||||
PX_UNUSED(attributes0);
|
||||
PX_UNUSED(attributes1);
|
||||
PX_UNUSED(filterData0);
|
||||
PX_UNUSED(filterData1);
|
||||
PX_UNUSED(constantBlockSize);
|
||||
PX_UNUSED(constantBlock);
|
||||
|
||||
// all initial and persisting reports for everything, with per-point data
|
||||
pairFlags = PxPairFlag::eSOLVE_CONTACT | PxPairFlag::eDETECT_DISCRETE_CONTACT
|
||||
| PxPairFlag::eNOTIFY_TOUCH_FOUND
|
||||
| PxPairFlag::eNOTIFY_TOUCH_PERSISTS
|
||||
| PxPairFlag::eNOTIFY_CONTACT_POINTS
|
||||
| PxPairFlag::eMODIFY_CONTACTS;
|
||||
return PxFilterFlag::eDEFAULT;
|
||||
}
|
||||
|
||||
class ContactModifyCallback: public PxContactModifyCallback
|
||||
{
|
||||
void onContactModify(PxContactModifyPair* const pairs, PxU32 count)
|
||||
{
|
||||
#if MODIFY_MASS_PROPERTIES
|
||||
//We define a maximum mass ratio that we will accept in this test, which is a ratio of 2
|
||||
const PxReal maxMassRatio = 2.f;
|
||||
|
||||
for(PxU32 i = 0; i < count; i++)
|
||||
{
|
||||
const PxRigidDynamic* dynamic0 = pairs[i].actor[0]->is<PxRigidDynamic>();
|
||||
const PxRigidDynamic* dynamic1 = pairs[i].actor[1]->is<PxRigidDynamic>();
|
||||
if(dynamic0 != NULL && dynamic1 != NULL)
|
||||
{
|
||||
//We only want to perform local mass modification between 2 dynamic bodies because we intend on
|
||||
//normalizing the mass ratios between the pair within a tolerable range
|
||||
|
||||
PxReal mass0 = dynamic0->getMass();
|
||||
PxReal mass1 = dynamic1->getMass();
|
||||
|
||||
if(mass0 > mass1)
|
||||
{
|
||||
//dynamic0 is heavier than dynamic1 so we will locally increase the mass of dynamic1
|
||||
//to be half the mass of dynamic0.
|
||||
PxReal ratio = mass0/mass1;
|
||||
if(ratio > maxMassRatio)
|
||||
{
|
||||
PxReal invMassScale = maxMassRatio/ratio;
|
||||
pairs[i].contacts.setInvMassScale1(invMassScale);
|
||||
pairs[i].contacts.setInvInertiaScale1(invMassScale);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//dynamic1 is heavier than dynamic0 so we will locally increase the mass of dynamic0
|
||||
//to be half the mass of dynamic1.
|
||||
PxReal ratio = mass1/mass0;
|
||||
if(ratio > maxMassRatio)
|
||||
{
|
||||
PxReal invMassScale = maxMassRatio/ratio;
|
||||
pairs[i].contacts.setInvMassScale0(invMassScale);
|
||||
pairs[i].contacts.setInvInertiaScale0(invMassScale);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
ContactModifyCallback gContactModifyCallback;
|
||||
|
||||
PxU32 extractContactsWithMassScale(const PxContactPair& pair, PxContactPairPoint* userBuffer, PxU32 bufferSize, PxReal& invMassScale0, PxReal& invMassScale1)
|
||||
{
|
||||
const PxU8* contactStream = pair.contactPoints;
|
||||
const PxU8* patchStream = pair.contactPatches;
|
||||
const PxU32* faceIndices = pair.getInternalFaceIndices();
|
||||
|
||||
PxU32 nbContacts = 0;
|
||||
|
||||
if(pair.contactCount && bufferSize)
|
||||
{
|
||||
PxContactStreamIterator iter(patchStream, contactStream, faceIndices, pair.patchCount, pair.contactCount);
|
||||
|
||||
const PxReal* impulses = reinterpret_cast<const PxReal*>(pair.contactImpulses);
|
||||
|
||||
PxU32 flippedContacts = (pair.flags & PxContactPairFlag::eINTERNAL_CONTACTS_ARE_FLIPPED);
|
||||
PxU32 hasImpulses = (pair.flags & PxContactPairFlag::eINTERNAL_HAS_IMPULSES);
|
||||
|
||||
|
||||
invMassScale0 = iter.getInvMassScale0();
|
||||
invMassScale1 = iter.getInvMassScale1();
|
||||
while(iter.hasNextPatch())
|
||||
{
|
||||
iter.nextPatch();
|
||||
while(iter.hasNextContact())
|
||||
{
|
||||
iter.nextContact();
|
||||
PxContactPairPoint& dst = userBuffer[nbContacts];
|
||||
dst.position = iter.getContactPoint();
|
||||
dst.separation = iter.getSeparation();
|
||||
dst.normal = iter.getContactNormal();
|
||||
if (!flippedContacts)
|
||||
{
|
||||
dst.internalFaceIndex0 = iter.getFaceIndex0();
|
||||
dst.internalFaceIndex1 = iter.getFaceIndex1();
|
||||
}
|
||||
else
|
||||
{
|
||||
dst.internalFaceIndex0 = iter.getFaceIndex1();
|
||||
dst.internalFaceIndex1 = iter.getFaceIndex0();
|
||||
}
|
||||
|
||||
if (hasImpulses)
|
||||
{
|
||||
PxReal impulse = impulses[nbContacts];
|
||||
dst.impulse = dst.normal * impulse;
|
||||
}
|
||||
else
|
||||
dst.impulse = PxVec3(0.0f);
|
||||
++nbContacts;
|
||||
if(nbContacts == bufferSize)
|
||||
return nbContacts;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nbContacts;
|
||||
}
|
||||
|
||||
|
||||
|
||||
class ContactReportCallback: public PxSimulationEventCallback
|
||||
{
|
||||
void onConstraintBreak(PxConstraintInfo* constraints, PxU32 count) { PX_UNUSED(constraints); PX_UNUSED(count); }
|
||||
void onWake(PxActor** actors, PxU32 count) { PX_UNUSED(actors); PX_UNUSED(count); }
|
||||
void onSleep(PxActor** actors, PxU32 count) { PX_UNUSED(actors); PX_UNUSED(count); }
|
||||
void onTrigger(PxTriggerPair* pairs, PxU32 count) { PX_UNUSED(pairs); PX_UNUSED(count); }
|
||||
void onAdvance(const PxRigidBody*const*, const PxTransform*, const PxU32) {}
|
||||
void onContact(const PxContactPairHeader& pairHeader, const PxContactPair* pairs, PxU32 nbPairs)
|
||||
{
|
||||
PX_UNUSED((pairHeader));
|
||||
std::vector<PxContactPairPoint> contactPoints;
|
||||
|
||||
|
||||
for(PxU32 i=0;i<nbPairs;i++)
|
||||
{
|
||||
PxU32 contactCount = pairs[i].contactCount;
|
||||
if(contactCount)
|
||||
{
|
||||
contactPoints.resize(contactCount);
|
||||
PxReal invMassScale[2];
|
||||
extractContactsWithMassScale(pairs[i], &contactPoints[0], contactCount, invMassScale[0], invMassScale[1]);
|
||||
|
||||
for(PxU32 j=0;j<contactCount;j++)
|
||||
{
|
||||
gContactPositions.push_back(contactPoints[j].position);
|
||||
//Push back reported contact impulses
|
||||
gContactImpulses.push_back(contactPoints[j].impulse);
|
||||
|
||||
//Compute the effective linear/angular impulses for each body.
|
||||
//Note that the local mass scaling permits separate scales for invMass and invInertia.
|
||||
for(PxU32 k = 0; k < 2; ++k)
|
||||
{
|
||||
const PxRigidDynamic* dynamic = pairHeader.actors[k]->is<PxRigidDynamic>();
|
||||
PxVec3 linImpulse(0.f), angImpulse(0.f);
|
||||
if(dynamic != NULL)
|
||||
{
|
||||
PxRigidBodyExt::computeLinearAngularImpulse(*dynamic, dynamic->getGlobalPose(), contactPoints[j].position,
|
||||
k == 0 ? contactPoints[j].impulse : -contactPoints[j].impulse, invMassScale[k], invMassScale[k], linImpulse, angImpulse);
|
||||
}
|
||||
gContactLinearImpulses[k].push_back(linImpulse);
|
||||
gContactAngularImpulses[k].push_back(angImpulse);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ContactReportCallback gContactReportCallback;
|
||||
|
||||
void createStack(const PxTransform& t, PxU32 size, PxReal halfExtent)
|
||||
{
|
||||
PxShape* shape = gPhysics->createShape(PxBoxGeometry(halfExtent, halfExtent, halfExtent), *gMaterial);
|
||||
for(PxU32 i=0; i<size;i++)
|
||||
{
|
||||
PxTransform localTm(PxVec3(0, PxReal(i*2+1), 0) * halfExtent);
|
||||
PxRigidDynamic* body = gPhysics->createRigidDynamic(t.transform(localTm));
|
||||
body->attachShape(*shape);
|
||||
PxRigidBodyExt::updateMassAndInertia(*body, (i+1)*(i+1)*(i+1)*10.0f);
|
||||
gScene->addActor(*body);
|
||||
}
|
||||
shape->release();
|
||||
}
|
||||
|
||||
void initPhysics(bool /*interactive*/)
|
||||
{
|
||||
gFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gAllocator, gErrorCallback);
|
||||
gPvd = PxCreatePvd(*gFoundation);
|
||||
PxPvdTransport* transport = PxDefaultPvdSocketTransportCreate(PVD_HOST, 5425, 10);
|
||||
gPvd->connect(*transport,PxPvdInstrumentationFlag::eALL);
|
||||
|
||||
gPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, PxTolerancesScale(), true, gPvd);
|
||||
PxInitExtensions(*gPhysics, gPvd);
|
||||
|
||||
PxU32 numCores = SnippetUtils::getNbPhysicalCores();
|
||||
gDispatcher = PxDefaultCpuDispatcherCreate(numCores == 0 ? 0 : numCores - 1);
|
||||
PxSceneDesc sceneDesc(gPhysics->getTolerancesScale());
|
||||
sceneDesc.cpuDispatcher = gDispatcher;
|
||||
sceneDesc.gravity = PxVec3(0, -9.81f, 0);
|
||||
sceneDesc.filterShader = contactReportFilterShader;
|
||||
sceneDesc.simulationEventCallback = &gContactReportCallback;
|
||||
sceneDesc.contactModifyCallback = &gContactModifyCallback;
|
||||
gScene = gPhysics->createScene(sceneDesc);
|
||||
|
||||
PxPvdSceneClient* pvdClient = gScene->getScenePvdClient();
|
||||
if(pvdClient)
|
||||
{
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONTACTS, true);
|
||||
}
|
||||
|
||||
gMaterial = gPhysics->createMaterial(0.5f, 0.5f, 0.6f);
|
||||
|
||||
PxRigidStatic* groundPlane = PxCreatePlane(*gPhysics, PxPlane(0,1,0,0), *gMaterial);
|
||||
gScene->addActor(*groundPlane);
|
||||
createStack(PxTransform(PxVec3(0,0.0f,10.0f)), 5, 2.0f);
|
||||
}
|
||||
|
||||
void stepPhysics(bool /*interactive*/)
|
||||
{
|
||||
gContactPositions.clear();
|
||||
gContactImpulses.clear();
|
||||
|
||||
gScene->simulate(1.0f/60.0f);
|
||||
gScene->fetchResults(true);
|
||||
printf("%d contact reports\n", PxU32(gContactPositions.size()));
|
||||
}
|
||||
|
||||
void cleanupPhysics(bool /*interactive*/)
|
||||
{
|
||||
PX_RELEASE(gScene);
|
||||
PX_RELEASE(gDispatcher);
|
||||
PxCloseExtensions();
|
||||
PX_RELEASE(gPhysics);
|
||||
if(gPvd)
|
||||
{
|
||||
PxPvdTransport* transport = gPvd->getTransport();
|
||||
gPvd->release(); gPvd = NULL;
|
||||
PX_RELEASE(transport);
|
||||
}
|
||||
PX_RELEASE(gFoundation);
|
||||
|
||||
printf("SnippetContactModification done.\n");
|
||||
}
|
||||
|
||||
int snippetMain(int, const char*const*)
|
||||
{
|
||||
#ifdef RENDER_SNIPPET
|
||||
extern void renderLoop();
|
||||
renderLoop();
|
||||
#else
|
||||
initPhysics(false);
|
||||
for(PxU32 i=0; i<250; i++)
|
||||
stepPhysics(false);
|
||||
cleanupPhysics(false);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -0,0 +1,135 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifdef RENDER_SNIPPET
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
#include "../snippetrender/SnippetRender.h"
|
||||
#include "../snippetrender/SnippetCamera.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
extern void initPhysics(bool interactive);
|
||||
extern void stepPhysics(bool interactive);
|
||||
extern void cleanupPhysics(bool interactive);
|
||||
|
||||
extern std::vector<PxVec3> gContactPositions;
|
||||
extern std::vector<PxVec3> gContactImpulses;
|
||||
std::vector<PxVec3> gContactVertices;
|
||||
|
||||
namespace
|
||||
{
|
||||
Snippets::Camera* sCamera;
|
||||
|
||||
void motionCallback(int x, int y)
|
||||
{
|
||||
sCamera->handleMotion(x, y);
|
||||
}
|
||||
|
||||
void keyboardCallback(unsigned char key, int x, int y)
|
||||
{
|
||||
if(key==27)
|
||||
exit(0);
|
||||
|
||||
sCamera->handleKey(key, x, y);
|
||||
}
|
||||
|
||||
void mouseCallback(int button, int state, int x, int y)
|
||||
{
|
||||
sCamera->handleMouse(button, state, x, y);
|
||||
}
|
||||
|
||||
void idleCallback()
|
||||
{
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
void renderCallback()
|
||||
{
|
||||
stepPhysics(true);
|
||||
|
||||
Snippets::startRender(sCamera->getEye(), sCamera->getDir());
|
||||
|
||||
PxScene* scene;
|
||||
PxGetPhysics().getScenes(&scene,1);
|
||||
PxU32 nbActors = scene->getNbActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC);
|
||||
if(nbActors)
|
||||
{
|
||||
std::vector<PxRigidActor*> actors(nbActors);
|
||||
scene->getActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC, reinterpret_cast<PxActor**>(&actors[0]), nbActors);
|
||||
Snippets::renderActors(&actors[0], static_cast<PxU32>(actors.size()), true);
|
||||
}
|
||||
|
||||
if(gContactPositions.size())
|
||||
{
|
||||
gContactVertices.clear();
|
||||
for(PxU32 i=0;i<gContactPositions.size();i++)
|
||||
{
|
||||
gContactVertices.push_back(gContactPositions[i]);
|
||||
gContactVertices.push_back(gContactPositions[i]+gContactImpulses[i]*0.1f);
|
||||
}
|
||||
glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glVertexPointer(3, GL_FLOAT, 0, &gContactVertices[0]);
|
||||
glDrawArrays(GL_LINES, 0, GLint(gContactVertices.size()));
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
}
|
||||
|
||||
Snippets::finishRender();
|
||||
}
|
||||
|
||||
void exitCallback(void)
|
||||
{
|
||||
delete sCamera;
|
||||
cleanupPhysics(true);
|
||||
}
|
||||
}
|
||||
|
||||
void renderLoop()
|
||||
{
|
||||
sCamera = new Snippets::Camera(PxVec3(50.0f, 50.0f, 50.0f), PxVec3(-0.6f,-0.2f,-0.7f));
|
||||
|
||||
Snippets::setupDefaultWindow("PhysX Snippet ContactReport");
|
||||
Snippets::setupDefaultRenderState();
|
||||
|
||||
glutIdleFunc(idleCallback);
|
||||
glutDisplayFunc(renderCallback);
|
||||
glutKeyboardFunc(keyboardCallback);
|
||||
glutMouseFunc(mouseCallback);
|
||||
glutMotionFunc(motionCallback);
|
||||
motionCallback(0,0);
|
||||
|
||||
atexit(exitCallback);
|
||||
|
||||
initPhysics(true);
|
||||
glutMainLoop();
|
||||
}
|
||||
#endif
|
||||
207
physx/snippets/snippetcontactreport/SnippetContactReport.cpp
Normal file
207
physx/snippets/snippetcontactreport/SnippetContactReport.cpp
Normal file
@ -0,0 +1,207 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
// ****************************************************************************
|
||||
// This snippet illustrates the use of simple contact reports.
|
||||
//
|
||||
// It defines a filter shader function that requests touch reports for
|
||||
// all pairs, and a contact callback function that saves the contact points.
|
||||
// It configures the scene to use this filter and callback, and prints the
|
||||
// number of contact reports each frame. If rendering, it renders each
|
||||
// contact as a line whose length and direction are defined by the contact
|
||||
// impulse.
|
||||
//
|
||||
// ****************************************************************************
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
|
||||
#include "../snippetutils/SnippetUtils.h"
|
||||
#include "../snippetcommon/SnippetPrint.h"
|
||||
#include "../snippetcommon/SnippetPVD.h"
|
||||
|
||||
|
||||
using namespace physx;
|
||||
|
||||
|
||||
PxDefaultAllocator gAllocator;
|
||||
PxDefaultErrorCallback gErrorCallback;
|
||||
|
||||
PxFoundation* gFoundation = NULL;
|
||||
PxPhysics* gPhysics = NULL;
|
||||
|
||||
PxDefaultCpuDispatcher* gDispatcher = NULL;
|
||||
PxScene* gScene = NULL;
|
||||
PxMaterial* gMaterial = NULL;
|
||||
PxPvd* gPvd = NULL;
|
||||
|
||||
std::vector<PxVec3> gContactPositions;
|
||||
std::vector<PxVec3> gContactImpulses;
|
||||
|
||||
|
||||
PxFilterFlags contactReportFilterShader(PxFilterObjectAttributes attributes0, PxFilterData filterData0,
|
||||
PxFilterObjectAttributes attributes1, PxFilterData filterData1,
|
||||
PxPairFlags& pairFlags, const void* constantBlock, PxU32 constantBlockSize)
|
||||
{
|
||||
PX_UNUSED(attributes0);
|
||||
PX_UNUSED(attributes1);
|
||||
PX_UNUSED(filterData0);
|
||||
PX_UNUSED(filterData1);
|
||||
PX_UNUSED(constantBlockSize);
|
||||
PX_UNUSED(constantBlock);
|
||||
|
||||
// all initial and persisting reports for everything, with per-point data
|
||||
pairFlags = PxPairFlag::eSOLVE_CONTACT | PxPairFlag::eDETECT_DISCRETE_CONTACT
|
||||
| PxPairFlag::eNOTIFY_TOUCH_FOUND
|
||||
| PxPairFlag::eNOTIFY_TOUCH_PERSISTS
|
||||
| PxPairFlag::eNOTIFY_CONTACT_POINTS;
|
||||
return PxFilterFlag::eDEFAULT;
|
||||
}
|
||||
|
||||
class ContactReportCallback: public PxSimulationEventCallback
|
||||
{
|
||||
void onConstraintBreak(PxConstraintInfo* constraints, PxU32 count) { PX_UNUSED(constraints); PX_UNUSED(count); }
|
||||
void onWake(PxActor** actors, PxU32 count) { PX_UNUSED(actors); PX_UNUSED(count); }
|
||||
void onSleep(PxActor** actors, PxU32 count) { PX_UNUSED(actors); PX_UNUSED(count); }
|
||||
void onTrigger(PxTriggerPair* pairs, PxU32 count) { PX_UNUSED(pairs); PX_UNUSED(count); }
|
||||
void onAdvance(const PxRigidBody*const*, const PxTransform*, const PxU32) {}
|
||||
void onContact(const PxContactPairHeader& pairHeader, const PxContactPair* pairs, PxU32 nbPairs)
|
||||
{
|
||||
PX_UNUSED((pairHeader));
|
||||
std::vector<PxContactPairPoint> contactPoints;
|
||||
|
||||
for(PxU32 i=0;i<nbPairs;i++)
|
||||
{
|
||||
PxU32 contactCount = pairs[i].contactCount;
|
||||
if(contactCount)
|
||||
{
|
||||
contactPoints.resize(contactCount);
|
||||
pairs[i].extractContacts(&contactPoints[0], contactCount);
|
||||
|
||||
for(PxU32 j=0;j<contactCount;j++)
|
||||
{
|
||||
gContactPositions.push_back(contactPoints[j].position);
|
||||
gContactImpulses.push_back(contactPoints[j].impulse);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ContactReportCallback gContactReportCallback;
|
||||
|
||||
void createStack(const PxTransform& t, PxU32 size, PxReal halfExtent)
|
||||
{
|
||||
PxShape* shape = gPhysics->createShape(PxBoxGeometry(halfExtent, halfExtent, halfExtent), *gMaterial);
|
||||
for(PxU32 i=0; i<size;i++)
|
||||
{
|
||||
for(PxU32 j=0;j<size-i;j++)
|
||||
{
|
||||
PxTransform localTm(PxVec3(PxReal(j*2) - PxReal(size-i), PxReal(i*2+1), 0) * halfExtent);
|
||||
PxRigidDynamic* body = gPhysics->createRigidDynamic(t.transform(localTm));
|
||||
body->attachShape(*shape);
|
||||
PxRigidBodyExt::updateMassAndInertia(*body, 10.0f);
|
||||
gScene->addActor(*body);
|
||||
}
|
||||
}
|
||||
shape->release();
|
||||
}
|
||||
|
||||
void initPhysics(bool /*interactive*/)
|
||||
{
|
||||
gFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gAllocator, gErrorCallback);
|
||||
gPvd = PxCreatePvd(*gFoundation);
|
||||
PxPvdTransport* transport = PxDefaultPvdSocketTransportCreate(PVD_HOST, 5425, 10);
|
||||
gPvd->connect(*transport,PxPvdInstrumentationFlag::eALL);
|
||||
gPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, PxTolerancesScale(),true,gPvd);
|
||||
PxInitExtensions(*gPhysics,gPvd);
|
||||
PxU32 numCores = SnippetUtils::getNbPhysicalCores();
|
||||
gDispatcher = PxDefaultCpuDispatcherCreate(numCores == 0 ? 0 : numCores - 1);
|
||||
PxSceneDesc sceneDesc(gPhysics->getTolerancesScale());
|
||||
sceneDesc.cpuDispatcher = gDispatcher;
|
||||
sceneDesc.gravity = PxVec3(0, -9.81f, 0);
|
||||
sceneDesc.filterShader = contactReportFilterShader;
|
||||
sceneDesc.simulationEventCallback = &gContactReportCallback;
|
||||
gScene = gPhysics->createScene(sceneDesc);
|
||||
|
||||
PxPvdSceneClient* pvdClient = gScene->getScenePvdClient();
|
||||
if(pvdClient)
|
||||
{
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONTACTS, true);
|
||||
}
|
||||
gMaterial = gPhysics->createMaterial(0.5f, 0.5f, 0.6f);
|
||||
|
||||
PxRigidStatic* groundPlane = PxCreatePlane(*gPhysics, PxPlane(0,1,0,0), *gMaterial);
|
||||
gScene->addActor(*groundPlane);
|
||||
createStack(PxTransform(PxVec3(0,3.0f,10.0f)), 5, 2.0f);
|
||||
}
|
||||
|
||||
void stepPhysics(bool /*interactive*/)
|
||||
{
|
||||
gContactPositions.clear();
|
||||
gContactImpulses.clear();
|
||||
|
||||
gScene->simulate(1.0f/60.0f);
|
||||
gScene->fetchResults(true);
|
||||
printf("%d contact reports\n", PxU32(gContactPositions.size()));
|
||||
}
|
||||
|
||||
void cleanupPhysics(bool /*interactive*/)
|
||||
{
|
||||
PX_RELEASE(gScene);
|
||||
PX_RELEASE(gDispatcher);
|
||||
PxCloseExtensions();
|
||||
PX_RELEASE(gPhysics);
|
||||
if(gPvd)
|
||||
{
|
||||
PxPvdTransport* transport = gPvd->getTransport();
|
||||
gPvd->release(); gPvd = NULL;
|
||||
PX_RELEASE(transport);
|
||||
}
|
||||
PX_RELEASE(gFoundation);
|
||||
|
||||
printf("SnippetContactReport done.\n");
|
||||
}
|
||||
|
||||
int snippetMain(int, const char*const*)
|
||||
{
|
||||
#ifdef RENDER_SNIPPET
|
||||
extern void renderLoop();
|
||||
renderLoop();
|
||||
#else
|
||||
initPhysics(false);
|
||||
for(PxU32 i=0; i<250; i++)
|
||||
stepPhysics(false);
|
||||
cleanupPhysics(false);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -0,0 +1,135 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifdef RENDER_SNIPPET
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
#include "../snippetrender/SnippetRender.h"
|
||||
#include "../snippetrender/SnippetCamera.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
extern void initPhysics(bool interactive);
|
||||
extern void stepPhysics(bool interactive);
|
||||
extern void cleanupPhysics(bool interactive);
|
||||
|
||||
extern std::vector<PxVec3> gContactPositions;
|
||||
extern std::vector<PxVec3> gContactImpulses;
|
||||
std::vector<PxVec3> gContactVertices;
|
||||
|
||||
namespace
|
||||
{
|
||||
Snippets::Camera* sCamera;
|
||||
|
||||
void motionCallback(int x, int y)
|
||||
{
|
||||
sCamera->handleMotion(x, y);
|
||||
}
|
||||
|
||||
void keyboardCallback(unsigned char key, int x, int y)
|
||||
{
|
||||
if(key==27)
|
||||
exit(0);
|
||||
|
||||
sCamera->handleKey(key, x, y);
|
||||
}
|
||||
|
||||
void mouseCallback(int button, int state, int x, int y)
|
||||
{
|
||||
sCamera->handleMouse(button, state, x, y);
|
||||
}
|
||||
|
||||
void idleCallback()
|
||||
{
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
void renderCallback()
|
||||
{
|
||||
stepPhysics(true);
|
||||
|
||||
Snippets::startRender(sCamera->getEye(), sCamera->getDir());
|
||||
|
||||
PxScene* scene;
|
||||
PxGetPhysics().getScenes(&scene,1);
|
||||
PxU32 nbActors = scene->getNbActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC);
|
||||
if(nbActors)
|
||||
{
|
||||
std::vector<PxRigidActor*> actors(nbActors);
|
||||
scene->getActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC, reinterpret_cast<PxActor**>(&actors[0]), nbActors);
|
||||
Snippets::renderActors(&actors[0], static_cast<PxU32>(actors.size()), true);
|
||||
}
|
||||
|
||||
if(gContactPositions.size())
|
||||
{
|
||||
gContactVertices.clear();
|
||||
for(PxU32 i=0;i<gContactPositions.size();i++)
|
||||
{
|
||||
gContactVertices.push_back(gContactPositions[i]);
|
||||
gContactVertices.push_back(gContactPositions[i]+gContactImpulses[i]*0.1f);
|
||||
}
|
||||
glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glVertexPointer(3, GL_FLOAT, 0, &gContactVertices[0]);
|
||||
glDrawArrays(GL_LINES, 0, GLint(gContactVertices.size()));
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
}
|
||||
|
||||
Snippets::finishRender();
|
||||
}
|
||||
|
||||
void exitCallback(void)
|
||||
{
|
||||
delete sCamera;
|
||||
cleanupPhysics(true);
|
||||
}
|
||||
}
|
||||
|
||||
void renderLoop()
|
||||
{
|
||||
sCamera = new Snippets::Camera(PxVec3(50.0f, 50.0f, 50.0f), PxVec3(-0.6f,-0.2f,-0.7f));
|
||||
|
||||
Snippets::setupDefaultWindow("PhysX Snippet ContactReport");
|
||||
Snippets::setupDefaultRenderState();
|
||||
|
||||
glutIdleFunc(idleCallback);
|
||||
glutDisplayFunc(renderCallback);
|
||||
glutKeyboardFunc(keyboardCallback);
|
||||
glutMouseFunc(mouseCallback);
|
||||
glutMotionFunc(motionCallback);
|
||||
motionCallback(0,0);
|
||||
|
||||
atexit(exitCallback);
|
||||
|
||||
initPhysics(true);
|
||||
glutMainLoop();
|
||||
}
|
||||
#endif
|
||||
@ -0,0 +1,334 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
// ****************************************************************************
|
||||
// This snippet illustrates the use of simple contact reports in combination
|
||||
// with continuous collision detection (CCD). Furthermore, extra contact report
|
||||
// data will be requested.
|
||||
//
|
||||
// The snippet defines a filter shader function that enables CCD and requests
|
||||
// touch reports for all pairs, and a contact callback function that saves the
|
||||
// contact points and the actor positions at time of impact.
|
||||
// It configures the scene to use this filter and callback, enables CCD and
|
||||
// prints the number of contact points found. If rendering, it renders each
|
||||
// contact as a line whose length and direction are defined by the contact
|
||||
// impulse (the line points in the opposite direction of the impulse). In
|
||||
// addition, the path of the fast moving dynamic object is drawn with lines.
|
||||
//
|
||||
// ****************************************************************************
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
|
||||
#include "../snippetutils/SnippetUtils.h"
|
||||
#include "../snippetcommon/SnippetPrint.h"
|
||||
#include "../snippetcommon/SnippetPVD.h"
|
||||
|
||||
|
||||
using namespace physx;
|
||||
|
||||
PxDefaultAllocator gAllocator;
|
||||
PxDefaultErrorCallback gErrorCallback;
|
||||
|
||||
PxFoundation* gFoundation = NULL;
|
||||
PxPhysics* gPhysics = NULL;
|
||||
PxCooking* gCooking = NULL;
|
||||
|
||||
PxDefaultCpuDispatcher* gDispatcher = NULL;
|
||||
PxScene* gScene = NULL;
|
||||
PxMaterial* gMaterial = NULL;
|
||||
|
||||
PxTriangleMesh* gTriangleMesh = NULL;
|
||||
PxRigidStatic* gTriangleMeshActor = NULL;
|
||||
PxRigidDynamic* gSphereActor = NULL;
|
||||
PxPvd* gPvd = NULL;
|
||||
|
||||
PxU32 gSimStepCount = 0;
|
||||
|
||||
std::vector<PxVec3> gContactPositions;
|
||||
std::vector<PxVec3> gContactImpulses;
|
||||
std::vector<PxVec3> gContactSphereActorPositions;
|
||||
|
||||
|
||||
PxFilterFlags contactReportFilterShader(PxFilterObjectAttributes attributes0, PxFilterData filterData0,
|
||||
PxFilterObjectAttributes attributes1, PxFilterData filterData1,
|
||||
PxPairFlags& pairFlags, const void* constantBlock, PxU32 constantBlockSize)
|
||||
{
|
||||
PX_UNUSED(attributes0);
|
||||
PX_UNUSED(attributes1);
|
||||
PX_UNUSED(filterData0);
|
||||
PX_UNUSED(filterData1);
|
||||
PX_UNUSED(constantBlockSize);
|
||||
PX_UNUSED(constantBlock);
|
||||
|
||||
//
|
||||
// Enable CCD for the pair, request contact reports for initial and CCD contacts.
|
||||
// Additionally, provide information per contact point and provide the actor
|
||||
// pose at the time of contact.
|
||||
//
|
||||
|
||||
pairFlags = PxPairFlag::eCONTACT_DEFAULT
|
||||
| PxPairFlag::eDETECT_CCD_CONTACT
|
||||
| PxPairFlag::eNOTIFY_TOUCH_CCD
|
||||
| PxPairFlag::eNOTIFY_TOUCH_FOUND
|
||||
| PxPairFlag::eNOTIFY_CONTACT_POINTS
|
||||
| PxPairFlag::eCONTACT_EVENT_POSE;
|
||||
return PxFilterFlag::eDEFAULT;
|
||||
}
|
||||
|
||||
class ContactReportCallback: public PxSimulationEventCallback
|
||||
{
|
||||
void onConstraintBreak(PxConstraintInfo* constraints, PxU32 count) { PX_UNUSED(constraints); PX_UNUSED(count); }
|
||||
void onWake(PxActor** actors, PxU32 count) { PX_UNUSED(actors); PX_UNUSED(count); }
|
||||
void onSleep(PxActor** actors, PxU32 count) { PX_UNUSED(actors); PX_UNUSED(count); }
|
||||
void onTrigger(PxTriggerPair* pairs, PxU32 count) { PX_UNUSED(pairs); PX_UNUSED(count); }
|
||||
void onAdvance(const PxRigidBody*const*, const PxTransform*, const PxU32) {}
|
||||
void onContact(const PxContactPairHeader& pairHeader, const PxContactPair* pairs, PxU32 nbPairs)
|
||||
{
|
||||
std::vector<PxContactPairPoint> contactPoints;
|
||||
|
||||
PxTransform spherePose(PxIdentity);
|
||||
PxU32 nextPairIndex = 0xffffffff;
|
||||
|
||||
PxContactPairExtraDataIterator iter(pairHeader.extraDataStream, pairHeader.extraDataStreamSize);
|
||||
bool hasItemSet = iter.nextItemSet();
|
||||
if (hasItemSet)
|
||||
nextPairIndex = iter.contactPairIndex;
|
||||
|
||||
for(PxU32 i=0; i < nbPairs; i++)
|
||||
{
|
||||
//
|
||||
// Get the pose of the dynamic object at time of impact.
|
||||
//
|
||||
if (nextPairIndex == i)
|
||||
{
|
||||
if (pairHeader.actors[0]->is<PxRigidDynamic>())
|
||||
spherePose = iter.eventPose->globalPose[0];
|
||||
else
|
||||
spherePose = iter.eventPose->globalPose[1];
|
||||
|
||||
gContactSphereActorPositions.push_back(spherePose.p);
|
||||
|
||||
hasItemSet = iter.nextItemSet();
|
||||
if (hasItemSet)
|
||||
nextPairIndex = iter.contactPairIndex;
|
||||
}
|
||||
|
||||
//
|
||||
// Get the contact points for the pair.
|
||||
//
|
||||
const PxContactPair& cPair = pairs[i];
|
||||
if (cPair.events & (PxPairFlag::eNOTIFY_TOUCH_FOUND | PxPairFlag::eNOTIFY_TOUCH_CCD))
|
||||
{
|
||||
PxU32 contactCount = cPair.contactCount;
|
||||
contactPoints.resize(contactCount);
|
||||
cPair.extractContacts(&contactPoints[0], contactCount);
|
||||
|
||||
for(PxU32 j=0; j < contactCount; j++)
|
||||
{
|
||||
gContactPositions.push_back(contactPoints[j].position);
|
||||
gContactImpulses.push_back(contactPoints[j].impulse);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ContactReportCallback gContactReportCallback;
|
||||
|
||||
void initScene()
|
||||
{
|
||||
//
|
||||
// Create a static triangle mesh
|
||||
//
|
||||
|
||||
PxVec3 vertices[] = { PxVec3(-8.0f, 0.0f, -3.0f),
|
||||
PxVec3(-8.0f, 0.0f, 3.0f),
|
||||
PxVec3(0.0f, 0.0f, 3.0f),
|
||||
PxVec3(0.0f, 0.0f, -3.0f),
|
||||
PxVec3(-8.0f, 10.0f, -3.0f),
|
||||
PxVec3(-8.0f, 10.0f, 3.0f),
|
||||
PxVec3(0.0f, 10.0f, 3.0f),
|
||||
PxVec3(0.0f, 10.0f, -3.0f),
|
||||
};
|
||||
|
||||
PxU32 vertexCount = sizeof(vertices) / sizeof(vertices[0]);
|
||||
|
||||
PxU32 triangleIndices[] = { 0, 1, 2,
|
||||
0, 2, 3,
|
||||
0, 5, 1,
|
||||
0, 4, 5,
|
||||
4, 6, 5,
|
||||
4, 7, 6
|
||||
};
|
||||
PxU32 triangleCount = (sizeof(triangleIndices) / sizeof(triangleIndices[0])) / 3;
|
||||
|
||||
PxTriangleMeshDesc triangleMeshDesc;
|
||||
triangleMeshDesc.points.count = vertexCount;
|
||||
triangleMeshDesc.points.data = vertices;
|
||||
triangleMeshDesc.points.stride = sizeof(PxVec3);
|
||||
triangleMeshDesc.triangles.count = triangleCount;
|
||||
triangleMeshDesc.triangles.data = triangleIndices;
|
||||
triangleMeshDesc.triangles.stride = 3 * sizeof(PxU32);
|
||||
|
||||
gTriangleMesh = gCooking->createTriangleMesh(triangleMeshDesc, gPhysics->getPhysicsInsertionCallback());
|
||||
|
||||
if (!gTriangleMesh)
|
||||
return;
|
||||
|
||||
gTriangleMeshActor = gPhysics->createRigidStatic(PxTransform(PxVec3(0.0f, 1.0f, 0.0f), PxQuat(PxHalfPi / 60.0f, PxVec3(0.0f, 1.0f, 0.0f))));
|
||||
|
||||
if (!gTriangleMeshActor)
|
||||
return;
|
||||
|
||||
PxTriangleMeshGeometry triGeom(gTriangleMesh);
|
||||
PxShape* triangleMeshShape = PxRigidActorExt::createExclusiveShape(*gTriangleMeshActor, triGeom, *gMaterial);
|
||||
|
||||
if (!triangleMeshShape)
|
||||
return;
|
||||
|
||||
gScene->addActor(*gTriangleMeshActor);
|
||||
|
||||
|
||||
//
|
||||
// Create a fast moving sphere that will hit and bounce off the static triangle mesh 3 times
|
||||
// in one simulation step.
|
||||
//
|
||||
|
||||
PxTransform spherePose(PxVec3(0.0f, 5.0f, 1.0f));
|
||||
gContactSphereActorPositions.push_back(spherePose.p);
|
||||
gSphereActor = gPhysics->createRigidDynamic(spherePose);
|
||||
gSphereActor->setRigidBodyFlag(PxRigidBodyFlag::eENABLE_CCD, true);
|
||||
|
||||
if (!gSphereActor)
|
||||
return;
|
||||
|
||||
PxSphereGeometry sphereGeom(1.0f);
|
||||
PxShape* sphereShape = PxRigidActorExt::createExclusiveShape(*gSphereActor, sphereGeom, *gMaterial);
|
||||
|
||||
if (!sphereShape)
|
||||
return;
|
||||
|
||||
PxRigidBodyExt::updateMassAndInertia(*gSphereActor, 1.0f);
|
||||
|
||||
PxReal velMagn = 900.0f;
|
||||
PxVec3 vel = PxVec3(-1.0f, -1.0f, 0.0f);
|
||||
vel.normalize();
|
||||
vel *= velMagn;
|
||||
gSphereActor->setLinearVelocity(vel);
|
||||
|
||||
gScene->addActor(*gSphereActor);
|
||||
}
|
||||
|
||||
void initPhysics(bool /*interactive*/)
|
||||
{
|
||||
gFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gAllocator, gErrorCallback);
|
||||
gPvd = PxCreatePvd(*gFoundation);
|
||||
PxPvdTransport* transport = PxDefaultPvdSocketTransportCreate(PVD_HOST, 5425, 10);
|
||||
gPvd->connect(*transport,PxPvdInstrumentationFlag::eALL);
|
||||
|
||||
gPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, PxTolerancesScale(),true,gPvd);
|
||||
gCooking = PxCreateCooking(PX_PHYSICS_VERSION, *gFoundation, PxCookingParams(PxTolerancesScale()));
|
||||
PxInitExtensions(*gPhysics, gPvd);
|
||||
|
||||
PxU32 numCores = SnippetUtils::getNbPhysicalCores();
|
||||
gDispatcher = PxDefaultCpuDispatcherCreate(numCores == 0 ? 0 : numCores - 1);
|
||||
PxSceneDesc sceneDesc(gPhysics->getTolerancesScale());
|
||||
sceneDesc.cpuDispatcher = gDispatcher;
|
||||
sceneDesc.gravity = PxVec3(0, 0, 0);
|
||||
sceneDesc.filterShader = contactReportFilterShader;
|
||||
sceneDesc.simulationEventCallback = &gContactReportCallback;
|
||||
sceneDesc.flags |= PxSceneFlag::eENABLE_CCD;
|
||||
sceneDesc.ccdMaxPasses = 4;
|
||||
|
||||
gScene = gPhysics->createScene(sceneDesc);
|
||||
PxPvdSceneClient* pvdClient = gScene->getScenePvdClient();
|
||||
if(pvdClient)
|
||||
{
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONTACTS, true);
|
||||
}
|
||||
gMaterial = gPhysics->createMaterial(0.5f, 0.5f, 1.0f);
|
||||
|
||||
initScene();
|
||||
}
|
||||
|
||||
void stepPhysics(bool /*interactive*/)
|
||||
{
|
||||
if (!gSimStepCount)
|
||||
{
|
||||
gScene->simulate(1.0f/60.0f);
|
||||
gScene->fetchResults(true);
|
||||
printf("%d contact points\n", PxU32(gContactPositions.size()));
|
||||
|
||||
if (gSphereActor)
|
||||
gContactSphereActorPositions.push_back(gSphereActor->getGlobalPose().p);
|
||||
|
||||
gSimStepCount = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void cleanupPhysics(bool /*interactive*/)
|
||||
{
|
||||
PX_RELEASE(gSphereActor);
|
||||
PX_RELEASE(gTriangleMeshActor);
|
||||
PX_RELEASE(gTriangleMesh);
|
||||
|
||||
PX_RELEASE(gScene);
|
||||
PX_RELEASE(gDispatcher);
|
||||
PxCloseExtensions();
|
||||
PX_RELEASE(gPhysics);
|
||||
PX_RELEASE(gCooking);
|
||||
if(gPvd)
|
||||
{
|
||||
PxPvdTransport* transport = gPvd->getTransport();
|
||||
gPvd->release(); gPvd = NULL;
|
||||
PX_RELEASE(transport);
|
||||
}
|
||||
PX_RELEASE(gFoundation);
|
||||
|
||||
printf("SnippetContactReportCCD done.\n");
|
||||
}
|
||||
|
||||
int snippetMain(int, const char*const*)
|
||||
{
|
||||
#ifdef RENDER_SNIPPET
|
||||
extern void renderLoop();
|
||||
renderLoop();
|
||||
#else
|
||||
initPhysics(false);
|
||||
|
||||
stepPhysics(false);
|
||||
|
||||
cleanupPhysics(false);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -0,0 +1,155 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifdef RENDER_SNIPPET
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
#include "../snippetrender/SnippetRender.h"
|
||||
#include "../snippetrender/SnippetCamera.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
extern void initPhysics(bool interactive);
|
||||
extern void stepPhysics(bool interactive);
|
||||
extern void cleanupPhysics(bool interactive);
|
||||
|
||||
extern std::vector<PxVec3> gContactPositions;
|
||||
extern std::vector<PxVec3> gContactImpulses;
|
||||
extern std::vector<PxVec3> gContactSphereActorPositions;
|
||||
std::vector<PxVec3> gContactVertices;
|
||||
|
||||
namespace
|
||||
{
|
||||
Snippets::Camera* sCamera;
|
||||
|
||||
void motionCallback(int x, int y)
|
||||
{
|
||||
sCamera->handleMotion(x, y);
|
||||
}
|
||||
|
||||
void keyboardCallback(unsigned char key, int x, int y)
|
||||
{
|
||||
if(key==27)
|
||||
exit(0);
|
||||
|
||||
sCamera->handleKey(key, x, y);
|
||||
}
|
||||
|
||||
void mouseCallback(int button, int state, int x, int y)
|
||||
{
|
||||
sCamera->handleMouse(button, state, x, y);
|
||||
}
|
||||
|
||||
void idleCallback()
|
||||
{
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
void renderCallback()
|
||||
{
|
||||
stepPhysics(true);
|
||||
|
||||
Snippets::startRender(sCamera->getEye(), sCamera->getDir());
|
||||
|
||||
PxScene* scene;
|
||||
PxGetPhysics().getScenes(&scene,1);
|
||||
PxU32 nbActors = scene->getNbActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC);
|
||||
if(nbActors)
|
||||
{
|
||||
std::vector<PxRigidActor*> actors(nbActors);
|
||||
scene->getActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC, reinterpret_cast<PxActor**>(&actors[0]), nbActors);
|
||||
Snippets::renderActors(&actors[0], static_cast<PxU32>(actors.size()), true);
|
||||
}
|
||||
|
||||
if(gContactPositions.size())
|
||||
{
|
||||
gContactVertices.clear();
|
||||
for(PxU32 i=0; i < gContactPositions.size(); i++)
|
||||
{
|
||||
gContactVertices.push_back(gContactPositions[i]);
|
||||
gContactVertices.push_back(gContactPositions[i]-gContactImpulses[i]*0.0001f);
|
||||
}
|
||||
glDisable(GL_LIGHTING);
|
||||
glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glVertexPointer(3, GL_FLOAT, 0, &gContactVertices[0]);
|
||||
glDrawArrays(GL_LINES, 0, GLint(gContactVertices.size()));
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glEnable(GL_LIGHTING);
|
||||
}
|
||||
|
||||
if(gContactSphereActorPositions.size())
|
||||
{
|
||||
gContactVertices.clear();
|
||||
for(PxU32 i=0; i < gContactSphereActorPositions.size() - 1; i++)
|
||||
{
|
||||
gContactVertices.push_back(gContactSphereActorPositions[i]);
|
||||
gContactVertices.push_back(gContactSphereActorPositions[i+1]);
|
||||
}
|
||||
glDisable(GL_LIGHTING);
|
||||
glColor4f(1.0f, 1.0f, 0.0f, 1.0f);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glVertexPointer(3, GL_FLOAT, 0, &gContactVertices[0]);
|
||||
glDrawArrays(GL_LINES, 0, GLint(gContactVertices.size()));
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glEnable(GL_LIGHTING);
|
||||
}
|
||||
|
||||
Snippets::finishRender();
|
||||
}
|
||||
|
||||
void exitCallback(void)
|
||||
{
|
||||
delete sCamera;
|
||||
cleanupPhysics(true);
|
||||
}
|
||||
}
|
||||
|
||||
void renderLoop()
|
||||
{
|
||||
sCamera = new Snippets::Camera(PxVec3(-1.5f, 6.0f, 14.0f), PxVec3(-0.1f,0.0f,-0.7f));
|
||||
|
||||
Snippets::setupDefaultWindow("PhysX Snippet ContactReport CCD");
|
||||
Snippets::setupDefaultRenderState();
|
||||
|
||||
glutIdleFunc(idleCallback);
|
||||
glutDisplayFunc(renderCallback);
|
||||
glutKeyboardFunc(keyboardCallback);
|
||||
glutMouseFunc(mouseCallback);
|
||||
glutMotionFunc(motionCallback);
|
||||
motionCallback(0,0);
|
||||
|
||||
atexit(exitCallback);
|
||||
|
||||
initPhysics(true);
|
||||
glutMainLoop();
|
||||
}
|
||||
#endif
|
||||
325
physx/snippets/snippetconvert/SnippetConvert.cpp
Normal file
325
physx/snippets/snippetconvert/SnippetConvert.cpp
Normal file
@ -0,0 +1,325 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
|
||||
// ***********************************************************************************************
|
||||
// This snippet illustrates how to convert PhysX 3 serialized binary files from one platform to
|
||||
// another. The conversion requires three input files:
|
||||
//
|
||||
// 1. A metadata file that was created on the source platform. This file specifies the
|
||||
// source platform as well as the layout of PhysX data structures on the source platform.
|
||||
// 2. A metadata file that was created on the target platform. This file specifies the target
|
||||
// (destination) platform as well as the layout of PhysX data structures on the target platform.
|
||||
// 3. A source file containing a binary serialized collection. The platform this file was created
|
||||
// on needs to match with the platform the source metadata file has been created on.
|
||||
//
|
||||
// A set of pre-built binary metadata files for various platforms is included with the PhysX SDK
|
||||
// at [path to installed PhysX SDK]/Tools/BinaryMetaData.
|
||||
//
|
||||
// Optionally this snippet allows to create a example file with binary serialized data for the
|
||||
// platform the snippet runs on.
|
||||
//
|
||||
// The conversion snippet only compiles and runs on authoring platforms (windows, osx and linux).
|
||||
//
|
||||
// SnippetConvert is a simple command-line tool supporting the following options::
|
||||
//
|
||||
// --srcMetadata=<filename> Specify the source metadata (and the source platform)
|
||||
// --dstMetadata=<filename> Specify the target metadata (and the target platform)
|
||||
// --srcBinFile=<filename> Source binary file to convert (serialized on target platform)
|
||||
// --dstBinFile=<filename> Outputs target binary file
|
||||
// --generateExampleFile=<filename> Generates an example file
|
||||
// --dumpBinaryMetaData=<filename> Dump binary meta data for current runtime platform
|
||||
// --verbose Enables verbose mode
|
||||
//
|
||||
// ***********************************************************************************************
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "../snippetcommon/SnippetPrint.h"
|
||||
#include "../snippetutils/SnippetUtils.h"
|
||||
|
||||
|
||||
using namespace physx;
|
||||
PxDefaultAllocator gAllocator;
|
||||
PxDefaultErrorCallback gErrorCallback;
|
||||
|
||||
PxFoundation* gFoundation = NULL;
|
||||
PxPhysics* gPhysics = NULL;
|
||||
PxSerializationRegistry* gSerializationRegistry = NULL;
|
||||
|
||||
|
||||
struct CmdLineParameters
|
||||
{
|
||||
bool verbose;
|
||||
const char* srcMetadata;
|
||||
const char* dstMetadata;
|
||||
const char* srcBinFile;
|
||||
const char* dstBinFile;
|
||||
const char* exampleFile;
|
||||
const char* dumpMetaDataFile;
|
||||
|
||||
CmdLineParameters()
|
||||
: verbose(false)
|
||||
, srcMetadata(NULL)
|
||||
, dstMetadata(NULL)
|
||||
, srcBinFile(NULL)
|
||||
, dstBinFile(NULL)
|
||||
, exampleFile(NULL)
|
||||
, dumpMetaDataFile(NULL)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
static bool match(const char* opt, const char* ref)
|
||||
{
|
||||
std::string s1(opt);
|
||||
std::string s2(ref);
|
||||
return !s1.compare(0, s2.length(), s2);
|
||||
}
|
||||
|
||||
static void printHelpMsg()
|
||||
{
|
||||
printf("SnippetConvert usage:\n"
|
||||
"SnippetConvert "
|
||||
"--srcMetadata=<filename> "
|
||||
"--dstMetadata=<filename> "
|
||||
"--srcBinFile=<filename> "
|
||||
"--dstBinFile=<filename> "
|
||||
"--generateExampleFile=<filename> "
|
||||
"--dumpBinaryMetaData=<filename> "
|
||||
"--verbose \n"
|
||||
"A set of pre-built binary metadata is included with the PhysX SDK "
|
||||
"at [path to installed PhysX SDK]/Tools/BinaryMetaData.\n");
|
||||
|
||||
printf("--srcMetadata=<filename>\n");
|
||||
printf(" Defines source metadata file\n");
|
||||
|
||||
printf("--dstMetadata=<filename>\n");
|
||||
printf(" Defines target metadata file\n");
|
||||
|
||||
printf("--srcBinFile=<filename>\n");
|
||||
printf(" Source binary file to convert\n");
|
||||
|
||||
printf("--dstBinFile=<filename>\n");
|
||||
printf(" Outputs target binary file\n");
|
||||
|
||||
printf("--generateExampleFile=<filename>\n");
|
||||
printf(" Generates an example file\n");
|
||||
|
||||
printf("--dumpBinaryMetaData=<filename>\n");
|
||||
printf(" Dump binary meta data for current runtime platform\n");
|
||||
|
||||
printf("--verbose\n");
|
||||
printf(" Enables verbose mode\n");
|
||||
}
|
||||
|
||||
static bool parseCommandLine(CmdLineParameters& result, int argc, const char *const*argv)
|
||||
{
|
||||
if( argc <= 1 )
|
||||
{
|
||||
printHelpMsg();
|
||||
return false;
|
||||
}
|
||||
|
||||
#define GET_PARAMETER(v, s) \
|
||||
{ \
|
||||
v = argv[i] + strlen(s); \
|
||||
if( v == NULL ) \
|
||||
{ \
|
||||
printf("[ERROR] \"%s\" should have extra parameter\n", argv[i]);\
|
||||
printHelpMsg(); \
|
||||
return false; \
|
||||
} \
|
||||
}
|
||||
|
||||
for(int i = 0; i < argc; ++i)
|
||||
{
|
||||
if(argv[i][0] != '-' || argv[i][1] != '-')
|
||||
{
|
||||
if( i > 0 )
|
||||
{
|
||||
printf( "[ERROR] Unknown command line parameter \"%s\"\n", argv[i] );
|
||||
printHelpMsg();
|
||||
return false;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if(match(argv[i], "--verbose"))
|
||||
{
|
||||
result.verbose = true;
|
||||
}
|
||||
else if(match(argv[i], "--srcMetadata="))
|
||||
{
|
||||
GET_PARAMETER(result.srcMetadata, "--srcMetadata=");
|
||||
}
|
||||
else if(match(argv[i], "--dstMetadata="))
|
||||
{
|
||||
GET_PARAMETER(result.dstMetadata, "--dstMetadata=");
|
||||
}
|
||||
else if(match(argv[i], "--srcBinFile="))
|
||||
{
|
||||
GET_PARAMETER(result.srcBinFile, "--srcBinFile=");
|
||||
}
|
||||
else if(match(argv[i], "--dstBinFile="))
|
||||
{
|
||||
GET_PARAMETER(result.dstBinFile, "--dstBinFile=");
|
||||
}
|
||||
else if(match(argv[i], "--generateExampleFile="))
|
||||
{
|
||||
GET_PARAMETER(result.exampleFile, "--generateExampleFile=");
|
||||
break;
|
||||
}
|
||||
else if (match(argv[i], "--dumpBinaryMetaData="))
|
||||
{
|
||||
GET_PARAMETER(result.dumpMetaDataFile, "--dumpBinaryMetaData=");
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( "[ERROR] Unknown command line parameter \"%s\"\n", argv[i] );
|
||||
printHelpMsg();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if( result.exampleFile || result.dumpMetaDataFile)
|
||||
return true;
|
||||
|
||||
if( !result.srcMetadata || !result.dstMetadata || !result.srcBinFile || !result.dstBinFile)
|
||||
{
|
||||
printf("[ERROR] Missed args!! \n");
|
||||
printHelpMsg();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool generateExampleFile(const char* filename)
|
||||
{
|
||||
PxCollection* collection = PxCreateCollection();
|
||||
PX_ASSERT( collection );
|
||||
|
||||
PxMaterial *material = gPhysics->createMaterial(0.5f, 0.5f, 0.6f);
|
||||
PX_ASSERT( material );
|
||||
PxShape* shape = gPhysics->createShape(PxBoxGeometry(2.f, 2.f, 2.f), *material);
|
||||
PxRigidStatic* theStatic = PxCreateStatic(*gPhysics, PxTransform(PxIdentity), *shape);
|
||||
|
||||
collection->add(*material);
|
||||
collection->add(*shape);
|
||||
collection->add(*theStatic);
|
||||
|
||||
PxDefaultFileOutputStream s(filename);
|
||||
bool bret = PxSerialization::serializeCollectionToBinary(s, *collection, *gSerializationRegistry);
|
||||
collection->release();
|
||||
return bret;
|
||||
}
|
||||
|
||||
static bool dumpBinaryMetaData(const char* filename)
|
||||
{
|
||||
PxDefaultFileOutputStream s(filename);
|
||||
PxSerialization::dumpBinaryMetaData(s, *gSerializationRegistry);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void initPhysics()
|
||||
{
|
||||
gFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gAllocator, gErrorCallback);
|
||||
|
||||
gPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, PxTolerancesScale(),true);
|
||||
|
||||
gSerializationRegistry = PxSerialization::createSerializationRegistry(*gPhysics);
|
||||
|
||||
PxInitVehicleSDK(*gPhysics, gSerializationRegistry);
|
||||
}
|
||||
|
||||
static void cleanupPhysics()
|
||||
{
|
||||
PxCloseVehicleSDK(gSerializationRegistry);
|
||||
|
||||
gSerializationRegistry->release();
|
||||
|
||||
gPhysics->release();
|
||||
gFoundation->release();
|
||||
|
||||
printf("SnippetConvert done.\n");
|
||||
}
|
||||
|
||||
int snippetMain(int argc, const char *const*argv)
|
||||
{
|
||||
CmdLineParameters result;
|
||||
if(!parseCommandLine(result, argc, argv))
|
||||
return 1;
|
||||
|
||||
bool bret = false;
|
||||
initPhysics();
|
||||
if(result.exampleFile || result.dumpMetaDataFile)
|
||||
{
|
||||
if (result.exampleFile)
|
||||
{
|
||||
bret = generateExampleFile(result.exampleFile);
|
||||
}
|
||||
if (result.dumpMetaDataFile)
|
||||
{
|
||||
bret &= dumpBinaryMetaData(result.dumpMetaDataFile);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PxBinaryConverter* binaryConverter = PxSerialization::createBinaryConverter();
|
||||
if(result.verbose)
|
||||
binaryConverter->setReportMode(PxConverterReportMode::eVERBOSE);
|
||||
else
|
||||
binaryConverter->setReportMode(PxConverterReportMode::eNORMAL);
|
||||
|
||||
|
||||
PxDefaultFileInputData srcMetaDataStream(result.srcMetadata);
|
||||
PxDefaultFileInputData dstMetaDataStream(result.dstMetadata);
|
||||
bret = binaryConverter->setMetaData(srcMetaDataStream, dstMetaDataStream);
|
||||
if(!bret)
|
||||
{
|
||||
printf("setMetaData failed\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
PxDefaultFileInputData srcBinaryDataStream(result.srcBinFile);
|
||||
PxDefaultFileOutputStream dstBinaryDataStream(result.dstBinFile);
|
||||
binaryConverter->convert(srcBinaryDataStream, srcBinaryDataStream.getLength(), dstBinaryDataStream);
|
||||
}
|
||||
|
||||
binaryConverter->release();
|
||||
}
|
||||
|
||||
cleanupPhysics();
|
||||
|
||||
return !bret;
|
||||
}
|
||||
@ -0,0 +1,178 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
// ****************************************************************************
|
||||
// This snippet creates convex meshes with different cooking settings
|
||||
// and shows how these settings affect the convex mesh creation performance and
|
||||
// the size of the resulting cooked meshes.
|
||||
// ****************************************************************************
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
|
||||
#include "../snippetutils/SnippetUtils.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
PxDefaultAllocator gAllocator;
|
||||
PxDefaultErrorCallback gErrorCallback;
|
||||
|
||||
PxFoundation* gFoundation = NULL;
|
||||
PxPhysics* gPhysics = NULL;
|
||||
PxCooking* gCooking = NULL;
|
||||
|
||||
float rand(float loVal, float hiVal)
|
||||
{
|
||||
return loVal + (float(rand())/float(RAND_MAX))*(hiVal - loVal);
|
||||
}
|
||||
|
||||
template<PxConvexMeshCookingType::Enum convexMeshCookingType, bool directInsertion, PxU32 gaussMapLimit>
|
||||
void createRandomConvex(PxU32 numVerts, const PxVec3* verts)
|
||||
{
|
||||
PxCookingParams params = gCooking->getParams();
|
||||
|
||||
// Use the new (default) PxConvexMeshCookingType::eQUICKHULL
|
||||
params.convexMeshCookingType = convexMeshCookingType;
|
||||
|
||||
// If the gaussMapLimit is chosen higher than the number of output vertices, no gauss map is added to the convex mesh data (here 256).
|
||||
// If the gaussMapLimit is chosen lower than the number of output vertices, a gauss map is added to the convex mesh data (here 16).
|
||||
params.gaussMapLimit = gaussMapLimit;
|
||||
gCooking->setParams(params);
|
||||
|
||||
// Setup the convex mesh descriptor
|
||||
PxConvexMeshDesc desc;
|
||||
|
||||
// We provide points only, therefore the PxConvexFlag::eCOMPUTE_CONVEX flag must be specified
|
||||
desc.points.data = verts;
|
||||
desc.points.count = numVerts;
|
||||
desc.points.stride = sizeof(PxVec3);
|
||||
desc.flags = PxConvexFlag::eCOMPUTE_CONVEX;
|
||||
|
||||
PxU32 meshSize = 0;
|
||||
PxConvexMesh* convex = NULL;
|
||||
|
||||
PxU64 startTime = SnippetUtils::getCurrentTimeCounterValue();
|
||||
|
||||
if(directInsertion)
|
||||
{
|
||||
// Directly insert mesh into PhysX
|
||||
convex = gCooking->createConvexMesh(desc, gPhysics->getPhysicsInsertionCallback());
|
||||
PX_ASSERT(convex);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Serialize the cooked mesh into a stream.
|
||||
PxDefaultMemoryOutputStream outStream;
|
||||
bool res = gCooking->cookConvexMesh(desc, outStream);
|
||||
PX_UNUSED(res);
|
||||
PX_ASSERT(res);
|
||||
meshSize = outStream.getSize();
|
||||
|
||||
// Create the mesh from a stream.
|
||||
PxDefaultMemoryInputData inStream(outStream.getData(), outStream.getSize());
|
||||
convex = gPhysics->createConvexMesh(inStream);
|
||||
PX_ASSERT(convex);
|
||||
}
|
||||
|
||||
// Print the elapsed time for comparison
|
||||
PxU64 stopTime = SnippetUtils::getCurrentTimeCounterValue();
|
||||
float elapsedTime = SnippetUtils::getElapsedTimeInMilliseconds(stopTime - startTime);
|
||||
printf("\t -----------------------------------------------\n");
|
||||
printf("\t Create convex mesh with %d triangles: \n", numVerts);
|
||||
directInsertion ? printf("\t\t Direct mesh insertion enabled\n") : printf("\t\t Direct mesh insertion disabled\n");
|
||||
printf("\t\t Gauss map limit: %d \n", gaussMapLimit);
|
||||
printf("\t\t Created hull number of vertices: %d \n", convex->getNbVertices());
|
||||
printf("\t\t Created hull number of polygons: %d \n", convex->getNbPolygons());
|
||||
printf("\t Elapsed time in ms: %f \n", double(elapsedTime));
|
||||
if (!directInsertion)
|
||||
{
|
||||
printf("\t Mesh size: %d \n", meshSize);
|
||||
}
|
||||
|
||||
convex->release();
|
||||
}
|
||||
|
||||
void createConvexMeshes()
|
||||
{
|
||||
const PxU32 numVerts = 64;
|
||||
PxVec3* vertices = new PxVec3[numVerts];
|
||||
|
||||
// Prepare random verts
|
||||
for(PxU32 i = 0; i < numVerts; i++)
|
||||
{
|
||||
vertices[i] = PxVec3(rand(-20.0f, 20.0f), rand(-20.0f, 20.0f), rand(-20.0f, 20.0f));
|
||||
}
|
||||
|
||||
// Create convex mesh using the quickhull algorithm with different settings
|
||||
printf("-----------------------------------------------\n");
|
||||
printf("Create convex mesh using the quickhull algorithm: \n\n");
|
||||
|
||||
// The default convex mesh creation serializing to a stream, useful for offline cooking.
|
||||
createRandomConvex<PxConvexMeshCookingType::eQUICKHULL, false, 16>(numVerts, vertices);
|
||||
|
||||
// The default convex mesh creation without the additional gauss map data.
|
||||
createRandomConvex<PxConvexMeshCookingType::eQUICKHULL, false, 256>(numVerts, vertices);
|
||||
|
||||
// Convex mesh creation inserting the mesh directly into PhysX.
|
||||
// Useful for runtime cooking.
|
||||
createRandomConvex<PxConvexMeshCookingType::eQUICKHULL, true, 16>(numVerts, vertices);
|
||||
|
||||
// Convex mesh creation inserting the mesh directly into PhysX, without gauss map data.
|
||||
// Useful for runtime cooking.
|
||||
createRandomConvex<PxConvexMeshCookingType::eQUICKHULL, true, 256>(numVerts, vertices);
|
||||
|
||||
delete [] vertices;
|
||||
}
|
||||
|
||||
void initPhysics()
|
||||
{
|
||||
gFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gAllocator, gErrorCallback);
|
||||
gPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, PxTolerancesScale(),true);
|
||||
gCooking = PxCreateCooking(PX_PHYSICS_VERSION, *gFoundation, PxCookingParams(PxTolerancesScale()));
|
||||
}
|
||||
|
||||
void cleanupPhysics()
|
||||
{
|
||||
gPhysics->release();
|
||||
gCooking->release();
|
||||
gFoundation->release();
|
||||
|
||||
printf("SnippetConvexMeshCreate done.\n");
|
||||
}
|
||||
|
||||
|
||||
int snippetMain(int, const char*const*)
|
||||
{
|
||||
initPhysics();
|
||||
createConvexMeshes();
|
||||
cleanupPhysics();
|
||||
|
||||
return 0;
|
||||
}
|
||||
231
physx/snippets/snippetcustomjoint/PulleyJoint.cpp
Normal file
231
physx/snippets/snippetcustomjoint/PulleyJoint.cpp
Normal file
@ -0,0 +1,231 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
|
||||
#include "PulleyJoint.h"
|
||||
#include <assert.h>
|
||||
#include "PxConstraint.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
|
||||
PxConstraintShaderTable PulleyJoint::sShaderTable = { &PulleyJoint::solverPrep, &PulleyJoint::project, &PulleyJoint::visualize, PxConstraintFlag::Enum(0) };
|
||||
|
||||
PulleyJoint::PulleyJoint(PxPhysics& physics, PxRigidBody& body0, const PxTransform& localFrame0, const PxVec3& attachment0,
|
||||
PxRigidBody& body1, const PxTransform& localFrame1, const PxVec3& attachment1)
|
||||
{
|
||||
mConstraint = physics.createConstraint(&body0, &body1, *this, PulleyJoint::sShaderTable, sizeof(PulleyJointData));
|
||||
|
||||
mBody[0] = &body0;
|
||||
mBody[1] = &body1;
|
||||
|
||||
// keep these around in case the CoM gets relocated
|
||||
mLocalPose[0] = localFrame0.getNormalized();
|
||||
mLocalPose[1] = localFrame1.getNormalized();
|
||||
|
||||
// the data which will be fed to the joint solver and projection shaders
|
||||
mData.attachment0 = attachment0;
|
||||
mData.attachment1 = attachment1;
|
||||
mData.distance = 1.0f;
|
||||
mData.ratio = 1.0f;
|
||||
mData.c2b[0] = body0.getCMassLocalPose().transformInv(mLocalPose[0]);
|
||||
mData.c2b[1] = body1.getCMassLocalPose().transformInv(mLocalPose[1]);
|
||||
}
|
||||
|
||||
void PulleyJoint::release()
|
||||
{
|
||||
mConstraint->release();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////// attribute accessors and mutators
|
||||
|
||||
|
||||
void PulleyJoint::setAttachment0(const PxVec3& pos)
|
||||
{
|
||||
mData.attachment0 = pos;
|
||||
mConstraint->markDirty();
|
||||
}
|
||||
|
||||
PxVec3 PulleyJoint::getAttachment0() const
|
||||
{
|
||||
return mData.attachment0;
|
||||
}
|
||||
|
||||
void PulleyJoint::setAttachment1(const PxVec3& pos)
|
||||
{
|
||||
mData.attachment1 = pos;
|
||||
mConstraint->markDirty();
|
||||
}
|
||||
|
||||
PxVec3 PulleyJoint::getAttachment1() const
|
||||
{
|
||||
return mData.attachment1;
|
||||
}
|
||||
|
||||
void PulleyJoint::setDistance(float totalDistance)
|
||||
{
|
||||
mData.distance = totalDistance;
|
||||
mConstraint->markDirty();
|
||||
}
|
||||
|
||||
float PulleyJoint::getDistance() const
|
||||
{
|
||||
return mData.distance;
|
||||
}
|
||||
|
||||
void PulleyJoint::setRatio(float ratio)
|
||||
{
|
||||
mData.ratio = ratio;
|
||||
mConstraint->markDirty();
|
||||
}
|
||||
|
||||
float PulleyJoint::getRatio() const
|
||||
{
|
||||
return mData.ratio;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////// PxConstraintConnector methods
|
||||
|
||||
void* PulleyJoint::prepareData()
|
||||
{
|
||||
return &mData;
|
||||
}
|
||||
|
||||
void PulleyJoint::onConstraintRelease()
|
||||
{
|
||||
delete this;
|
||||
}
|
||||
|
||||
void PulleyJoint::onComShift(PxU32 actor)
|
||||
{
|
||||
mData.c2b[actor] = mBody[actor]->getCMassLocalPose().transformInv(mLocalPose[actor]);
|
||||
mConstraint->markDirty();
|
||||
}
|
||||
|
||||
void PulleyJoint::onOriginShift(const PxVec3& shift)
|
||||
{
|
||||
mData.attachment0 -= shift;
|
||||
mData.attachment1 -= shift;
|
||||
}
|
||||
|
||||
void* PulleyJoint::getExternalReference(PxU32& typeID)
|
||||
{
|
||||
typeID = TYPE_ID;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////// work functions
|
||||
|
||||
|
||||
PxU32 PulleyJoint::solverPrep(Px1DConstraint* constraints,
|
||||
PxVec3& body0WorldOffset,
|
||||
PxU32 maxConstraints,
|
||||
PxConstraintInvMassScale&,
|
||||
const void* constantBlock,
|
||||
const PxTransform& bA2w,
|
||||
const PxTransform& bB2w,
|
||||
bool /*useExtendedLimits*/,
|
||||
PxVec3& cA2wOut, PxVec3& cB2wOut)
|
||||
{
|
||||
PX_UNUSED(maxConstraints);
|
||||
|
||||
const PulleyJointData& data = *reinterpret_cast<const PulleyJointData*>(constantBlock);
|
||||
|
||||
PxTransform cA2w = bA2w.transform(data.c2b[0]);
|
||||
PxTransform cB2w = bB2w.transform(data.c2b[1]);
|
||||
|
||||
cA2wOut = cA2w.p;
|
||||
cB2wOut = cB2w.p;
|
||||
|
||||
body0WorldOffset = cB2w.p - bA2w.p;
|
||||
|
||||
PxVec3 directionA = data.attachment0 - cA2w.p;
|
||||
PxReal distanceA = directionA.normalize();
|
||||
|
||||
PxVec3 directionB = data.attachment1 - cB2w.p;
|
||||
PxReal distanceB = directionB.normalize();
|
||||
|
||||
directionB *= data.ratio;
|
||||
|
||||
PxReal totalDistance = distanceA + distanceB;
|
||||
|
||||
// compute geometric error:
|
||||
PxReal geometricError = (data.distance - totalDistance);
|
||||
|
||||
Px1DConstraint *c = constraints;
|
||||
// constraint is breakable, so we need to output forces
|
||||
c->flags = Px1DConstraintFlag::eOUTPUT_FORCE;
|
||||
|
||||
if (geometricError < 0.0f)
|
||||
{
|
||||
c->maxImpulse = PX_MAX_F32;
|
||||
c->minImpulse = 0;
|
||||
c->geometricError = geometricError;
|
||||
}
|
||||
else if(geometricError > 0.0f)
|
||||
{
|
||||
c->maxImpulse = 0;
|
||||
c->minImpulse = -PX_MAX_F32;
|
||||
c->geometricError = geometricError;
|
||||
}
|
||||
|
||||
c->linear0 = directionA; c->angular0 = (cA2w.p - bA2w.p).cross(c->linear0);
|
||||
c->linear1 = -directionB; c->angular1 = (cB2w.p - bB2w.p).cross(c->linear1);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void PulleyJoint::project(const void* constantBlock,
|
||||
PxTransform& bodyAToWorld,
|
||||
PxTransform& bodyBToWorld,
|
||||
bool projectToA)
|
||||
{
|
||||
PX_UNUSED(constantBlock);
|
||||
PX_UNUSED(bodyAToWorld);
|
||||
PX_UNUSED(bodyBToWorld);
|
||||
PX_UNUSED(projectToA);
|
||||
}
|
||||
|
||||
void PulleyJoint::visualize(PxConstraintVisualizer& viz,
|
||||
const void* constantBlock,
|
||||
const PxTransform& body0Transform,
|
||||
const PxTransform& body1Transform,
|
||||
PxU32 flags)
|
||||
{
|
||||
PX_UNUSED(flags);
|
||||
const PulleyJointData& data = *reinterpret_cast<const PulleyJointData*>(constantBlock);
|
||||
|
||||
PxTransform cA2w = body0Transform * data.c2b[0];
|
||||
PxTransform cB2w = body1Transform * data.c2b[1];
|
||||
viz.visualizeJointFrames(cA2w, cB2w);
|
||||
viz.visualizeJointFrames(PxTransform(data.attachment0), PxTransform(data.attachment1));
|
||||
}
|
||||
|
||||
141
physx/snippets/snippetcustomjoint/PulleyJoint.h
Normal file
141
physx/snippets/snippetcustomjoint/PulleyJoint.h
Normal file
@ -0,0 +1,141 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifndef PULLEY_JOINT_H
|
||||
#define PULLEY_JOINT_H
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
|
||||
// a pulley joint constrains two actors such that the sum of their distances from their respective anchor points at their attachment points
|
||||
// is a fixed value (the parameter 'distance'). Only dynamic actors are supported.
|
||||
//
|
||||
// The constraint equation is as follows:
|
||||
//
|
||||
// |anchor0 - attachment0| + |anchor1 - attachment1| * ratio = distance
|
||||
//
|
||||
// where 'ratio' provides mechanical advantage.
|
||||
//
|
||||
// The above equation results in a singularity when the anchor point is coincident with the attachment point; for simplicity
|
||||
// the constraint does not attempt to handle this case robustly.
|
||||
|
||||
|
||||
|
||||
class PulleyJoint : public physx::PxConstraintConnector
|
||||
{
|
||||
public:
|
||||
|
||||
static const physx::PxU32 TYPE_ID = physx::PxConcreteType::eFIRST_USER_EXTENSION;
|
||||
|
||||
PulleyJoint(physx::PxPhysics& physics,
|
||||
physx::PxRigidBody& body0, const physx::PxTransform& localFrame0, const physx::PxVec3& attachment0,
|
||||
physx::PxRigidBody& body1, const physx::PxTransform& localFrame1, const physx::PxVec3& attachment1);
|
||||
|
||||
void release();
|
||||
|
||||
// attribute accessor and mutators
|
||||
|
||||
void setAttachment0(const physx::PxVec3& pos);
|
||||
physx::PxVec3 getAttachment0() const;
|
||||
|
||||
void setAttachment1(const physx::PxVec3& pos);
|
||||
physx::PxVec3 getAttachment1() const;
|
||||
|
||||
void setDistance(physx::PxReal totalDistance);
|
||||
physx::PxReal getDistance() const;
|
||||
|
||||
void setRatio(physx::PxReal ratio);
|
||||
physx::PxReal getRatio() const;
|
||||
|
||||
// PxConstraintConnector boilerplate
|
||||
|
||||
void* prepareData();
|
||||
void onConstraintRelease();
|
||||
void onComShift(physx::PxU32 actor);
|
||||
void onOriginShift(const physx::PxVec3& shift);
|
||||
void* getExternalReference(physx::PxU32& typeID);
|
||||
|
||||
|
||||
bool updatePvdProperties(physx::pvdsdk::PvdDataStream&,
|
||||
const physx::PxConstraint*,
|
||||
physx::PxPvdUpdateType::Enum) const { return true; }
|
||||
physx::PxBase* getSerializable() { return NULL; }
|
||||
|
||||
virtual physx::PxConstraintSolverPrep getPrep() const { return sShaderTable.solverPrep; }
|
||||
|
||||
virtual const void* getConstantBlock() const { return &mData; }
|
||||
|
||||
private:
|
||||
|
||||
static physx::PxU32 solverPrep(physx::Px1DConstraint* constraints,
|
||||
physx::PxVec3& body0WorldOffset,
|
||||
physx::PxU32 maxConstraints,
|
||||
physx::PxConstraintInvMassScale&,
|
||||
const void* constantBlock,
|
||||
const physx::PxTransform& bA2w,
|
||||
const physx::PxTransform& bB2w,
|
||||
bool useExtendedLimits,
|
||||
physx::PxVec3& cA2wOut, physx::PxVec3& cB2wOut);
|
||||
|
||||
|
||||
static void visualize(physx::PxConstraintVisualizer& viz,
|
||||
const void* constantBlock,
|
||||
const physx::PxTransform& body0Transform,
|
||||
const physx::PxTransform& body1Transform,
|
||||
physx::PxU32 flags);
|
||||
|
||||
static void project(const void* constantBlock,
|
||||
physx::PxTransform& bodyAToWorld,
|
||||
physx::PxTransform& bodyBToWorld,
|
||||
bool projectToA);
|
||||
|
||||
|
||||
struct PulleyJointData
|
||||
{
|
||||
physx::PxTransform c2b[2];
|
||||
|
||||
physx::PxVec3 attachment0;
|
||||
physx::PxVec3 attachment1;
|
||||
|
||||
physx::PxReal distance;
|
||||
physx::PxReal ratio;
|
||||
physx::PxReal tolerance;
|
||||
};
|
||||
|
||||
physx::PxRigidBody* mBody[2];
|
||||
physx::PxTransform mLocalPose[2];
|
||||
|
||||
physx::PxConstraint* mConstraint;
|
||||
PulleyJointData mData;
|
||||
static physx::PxConstraintShaderTable
|
||||
sShaderTable;
|
||||
|
||||
~PulleyJoint() {}
|
||||
};
|
||||
|
||||
#endif
|
||||
144
physx/snippets/snippetcustomjoint/SnippetCustomJoint.cpp
Normal file
144
physx/snippets/snippetcustomjoint/SnippetCustomJoint.cpp
Normal file
@ -0,0 +1,144 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
// ****************************************************************************
|
||||
// This snippet illustrates the implementation and use of a pulley joint
|
||||
// using physx' custom constraint framework.
|
||||
// ****************************************************************************
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
|
||||
#include "../snippetcommon/SnippetPrint.h"
|
||||
#include "../snippetcommon/SnippetPVD.h"
|
||||
#include "../snippetutils/SnippetUtils.h"
|
||||
|
||||
#include "PulleyJoint.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
PxDefaultAllocator gAllocator;
|
||||
PxDefaultErrorCallback gErrorCallback;
|
||||
|
||||
PxFoundation* gFoundation = NULL;
|
||||
PxPhysics* gPhysics = NULL;
|
||||
|
||||
PxDefaultCpuDispatcher* gDispatcher = NULL;
|
||||
PxScene* gScene = NULL;
|
||||
|
||||
PxMaterial* gMaterial = NULL;
|
||||
PxPvd* gPvd = NULL;
|
||||
|
||||
void initPhysics(bool /*interactive*/)
|
||||
{
|
||||
gFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gAllocator, gErrorCallback);
|
||||
|
||||
gPvd = PxCreatePvd(*gFoundation);
|
||||
PxPvdTransport* transport = PxDefaultPvdSocketTransportCreate(PVD_HOST, 5425, 10);
|
||||
gPvd->connect(*transport,PxPvdInstrumentationFlag::eALL);
|
||||
|
||||
gPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, PxTolerancesScale(), true, gPvd);
|
||||
|
||||
PxSceneDesc sceneDesc(gPhysics->getTolerancesScale());
|
||||
sceneDesc.gravity = PxVec3(0.0f, -9.81f, 0.0f);
|
||||
gDispatcher = PxDefaultCpuDispatcherCreate(2);
|
||||
sceneDesc.cpuDispatcher = gDispatcher;
|
||||
sceneDesc.filterShader = PxDefaultSimulationFilterShader;
|
||||
gScene = gPhysics->createScene(sceneDesc);
|
||||
|
||||
PxPvdSceneClient* pvdClient = gScene->getScenePvdClient();
|
||||
if(pvdClient)
|
||||
{
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONSTRAINTS, true);
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONTACTS, true);
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_SCENEQUERIES, true);
|
||||
}
|
||||
|
||||
gMaterial = gPhysics->createMaterial(0.5f, 0.5f, 0.6f);
|
||||
|
||||
PxRigidStatic* groundPlane = PxCreatePlane(*gPhysics, PxPlane(0,1,0,0), *gMaterial);
|
||||
gScene->addActor(*groundPlane);
|
||||
|
||||
// two boxes connected by the pulley, one twice the density of the other
|
||||
|
||||
PxBoxGeometry boxGeom(1.0f, 1.0f, 1.0f);
|
||||
PxRigidDynamic* box0 = PxCreateDynamic(*gPhysics, PxTransform(PxVec3(5,5,0)), boxGeom, *gMaterial, 1.0f);
|
||||
PxRigidDynamic* box1 = PxCreateDynamic(*gPhysics, PxTransform(PxVec3(0,5,0)), boxGeom, *gMaterial, 2.0f);
|
||||
|
||||
PulleyJoint* joint = new PulleyJoint(*gPhysics, *box0, PxTransform(PxVec3(0.0f,1.0f,0.0f)), PxVec3(5.0f,10.0f,0.0f),
|
||||
*box1, PxTransform(PxVec3(0.0f,1.0f,0.0f)), PxVec3(0.0f,10.0f,0.0f));
|
||||
|
||||
joint->setDistance(8.0f);
|
||||
|
||||
gScene->addActor(*box0);
|
||||
gScene->addActor(*box1);
|
||||
}
|
||||
|
||||
void stepPhysics(bool /*interactive*/)
|
||||
{
|
||||
gScene->simulate(1.0f/60.0f);
|
||||
gScene->fetchResults(true);
|
||||
}
|
||||
|
||||
void cleanupPhysics(bool /*interactive*/)
|
||||
{
|
||||
PX_RELEASE(gScene);
|
||||
PX_RELEASE(gDispatcher);
|
||||
PX_RELEASE(gPhysics);
|
||||
if(gPvd)
|
||||
{
|
||||
PxPvdTransport* transport = gPvd->getTransport();
|
||||
gPvd->release(); gPvd = NULL;
|
||||
PX_RELEASE(transport);
|
||||
}
|
||||
PX_RELEASE(gFoundation);
|
||||
|
||||
printf("SnippetCustomJoint done.\n");
|
||||
}
|
||||
|
||||
void keyPress(unsigned char, const PxTransform&)
|
||||
{
|
||||
}
|
||||
|
||||
int snippetMain(int, const char*const*)
|
||||
{
|
||||
#ifdef RENDER_SNIPPET
|
||||
extern void renderLoop();
|
||||
renderLoop();
|
||||
#else
|
||||
static const PxU32 frameCount = 100;
|
||||
initPhysics(false);
|
||||
for(PxU32 i=0; i<frameCount; i++)
|
||||
stepPhysics(false);
|
||||
cleanupPhysics(false);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
120
physx/snippets/snippetcustomjoint/SnippetCustomJointRender.cpp
Normal file
120
physx/snippets/snippetcustomjoint/SnippetCustomJointRender.cpp
Normal file
@ -0,0 +1,120 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifdef RENDER_SNIPPET
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
|
||||
#include "../snippetrender/SnippetRender.h"
|
||||
#include "../snippetrender/SnippetCamera.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
extern void initPhysics(bool interactive);
|
||||
extern void stepPhysics(bool interactive);
|
||||
extern void cleanupPhysics(bool interactive);
|
||||
extern void keyPress(unsigned char key, const PxTransform& camera);
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
Snippets::Camera* sCamera;
|
||||
|
||||
void motionCallback(int x, int y)
|
||||
{
|
||||
sCamera->handleMotion(x, y);
|
||||
}
|
||||
|
||||
void keyboardCallback(unsigned char key, int x, int y)
|
||||
{
|
||||
if(key==27)
|
||||
exit(0);
|
||||
|
||||
if(!sCamera->handleKey(key, x, y))
|
||||
keyPress(key, sCamera->getTransform());
|
||||
}
|
||||
|
||||
void mouseCallback(int button, int state, int x, int y)
|
||||
{
|
||||
sCamera->handleMouse(button, state, x, y);
|
||||
}
|
||||
|
||||
void idleCallback()
|
||||
{
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
void renderCallback()
|
||||
{
|
||||
stepPhysics(true);
|
||||
|
||||
Snippets::startRender(sCamera->getEye(), sCamera->getDir());
|
||||
|
||||
PxScene* scene;
|
||||
PxGetPhysics().getScenes(&scene,1);
|
||||
PxU32 nbActors = scene->getNbActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC);
|
||||
if(nbActors)
|
||||
{
|
||||
std::vector<PxRigidActor*> actors(nbActors);
|
||||
scene->getActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC, reinterpret_cast<PxActor**>(&actors[0]), nbActors);
|
||||
Snippets::renderActors(&actors[0], static_cast<PxU32>(actors.size()), true);
|
||||
}
|
||||
|
||||
Snippets::finishRender();
|
||||
}
|
||||
|
||||
void exitCallback(void)
|
||||
{
|
||||
delete sCamera;
|
||||
cleanupPhysics(true);
|
||||
}
|
||||
}
|
||||
|
||||
void renderLoop()
|
||||
{
|
||||
sCamera = new Snippets::Camera(PxVec3(50.0f, 50.0f, 50.0f), PxVec3(-0.6f,-0.2f,-0.7f));
|
||||
|
||||
Snippets::setupDefaultWindow("PhysX Snippet HelloWorld");
|
||||
Snippets::setupDefaultRenderState();
|
||||
|
||||
glutIdleFunc(idleCallback);
|
||||
glutDisplayFunc(renderCallback);
|
||||
glutKeyboardFunc(keyboardCallback);
|
||||
glutMouseFunc(mouseCallback);
|
||||
glutMotionFunc(motionCallback);
|
||||
motionCallback(0,0);
|
||||
|
||||
atexit(exitCallback);
|
||||
|
||||
initPhysics(true);
|
||||
glutMainLoop();
|
||||
}
|
||||
#endif
|
||||
225
physx/snippets/snippetcustomprofiler/SnippetCustomProfiler.cpp
Normal file
225
physx/snippets/snippetcustomprofiler/SnippetCustomProfiler.cpp
Normal file
@ -0,0 +1,225 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
// ****************************************************************************
|
||||
// This snippet illustrates how to setup a custom profiler, and potentially
|
||||
// re-route it to PVD's profiling functions.
|
||||
// ****************************************************************************
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
|
||||
#include "../snippetcommon/SnippetPrint.h"
|
||||
#include "../snippetcommon/SnippetPVD.h"
|
||||
#include "../snippetutils/SnippetUtils.h"
|
||||
|
||||
|
||||
using namespace physx;
|
||||
|
||||
PxDefaultAllocator gAllocator;
|
||||
PxDefaultErrorCallback gErrorCallback;
|
||||
|
||||
PxFoundation* gFoundation = NULL;
|
||||
PxPhysics* gPhysics = NULL;
|
||||
|
||||
PxDefaultCpuDispatcher* gDispatcher = NULL;
|
||||
PxScene* gScene = NULL;
|
||||
|
||||
PxMaterial* gMaterial = NULL;
|
||||
|
||||
PxPvd* gPvd = NULL;
|
||||
|
||||
PxReal stackZ = 10.0f;
|
||||
|
||||
PxRigidDynamic* createDynamic(const PxTransform& t, const PxGeometry& geometry, const PxVec3& velocity=PxVec3(0))
|
||||
{
|
||||
PxRigidDynamic* dynamic = PxCreateDynamic(*gPhysics, t, geometry, *gMaterial, 10.0f);
|
||||
dynamic->setAngularDamping(0.5f);
|
||||
dynamic->setLinearVelocity(velocity);
|
||||
gScene->addActor(*dynamic);
|
||||
return dynamic;
|
||||
}
|
||||
|
||||
void createStack(const PxTransform& t, PxU32 size, PxReal halfExtent)
|
||||
{
|
||||
PxShape* shape = gPhysics->createShape(PxBoxGeometry(halfExtent, halfExtent, halfExtent), *gMaterial);
|
||||
for(PxU32 i=0; i<size;i++)
|
||||
{
|
||||
for(PxU32 j=0;j<size-i;j++)
|
||||
{
|
||||
PxTransform localTm(PxVec3(PxReal(j*2) - PxReal(size-i), PxReal(i*2+1), 0) * halfExtent);
|
||||
PxRigidDynamic* body = gPhysics->createRigidDynamic(t.transform(localTm));
|
||||
body->attachShape(*shape);
|
||||
PxRigidBodyExt::updateMassAndInertia(*body, 10.0f);
|
||||
gScene->addActor(*body);
|
||||
}
|
||||
}
|
||||
shape->release();
|
||||
}
|
||||
|
||||
static const bool gCallPVDProfilingFunctions = false;
|
||||
|
||||
class CustomProfilerCallback : public PxProfilerCallback
|
||||
{
|
||||
public:
|
||||
virtual ~CustomProfilerCallback() {}
|
||||
|
||||
virtual void* zoneStart(const char* eventName, bool detached, uint64_t contextId)
|
||||
{
|
||||
// Option 1: add your own profiling code here (before calling the PVD function).
|
||||
// If you call the PVD profiling function below, adding your own profiling code here
|
||||
// means it will capture the cost of the PVD zoneStart function.
|
||||
|
||||
// NB: we don't have an actual profiler implementation in the snippet so we just call printf instead
|
||||
printf("start: %s\n", eventName);
|
||||
|
||||
// Optional: call the PVD function if you want to see the profiling results in PVD.
|
||||
void* profilerData = gCallPVDProfilingFunctions ? gPvd->zoneStart(eventName, detached, contextId) : NULL;
|
||||
|
||||
// Option 2: add your own profiling code here (after calling the PVD function).
|
||||
// If you call the PVD profiling function above, adding your own profiling code here
|
||||
// means its cost will be captured by the PVD profiler.
|
||||
|
||||
return profilerData;
|
||||
}
|
||||
|
||||
virtual void zoneEnd(void* profilerData, const char* eventName, bool detached, uint64_t contextId)
|
||||
{
|
||||
// Option 2: add your own profiling code here (before calling the PVD function).
|
||||
// If you call the PVD profiling function below, adding your own profiling code here
|
||||
// means its cost will be captured by the PVD profiler.
|
||||
|
||||
// Optional: call the PVD function if you want to see the profiling results in PVD.
|
||||
if(gCallPVDProfilingFunctions)
|
||||
gPvd->zoneEnd(profilerData, eventName, detached, contextId);
|
||||
|
||||
// Option 1: add your own profiling code here (after calling the PVD function).
|
||||
// If you call the PVD profiling function above, adding your own profiling code here
|
||||
// means it will capture the cost of the PVD zoneEnd function.
|
||||
|
||||
// NB: we don't have an actual profiler implementation in the snippet so we just call printf instead
|
||||
printf("end: %s\n", eventName);
|
||||
}
|
||||
|
||||
}gCustomProfilerCallback;
|
||||
|
||||
void initPhysics(bool interactive)
|
||||
{
|
||||
gFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gAllocator, gErrorCallback);
|
||||
|
||||
gPvd = PxCreatePvd(*gFoundation);
|
||||
PxPvdTransport* transport = PxDefaultPvdSocketTransportCreate(PVD_HOST, 5425, 10);
|
||||
|
||||
// During the "connect" call, PVD sets itself up as the profiler if PxPvdInstrumentationFlag::ePROFILE is used.
|
||||
// That is, it internally calls PxSetProfilerCallback() to setup its own profiling callback. Any calls to
|
||||
// PxSetProfilerCallback() prior to calling "connect" is thus lost.
|
||||
gPvd->connect(*transport, PxPvdInstrumentationFlag::eALL);
|
||||
|
||||
// This call should be performed after PVD is initialized, otherwise it will have no effect.
|
||||
PxSetProfilerCallback(&gCustomProfilerCallback);
|
||||
|
||||
gPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, PxTolerancesScale(), true, gPvd);
|
||||
|
||||
PxSceneDesc sceneDesc(gPhysics->getTolerancesScale());
|
||||
sceneDesc.gravity = PxVec3(0.0f, -9.81f, 0.0f);
|
||||
gDispatcher = PxDefaultCpuDispatcherCreate(2);
|
||||
sceneDesc.cpuDispatcher = gDispatcher;
|
||||
sceneDesc.filterShader = PxDefaultSimulationFilterShader;
|
||||
gScene = gPhysics->createScene(sceneDesc);
|
||||
|
||||
PxPvdSceneClient* pvdClient = gScene->getScenePvdClient();
|
||||
if(pvdClient)
|
||||
{
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONSTRAINTS, true);
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONTACTS, true);
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_SCENEQUERIES, true);
|
||||
}
|
||||
gMaterial = gPhysics->createMaterial(0.5f, 0.5f, 0.6f);
|
||||
|
||||
PxRigidStatic* groundPlane = PxCreatePlane(*gPhysics, PxPlane(0,1,0,0), *gMaterial);
|
||||
gScene->addActor(*groundPlane);
|
||||
|
||||
for(PxU32 i=0;i<5;i++)
|
||||
createStack(PxTransform(PxVec3(0,0,stackZ-=10.0f)), 10, 2.0f);
|
||||
|
||||
if(!interactive)
|
||||
createDynamic(PxTransform(PxVec3(0,40,100)), PxSphereGeometry(10), PxVec3(0,-50,-100));
|
||||
}
|
||||
|
||||
void stepPhysics(bool /*interactive*/)
|
||||
{
|
||||
gScene->simulate(1.0f/60.0f);
|
||||
gScene->fetchResults(true);
|
||||
}
|
||||
|
||||
void cleanupPhysics(bool /*interactive*/)
|
||||
|
||||
{ PX_RELEASE(gScene);
|
||||
PX_RELEASE(gDispatcher);
|
||||
PX_RELEASE(gPhysics);
|
||||
if(gPvd)
|
||||
{
|
||||
PxPvdTransport* transport = gPvd->getTransport();
|
||||
gPvd->release(); gPvd = NULL;
|
||||
PX_RELEASE(transport);
|
||||
}
|
||||
PX_RELEASE(gFoundation);
|
||||
|
||||
#if (PX_DEBUG || PX_CHECKED || PX_PROFILE)
|
||||
printf("SnippetCustomProfiler done.\n");
|
||||
#else
|
||||
printf("Warning: SnippetCustomProfiler does not capture the profiler timings in release build.\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
void keyPress(unsigned char key, const PxTransform& camera)
|
||||
{
|
||||
switch(toupper(key))
|
||||
{
|
||||
case 'B': createStack(PxTransform(PxVec3(0,0,stackZ-=10.0f)), 10, 2.0f); break;
|
||||
case ' ': createDynamic(camera, PxSphereGeometry(3.0f), camera.rotate(PxVec3(0,0,-1))*200); break;
|
||||
}
|
||||
}
|
||||
|
||||
int snippetMain(int, const char*const*)
|
||||
{
|
||||
#ifdef RENDER_SNIPPET
|
||||
extern void renderLoop();
|
||||
renderLoop();
|
||||
#else
|
||||
static const PxU32 frameCount = 100;
|
||||
initPhysics(false);
|
||||
for(PxU32 i=0; i<frameCount; i++)
|
||||
stepPhysics(false);
|
||||
cleanupPhysics(false);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -0,0 +1,120 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifdef RENDER_SNIPPET
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
|
||||
#include "../snippetrender/SnippetRender.h"
|
||||
#include "../snippetrender/SnippetCamera.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
extern void initPhysics(bool interactive);
|
||||
extern void stepPhysics(bool interactive);
|
||||
extern void cleanupPhysics(bool interactive);
|
||||
extern void keyPress(unsigned char key, const PxTransform& camera);
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
Snippets::Camera* sCamera;
|
||||
|
||||
void motionCallback(int x, int y)
|
||||
{
|
||||
sCamera->handleMotion(x, y);
|
||||
}
|
||||
|
||||
void keyboardCallback(unsigned char key, int x, int y)
|
||||
{
|
||||
if(key==27)
|
||||
exit(0);
|
||||
|
||||
if(!sCamera->handleKey(key, x, y))
|
||||
keyPress(key, sCamera->getTransform());
|
||||
}
|
||||
|
||||
void mouseCallback(int button, int state, int x, int y)
|
||||
{
|
||||
sCamera->handleMouse(button, state, x, y);
|
||||
}
|
||||
|
||||
void idleCallback()
|
||||
{
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
void renderCallback()
|
||||
{
|
||||
stepPhysics(true);
|
||||
|
||||
Snippets::startRender(sCamera->getEye(), sCamera->getDir());
|
||||
|
||||
PxScene* scene;
|
||||
PxGetPhysics().getScenes(&scene,1);
|
||||
PxU32 nbActors = scene->getNbActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC);
|
||||
if(nbActors)
|
||||
{
|
||||
std::vector<PxRigidActor*> actors(nbActors);
|
||||
scene->getActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC, reinterpret_cast<PxActor**>(&actors[0]), nbActors);
|
||||
Snippets::renderActors(&actors[0], static_cast<PxU32>(actors.size()), true);
|
||||
}
|
||||
|
||||
Snippets::finishRender();
|
||||
}
|
||||
|
||||
void exitCallback(void)
|
||||
{
|
||||
delete sCamera;
|
||||
cleanupPhysics(true);
|
||||
}
|
||||
}
|
||||
|
||||
void renderLoop()
|
||||
{
|
||||
sCamera = new Snippets::Camera(PxVec3(50.0f, 50.0f, 50.0f), PxVec3(-0.6f,-0.2f,-0.7f));
|
||||
|
||||
Snippets::setupDefaultWindow("PhysX Snippet CustomProfiler");
|
||||
Snippets::setupDefaultRenderState();
|
||||
|
||||
glutIdleFunc(idleCallback);
|
||||
glutDisplayFunc(renderCallback);
|
||||
glutKeyboardFunc(keyboardCallback);
|
||||
glutMouseFunc(mouseCallback);
|
||||
glutMotionFunc(motionCallback);
|
||||
motionCallback(0,0);
|
||||
|
||||
atexit(exitCallback);
|
||||
|
||||
initPhysics(true);
|
||||
glutMainLoop();
|
||||
}
|
||||
#endif
|
||||
271
physx/snippets/snippetdeformablemesh/SnippetDeformableMesh.cpp
Normal file
271
physx/snippets/snippetdeformablemesh/SnippetDeformableMesh.cpp
Normal file
@ -0,0 +1,271 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
// ****************************************************************************
|
||||
// This snippet shows how to use deformable meshes in PhysX.
|
||||
// ****************************************************************************
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
|
||||
#include "../snippetcommon/SnippetPrint.h"
|
||||
#include "../snippetcommon/SnippetPVD.h"
|
||||
#include "../snippetutils/SnippetUtils.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
PxDefaultAllocator gAllocator;
|
||||
PxDefaultErrorCallback gErrorCallback;
|
||||
|
||||
PxFoundation* gFoundation = NULL;
|
||||
PxPhysics* gPhysics = NULL;
|
||||
PxCooking* gCooking = NULL;
|
||||
|
||||
PxDefaultCpuDispatcher* gDispatcher = NULL;
|
||||
PxScene* gScene = NULL;
|
||||
|
||||
PxMaterial* gMaterial = NULL;
|
||||
|
||||
PxPvd* gPvd = NULL;
|
||||
|
||||
PxTriangleMesh* gMesh = NULL;
|
||||
PxRigidStatic* gActor = NULL;
|
||||
|
||||
PxReal stackZ = 10.0f;
|
||||
|
||||
static const PxU32 gGridSize = 8;
|
||||
static const PxReal gGridStep = 512.0f / PxReal(gGridSize-1);
|
||||
static float gTime = 0.0f;
|
||||
|
||||
static PxRigidDynamic* createDynamic(const PxTransform& t, const PxGeometry& geometry, const PxVec3& velocity=PxVec3(0), PxReal density=1.0f)
|
||||
{
|
||||
PxRigidDynamic* dynamic = PxCreateDynamic(*gPhysics, t, geometry, *gMaterial, density);
|
||||
dynamic->setLinearVelocity(velocity);
|
||||
gScene->addActor(*dynamic);
|
||||
return dynamic;
|
||||
}
|
||||
|
||||
static void createStack(const PxTransform& t, PxU32 size, PxReal halfExtent)
|
||||
{
|
||||
PxShape* shape = gPhysics->createShape(PxBoxGeometry(halfExtent, halfExtent, halfExtent), *gMaterial);
|
||||
for(PxU32 i=0; i<size;i++)
|
||||
{
|
||||
for(PxU32 j=0;j<size-i;j++)
|
||||
{
|
||||
PxTransform localTm(PxVec3(PxReal(j*2) - PxReal(size-i), PxReal(i*2+1), 0) * halfExtent);
|
||||
PxRigidDynamic* body = gPhysics->createRigidDynamic(t.transform(localTm));
|
||||
body->attachShape(*shape);
|
||||
PxRigidBodyExt::updateMassAndInertia(*body, 10.0f);
|
||||
gScene->addActor(*body);
|
||||
}
|
||||
}
|
||||
shape->release();
|
||||
}
|
||||
|
||||
struct Triangle
|
||||
{
|
||||
PxU32 ind0, ind1, ind2;
|
||||
};
|
||||
|
||||
static void updateVertices(PxVec3* verts, float amplitude=0.0f)
|
||||
{
|
||||
const PxU32 gridSize = gGridSize;
|
||||
const PxReal gridStep = gGridStep;
|
||||
|
||||
for(PxU32 a=0; a<gridSize; a++)
|
||||
{
|
||||
const float coeffA = float(a)/float(gridSize);
|
||||
for(PxU32 b=0; b<gridSize; b++)
|
||||
{
|
||||
const float coeffB = float(b)/float(gridSize);
|
||||
|
||||
const float y = 20.0f + sinf(coeffA*PxTwoPi)*cosf(coeffB*PxTwoPi)*amplitude;
|
||||
|
||||
verts[a * gridSize + b] = PxVec3(-400.0f + b*gridStep, y, -400.0f + a*gridStep);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static PxTriangleMesh* createMeshGround()
|
||||
{
|
||||
const PxU32 gridSize = gGridSize;
|
||||
|
||||
PxVec3 verts[gridSize * gridSize];
|
||||
|
||||
const PxU32 nbTriangles = 2 * (gridSize - 1) * (gridSize-1);
|
||||
|
||||
Triangle indices[nbTriangles];
|
||||
|
||||
updateVertices(verts);
|
||||
|
||||
for (PxU32 a = 0; a < (gridSize-1); ++a)
|
||||
{
|
||||
for (PxU32 b = 0; b < (gridSize-1); ++b)
|
||||
{
|
||||
Triangle& tri0 = indices[(a * (gridSize-1) + b) * 2];
|
||||
Triangle& tri1 = indices[((a * (gridSize-1) + b) * 2) + 1];
|
||||
|
||||
tri0.ind0 = a * gridSize + b + 1;
|
||||
tri0.ind1 = a * gridSize + b;
|
||||
tri0.ind2 = (a + 1) * gridSize + b + 1;
|
||||
|
||||
tri1.ind0 = (a + 1) * gridSize + b + 1;
|
||||
tri1.ind1 = a * gridSize + b;
|
||||
tri1.ind2 = (a + 1) * gridSize + b;
|
||||
}
|
||||
}
|
||||
|
||||
PxTriangleMeshDesc meshDesc;
|
||||
meshDesc.points.data = verts;
|
||||
meshDesc.points.count = gridSize * gridSize;
|
||||
meshDesc.points.stride = sizeof(PxVec3);
|
||||
meshDesc.triangles.count = nbTriangles;
|
||||
meshDesc.triangles.data = indices;
|
||||
meshDesc.triangles.stride = sizeof(Triangle);
|
||||
|
||||
PxTriangleMesh* triMesh = gCooking->createTriangleMesh(meshDesc, gPhysics->getPhysicsInsertionCallback());
|
||||
|
||||
return triMesh;
|
||||
}
|
||||
|
||||
void initPhysics(bool /*interactive*/)
|
||||
{
|
||||
gFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gAllocator, gErrorCallback);
|
||||
|
||||
gPvd = PxCreatePvd(*gFoundation);
|
||||
PxPvdTransport* transport = PxDefaultPvdSocketTransportCreate(PVD_HOST, 5425, 10);
|
||||
gPvd->connect(*transport,PxPvdInstrumentationFlag::eALL);
|
||||
|
||||
gPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, PxTolerancesScale(), true, gPvd);
|
||||
|
||||
PxCookingParams cookingParams(gPhysics->getTolerancesScale());
|
||||
|
||||
// Deformable meshes are only supported with PxMeshMidPhase::eBVH33.
|
||||
cookingParams.midphaseDesc.setToDefault(PxMeshMidPhase::eBVH33);
|
||||
// We need to disable the mesh cleaning part so that the vertex mapping remains untouched.
|
||||
cookingParams.meshPreprocessParams = PxMeshPreprocessingFlag::eDISABLE_CLEAN_MESH;
|
||||
|
||||
gCooking = PxCreateCooking(PX_PHYSICS_VERSION, *gFoundation, cookingParams);
|
||||
|
||||
PxSceneDesc sceneDesc(gPhysics->getTolerancesScale());
|
||||
sceneDesc.gravity = PxVec3(0.0f, -9.81f, 0.0f);
|
||||
gDispatcher = PxDefaultCpuDispatcherCreate(2);
|
||||
sceneDesc.cpuDispatcher = gDispatcher;
|
||||
sceneDesc.filterShader = PxDefaultSimulationFilterShader;
|
||||
|
||||
gScene = gPhysics->createScene(sceneDesc);
|
||||
|
||||
PxPvdSceneClient* pvdClient = gScene->getScenePvdClient();
|
||||
if(pvdClient)
|
||||
{
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONSTRAINTS, true);
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONTACTS, true);
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_SCENEQUERIES, true);
|
||||
}
|
||||
|
||||
gMaterial = gPhysics->createMaterial(0.5f, 0.5f, 0.6f);
|
||||
|
||||
PxTriangleMesh* mesh = createMeshGround();
|
||||
gMesh = mesh;
|
||||
|
||||
PxTriangleMeshGeometry geom(mesh);
|
||||
|
||||
PxRigidStatic* groundMesh = gPhysics->createRigidStatic(PxTransform(PxVec3(0, 2, 0)));
|
||||
gActor = groundMesh;
|
||||
PxShape* shape = gPhysics->createShape(geom, *gMaterial);
|
||||
|
||||
{
|
||||
shape->setContactOffset(0.02f);
|
||||
// A negative rest offset helps to avoid jittering when the deformed mesh moves away from objects resting on it.
|
||||
shape->setRestOffset(-0.5f);
|
||||
}
|
||||
|
||||
groundMesh->attachShape(*shape);
|
||||
gScene->addActor(*groundMesh);
|
||||
|
||||
createStack(PxTransform(PxVec3(0,22,0)), 10, 2.0f);
|
||||
}
|
||||
|
||||
void stepPhysics(bool /*interactive*/)
|
||||
{
|
||||
{
|
||||
PxVec3* verts = gMesh->getVerticesForModification();
|
||||
gTime += 0.01f;
|
||||
updateVertices(verts, sinf(gTime)*20.0f);
|
||||
PxBounds3 newBounds = gMesh->refitBVH();
|
||||
PX_UNUSED(newBounds);
|
||||
|
||||
// Reset filtering to tell the broadphase about the new mesh bounds.
|
||||
gScene->resetFiltering(*gActor);
|
||||
}
|
||||
gScene->simulate(1.0f/60.0f);
|
||||
gScene->fetchResults(true);
|
||||
}
|
||||
|
||||
void cleanupPhysics(bool /*interactive*/)
|
||||
{
|
||||
PX_RELEASE(gScene);
|
||||
PX_RELEASE(gDispatcher);
|
||||
PX_RELEASE(gPhysics);
|
||||
PX_RELEASE(gCooking);
|
||||
if(gPvd)
|
||||
{
|
||||
PxPvdTransport* transport = gPvd->getTransport();
|
||||
gPvd->release(); gPvd = NULL;
|
||||
PX_RELEASE(transport);
|
||||
}
|
||||
PX_RELEASE(gFoundation);
|
||||
|
||||
printf("SnippetDeformableMesh done.\n");
|
||||
}
|
||||
|
||||
void keyPress(unsigned char key, const PxTransform& camera)
|
||||
{
|
||||
switch(toupper(key))
|
||||
{
|
||||
case ' ': createDynamic(camera, PxSphereGeometry(3.0f), camera.rotate(PxVec3(0,0,-1))*200, 3.0f); break;
|
||||
}
|
||||
}
|
||||
|
||||
int snippetMain(int, const char*const*)
|
||||
{
|
||||
#ifdef RENDER_SNIPPET
|
||||
extern void renderLoop();
|
||||
renderLoop();
|
||||
#else
|
||||
static const PxU32 frameCount = 100;
|
||||
initPhysics(false);
|
||||
for(PxU32 i=0; i<frameCount; i++)
|
||||
stepPhysics(false);
|
||||
cleanupPhysics(false);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -0,0 +1,121 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifdef RENDER_SNIPPET
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
|
||||
#include "../snippetrender/SnippetRender.h"
|
||||
#include "../snippetrender/SnippetCamera.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
extern void initPhysics(bool interactive);
|
||||
extern void stepPhysics(bool interactive);
|
||||
extern void cleanupPhysics(bool interactive);
|
||||
extern void keyPress(unsigned char key, const PxTransform& camera);
|
||||
|
||||
namespace
|
||||
{
|
||||
Snippets::Camera* sCamera;
|
||||
|
||||
void motionCallback(int x, int y)
|
||||
{
|
||||
sCamera->handleMotion(x, y);
|
||||
}
|
||||
|
||||
void keyboardCallback(unsigned char key, int x, int y)
|
||||
{
|
||||
if(key==27)
|
||||
exit(0);
|
||||
|
||||
if(!sCamera->handleKey(key, x, y))
|
||||
keyPress(key, sCamera->getTransform());
|
||||
}
|
||||
|
||||
void mouseCallback(int button, int state, int x, int y)
|
||||
{
|
||||
sCamera->handleMouse(button, state, x, y);
|
||||
}
|
||||
|
||||
void idleCallback()
|
||||
{
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
void renderCallback()
|
||||
{
|
||||
stepPhysics(true);
|
||||
|
||||
// glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
|
||||
Snippets::startRender(sCamera->getEye(), sCamera->getDir());
|
||||
|
||||
PxScene* scene;
|
||||
PxGetPhysics().getScenes(&scene,1);
|
||||
PxU32 nbActors = scene->getNbActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC);
|
||||
if(nbActors)
|
||||
{
|
||||
std::vector<PxRigidActor*> actors(nbActors);
|
||||
scene->getActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC, reinterpret_cast<PxActor**>(&actors[0]), nbActors);
|
||||
Snippets::renderActors(&actors[0], static_cast<PxU32>(actors.size()), true);
|
||||
}
|
||||
|
||||
Snippets::finishRender();
|
||||
}
|
||||
|
||||
void exitCallback(void)
|
||||
{
|
||||
delete sCamera;
|
||||
cleanupPhysics(true);
|
||||
}
|
||||
}
|
||||
|
||||
void renderLoop()
|
||||
{
|
||||
sCamera = new Snippets::Camera(PxVec3(50.0f, 50.0f, 50.0f), PxVec3(-0.6f,-0.2f,-0.7f));
|
||||
|
||||
Snippets::setupDefaultWindow("PhysX Snippet DeformableMesh");
|
||||
Snippets::setupDefaultRenderState();
|
||||
|
||||
glutIdleFunc(idleCallback);
|
||||
glutDisplayFunc(renderCallback);
|
||||
glutKeyboardFunc(keyboardCallback);
|
||||
glutMouseFunc(mouseCallback);
|
||||
glutMotionFunc(motionCallback);
|
||||
motionCallback(0,0);
|
||||
|
||||
atexit(exitCallback);
|
||||
|
||||
initPhysics(true);
|
||||
glutMainLoop();
|
||||
}
|
||||
#endif
|
||||
321
physx/snippets/snippetdelayloadhook/SnippetDelayLoadHook.cpp
Normal file
321
physx/snippets/snippetdelayloadhook/SnippetDelayLoadHook.cpp
Normal file
@ -0,0 +1,321 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
// ****************************************************************************
|
||||
// This snippet illustrates the use of the dll delay load hooks in physx.
|
||||
//
|
||||
// The hooks are needed if the application executable either doesn't reside
|
||||
// in the same directory as the PhysX dlls, or if the PhysX dlls have been renamed.
|
||||
// Some PhysX dlls delay load the PhysXFoundation, PhysXCommon or PhysXGpu dlls and
|
||||
// the non-standard names or loactions of these dlls need to be communicated so the
|
||||
// delay loading can succeed.
|
||||
//
|
||||
// This snippet shows how this can be done using the delay load hooks.
|
||||
//
|
||||
// In order to show functionality with the renamed dlls some basic physics
|
||||
// simulation is performed.
|
||||
// ****************************************************************************
|
||||
|
||||
#include <ctype.h>
|
||||
#include <wtypes.h>
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
// Include the delay load hook headers
|
||||
#include "common/windows/PxWindowsDelayLoadHook.h"
|
||||
|
||||
#include "../snippetcommon/SnippetPrint.h"
|
||||
#include "../snippetcommon/SnippetPVD.h"
|
||||
#include "../snippetutils/SnippetUtils.h"
|
||||
|
||||
// This snippet uses the default PhysX distro dlls, making the example here somewhat artificial,
|
||||
// as default locations and default naming makes implementing delay load hooks unnecessary.
|
||||
#define APP_BIN_DIR "..\\"
|
||||
#if PX_WIN64
|
||||
#define DLL_NAME_BITS "64"
|
||||
#else
|
||||
#define DLL_NAME_BITS "32"
|
||||
#endif
|
||||
#if PX_DEBUG
|
||||
#define DLL_DIR "debug\\"
|
||||
#elif PX_CHECKED
|
||||
#define DLL_DIR "checked\\"
|
||||
#elif PX_PROFILE
|
||||
#define DLL_DIR "profile\\"
|
||||
#else
|
||||
#define DLL_DIR "release\\"
|
||||
#endif
|
||||
|
||||
const char* foundationLibraryPath = APP_BIN_DIR DLL_DIR "PhysXFoundation_" DLL_NAME_BITS ".dll";
|
||||
const char* commonLibraryPath = APP_BIN_DIR DLL_DIR "PhysXCommon_" DLL_NAME_BITS ".dll";
|
||||
const char* physxLibraryPath = APP_BIN_DIR DLL_DIR "PhysX_" DLL_NAME_BITS ".dll";
|
||||
const char* gpuLibraryPath = APP_BIN_DIR DLL_DIR "PhysXGpu_" DLL_NAME_BITS ".dll";
|
||||
|
||||
HMODULE foundationLibrary = NULL;
|
||||
HMODULE commonLibrary = NULL;
|
||||
HMODULE physxLibrary = NULL;
|
||||
|
||||
using namespace physx;
|
||||
|
||||
PxDefaultAllocator gAllocator;
|
||||
PxDefaultErrorCallback gErrorCallback;
|
||||
|
||||
PxFoundation* gFoundation = NULL;
|
||||
PxPhysics* gPhysics = NULL;
|
||||
|
||||
PxDefaultCpuDispatcher* gDispatcher = NULL;
|
||||
PxScene* gScene = NULL;
|
||||
|
||||
PxMaterial* gMaterial = NULL;
|
||||
|
||||
PxPvd* gPvd = NULL;
|
||||
|
||||
// typedef the PhysX entry points
|
||||
typedef PxFoundation*(PxCreateFoundation_FUNC)(PxU32, PxAllocatorCallback&, PxErrorCallback&);
|
||||
typedef PxPhysics* (PxCreatePhysics_FUNC)(PxU32,PxFoundation&,const PxTolerancesScale& scale,bool,PxPvd*);
|
||||
typedef void (PxSetPhysXDelayLoadHook_FUNC)(const PxDelayLoadHook* hook);
|
||||
typedef void (PxSetPhysXCommonDelayLoadHook_FUNC)(const PxDelayLoadHook* hook);
|
||||
typedef void (PxSetPhysXGpuLoadHook_FUNC)(const PxGpuLoadHook* hook);
|
||||
typedef int (PxGetSuggestedCudaDeviceOrdinal_FUNC)(PxErrorCallback& errc);
|
||||
typedef PxCudaContextManager* (PxCreateCudaContextManager_FUNC)(PxFoundation& foundation, const PxCudaContextManagerDesc& desc, physx::PxProfilerCallback* profilerCallback);
|
||||
|
||||
// set the function pointers to NULL
|
||||
PxCreateFoundation_FUNC* s_PxCreateFoundation_Func = NULL;
|
||||
PxCreatePhysics_FUNC* s_PxCreatePhysics_Func = NULL;
|
||||
PxSetPhysXDelayLoadHook_FUNC* s_PxSetPhysXDelayLoadHook_Func = NULL;
|
||||
PxSetPhysXCommonDelayLoadHook_FUNC* s_PxSetPhysXCommonDelayLoadHook_Func = NULL;
|
||||
PxSetPhysXGpuLoadHook_FUNC* s_PxSetPhysXGpuLoadHook_Func = NULL;
|
||||
PxGetSuggestedCudaDeviceOrdinal_FUNC* s_PxGetSuggestedCudaDeviceOrdinal_Func = NULL;
|
||||
PxCreateCudaContextManager_FUNC* s_PxCreateCudaContextManager_Func = NULL;
|
||||
|
||||
bool loadPhysicsExplicitely()
|
||||
{
|
||||
// load the dlls
|
||||
foundationLibrary = LoadLibraryA(foundationLibraryPath);
|
||||
if(!foundationLibrary)
|
||||
return false;
|
||||
|
||||
commonLibrary = LoadLibraryA(commonLibraryPath);
|
||||
if(!commonLibrary)
|
||||
{
|
||||
FreeLibrary(foundationLibrary);
|
||||
return false;
|
||||
}
|
||||
|
||||
physxLibrary = LoadLibraryA(physxLibraryPath);
|
||||
if(!physxLibrary)
|
||||
{
|
||||
FreeLibrary(foundationLibrary);
|
||||
FreeLibrary(commonLibrary);
|
||||
return false;
|
||||
}
|
||||
|
||||
// get the function pointers
|
||||
s_PxCreateFoundation_Func = (PxCreateFoundation_FUNC*)GetProcAddress(foundationLibrary, "PxCreateFoundation");
|
||||
s_PxCreatePhysics_Func = (PxCreatePhysics_FUNC*)GetProcAddress(physxLibrary, "PxCreateBasePhysics");
|
||||
s_PxSetPhysXDelayLoadHook_Func = (PxSetPhysXDelayLoadHook_FUNC*)GetProcAddress(physxLibrary, "PxSetPhysXDelayLoadHook");
|
||||
s_PxSetPhysXCommonDelayLoadHook_Func = (PxSetPhysXCommonDelayLoadHook_FUNC*)GetProcAddress(commonLibrary, "PxSetPhysXCommonDelayLoadHook");
|
||||
|
||||
s_PxSetPhysXGpuLoadHook_Func = (PxSetPhysXGpuLoadHook_FUNC*)GetProcAddress(physxLibrary, "PxSetPhysXGpuLoadHook");
|
||||
s_PxGetSuggestedCudaDeviceOrdinal_Func = (PxGetSuggestedCudaDeviceOrdinal_FUNC*)GetProcAddress(physxLibrary, "PxGetSuggestedCudaDeviceOrdinal");
|
||||
s_PxCreateCudaContextManager_Func = (PxCreateCudaContextManager_FUNC*)GetProcAddress(physxLibrary, "PxCreateCudaContextManager");
|
||||
|
||||
// check if we have all required function pointers
|
||||
if(s_PxCreateFoundation_Func == NULL || s_PxCreatePhysics_Func == NULL || s_PxSetPhysXDelayLoadHook_Func == NULL || s_PxSetPhysXCommonDelayLoadHook_Func == NULL)
|
||||
return false;
|
||||
|
||||
if(s_PxSetPhysXGpuLoadHook_Func == NULL || s_PxGetSuggestedCudaDeviceOrdinal_Func == NULL || s_PxCreateCudaContextManager_Func == NULL)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// unload the dlls
|
||||
void unloadPhysicsExplicitely()
|
||||
{
|
||||
FreeLibrary(physxLibrary);
|
||||
FreeLibrary(commonLibrary);
|
||||
FreeLibrary(foundationLibrary);
|
||||
}
|
||||
|
||||
// Overriding the PxDelayLoadHook allows the load of a custom name dll inside PhysX, PhysXCommon and PhysXCooking dlls
|
||||
struct SnippetDelayLoadHook : public PxDelayLoadHook
|
||||
{
|
||||
virtual const char* getPhysXFoundationDllName() const
|
||||
{
|
||||
return foundationLibraryPath;
|
||||
}
|
||||
|
||||
virtual const char* getPhysXCommonDllName() const
|
||||
{
|
||||
return commonLibraryPath;
|
||||
}
|
||||
};
|
||||
|
||||
// Overriding the PxGpuLoadHook allows the load of a custom GPU name dll
|
||||
struct SnippetGpuLoadHook : public PxGpuLoadHook
|
||||
{
|
||||
virtual const char* getPhysXGpuDllName() const
|
||||
{
|
||||
return gpuLibraryPath;
|
||||
}
|
||||
};
|
||||
|
||||
PxReal stackZ = 10.0f;
|
||||
|
||||
PxRigidDynamic* createDynamic(const PxTransform& t, const PxGeometry& geometry, const PxVec3& velocity=PxVec3(0))
|
||||
{
|
||||
PxRigidDynamic* dynamic = PxCreateDynamic(*gPhysics, t, geometry, *gMaterial, 10.0f);
|
||||
dynamic->setAngularDamping(0.5f);
|
||||
dynamic->setLinearVelocity(velocity);
|
||||
gScene->addActor(*dynamic);
|
||||
return dynamic;
|
||||
}
|
||||
|
||||
void createStack(const PxTransform& t, PxU32 size, PxReal halfExtent)
|
||||
{
|
||||
PxShape* shape = gPhysics->createShape(PxBoxGeometry(halfExtent, halfExtent, halfExtent), *gMaterial);
|
||||
for(PxU32 i=0; i<size;i++)
|
||||
{
|
||||
for(PxU32 j=0;j<size-i;j++)
|
||||
{
|
||||
PxTransform localTm(PxVec3(PxReal(j*2) - PxReal(size-i), PxReal(i*2+1), 0) * halfExtent);
|
||||
PxRigidDynamic* body = gPhysics->createRigidDynamic(t.transform(localTm));
|
||||
body->attachShape(*shape);
|
||||
PxRigidBodyExt::updateMassAndInertia(*body, 10.0f);
|
||||
gScene->addActor(*body);
|
||||
}
|
||||
}
|
||||
shape->release();
|
||||
}
|
||||
|
||||
void initPhysics(bool interactive)
|
||||
{
|
||||
// load the explictely named dlls
|
||||
const bool isLoaded = loadPhysicsExplicitely();
|
||||
if (!isLoaded)
|
||||
return;
|
||||
|
||||
gFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gAllocator, gErrorCallback);
|
||||
|
||||
// set PhysX and PhysXCommon delay load hook, this must be done before the create physics is called, before
|
||||
// the PhysXFoundation, PhysXCommon delay load happens.
|
||||
SnippetDelayLoadHook delayLoadHook;
|
||||
s_PxSetPhysXDelayLoadHook_Func(&delayLoadHook);
|
||||
s_PxSetPhysXCommonDelayLoadHook_Func(&delayLoadHook);
|
||||
|
||||
// set PhysXGpu load hook
|
||||
SnippetGpuLoadHook gpuLoadHook;
|
||||
s_PxSetPhysXGpuLoadHook_Func(&gpuLoadHook);
|
||||
|
||||
gPvd = PxCreatePvd(*gFoundation);
|
||||
PxPvdTransport* transport = PxDefaultPvdSocketTransportCreate(PVD_HOST, 5425, 10);
|
||||
gPvd->connect(*transport,PxPvdInstrumentationFlag::eALL);
|
||||
|
||||
gPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, PxTolerancesScale(),true,gPvd);
|
||||
|
||||
// We setup the delay load hooks first
|
||||
|
||||
PxSceneDesc sceneDesc(gPhysics->getTolerancesScale());
|
||||
sceneDesc.gravity = PxVec3(0.0f, -9.81f, 0.0f);
|
||||
gDispatcher = PxDefaultCpuDispatcherCreate(2);
|
||||
sceneDesc.cpuDispatcher = gDispatcher;
|
||||
sceneDesc.filterShader = PxDefaultSimulationFilterShader;
|
||||
gScene = gPhysics->createScene(sceneDesc);
|
||||
|
||||
PxPvdSceneClient* pvdClient = gScene->getScenePvdClient();
|
||||
if(pvdClient)
|
||||
{
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONSTRAINTS, true);
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONTACTS, true);
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_SCENEQUERIES, true);
|
||||
}
|
||||
gMaterial = gPhysics->createMaterial(0.5f, 0.5f, 0.6f);
|
||||
|
||||
PxRigidStatic* groundPlane = PxCreatePlane(*gPhysics, PxPlane(0,1,0,0), *gMaterial);
|
||||
gScene->addActor(*groundPlane);
|
||||
|
||||
for(PxU32 i=0;i<5;i++)
|
||||
createStack(PxTransform(PxVec3(0,0,stackZ-=10.0f)), 10, 2.0f);
|
||||
|
||||
if(!interactive)
|
||||
createDynamic(PxTransform(PxVec3(0,40,100)), PxSphereGeometry(10), PxVec3(0,-50,-100));
|
||||
}
|
||||
|
||||
void stepPhysics(bool /*interactive*/)
|
||||
{
|
||||
if (gScene)
|
||||
{
|
||||
gScene->simulate(1.0f/60.0f);
|
||||
gScene->fetchResults(true);
|
||||
}
|
||||
}
|
||||
|
||||
void cleanupPhysics(bool /*interactive*/)
|
||||
{
|
||||
PX_RELEASE(gScene);
|
||||
PX_RELEASE(gDispatcher);
|
||||
PX_RELEASE(gPhysics);
|
||||
|
||||
if(gPvd)
|
||||
{
|
||||
PxPvdTransport* transport = gPvd->getTransport();
|
||||
gPvd->release(); gPvd = NULL;
|
||||
PX_RELEASE(transport);
|
||||
}
|
||||
|
||||
PX_RELEASE(gFoundation);
|
||||
|
||||
unloadPhysicsExplicitely();
|
||||
|
||||
printf("SnippetDelayLoadHook done.\n");
|
||||
}
|
||||
|
||||
void keyPress(unsigned char key, const PxTransform& camera)
|
||||
{
|
||||
switch(toupper(key))
|
||||
{
|
||||
case 'B': createStack(PxTransform(PxVec3(0,0,stackZ-=10.0f)), 10, 2.0f); break;
|
||||
case ' ': createDynamic(camera, PxSphereGeometry(3.0f), camera.rotate(PxVec3(0,0,-1))*200); break;
|
||||
}
|
||||
}
|
||||
|
||||
int snippetMain(int, const char*const*)
|
||||
{
|
||||
#ifdef RENDER_SNIPPET
|
||||
extern void renderLoop();
|
||||
renderLoop();
|
||||
#else
|
||||
static const PxU32 frameCount = 100;
|
||||
initPhysics(false);
|
||||
for(PxU32 i=0; i<frameCount; i++)
|
||||
stepPhysics(false);
|
||||
cleanupPhysics(false);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -0,0 +1,122 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifdef RENDER_SNIPPET
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
|
||||
#include "../snippetrender/SnippetRender.h"
|
||||
#include "../snippetrender/SnippetCamera.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
extern void initPhysics(bool interactive);
|
||||
extern void stepPhysics(bool interactive);
|
||||
extern void cleanupPhysics(bool interactive);
|
||||
extern void keyPress(unsigned char key, const PxTransform& camera);
|
||||
extern PxScene* gScene;
|
||||
|
||||
namespace
|
||||
{
|
||||
Snippets::Camera* sCamera;
|
||||
|
||||
void motionCallback(int x, int y)
|
||||
{
|
||||
sCamera->handleMotion(x, y);
|
||||
}
|
||||
|
||||
void keyboardCallback(unsigned char key, int x, int y)
|
||||
{
|
||||
if(key==27)
|
||||
exit(0);
|
||||
|
||||
if(!sCamera->handleKey(key, x, y))
|
||||
keyPress(key, sCamera->getTransform());
|
||||
}
|
||||
|
||||
void mouseCallback(int button, int state, int x, int y)
|
||||
{
|
||||
sCamera->handleMouse(button, state, x, y);
|
||||
}
|
||||
|
||||
void idleCallback()
|
||||
{
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
void renderCallback()
|
||||
{
|
||||
stepPhysics(true);
|
||||
|
||||
Snippets::startRender(sCamera->getEye(), sCamera->getDir());
|
||||
|
||||
if (gScene)
|
||||
{
|
||||
PxU32 nbActors = gScene->getNbActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC);
|
||||
if(nbActors)
|
||||
{
|
||||
std::vector<PxRigidActor*> actors(nbActors);
|
||||
gScene->getActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC, reinterpret_cast<PxActor**>(&actors[0]), nbActors);
|
||||
Snippets::renderActors(&actors[0], static_cast<PxU32>(actors.size()), true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Snippets::finishRender();
|
||||
}
|
||||
|
||||
void exitCallback(void)
|
||||
{
|
||||
delete sCamera;
|
||||
cleanupPhysics(true);
|
||||
}
|
||||
}
|
||||
|
||||
void renderLoop()
|
||||
{
|
||||
sCamera = new Snippets::Camera(PxVec3(50.0f, 50.0f, 50.0f), PxVec3(-0.6f,-0.2f,-0.7f));
|
||||
|
||||
Snippets::setupDefaultWindow("PhysX Snippet Delay Load Hook");
|
||||
Snippets::setupDefaultRenderState();
|
||||
|
||||
glutIdleFunc(idleCallback);
|
||||
glutDisplayFunc(renderCallback);
|
||||
glutKeyboardFunc(keyboardCallback);
|
||||
glutMouseFunc(mouseCallback);
|
||||
glutMotionFunc(motionCallback);
|
||||
motionCallback(0,0);
|
||||
|
||||
atexit(exitCallback);
|
||||
|
||||
initPhysics(true);
|
||||
glutMainLoop();
|
||||
}
|
||||
#endif
|
||||
208
physx/snippets/snippethellogrb/SnippetHelloGRB.cpp
Normal file
208
physx/snippets/snippethellogrb/SnippetHelloGRB.cpp
Normal file
@ -0,0 +1,208 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
// ****************************************************************************
|
||||
// This snippet illustrates simple use of physx
|
||||
//
|
||||
// It creates a number of box stacks on a plane, and if rendering, allows the
|
||||
// user to create new stacks and fire a ball from the camera position
|
||||
// ****************************************************************************
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
|
||||
#include "../snippetcommon/SnippetPrint.h"
|
||||
#include "../snippetcommon/SnippetPVD.h"
|
||||
#include "../snippetutils/SnippetUtils.h"
|
||||
|
||||
|
||||
using namespace physx;
|
||||
|
||||
PxDefaultAllocator gAllocator;
|
||||
PxDefaultErrorCallback gErrorCallback;
|
||||
|
||||
PxFoundation* gFoundation = NULL;
|
||||
PxPhysics* gPhysics = NULL;
|
||||
|
||||
PxDefaultCpuDispatcher* gDispatcher = NULL;
|
||||
PxScene* gScene = NULL;
|
||||
|
||||
PxMaterial* gMaterial = NULL;
|
||||
|
||||
PxPvd* gPvd = NULL;
|
||||
|
||||
PxCudaContextManager* gCudaContextManager = NULL;
|
||||
|
||||
PxReal stackZ = 10.0f;
|
||||
|
||||
PxRigidDynamic* createDynamic(const PxTransform& t, const PxGeometry& geometry, const PxVec3& velocity=PxVec3(0))
|
||||
{
|
||||
PxRigidDynamic* dynamic = PxCreateDynamic(*gPhysics, t, geometry, *gMaterial, 10.0f);
|
||||
dynamic->setAngularDamping(0.5f);
|
||||
dynamic->setLinearVelocity(velocity);
|
||||
gScene->addActor(*dynamic);
|
||||
return dynamic;
|
||||
}
|
||||
|
||||
void createStack(const PxTransform& t, PxU32 size, PxReal halfExtent)
|
||||
{
|
||||
PxShape* shape = gPhysics->createShape(PxBoxGeometry(halfExtent, halfExtent, halfExtent), *gMaterial);
|
||||
for(PxU32 i=0; i<size;i++)
|
||||
{
|
||||
for(PxU32 j=0;j<size-i;j++)
|
||||
{
|
||||
PxTransform localTm(PxVec3(PxReal(j*2) - PxReal(size-i), PxReal(i*2+1), 0) * halfExtent);
|
||||
PxRigidDynamic* body = gPhysics->createRigidDynamic(t.transform(localTm));
|
||||
body->attachShape(*shape);
|
||||
PxRigidBodyExt::updateMassAndInertia(*body, 10.0f);
|
||||
gScene->addActor(*body);
|
||||
}
|
||||
}
|
||||
shape->release();
|
||||
}
|
||||
|
||||
void initPhysics(bool /*interactive*/)
|
||||
{
|
||||
gFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gAllocator, gErrorCallback);
|
||||
gPvd = PxCreatePvd(*gFoundation);
|
||||
PxPvdTransport* transport = PxDefaultPvdSocketTransportCreate(PVD_HOST, 5425, 10);
|
||||
gPvd->connect(*transport, PxPvdInstrumentationFlag::ePROFILE);
|
||||
|
||||
gPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, PxTolerancesScale(), true, gPvd);
|
||||
|
||||
PxCudaContextManagerDesc cudaContextManagerDesc;
|
||||
|
||||
#ifdef RENDER_SNIPPET
|
||||
cudaContextManagerDesc.interopMode = PxCudaInteropMode::OGL_INTEROP; //Choose interop mode. As the snippets use OGL, we select OGL_INTEROP
|
||||
//when using D3D, cudaContextManagerDesc.graphicsDevice must be set as the graphics device pointer.
|
||||
#else
|
||||
cudaContextManagerDesc.interopMode = PxCudaInteropMode::NO_INTEROP;
|
||||
#endif
|
||||
|
||||
|
||||
gCudaContextManager = PxCreateCudaContextManager(*gFoundation, cudaContextManagerDesc, PxGetProfilerCallback()); //Create the CUDA context manager, required for GRB to dispatch CUDA kernels.
|
||||
if( gCudaContextManager )
|
||||
{
|
||||
if( !gCudaContextManager->contextIsValid() )
|
||||
{
|
||||
gCudaContextManager->release();
|
||||
gCudaContextManager = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
PxSceneDesc sceneDesc(gPhysics->getTolerancesScale());
|
||||
sceneDesc.gravity = PxVec3(0.0f, -9.81f, 0.0f);
|
||||
gDispatcher = PxDefaultCpuDispatcherCreate(4); //Create a CPU dispatcher using 4 worther threads
|
||||
sceneDesc.cpuDispatcher = gDispatcher;
|
||||
sceneDesc.filterShader = PxDefaultSimulationFilterShader;
|
||||
|
||||
sceneDesc.cudaContextManager = gCudaContextManager; //Set the CUDA context manager, used by GRB.
|
||||
|
||||
sceneDesc.flags |= PxSceneFlag::eENABLE_GPU_DYNAMICS; //Enable GPU dynamics - without this enabled, simulation (contact gen and solver) will run on the CPU.
|
||||
sceneDesc.flags |= PxSceneFlag::eENABLE_PCM; //Enable PCM. PCM NP is supported on GPU. Legacy contact gen will fall back to CPU
|
||||
sceneDesc.flags |= PxSceneFlag::eENABLE_STABILIZATION; //Improve solver stability by enabling post-stabilization.
|
||||
sceneDesc.broadPhaseType = PxBroadPhaseType::eGPU; //Enable GPU broad phase. Without this set, broad phase will run on the CPU.
|
||||
sceneDesc.gpuMaxNumPartitions = 8; //Defines the maximum number of partitions used by the solver. Only power-of-2 values are valid.
|
||||
//A value of 8 generally gives best balance between performance and stability.
|
||||
|
||||
gScene = gPhysics->createScene(sceneDesc);
|
||||
|
||||
|
||||
PxPvdSceneClient* pvdClient = gScene->getScenePvdClient();
|
||||
if (pvdClient)
|
||||
{
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONSTRAINTS, false);
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONTACTS, false);
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_SCENEQUERIES, false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
gMaterial = gPhysics->createMaterial(0.5f, 0.5f, 0.6f);
|
||||
|
||||
PxRigidStatic* groundPlane = PxCreatePlane(*gPhysics, PxPlane(0,1,0,0), *gMaterial);
|
||||
gScene->addActor(*groundPlane);
|
||||
|
||||
for(PxU32 i=0;i<40;i++)
|
||||
createStack(PxTransform(PxVec3(0,0,stackZ-=10.0f)), 20, 1.0f);
|
||||
|
||||
PxRigidDynamic* ball = createDynamic(PxTransform(PxVec3(0,20,100)), PxSphereGeometry(5), PxVec3(0,-25,-100));
|
||||
PxRigidBodyExt::updateMassAndInertia(*ball, 1000.f);
|
||||
}
|
||||
|
||||
void stepPhysics(bool /*interactive*/)
|
||||
{
|
||||
gScene->simulate(1.0f/60.0f);
|
||||
gScene->fetchResults(true);
|
||||
}
|
||||
|
||||
void cleanupPhysics(bool /*interactive*/)
|
||||
{
|
||||
PX_RELEASE(gScene);
|
||||
PX_RELEASE(gDispatcher);
|
||||
PX_RELEASE(gPhysics);
|
||||
|
||||
if(gPvd)
|
||||
{
|
||||
PxPvdTransport* transport = gPvd->getTransport();
|
||||
gPvd->release(); gPvd = NULL;
|
||||
PX_RELEASE(transport);
|
||||
}
|
||||
|
||||
PX_RELEASE(gCudaContextManager);
|
||||
PX_RELEASE(gFoundation);
|
||||
|
||||
printf("SnippetHelloWorld done.\n");
|
||||
}
|
||||
|
||||
void keyPress(const char key, const PxTransform& camera)
|
||||
{
|
||||
switch(toupper(key))
|
||||
{
|
||||
case 'B': createStack(PxTransform(PxVec3(0,0,stackZ-=10.0f)), 10, 2.0f); break;
|
||||
case ' ': createDynamic(camera, PxSphereGeometry(3.0f), camera.rotate(PxVec3(0,0,-1))*200); break;
|
||||
}
|
||||
}
|
||||
|
||||
int snippetMain(int, const char*const*)
|
||||
{
|
||||
#ifdef RENDER_SNIPPET
|
||||
extern void renderLoop();
|
||||
renderLoop();
|
||||
#else
|
||||
static const PxU32 frameCount = 100;
|
||||
initPhysics(false);
|
||||
for(PxU32 i=0; i<frameCount; i++)
|
||||
stepPhysics(false);
|
||||
cleanupPhysics(false);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
120
physx/snippets/snippethellogrb/SnippetHelloGRBRender.cpp
Normal file
120
physx/snippets/snippethellogrb/SnippetHelloGRBRender.cpp
Normal file
@ -0,0 +1,120 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifdef RENDER_SNIPPET
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
|
||||
#include "../snippetrender/SnippetRender.h"
|
||||
#include "../snippetrender/SnippetCamera.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
extern void initPhysics(bool interactive);
|
||||
extern void stepPhysics(bool interactive);
|
||||
extern void cleanupPhysics(bool interactive);
|
||||
extern void keyPress(const char key, const PxTransform& camera);
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
Snippets::Camera* sCamera;
|
||||
|
||||
void motionCallback(int x, int y)
|
||||
{
|
||||
sCamera->handleMotion(x, y);
|
||||
}
|
||||
|
||||
void keyboardCallback(unsigned char key, int x, int y)
|
||||
{
|
||||
if(key==27)
|
||||
exit(0);
|
||||
|
||||
if(!sCamera->handleKey(key, x, y))
|
||||
keyPress(key, sCamera->getTransform());
|
||||
}
|
||||
|
||||
void mouseCallback(int button, int state, int x, int y)
|
||||
{
|
||||
sCamera->handleMouse(button, state, x, y);
|
||||
}
|
||||
|
||||
void idleCallback()
|
||||
{
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
void renderCallback()
|
||||
{
|
||||
stepPhysics(true);
|
||||
|
||||
Snippets::startRender(sCamera->getEye(), sCamera->getDir());
|
||||
|
||||
PxScene* scene;
|
||||
PxGetPhysics().getScenes(&scene,1);
|
||||
PxU32 nbActors = scene->getNbActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC);
|
||||
if(nbActors)
|
||||
{
|
||||
std::vector<PxRigidActor*> actors(nbActors);
|
||||
scene->getActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC, (PxActor**)&actors[0], nbActors);
|
||||
Snippets::renderActors(&actors[0], (PxU32)actors.size(), true);
|
||||
}
|
||||
|
||||
Snippets::finishRender();
|
||||
}
|
||||
|
||||
void exitCallback(void)
|
||||
{
|
||||
delete sCamera;
|
||||
}
|
||||
}
|
||||
|
||||
void renderLoop()
|
||||
{
|
||||
sCamera = new Snippets::Camera(PxVec3(50.0f, 50.0f, 50.0f), PxVec3(-0.6f,-0.2f,-0.7f));
|
||||
|
||||
Snippets::setupDefaultWindow("PhysX Snippet HelloWorld");
|
||||
Snippets::setupDefaultRenderState();
|
||||
|
||||
glutIdleFunc(idleCallback);
|
||||
glutDisplayFunc(renderCallback);
|
||||
glutKeyboardFunc(keyboardCallback);
|
||||
glutMouseFunc(mouseCallback);
|
||||
glutMotionFunc(motionCallback);
|
||||
motionCallback(0,0);
|
||||
|
||||
atexit(exitCallback);
|
||||
|
||||
initPhysics(true);
|
||||
glutMainLoop();
|
||||
cleanupPhysics(true);
|
||||
}
|
||||
#endif
|
||||
169
physx/snippets/snippethelloworld/SnippetHelloWorld.cpp
Normal file
169
physx/snippets/snippethelloworld/SnippetHelloWorld.cpp
Normal file
@ -0,0 +1,169 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
// ****************************************************************************
|
||||
// This snippet illustrates simple use of physx
|
||||
//
|
||||
// It creates a number of box stacks on a plane, and if rendering, allows the
|
||||
// user to create new stacks and fire a ball from the camera position
|
||||
// ****************************************************************************
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
|
||||
#include "../snippetcommon/SnippetPrint.h"
|
||||
#include "../snippetcommon/SnippetPVD.h"
|
||||
#include "../snippetutils/SnippetUtils.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
PxDefaultAllocator gAllocator;
|
||||
PxDefaultErrorCallback gErrorCallback;
|
||||
|
||||
PxFoundation* gFoundation = NULL;
|
||||
PxPhysics* gPhysics = NULL;
|
||||
|
||||
PxDefaultCpuDispatcher* gDispatcher = NULL;
|
||||
PxScene* gScene = NULL;
|
||||
|
||||
PxMaterial* gMaterial = NULL;
|
||||
|
||||
PxPvd* gPvd = NULL;
|
||||
|
||||
PxReal stackZ = 10.0f;
|
||||
|
||||
PxRigidDynamic* createDynamic(const PxTransform& t, const PxGeometry& geometry, const PxVec3& velocity=PxVec3(0))
|
||||
{
|
||||
PxRigidDynamic* dynamic = PxCreateDynamic(*gPhysics, t, geometry, *gMaterial, 10.0f);
|
||||
dynamic->setAngularDamping(0.5f);
|
||||
dynamic->setLinearVelocity(velocity);
|
||||
gScene->addActor(*dynamic);
|
||||
return dynamic;
|
||||
}
|
||||
|
||||
void createStack(const PxTransform& t, PxU32 size, PxReal halfExtent)
|
||||
{
|
||||
PxShape* shape = gPhysics->createShape(PxBoxGeometry(halfExtent, halfExtent, halfExtent), *gMaterial);
|
||||
for(PxU32 i=0; i<size;i++)
|
||||
{
|
||||
for(PxU32 j=0;j<size-i;j++)
|
||||
{
|
||||
PxTransform localTm(PxVec3(PxReal(j*2) - PxReal(size-i), PxReal(i*2+1), 0) * halfExtent);
|
||||
PxRigidDynamic* body = gPhysics->createRigidDynamic(t.transform(localTm));
|
||||
body->attachShape(*shape);
|
||||
PxRigidBodyExt::updateMassAndInertia(*body, 10.0f);
|
||||
gScene->addActor(*body);
|
||||
}
|
||||
}
|
||||
shape->release();
|
||||
}
|
||||
|
||||
void initPhysics(bool interactive)
|
||||
{
|
||||
gFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gAllocator, gErrorCallback);
|
||||
|
||||
gPvd = PxCreatePvd(*gFoundation);
|
||||
PxPvdTransport* transport = PxDefaultPvdSocketTransportCreate(PVD_HOST, 5425, 10);
|
||||
gPvd->connect(*transport,PxPvdInstrumentationFlag::eALL);
|
||||
|
||||
gPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, PxTolerancesScale(),true,gPvd);
|
||||
|
||||
PxSceneDesc sceneDesc(gPhysics->getTolerancesScale());
|
||||
sceneDesc.gravity = PxVec3(0.0f, -9.81f, 0.0f);
|
||||
gDispatcher = PxDefaultCpuDispatcherCreate(2);
|
||||
sceneDesc.cpuDispatcher = gDispatcher;
|
||||
sceneDesc.filterShader = PxDefaultSimulationFilterShader;
|
||||
gScene = gPhysics->createScene(sceneDesc);
|
||||
|
||||
PxPvdSceneClient* pvdClient = gScene->getScenePvdClient();
|
||||
if(pvdClient)
|
||||
{
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONSTRAINTS, true);
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONTACTS, true);
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_SCENEQUERIES, true);
|
||||
}
|
||||
gMaterial = gPhysics->createMaterial(0.5f, 0.5f, 0.6f);
|
||||
|
||||
PxRigidStatic* groundPlane = PxCreatePlane(*gPhysics, PxPlane(0,1,0,0), *gMaterial);
|
||||
gScene->addActor(*groundPlane);
|
||||
|
||||
for(PxU32 i=0;i<5;i++)
|
||||
createStack(PxTransform(PxVec3(0,0,stackZ-=10.0f)), 10, 2.0f);
|
||||
|
||||
if(!interactive)
|
||||
createDynamic(PxTransform(PxVec3(0,40,100)), PxSphereGeometry(10), PxVec3(0,-50,-100));
|
||||
}
|
||||
|
||||
void stepPhysics(bool /*interactive*/)
|
||||
{
|
||||
gScene->simulate(1.0f/60.0f);
|
||||
gScene->fetchResults(true);
|
||||
}
|
||||
|
||||
void cleanupPhysics(bool /*interactive*/)
|
||||
{
|
||||
PX_RELEASE(gScene);
|
||||
PX_RELEASE(gDispatcher);
|
||||
PX_RELEASE(gPhysics);
|
||||
if(gPvd)
|
||||
{
|
||||
PxPvdTransport* transport = gPvd->getTransport();
|
||||
gPvd->release(); gPvd = NULL;
|
||||
PX_RELEASE(transport);
|
||||
}
|
||||
PX_RELEASE(gFoundation);
|
||||
|
||||
printf("SnippetHelloWorld done.\n");
|
||||
}
|
||||
|
||||
void keyPress(unsigned char key, const PxTransform& camera)
|
||||
{
|
||||
switch(toupper(key))
|
||||
{
|
||||
case 'B': createStack(PxTransform(PxVec3(0,0,stackZ-=10.0f)), 10, 2.0f); break;
|
||||
case ' ': createDynamic(camera, PxSphereGeometry(3.0f), camera.rotate(PxVec3(0,0,-1))*200); break;
|
||||
}
|
||||
}
|
||||
|
||||
int snippetMain(int, const char*const*)
|
||||
{
|
||||
#ifdef RENDER_SNIPPET
|
||||
extern void renderLoop();
|
||||
renderLoop();
|
||||
#else
|
||||
static const PxU32 frameCount = 100;
|
||||
initPhysics(false);
|
||||
for(PxU32 i=0; i<frameCount; i++)
|
||||
stepPhysics(false);
|
||||
cleanupPhysics(false);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
120
physx/snippets/snippethelloworld/SnippetHelloWorldRender.cpp
Normal file
120
physx/snippets/snippethelloworld/SnippetHelloWorldRender.cpp
Normal file
@ -0,0 +1,120 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifdef RENDER_SNIPPET
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
|
||||
#include "../snippetrender/SnippetRender.h"
|
||||
#include "../snippetrender/SnippetCamera.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
extern void initPhysics(bool interactive);
|
||||
extern void stepPhysics(bool interactive);
|
||||
extern void cleanupPhysics(bool interactive);
|
||||
extern void keyPress(unsigned char key, const PxTransform& camera);
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
Snippets::Camera* sCamera;
|
||||
|
||||
void motionCallback(int x, int y)
|
||||
{
|
||||
sCamera->handleMotion(x, y);
|
||||
}
|
||||
|
||||
void keyboardCallback(unsigned char key, int x, int y)
|
||||
{
|
||||
if(key==27)
|
||||
exit(0);
|
||||
|
||||
if(!sCamera->handleKey(key, x, y))
|
||||
keyPress(key, sCamera->getTransform());
|
||||
}
|
||||
|
||||
void mouseCallback(int button, int state, int x, int y)
|
||||
{
|
||||
sCamera->handleMouse(button, state, x, y);
|
||||
}
|
||||
|
||||
void idleCallback()
|
||||
{
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
void renderCallback()
|
||||
{
|
||||
stepPhysics(true);
|
||||
|
||||
Snippets::startRender(sCamera->getEye(), sCamera->getDir());
|
||||
|
||||
PxScene* scene;
|
||||
PxGetPhysics().getScenes(&scene,1);
|
||||
PxU32 nbActors = scene->getNbActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC);
|
||||
if(nbActors)
|
||||
{
|
||||
std::vector<PxRigidActor*> actors(nbActors);
|
||||
scene->getActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC, reinterpret_cast<PxActor**>(&actors[0]), nbActors);
|
||||
Snippets::renderActors(&actors[0], static_cast<PxU32>(actors.size()), true);
|
||||
}
|
||||
|
||||
Snippets::finishRender();
|
||||
}
|
||||
|
||||
void exitCallback(void)
|
||||
{
|
||||
delete sCamera;
|
||||
cleanupPhysics(true);
|
||||
}
|
||||
}
|
||||
|
||||
void renderLoop()
|
||||
{
|
||||
sCamera = new Snippets::Camera(PxVec3(50.0f, 50.0f, 50.0f), PxVec3(-0.6f,-0.2f,-0.7f));
|
||||
|
||||
Snippets::setupDefaultWindow("PhysX Snippet HelloWorld");
|
||||
Snippets::setupDefaultRenderState();
|
||||
|
||||
glutIdleFunc(idleCallback);
|
||||
glutDisplayFunc(renderCallback);
|
||||
glutKeyboardFunc(keyboardCallback);
|
||||
glutMouseFunc(mouseCallback);
|
||||
glutMotionFunc(motionCallback);
|
||||
motionCallback(0,0);
|
||||
|
||||
atexit(exitCallback);
|
||||
|
||||
initPhysics(true);
|
||||
glutMainLoop();
|
||||
}
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,282 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifdef RENDER_SNIPPET
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
#include "PxImmediateMode.h"
|
||||
|
||||
#include "../snippetrender/SnippetRender.h"
|
||||
#include "../snippetrender/SnippetCamera.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
extern void initPhysics(bool interactive);
|
||||
extern void stepPhysics(bool interactive);
|
||||
extern void cleanupPhysics(bool interactive);
|
||||
extern void keyPress(unsigned char key, const PxTransform& camera);
|
||||
extern PxU32 getNbGeoms();
|
||||
extern const PxGeometryHolder* getGeoms();
|
||||
extern const PxTransform* getGeomPoses();
|
||||
extern PxU32 getNbContacts();
|
||||
extern const Gu::ContactPoint* getContacts();
|
||||
extern PxU32 getNbArticulations();
|
||||
extern Dy::ArticulationV** getArticulations();
|
||||
extern PxU32 getNbBounds();
|
||||
extern const PxBounds3* getBounds();
|
||||
|
||||
namespace
|
||||
{
|
||||
Snippets::Camera* sCamera;
|
||||
|
||||
void motionCallback(int x, int y)
|
||||
{
|
||||
sCamera->handleMotion(x, y);
|
||||
}
|
||||
|
||||
void keyboardCallback(unsigned char key, int x, int y)
|
||||
{
|
||||
if(key==27)
|
||||
exit(0);
|
||||
|
||||
if(!sCamera->handleKey(key, x, y))
|
||||
keyPress(key, sCamera->getTransform());
|
||||
}
|
||||
|
||||
void keyboardCallback2(int key, int /*x*/, int /*y*/)
|
||||
{
|
||||
keyPress(key, sCamera->getTransform());
|
||||
}
|
||||
|
||||
void mouseCallback(int button, int state, int x, int y)
|
||||
{
|
||||
sCamera->handleMouse(button, state, x, y);
|
||||
}
|
||||
|
||||
void idleCallback()
|
||||
{
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
static void DrawLine(const PxVec3& p0, const PxVec3& p1, const PxVec3& color)
|
||||
{
|
||||
glDisable(GL_LIGHTING);
|
||||
glColor4f(color.x, color.y, color.z, 1.0f);
|
||||
const PxVec3 Pts[] = { p0, p1 };
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glVertexPointer(3, GL_FLOAT, sizeof(PxVec3), &Pts[0].x);
|
||||
glDrawArrays(GL_LINES, 0, 2);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
glEnable(GL_LIGHTING);
|
||||
}
|
||||
|
||||
static void DrawFrame(const PxVec3& pt, float scale=1.0f)
|
||||
{
|
||||
DrawLine(pt, pt + PxVec3(scale, 0.0f, 0.0f), PxVec3(1.0f, 0.0f, 0.0f));
|
||||
DrawLine(pt, pt + PxVec3(0.0f, scale, 0.0f), PxVec3(0.0f, 1.0f, 0.0f));
|
||||
DrawLine(pt, pt + PxVec3(0.0f, 0.0f, scale), PxVec3(0.0f, 0.0f, 1.0f));
|
||||
}
|
||||
|
||||
static void DrawBounds(const PxBounds3& box)
|
||||
{
|
||||
DrawLine(PxVec3(box.minimum.x, box.minimum.y, box.minimum.z), PxVec3(box.maximum.x, box.minimum.y, box.minimum.z), PxVec3(1.0f, 1.0f, 0.0f));
|
||||
DrawLine(PxVec3(box.maximum.x, box.minimum.y, box.minimum.z), PxVec3(box.maximum.x, box.maximum.y, box.minimum.z), PxVec3(1.0f, 1.0f, 0.0f));
|
||||
DrawLine(PxVec3(box.maximum.x, box.maximum.y, box.minimum.z), PxVec3(box.minimum.x, box.maximum.y, box.minimum.z), PxVec3(1.0f, 1.0f, 0.0f));
|
||||
DrawLine(PxVec3(box.minimum.x, box.maximum.y, box.minimum.z), PxVec3(box.minimum.x, box.minimum.y, box.minimum.z), PxVec3(1.0f, 1.0f, 0.0f));
|
||||
DrawLine(PxVec3(box.minimum.x, box.minimum.y, box.minimum.z), PxVec3(box.minimum.x, box.minimum.y, box.maximum.z), PxVec3(1.0f, 1.0f, 0.0f));
|
||||
DrawLine(PxVec3(box.minimum.x, box.minimum.y, box.maximum.z), PxVec3(box.maximum.x, box.minimum.y, box.maximum.z), PxVec3(1.0f, 1.0f, 0.0f));
|
||||
DrawLine(PxVec3(box.maximum.x, box.minimum.y, box.maximum.z), PxVec3(box.maximum.x, box.maximum.y, box.maximum.z), PxVec3(1.0f, 1.0f, 0.0f));
|
||||
DrawLine(PxVec3(box.maximum.x, box.maximum.y, box.maximum.z), PxVec3(box.minimum.x, box.maximum.y, box.maximum.z), PxVec3(1.0f, 1.0f, 0.0f));
|
||||
DrawLine(PxVec3(box.minimum.x, box.maximum.y, box.maximum.z), PxVec3(box.minimum.x, box.minimum.y, box.maximum.z), PxVec3(1.0f, 1.0f, 0.0f));
|
||||
DrawLine(PxVec3(box.minimum.x, box.minimum.y, box.maximum.z), PxVec3(box.minimum.x, box.minimum.y, box.minimum.z), PxVec3(1.0f, 1.0f, 0.0f));
|
||||
DrawLine(PxVec3(box.maximum.x, box.minimum.y, box.minimum.z), PxVec3(box.maximum.x, box.minimum.y, box.maximum.z), PxVec3(1.0f, 1.0f, 0.0f));
|
||||
DrawLine(PxVec3(box.maximum.x, box.maximum.y, box.minimum.z), PxVec3(box.maximum.x, box.maximum.y, box.maximum.z), PxVec3(1.0f, 1.0f, 0.0f));
|
||||
DrawLine(PxVec3(box.minimum.x, box.maximum.y, box.minimum.z), PxVec3(box.minimum.x, box.maximum.y, box.maximum.z), PxVec3(1.0f, 1.0f, 0.0f));
|
||||
}
|
||||
|
||||
static void InitLighting()
|
||||
{
|
||||
glEnable(GL_COLOR_MATERIAL);
|
||||
|
||||
const float zero[] = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, zero);
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, zero);
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, zero);
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, zero);
|
||||
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0f);
|
||||
|
||||
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, zero);
|
||||
|
||||
glEnable(GL_LIGHTING);
|
||||
PxVec3 Dir(-1.0f, 1.0f, 0.5f);
|
||||
// PxVec3 Dir(0.0f, 1.0f, 0.0f);
|
||||
Dir.normalize();
|
||||
|
||||
const float AmbientValue = 0.3f;
|
||||
const float ambientColor0[] = { AmbientValue, AmbientValue, AmbientValue, 0.0f };
|
||||
glLightfv(GL_LIGHT0, GL_AMBIENT, ambientColor0);
|
||||
|
||||
const float specularColor0[] = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
glLightfv(GL_LIGHT0, GL_SPECULAR, specularColor0);
|
||||
|
||||
const float diffuseColor0[] = { 0.7f, 0.7f, 0.7f, 0.0f };
|
||||
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseColor0);
|
||||
|
||||
const float position0[] = { Dir.x, Dir.y, Dir.z, 0.0f };
|
||||
glLightfv(GL_LIGHT0, GL_POSITION, position0);
|
||||
|
||||
glEnable(GL_LIGHT0);
|
||||
|
||||
// glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
// glColor4f(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
if(0)
|
||||
{
|
||||
glEnable(GL_FOG);
|
||||
glFogi(GL_FOG_MODE,GL_LINEAR);
|
||||
//glFogi(GL_FOG_MODE,GL_EXP);
|
||||
//glFogi(GL_FOG_MODE,GL_EXP2);
|
||||
glFogf(GL_FOG_START, 0.0f);
|
||||
glFogf(GL_FOG_END, 100.0f);
|
||||
glFogf(GL_FOG_DENSITY, 0.005f);
|
||||
// glClearColor(0.2f, 0.2f, 0.2f, 1.0);
|
||||
// const PxVec3 FogColor(0.2f, 0.2f, 0.2f);
|
||||
const PxVec3 FogColor(1.0f);
|
||||
glFogfv(GL_FOG_COLOR, &FogColor.x);
|
||||
}
|
||||
}
|
||||
|
||||
void renderCallback()
|
||||
{
|
||||
stepPhysics(true);
|
||||
|
||||
/* if(0)
|
||||
{
|
||||
PxVec3 camPos = sCamera->getEye();
|
||||
PxVec3 camDir = sCamera->getDir();
|
||||
printf("camPos: (%ff, %ff, %ff)\n", camPos.x, camPos.y, camPos.z);
|
||||
printf("camDir: (%ff, %ff, %ff)\n", camDir.x, camDir.y, camDir.z);
|
||||
}*/
|
||||
|
||||
Snippets::startRender(sCamera->getEye(), sCamera->getDir());
|
||||
InitLighting();
|
||||
|
||||
const PxVec3 color(0.6f, 0.8f, 1.0f);
|
||||
// const PxVec3 color(0.75f, 0.75f, 1.0f);
|
||||
// const PxVec3 color(1.0f);
|
||||
|
||||
Snippets::renderGeoms(getNbGeoms(), getGeoms(), getGeomPoses(), true, color);
|
||||
|
||||
/* PxU32 getNbGeoms();
|
||||
const PxGeometry* getGeoms();
|
||||
const PxTransform* getGeomPoses();
|
||||
Snippets::renderGeoms(getNbGeoms(), getGeoms(), getGeomPoses(), true, PxVec3(1.0f));*/
|
||||
|
||||
/* PxBoxGeometry boxGeoms[10];
|
||||
for(PxU32 i=0;i<10;i++)
|
||||
boxGeoms[i].halfExtents = PxVec3(1.0f);
|
||||
|
||||
PxTransform poses[10];
|
||||
for(PxU32 i=0;i<10;i++)
|
||||
{
|
||||
poses[i] = PxTransform(PxIdentity);
|
||||
poses[i].p.y += 1.5f;
|
||||
poses[i].p.x = float(i)*2.5f;
|
||||
}
|
||||
|
||||
Snippets::renderGeoms(10, boxGeoms, poses, true, PxVec3(1.0f));*/
|
||||
|
||||
if(1)
|
||||
{
|
||||
const PxU32 nbContacts = getNbContacts();
|
||||
const Gu::ContactPoint* contacts = getContacts();
|
||||
for(PxU32 j=0;j<nbContacts;j++)
|
||||
{
|
||||
DrawFrame(contacts[j].point, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
if(0)
|
||||
{
|
||||
const PxU32 nbArticulations = getNbArticulations();
|
||||
Dy::ArticulationV** articulations = getArticulations();
|
||||
for(PxU32 j=0;j<nbArticulations;j++)
|
||||
{
|
||||
immediate::PxLinkData data[64];
|
||||
const PxU32 nbLinks = immediate::PxGetAllLinkData(articulations[j], data);
|
||||
for(PxU32 i=0;i<nbLinks;i++)
|
||||
{
|
||||
DrawFrame(data[i].pose.p, 1.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const PxBounds3* bounds = getBounds();
|
||||
const PxU32 nbBounds = getNbBounds();
|
||||
for(PxU32 i=0;i<nbBounds;i++)
|
||||
{
|
||||
DrawBounds(bounds[i]);
|
||||
}
|
||||
|
||||
Snippets::finishRender();
|
||||
}
|
||||
|
||||
void exitCallback(void)
|
||||
{
|
||||
delete sCamera;
|
||||
cleanupPhysics(true);
|
||||
}
|
||||
}
|
||||
|
||||
void renderLoop()
|
||||
{
|
||||
sCamera = new Snippets::Camera( PxVec3(8.526230f, 5.546278f, 5.448466f),
|
||||
PxVec3(-0.784231f, -0.210605f, -0.583632f));
|
||||
|
||||
Snippets::setupDefaultWindow("PhysX Snippet Immediate Articulation");
|
||||
Snippets::setupDefaultRenderState();
|
||||
|
||||
glutIdleFunc(idleCallback);
|
||||
glutDisplayFunc(renderCallback);
|
||||
glutKeyboardFunc(keyboardCallback);
|
||||
glutSpecialFunc(keyboardCallback2);
|
||||
glutMouseFunc(mouseCallback);
|
||||
glutMotionFunc(motionCallback);
|
||||
motionCallback(0,0);
|
||||
|
||||
atexit(exitCallback);
|
||||
|
||||
initPhysics(true);
|
||||
glutMainLoop();
|
||||
}
|
||||
|
||||
#endif
|
||||
1075
physx/snippets/snippetimmediatemode/SnippetImmediateMode.cpp
Normal file
1075
physx/snippets/snippetimmediatemode/SnippetImmediateMode.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,120 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#ifdef RENDER_SNIPPET
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
|
||||
#include "../snippetrender/SnippetRender.h"
|
||||
#include "../snippetrender/SnippetCamera.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
extern void initPhysics(bool interactive);
|
||||
extern void stepPhysics(bool interactive);
|
||||
extern void cleanupPhysics(bool interactive);
|
||||
extern void keyPress(const char key, const PxTransform& camera);
|
||||
|
||||
extern float cameraSpeed;
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
Snippets::Camera* sCamera;
|
||||
|
||||
void motionCallback(int x, int y)
|
||||
{
|
||||
sCamera->handleMotion(x, y);
|
||||
}
|
||||
|
||||
void keyboardCallback(unsigned char key, int x, int y)
|
||||
{
|
||||
if(key==27)
|
||||
exit(0);
|
||||
|
||||
if (!sCamera->handleKey(key, x, y, cameraSpeed))
|
||||
keyPress(key, sCamera->getTransform());
|
||||
}
|
||||
|
||||
void mouseCallback(int button, int state, int x, int y)
|
||||
{
|
||||
sCamera->handleMouse(button, state, x, y);
|
||||
}
|
||||
|
||||
void idleCallback()
|
||||
{
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
void renderCallback()
|
||||
{
|
||||
stepPhysics(true);
|
||||
|
||||
Snippets::startRender(sCamera->getEye(), sCamera->getDir(), 10.f, 100000.f);
|
||||
|
||||
PxScene* scene;
|
||||
PxGetPhysics().getScenes(&scene,1);
|
||||
PxU32 nbActors = scene->getNbActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC);
|
||||
if(nbActors)
|
||||
{
|
||||
std::vector<PxRigidActor*> actors(nbActors);
|
||||
scene->getActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC, reinterpret_cast<PxActor**>(&actors[0]), nbActors);
|
||||
Snippets::renderActors(&actors[0], PxU32(actors.size()), true);
|
||||
}
|
||||
|
||||
Snippets::finishRender();
|
||||
}
|
||||
|
||||
void exitCallback(void)
|
||||
{
|
||||
delete sCamera;
|
||||
cleanupPhysics(true);
|
||||
}
|
||||
}
|
||||
|
||||
void renderLoop()
|
||||
{
|
||||
sCamera = new Snippets::Camera(PxVec3(50.0f, 50.0f, 50.0f), PxVec3(-0.6f,-0.2f,-0.7f));
|
||||
|
||||
Snippets::setupDefaultWindow("PhysX Snippet Immediate Mode");
|
||||
Snippets::setupDefaultRenderState();
|
||||
|
||||
glutIdleFunc(idleCallback);
|
||||
glutDisplayFunc(renderCallback);
|
||||
glutKeyboardFunc(keyboardCallback);
|
||||
glutMouseFunc(mouseCallback);
|
||||
glutMotionFunc(motionCallback);
|
||||
motionCallback(0,0);
|
||||
|
||||
atexit(exitCallback);
|
||||
|
||||
initPhysics(true);
|
||||
glutMainLoop();
|
||||
}
|
||||
#endif
|
||||
204
physx/snippets/snippetjoint/SnippetJoint.cpp
Normal file
204
physx/snippets/snippetjoint/SnippetJoint.cpp
Normal file
@ -0,0 +1,204 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
// ****************************************************************************
|
||||
// This snippet illustrates simple use of joints in physx
|
||||
//
|
||||
// It creates a chain of objects joined by limited spherical joints, a chain
|
||||
// joined by fixed joints which is breakable, and a chain of damped D6 joints
|
||||
// ****************************************************************************
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
|
||||
#include "../snippetcommon/SnippetPrint.h"
|
||||
#include "../snippetcommon/SnippetPVD.h"
|
||||
#include "../snippetutils/SnippetUtils.h"
|
||||
|
||||
|
||||
using namespace physx;
|
||||
|
||||
PxDefaultAllocator gAllocator;
|
||||
PxDefaultErrorCallback gErrorCallback;
|
||||
|
||||
PxFoundation* gFoundation = NULL;
|
||||
PxPhysics* gPhysics = NULL;
|
||||
|
||||
PxDefaultCpuDispatcher* gDispatcher = NULL;
|
||||
PxScene* gScene = NULL;
|
||||
|
||||
PxMaterial* gMaterial = NULL;
|
||||
|
||||
PxPvd* gPvd = NULL;
|
||||
|
||||
PxReal chainZ = 10.0f;
|
||||
|
||||
PxRigidDynamic* createDynamic(const PxTransform& t, const PxGeometry& geometry, const PxVec3& velocity=PxVec3(0))
|
||||
{
|
||||
PxRigidDynamic* dynamic = PxCreateDynamic(*gPhysics, t, geometry, *gMaterial, 10.0f);
|
||||
dynamic->setAngularDamping(0.5f);
|
||||
dynamic->setLinearVelocity(velocity);
|
||||
gScene->addActor(*dynamic);
|
||||
return dynamic;
|
||||
}
|
||||
|
||||
// spherical joint limited to an angle of at most pi/4 radians (45 degrees)
|
||||
PxJoint* createLimitedSpherical(PxRigidActor* a0, const PxTransform& t0, PxRigidActor* a1, const PxTransform& t1)
|
||||
{
|
||||
PxSphericalJoint* j = PxSphericalJointCreate(*gPhysics, a0, t0, a1, t1);
|
||||
j->setLimitCone(PxJointLimitCone(PxPi/4, PxPi/4, 0.05f));
|
||||
j->setSphericalJointFlag(PxSphericalJointFlag::eLIMIT_ENABLED, true);
|
||||
return j;
|
||||
}
|
||||
|
||||
// revolute joint limited to an angle of at most pi/4 radians (45 degrees)
|
||||
|
||||
// fixed, breakable joint
|
||||
PxJoint* createBreakableFixed(PxRigidActor* a0, const PxTransform& t0, PxRigidActor* a1, const PxTransform& t1)
|
||||
{
|
||||
PxFixedJoint* j = PxFixedJointCreate(*gPhysics, a0, t0, a1, t1);
|
||||
j->setBreakForce(1000, 100000);
|
||||
j->setConstraintFlag(PxConstraintFlag::eDRIVE_LIMITS_ARE_FORCES, true);
|
||||
j->setConstraintFlag(PxConstraintFlag::eDISABLE_PREPROCESSING, true);
|
||||
return j;
|
||||
}
|
||||
|
||||
// D6 joint with a spring maintaining its position
|
||||
PxJoint* createDampedD6(PxRigidActor* a0, const PxTransform& t0, PxRigidActor* a1, const PxTransform& t1)
|
||||
{
|
||||
PxD6Joint* j = PxD6JointCreate(*gPhysics, a0, t0, a1, t1);
|
||||
j->setMotion(PxD6Axis::eSWING1, PxD6Motion::eFREE);
|
||||
j->setMotion(PxD6Axis::eSWING2, PxD6Motion::eFREE);
|
||||
j->setMotion(PxD6Axis::eTWIST, PxD6Motion::eFREE);
|
||||
j->setDrive(PxD6Drive::eSLERP, PxD6JointDrive(0, 1000, FLT_MAX, true));
|
||||
return j;
|
||||
}
|
||||
|
||||
typedef PxJoint* (*JointCreateFunction)(PxRigidActor* a0, const PxTransform& t0, PxRigidActor* a1, const PxTransform& t1);
|
||||
|
||||
// create a chain rooted at the origin and extending along the x-axis, all transformed by the argument t.
|
||||
|
||||
void createChain(const PxTransform& t, PxU32 length, const PxGeometry& g, PxReal separation, JointCreateFunction createJoint)
|
||||
{
|
||||
PxVec3 offset(separation/2, 0, 0);
|
||||
PxTransform localTm(offset);
|
||||
PxRigidDynamic* prev = NULL;
|
||||
|
||||
for(PxU32 i=0;i<length;i++)
|
||||
{
|
||||
PxRigidDynamic* current = PxCreateDynamic(*gPhysics, t*localTm, g, *gMaterial, 1.0f);
|
||||
(*createJoint)(prev, prev ? PxTransform(offset) : t, current, PxTransform(-offset));
|
||||
gScene->addActor(*current);
|
||||
prev = current;
|
||||
localTm.p.x += separation;
|
||||
}
|
||||
}
|
||||
|
||||
void initPhysics(bool /*interactive*/)
|
||||
{
|
||||
gFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gAllocator, gErrorCallback);
|
||||
gPvd = PxCreatePvd(*gFoundation);
|
||||
PxPvdTransport* transport = PxDefaultPvdSocketTransportCreate(PVD_HOST, 5425, 10);
|
||||
gPvd->connect(*transport,PxPvdInstrumentationFlag::eALL);
|
||||
|
||||
gPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, PxTolerancesScale(),true, gPvd);
|
||||
PxInitExtensions(*gPhysics, gPvd);
|
||||
|
||||
PxSceneDesc sceneDesc(gPhysics->getTolerancesScale());
|
||||
sceneDesc.gravity = PxVec3(0.0f, -9.81f, 0.0f);
|
||||
gDispatcher = PxDefaultCpuDispatcherCreate(2);
|
||||
sceneDesc.cpuDispatcher = gDispatcher;
|
||||
sceneDesc.filterShader = PxDefaultSimulationFilterShader;
|
||||
gScene = gPhysics->createScene(sceneDesc);
|
||||
|
||||
PxPvdSceneClient* pvdClient = gScene->getScenePvdClient();
|
||||
if(pvdClient)
|
||||
{
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONSTRAINTS, true);
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONTACTS, true);
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_SCENEQUERIES, true);
|
||||
}
|
||||
|
||||
gMaterial = gPhysics->createMaterial(0.5f, 0.5f, 0.6f);
|
||||
|
||||
PxRigidStatic* groundPlane = PxCreatePlane(*gPhysics, PxPlane(0,1,0,0), *gMaterial);
|
||||
gScene->addActor(*groundPlane);
|
||||
|
||||
createChain(PxTransform(PxVec3(0.0f, 20.0f, 0.0f)), 5, PxBoxGeometry(2.0f, 0.5f, 0.5f), 4.0f, createLimitedSpherical);
|
||||
createChain(PxTransform(PxVec3(0.0f, 20.0f, -10.0f)), 5, PxBoxGeometry(2.0f, 0.5f, 0.5f), 4.0f, createBreakableFixed);
|
||||
createChain(PxTransform(PxVec3(0.0f, 20.0f, -20.0f)), 5, PxBoxGeometry(2.0f, 0.5f, 0.5f), 4.0f, createDampedD6);
|
||||
}
|
||||
|
||||
void stepPhysics(bool /*interactive*/)
|
||||
{
|
||||
gScene->simulate(1.0f/60.0f);
|
||||
gScene->fetchResults(true);
|
||||
}
|
||||
|
||||
void cleanupPhysics(bool /*interactive*/)
|
||||
{
|
||||
PX_RELEASE(gScene);
|
||||
PX_RELEASE(gDispatcher);
|
||||
PxCloseExtensions();
|
||||
PX_RELEASE(gPhysics);
|
||||
if(gPvd)
|
||||
{
|
||||
PxPvdTransport* transport = gPvd->getTransport();
|
||||
gPvd->release(); gPvd = NULL;
|
||||
PX_RELEASE(transport);
|
||||
}
|
||||
PX_RELEASE(gFoundation);
|
||||
|
||||
printf("SnippetJoint done.\n");
|
||||
}
|
||||
|
||||
void keyPress(unsigned char key, const PxTransform& camera)
|
||||
{
|
||||
switch(toupper(key))
|
||||
{
|
||||
case ' ': createDynamic(camera, PxSphereGeometry(3.0f), camera.rotate(PxVec3(0,0,-1))*200); break;
|
||||
}
|
||||
}
|
||||
|
||||
int snippetMain(int, const char*const*)
|
||||
{
|
||||
#ifdef RENDER_SNIPPET
|
||||
extern void renderLoop();
|
||||
renderLoop();
|
||||
#else
|
||||
static const PxU32 frameCount = 100;
|
||||
initPhysics(false);
|
||||
for(PxU32 i=0; i<frameCount; i++)
|
||||
stepPhysics(false);
|
||||
cleanupPhysics(false);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
120
physx/snippets/snippetjoint/SnippetJointRender.cpp
Normal file
120
physx/snippets/snippetjoint/SnippetJointRender.cpp
Normal file
@ -0,0 +1,120 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifdef RENDER_SNIPPET
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
|
||||
#include "../snippetrender/SnippetRender.h"
|
||||
#include "../snippetrender/SnippetCamera.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
extern void initPhysics(bool interactive);
|
||||
extern void stepPhysics(bool interactive);
|
||||
extern void cleanupPhysics(bool interactive);
|
||||
extern void keyPress(unsigned char key, const PxTransform& camera);
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
Snippets::Camera* sCamera;
|
||||
|
||||
void motionCallback(int x, int y)
|
||||
{
|
||||
sCamera->handleMotion(x, y);
|
||||
}
|
||||
|
||||
void keyboardCallback(unsigned char key, int x, int y)
|
||||
{
|
||||
if(key==27)
|
||||
exit(0);
|
||||
|
||||
if(!sCamera->handleKey(key, x, y))
|
||||
keyPress(key, sCamera->getTransform());
|
||||
}
|
||||
|
||||
void mouseCallback(int button, int state, int x, int y)
|
||||
{
|
||||
sCamera->handleMouse(button, state, x, y);
|
||||
}
|
||||
|
||||
void idleCallback()
|
||||
{
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
void renderCallback()
|
||||
{
|
||||
stepPhysics(true);
|
||||
|
||||
Snippets::startRender(sCamera->getEye(), sCamera->getDir());
|
||||
|
||||
PxScene* scene;
|
||||
PxGetPhysics().getScenes(&scene,1);
|
||||
PxU32 nbActors = scene->getNbActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC);
|
||||
if(nbActors)
|
||||
{
|
||||
std::vector<PxRigidActor*> actors(nbActors);
|
||||
scene->getActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC, reinterpret_cast<PxActor**>(&actors[0]), nbActors);
|
||||
Snippets::renderActors(&actors[0], static_cast<PxU32>(actors.size()), true);
|
||||
}
|
||||
|
||||
Snippets::finishRender();
|
||||
}
|
||||
|
||||
void exitCallback(void)
|
||||
{
|
||||
delete sCamera;
|
||||
cleanupPhysics(true);
|
||||
}
|
||||
}
|
||||
|
||||
void renderLoop()
|
||||
{
|
||||
sCamera = new Snippets::Camera(PxVec3(50.0f, 50.0f, 50.0f), PxVec3(-0.6f,-0.2f,-0.7f));
|
||||
|
||||
Snippets::setupDefaultWindow("PhysX Snippet Joint");
|
||||
Snippets::setupDefaultRenderState();
|
||||
|
||||
glutIdleFunc(idleCallback);
|
||||
glutDisplayFunc(renderCallback);
|
||||
glutKeyboardFunc(keyboardCallback);
|
||||
glutMouseFunc(mouseCallback);
|
||||
glutMotionFunc(motionCallback);
|
||||
motionCallback(0,0);
|
||||
|
||||
atexit(exitCallback);
|
||||
|
||||
initPhysics(true);
|
||||
glutMainLoop();
|
||||
}
|
||||
#endif
|
||||
434
physx/snippets/snippetloadcollection/SnippetLoadCollection.cpp
Normal file
434
physx/snippets/snippetloadcollection/SnippetLoadCollection.cpp
Normal file
@ -0,0 +1,434 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
// ****************************************************************************
|
||||
// This snippet illustrates loading xml or binary serialized collections and instantiating the objects in a scene.
|
||||
//
|
||||
// It only compiles and runs on authoring platforms (windows, osx and linux).
|
||||
// The snippet supports connecting to PVD in order to display the scene.
|
||||
//
|
||||
// It is a simple command-line tool supporting the following options::
|
||||
// SnippetLoadCollection [--pvdhost=<ip address> ] [--pvdport=<ip port> ] [--pvdtimeout=<time ms> ] [--generateExampleFiles] <filename>...
|
||||
//
|
||||
// --pvdhost=<ip address> Defines ip address of PVD, default is 127.0.0.1
|
||||
// --pvdport=<ip port> Defines ip port of PVD, default is 5425
|
||||
// --pvdtimeout=<time ms> Defines time out of PVD, default is 10
|
||||
// --generateExampleFiles Generates a set of example files
|
||||
// <filename>... Input files containing serialized collections (either xml or binary)
|
||||
//
|
||||
// Multiple collection files can be specified. The snippet is currently restricted to load a list of collections which obey
|
||||
// the following rule: The first collection needs to be complete. All following collections - if any - may only maintain
|
||||
// dependencies to objects in the first collection.
|
||||
//
|
||||
// The set of example files that can be generated consists of
|
||||
// collection.xml|collection.bin: Can be used individually.
|
||||
// collectionA.xml|collectionA.bin: Can also be used individually but only contain materials and shapes without actors.
|
||||
// collectionB.xml|collectionB.bin: Need to be used together with collectionA files. The actors contained in collectionB
|
||||
// maintain references to objects in the collectionA.
|
||||
//
|
||||
// ****************************************************************************
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "../snippetcommon/SnippetPrint.h"
|
||||
#include "../snippetcommon/SnippetPVD.h"
|
||||
#include "../snippetutils/SnippetUtils.h"
|
||||
|
||||
#define MAX_INPUT_FILES 16
|
||||
|
||||
using namespace physx;
|
||||
|
||||
PxDefaultAllocator gAllocator;
|
||||
PxDefaultErrorCallback gErrorCallback;
|
||||
|
||||
PxFoundation* gFoundation = NULL;
|
||||
PxPhysics* gPhysics = NULL;
|
||||
PxCooking* gCooking = NULL;
|
||||
PxSerializationRegistry* gSerializationRegistry = NULL;
|
||||
|
||||
PxDefaultCpuDispatcher* gDispatcher = NULL;
|
||||
PxScene* gScene = NULL;
|
||||
|
||||
PxPvd* gPvd = NULL;
|
||||
|
||||
PxU8* gMemBlocks[MAX_INPUT_FILES];
|
||||
PxU32 gNbMemBlocks = 0;
|
||||
|
||||
struct CmdLineParameters
|
||||
{
|
||||
const char* pvdhost;
|
||||
PxU32 pvdport;
|
||||
PxU32 pvdtimeout;
|
||||
const char* inputFiles[MAX_INPUT_FILES];
|
||||
PxU32 nbFiles;
|
||||
bool generateExampleFiles;
|
||||
|
||||
CmdLineParameters() :
|
||||
pvdhost(PVD_HOST)
|
||||
, pvdport(5425)
|
||||
, pvdtimeout(10)
|
||||
, nbFiles(0)
|
||||
, generateExampleFiles(false)
|
||||
{}
|
||||
} gParameters;
|
||||
|
||||
static bool match(const char* opt, const char* ref)
|
||||
{
|
||||
std::string s1(opt);
|
||||
std::string s2(ref);
|
||||
return !s1.compare(0, s2.length(), s2);
|
||||
}
|
||||
|
||||
static void printHelpMsg()
|
||||
{
|
||||
printf("SnippetLoadCollection usage:\n"
|
||||
"SnippetLoadCollection "
|
||||
"[--pvdhost=<ip address> ] "
|
||||
"[--pvdport=<ip port> ]"
|
||||
"[--pvdtimeout=<time ms> ] "
|
||||
"[--generateExampleFiles]"
|
||||
"<filename>...\n\n"
|
||||
"Load binary or xml serialized collections and instatiate the objects in a PhysX scene.\n");
|
||||
|
||||
printf("--pvdhost=<ip address> \n");
|
||||
printf(" Defines ip address of PVD, default is 127.0.0.1 \n");
|
||||
|
||||
printf("--pvdport=<ip port> \n");
|
||||
printf(" Defines ip port of PVD, default is 5425\n");
|
||||
|
||||
printf("--pvdtimeout=<time ms> \n");
|
||||
printf(" Defines timeout of PVD, default is 10\n");
|
||||
|
||||
printf("--generateExampleFiles\n");
|
||||
printf(" Generates a set of example files\n");
|
||||
|
||||
printf("<filename>...\n");
|
||||
printf(" Input files (xml or binary), if a collection contains shared objects, it needs to be provided with the first file. \n\n");
|
||||
|
||||
}
|
||||
|
||||
static bool parseCommandLine(CmdLineParameters& result, int argc, const char *const*argv)
|
||||
{
|
||||
if( argc <= 1 )
|
||||
{
|
||||
printHelpMsg();
|
||||
return false;
|
||||
}
|
||||
|
||||
for(int i = 1; i < argc; ++i)
|
||||
{
|
||||
if(argv[i][0] != '-' || argv[i][1] != '-')
|
||||
{
|
||||
if (result.nbFiles < MAX_INPUT_FILES)
|
||||
{
|
||||
result.inputFiles[result.nbFiles++] = argv[i];
|
||||
}
|
||||
else
|
||||
printf( "[WARNING] more input files are specified than supported (maximum %d). Ignoring the file %s\n", MAX_INPUT_FILES, argv[i] );
|
||||
}
|
||||
else if(match(argv[i], "--pvdhost="))
|
||||
{
|
||||
const char* hostStr = argv[i] + strlen("--pvdhost=");
|
||||
if(hostStr)
|
||||
result.pvdhost = hostStr;
|
||||
}
|
||||
else if(match(argv[i], "--pvdport="))
|
||||
{
|
||||
const char* portStr = argv[i] + strlen("--pvdport=");
|
||||
if (portStr)
|
||||
result.pvdport = PxU32(atoi(portStr));
|
||||
}
|
||||
else if(match(argv[i], "--pvdtimeout="))
|
||||
{
|
||||
const char* timeoutStr = argv[i] + strlen("--pvdtimeout=");
|
||||
if (timeoutStr)
|
||||
result.pvdtimeout = PxU32(atoi(timeoutStr));
|
||||
}
|
||||
else if(match(argv[i], "--generateExampleFiles"))
|
||||
{
|
||||
result.generateExampleFiles = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( "[ERROR] Unknown command line parameter \"%s\"\n", argv[i] );
|
||||
printHelpMsg();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(result.nbFiles == 0 && !result.generateExampleFiles)
|
||||
{
|
||||
printf( "[ERROR] parameter missing.\n" );
|
||||
printHelpMsg();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool checkFile(bool& isBinary, const char* filename)
|
||||
{
|
||||
PxDefaultFileInputData fileStream(filename);
|
||||
if (fileStream.getLength() == 0)
|
||||
{
|
||||
printf( "[ERROR] input file %s can't be opened!\n", filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
char testString[17];
|
||||
fileStream.read(testString, 16);
|
||||
testString[16] = 0;
|
||||
|
||||
if (strcmp("SEBD", testString) == 0)
|
||||
{
|
||||
isBinary = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (strcmp("<PhysXCollection", testString) == 0)
|
||||
{
|
||||
isBinary = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
printf( "[ERROR] input file %s seems neither an xml nor a binary serialized collection file!\n", filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
static PxCollection* deserializeCollection(PxInputData& inputData, bool isBinary, PxCollection* sharedCollection, PxSerializationRegistry& sr)
|
||||
{
|
||||
PxCollection* collection = NULL;
|
||||
if(isBinary)
|
||||
{
|
||||
PxU32 length = inputData.getLength();
|
||||
PxU8* memBlock = static_cast<PxU8*>(malloc(length+PX_SERIAL_FILE_ALIGN-1));
|
||||
gMemBlocks[gNbMemBlocks++] = memBlock;
|
||||
void* alignedBlock = reinterpret_cast<void*>((size_t(memBlock)+PX_SERIAL_FILE_ALIGN-1)&~(PX_SERIAL_FILE_ALIGN-1));
|
||||
inputData.read(alignedBlock, length);
|
||||
collection = PxSerialization::createCollectionFromBinary(alignedBlock, sr, sharedCollection);
|
||||
}
|
||||
else
|
||||
{
|
||||
collection = PxSerialization::createCollectionFromXml(inputData, *gCooking, sr, sharedCollection);
|
||||
}
|
||||
|
||||
return collection;
|
||||
}
|
||||
|
||||
void initPhysics()
|
||||
{
|
||||
gFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gAllocator, gErrorCallback);
|
||||
|
||||
gPvd = PxCreatePvd(*gFoundation);
|
||||
PxPvdTransport* transport = PxDefaultPvdSocketTransportCreate(PVD_HOST, 5425, 10);
|
||||
gPvd->connect(*transport,PxPvdInstrumentationFlag::eALL);
|
||||
|
||||
gPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, PxTolerancesScale(), true, gPvd);
|
||||
PxInitExtensions(*gPhysics, gPvd);
|
||||
|
||||
PxSceneDesc sceneDesc(gPhysics->getTolerancesScale());
|
||||
sceneDesc.gravity = PxVec3(0, -9.81f, 0);
|
||||
gDispatcher = PxDefaultCpuDispatcherCreate(1);
|
||||
sceneDesc.cpuDispatcher = gDispatcher;
|
||||
sceneDesc.filterShader = PxDefaultSimulationFilterShader;
|
||||
gScene = gPhysics->createScene(sceneDesc);
|
||||
|
||||
PxPvdSceneClient* pvdClient = gScene->getScenePvdClient();
|
||||
if(pvdClient)
|
||||
{
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONSTRAINTS, true);
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONTACTS, true);
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_SCENEQUERIES, true);
|
||||
}
|
||||
|
||||
gCooking = PxCreateCooking(PX_PHYSICS_VERSION, *gFoundation, PxCookingParams(PxTolerancesScale()));
|
||||
|
||||
gSerializationRegistry = PxSerialization::createSerializationRegistry(*gPhysics);
|
||||
|
||||
}
|
||||
|
||||
void cleanupPhysics()
|
||||
{
|
||||
PX_RELEASE(gSerializationRegistry);
|
||||
PX_RELEASE(gScene);
|
||||
PX_RELEASE(gDispatcher);
|
||||
PxCloseExtensions();
|
||||
|
||||
PX_RELEASE(gPhysics); // releases of all objects
|
||||
PX_RELEASE(gCooking);
|
||||
|
||||
for(PxU32 i=0; i<gNbMemBlocks; i++)
|
||||
free(gMemBlocks[i]); // now that the objects have been released, it's safe to release the space they occupy
|
||||
|
||||
if(gPvd)
|
||||
{
|
||||
PxPvdTransport* transport = gPvd->getTransport();
|
||||
gPvd->release(); gPvd = NULL;
|
||||
PX_RELEASE(transport);
|
||||
}
|
||||
|
||||
PX_RELEASE(gFoundation);
|
||||
|
||||
printf("SnippetLoadCollection done.\n");
|
||||
}
|
||||
|
||||
static void serializeCollection(PxCollection& collection, PxCollection* externalRefs, const char* filename, bool toBinary)
|
||||
{
|
||||
PxDefaultFileOutputStream outputStream(filename);
|
||||
if (!outputStream.isValid())
|
||||
{
|
||||
printf( "[ERROR] Could not open file %s!\n", filename);
|
||||
return;
|
||||
}
|
||||
|
||||
bool bret;
|
||||
if (toBinary)
|
||||
{
|
||||
bret = PxSerialization::serializeCollectionToBinary(outputStream, collection, *gSerializationRegistry, externalRefs);
|
||||
}
|
||||
else
|
||||
{
|
||||
bret = PxSerialization::serializeCollectionToXml(outputStream, collection, *gSerializationRegistry, NULL, externalRefs);
|
||||
}
|
||||
|
||||
if(bret)
|
||||
printf( "Generated: \"%s\"\n", filename);
|
||||
else
|
||||
printf( "[ERROR] Failure when generating %s!\n", filename);
|
||||
}
|
||||
|
||||
static void generateExampleFiles()
|
||||
{
|
||||
PxCollection* collection = PxCreateCollection();
|
||||
PxCollection* collectionA = PxCreateCollection();
|
||||
PxCollection* collectionB = PxCreateCollection();
|
||||
PX_ASSERT( (collection != NULL) && (collectionA != NULL) && (collectionB != NULL) );
|
||||
|
||||
PxMaterial *material = gPhysics->createMaterial(0.5f, 0.5f, 0.6f);
|
||||
PX_ASSERT( material );
|
||||
PxShape* planeShape = gPhysics->createShape(PxPlaneGeometry(), *material);
|
||||
PxShape* boxShape = gPhysics->createShape(PxBoxGeometry(2.f, 2.f, 2.f), *material);
|
||||
PxRigidStatic* rigidStatic = PxCreateStatic(*gPhysics, PxTransform(PxVec3(0.f, 0.f, 0.f), PxQuat(PxHalfPi, PxVec3(0.f, 0.f, 1.f))), *planeShape);
|
||||
PxRigidDynamic* rigidDynamic = PxCreateDynamic(*gPhysics, PxTransform(PxVec3(0.f, 2.f, 0.f)), *boxShape, 1.f);
|
||||
|
||||
collection->add(*material);
|
||||
collection->add(*planeShape);
|
||||
collection->add(*boxShape);
|
||||
collection->add(*rigidStatic);
|
||||
collection->add(*rigidDynamic);
|
||||
PxSerialization::complete(*collection, *gSerializationRegistry);
|
||||
PX_ASSERT(PxSerialization::isSerializable(*collection, *gSerializationRegistry));
|
||||
|
||||
collectionA->add(*material);
|
||||
collectionA->add(*planeShape);
|
||||
collectionA->add(*boxShape);
|
||||
PxSerialization::complete(*collectionA, *gSerializationRegistry);
|
||||
PxSerialization::createSerialObjectIds(*collectionA, PxSerialObjectId(1));
|
||||
PX_ASSERT(PxSerialization::isSerializable(*collectionA, *gSerializationRegistry));
|
||||
|
||||
collectionB->add(*rigidStatic);
|
||||
collectionB->add(*rigidDynamic);
|
||||
PxSerialization::complete(*collectionB, *gSerializationRegistry, collectionA);
|
||||
PX_ASSERT(PxSerialization::isSerializable(*collectionB, *gSerializationRegistry, collectionA));
|
||||
|
||||
serializeCollection(*collection, NULL, "collection.xml", false);
|
||||
serializeCollection(*collectionA, NULL, "collectionA.xml", false);
|
||||
serializeCollection(*collectionB, collectionA, "collectionB.xml", false);
|
||||
serializeCollection(*collection, NULL, "collection.bin", true);
|
||||
serializeCollection(*collectionA, NULL, "collectionA.bin", true);
|
||||
serializeCollection(*collectionB, collectionA, "collectionB.bin", true);
|
||||
|
||||
collection->release();
|
||||
collectionA->release();
|
||||
collectionB->release();
|
||||
}
|
||||
|
||||
int snippetMain(int argc, const char *const* argv)
|
||||
{
|
||||
if(!parseCommandLine(gParameters, argc, argv))
|
||||
return 1;
|
||||
|
||||
initPhysics();
|
||||
|
||||
if(gParameters.generateExampleFiles)
|
||||
generateExampleFiles();
|
||||
|
||||
// collection that may have shared objects
|
||||
PxCollection* firstCollection = NULL;
|
||||
|
||||
for(PxU32 i=0; i<gParameters.nbFiles; i++)
|
||||
{
|
||||
const char* filename = gParameters.inputFiles[i];
|
||||
|
||||
bool isBinary;
|
||||
bool validFile = checkFile(isBinary, filename);
|
||||
|
||||
if (!validFile)
|
||||
break;
|
||||
|
||||
PxDefaultFileInputData inputStream(filename);
|
||||
PxCollection* collection = deserializeCollection(inputStream, isBinary, firstCollection, *gSerializationRegistry);
|
||||
if (!collection)
|
||||
{
|
||||
printf( "[ERROR] deserialization failure! filename: %s\n", filename);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( "Loaded: \"%s\"\n", filename);
|
||||
}
|
||||
|
||||
gScene->addCollection(*collection);
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
firstCollection = collection;
|
||||
}
|
||||
else
|
||||
{
|
||||
collection->release();
|
||||
}
|
||||
}
|
||||
|
||||
if (firstCollection)
|
||||
firstCollection->release();
|
||||
|
||||
for (unsigned i = 0; i < 20; i++)
|
||||
{
|
||||
gScene->simulate(1.0f/60.0f);
|
||||
gScene->fetchResults(true);
|
||||
}
|
||||
|
||||
cleanupPhysics();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
228
physx/snippets/snippetmbp/SnippetMBP.cpp
Normal file
228
physx/snippets/snippetmbp/SnippetMBP.cpp
Normal file
@ -0,0 +1,228 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
// ****************************************************************************
|
||||
// This snippet demonstrates the use of broad phase regions (MBP).
|
||||
//
|
||||
// It shows the setup of MBP and its regions. In this example 4 regions are setup
|
||||
// and set for the MBP. Created stacks are then simulated in multiple regions.
|
||||
// Note that current regions setup is not optimal, some objects get out of regions bounds.
|
||||
// In this case a warning is reported. It is possible to add PxBroadPhaseCallback
|
||||
// to scene to handle such cases.
|
||||
//
|
||||
// ****************************************************************************
|
||||
|
||||
#include <ctype.h>
|
||||
#include <vector>
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
|
||||
#include "../snippetutils/SnippetUtils.h"
|
||||
#include "../snippetcommon/SnippetPrint.h"
|
||||
#include "../snippetcommon/SnippetPVD.h"
|
||||
|
||||
|
||||
using namespace physx;
|
||||
|
||||
PxDefaultAllocator gAllocator;
|
||||
PxDefaultErrorCallback gErrorCallback;
|
||||
|
||||
PxFoundation* gFoundation = NULL;
|
||||
PxPhysics* gPhysics = NULL;
|
||||
|
||||
PxDefaultCpuDispatcher* gDispatcher = NULL;
|
||||
PxScene* gScene = NULL;
|
||||
|
||||
PxMaterial* gMaterial = NULL;
|
||||
|
||||
PxPvd* gPvd = NULL;
|
||||
|
||||
PxReal stackZ = 10.0f;
|
||||
|
||||
PxU32 gRegionHandles[4];
|
||||
|
||||
PxRigidDynamic* createDynamic(const PxTransform& t, const PxGeometry& geometry, const PxVec3& velocity=PxVec3(0))
|
||||
{
|
||||
PxRigidDynamic* dynamic = PxCreateDynamic(*gPhysics, t, geometry, *gMaterial, 10.0f);
|
||||
dynamic->setAngularDamping(0.5f);
|
||||
dynamic->setLinearVelocity(velocity);
|
||||
gScene->addActor(*dynamic);
|
||||
return dynamic;
|
||||
}
|
||||
|
||||
void createStack(const PxTransform& t, PxU32 size, PxReal halfExtent)
|
||||
{
|
||||
PxShape* shape = gPhysics->createShape(PxBoxGeometry(halfExtent, halfExtent, halfExtent), *gMaterial);
|
||||
for(PxU32 i=0; i<size;i++)
|
||||
{
|
||||
for(PxU32 j=0;j<size-i;j++)
|
||||
{
|
||||
PxTransform localTm(PxVec3(PxReal(j*2) - PxReal(size-i), PxReal(i*2+1), 0) * halfExtent);
|
||||
PxRigidDynamic* body = gPhysics->createRigidDynamic(t.transform(localTm));
|
||||
body->attachShape(*shape);
|
||||
PxRigidBodyExt::updateMassAndInertia(*body, 10.0f);
|
||||
gScene->addActor(*body);
|
||||
}
|
||||
}
|
||||
shape->release();
|
||||
}
|
||||
|
||||
class SnippetMBPBroadPhaseCallback : public physx::PxBroadPhaseCallback
|
||||
{
|
||||
std::vector<PxActor*> outOfBoundsActors;
|
||||
public:
|
||||
virtual void onObjectOutOfBounds(PxShape& /*shape*/, PxActor& actor)
|
||||
{
|
||||
PxU32 i = 0;
|
||||
for(; i < outOfBoundsActors.size(); ++i)
|
||||
{
|
||||
if(outOfBoundsActors[i] == &actor)
|
||||
break;
|
||||
}
|
||||
if(i == outOfBoundsActors.size())
|
||||
{
|
||||
outOfBoundsActors.push_back(&actor);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void onObjectOutOfBounds(PxAggregate& /*aggregate*/)
|
||||
{
|
||||
//This test does not use aggregates so no need to do anything here
|
||||
}
|
||||
|
||||
void purgeOutOfBoundsObjects()
|
||||
{
|
||||
for(PxU32 i = 0; i < outOfBoundsActors.size(); ++i)
|
||||
{
|
||||
outOfBoundsActors[i]->release();
|
||||
}
|
||||
outOfBoundsActors.clear();
|
||||
}
|
||||
} gBroadPhaseCallback;
|
||||
|
||||
|
||||
void initPhysics(bool interactive)
|
||||
{
|
||||
gFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gAllocator, gErrorCallback);
|
||||
gPvd = PxCreatePvd(*gFoundation);
|
||||
PxPvdTransport* transport = PxDefaultPvdSocketTransportCreate(PVD_HOST, 5425, 10);
|
||||
gPvd->connect(*transport,PxPvdInstrumentationFlag::eALL);
|
||||
|
||||
gPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, PxTolerancesScale(),true,gPvd);
|
||||
|
||||
PxSceneDesc sceneDesc(gPhysics->getTolerancesScale());
|
||||
sceneDesc.gravity = PxVec3(0.0f, -9.81f, 0.0f);
|
||||
|
||||
PxU32 numCores = SnippetUtils::getNbPhysicalCores();
|
||||
gDispatcher = PxDefaultCpuDispatcherCreate(numCores == 0 ? 0 : numCores - 1);
|
||||
sceneDesc.cpuDispatcher = gDispatcher;
|
||||
sceneDesc.filterShader = PxDefaultSimulationFilterShader;
|
||||
|
||||
sceneDesc.broadPhaseType = PxBroadPhaseType::eMBP;
|
||||
|
||||
gScene = gPhysics->createScene(sceneDesc);
|
||||
PxPvdSceneClient* pvdClient = gScene->getScenePvdClient();
|
||||
if(pvdClient)
|
||||
{
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONSTRAINTS, true);
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONTACTS, true);
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_SCENEQUERIES, true);
|
||||
}
|
||||
PxBroadPhaseRegion regions[4] =
|
||||
{
|
||||
{ PxBounds3(PxVec3(-100, -100, -100), PxVec3( 0, 100, 0)), reinterpret_cast<void*>(1) },
|
||||
{ PxBounds3(PxVec3(-100, -100, 0), PxVec3( 0, 100, 100)), reinterpret_cast<void*>(2) },
|
||||
{ PxBounds3(PxVec3( 0, -100, -100), PxVec3(100, 100, 0)), reinterpret_cast<void*>(3) },
|
||||
{ PxBounds3(PxVec3( 0, -100, 0), PxVec3(100, 100, 100)), reinterpret_cast<void*>(4) }
|
||||
};
|
||||
|
||||
for(PxU32 i=0;i<4;i++)
|
||||
gScene->addBroadPhaseRegion(regions[i]);
|
||||
|
||||
gScene->setBroadPhaseCallback(&gBroadPhaseCallback);
|
||||
|
||||
gMaterial = gPhysics->createMaterial(0.5f, 0.5f, 0.6f);
|
||||
|
||||
PxRigidStatic* groundPlane = PxCreatePlane(*gPhysics, PxPlane(0,1,0,0), *gMaterial);
|
||||
gScene->addActor(*groundPlane);
|
||||
|
||||
for(PxU32 i=0;i<5;i++)
|
||||
createStack(PxTransform(PxVec3(0,0,stackZ-=10.0f)), 10, 2.0f);
|
||||
|
||||
if(!interactive)
|
||||
createDynamic(PxTransform(PxVec3(0,40,100)), PxSphereGeometry(10), PxVec3(0,-50,-100));
|
||||
}
|
||||
|
||||
void stepPhysics(bool /*interactive*/)
|
||||
{
|
||||
gScene->simulate(1.0f/60.0f);
|
||||
gScene->fetchResults(true);
|
||||
gBroadPhaseCallback.purgeOutOfBoundsObjects();
|
||||
}
|
||||
|
||||
void cleanupPhysics(bool /*interactive*/)
|
||||
{
|
||||
PX_RELEASE(gScene);
|
||||
PX_RELEASE(gDispatcher);
|
||||
PX_RELEASE(gPhysics);
|
||||
if(gPvd)
|
||||
{
|
||||
PxPvdTransport* transport = gPvd->getTransport();
|
||||
gPvd->release(); gPvd = NULL;
|
||||
PX_RELEASE(transport);
|
||||
}
|
||||
PX_RELEASE(gFoundation);
|
||||
|
||||
printf("SnippetMBP done.\n");
|
||||
}
|
||||
|
||||
void keyPress(unsigned char key, const PxTransform& camera)
|
||||
{
|
||||
switch(toupper(key))
|
||||
{
|
||||
case 'B': createStack(PxTransform(PxVec3(0,0,stackZ-=10.0f)), 10, 2.0f); break;
|
||||
case ' ': createDynamic(camera, PxSphereGeometry(3.0f), camera.rotate(PxVec3(0,0,-1))*200); break;
|
||||
}
|
||||
}
|
||||
|
||||
int snippetMain(int, const char*const*)
|
||||
{
|
||||
#ifdef RENDER_SNIPPET
|
||||
extern void renderLoop();
|
||||
renderLoop();
|
||||
#else
|
||||
static const PxU32 frameCount = 100;
|
||||
initPhysics(false);
|
||||
for(PxU32 i=0; i<frameCount; i++)
|
||||
stepPhysics(false);
|
||||
cleanupPhysics(false);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
121
physx/snippets/snippetmbp/SnippetMBPRender.cpp
Normal file
121
physx/snippets/snippetmbp/SnippetMBPRender.cpp
Normal file
@ -0,0 +1,121 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifdef RENDER_SNIPPET
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
|
||||
#include "../snippetrender/SnippetRender.h"
|
||||
#include "../snippetrender/SnippetCamera.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
extern void initPhysics(bool interactive);
|
||||
extern void stepPhysics(bool interactive);
|
||||
extern void cleanupPhysics(bool interactive);
|
||||
extern void keyPress(unsigned char key, const PxTransform& camera);
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
Snippets::Camera* sCamera;
|
||||
|
||||
void motionCallback(int x, int y)
|
||||
{
|
||||
sCamera->handleMotion(x, y);
|
||||
}
|
||||
|
||||
void keyboardCallback(unsigned char key, int x, int y)
|
||||
{
|
||||
if(key==27)
|
||||
exit(0);
|
||||
|
||||
if(!sCamera->handleKey(key, x, y))
|
||||
keyPress(key, sCamera->getTransform());
|
||||
}
|
||||
|
||||
void mouseCallback(int button, int state, int x, int y)
|
||||
{
|
||||
sCamera->handleMouse(button, state, x, y);
|
||||
}
|
||||
|
||||
void idleCallback()
|
||||
{
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
void renderCallback()
|
||||
{
|
||||
stepPhysics(true);
|
||||
|
||||
Snippets::startRender(sCamera->getEye(), sCamera->getDir());
|
||||
|
||||
PxScene* scene;
|
||||
PxGetPhysics().getScenes(&scene,1);
|
||||
PxU32 nbActors = scene->getNbActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC);
|
||||
if(nbActors)
|
||||
{
|
||||
std::vector<PxRigidActor*> actors(nbActors);
|
||||
scene->getActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC, reinterpret_cast<PxActor**>(&actors[0]), nbActors);
|
||||
Snippets::renderActors(&actors[0], static_cast<PxU32>(actors.size()), true);
|
||||
}
|
||||
|
||||
Snippets::finishRender();
|
||||
}
|
||||
|
||||
void exitCallback(void)
|
||||
{
|
||||
delete sCamera;
|
||||
cleanupPhysics(true);
|
||||
}
|
||||
}
|
||||
|
||||
void renderLoop()
|
||||
{
|
||||
sCamera = new Snippets::Camera(PxVec3(50.0f, 50.0f, 50.0f), PxVec3(-0.6f,-0.2f,-0.7f));
|
||||
|
||||
Snippets::setupDefaultWindow("PhysX Snippet MBP");
|
||||
Snippets::setupDefaultRenderState();
|
||||
|
||||
glutIdleFunc(idleCallback);
|
||||
glutDisplayFunc(renderCallback);
|
||||
glutKeyboardFunc(keyboardCallback);
|
||||
glutMouseFunc(mouseCallback);
|
||||
glutMotionFunc(motionCallback);
|
||||
motionCallback(0,0);
|
||||
|
||||
atexit(exitCallback);
|
||||
|
||||
initPhysics(true);
|
||||
glutMainLoop();
|
||||
}
|
||||
|
||||
#endif
|
||||
264
physx/snippets/snippetmultithreading/SnippetMultiThreading.cpp
Normal file
264
physx/snippets/snippetmultithreading/SnippetMultiThreading.cpp
Normal file
@ -0,0 +1,264 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
|
||||
// ****************************************************************************
|
||||
// This snippet shows how to coordinate threads performing asynchronous
|
||||
// work during the scene simulation. After simulate() is called, user threads
|
||||
// are started that perform ray-casts against the scene. The call to
|
||||
// fetchResults() is delayed until all ray-casts have completed.
|
||||
// ****************************************************************************
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
|
||||
#include "../snippetutils/SnippetUtils.h"
|
||||
#include "../snippetcommon/SnippetPrint.h"
|
||||
#include "../snippetcommon/SnippetPVD.h"
|
||||
|
||||
|
||||
using namespace physx;
|
||||
|
||||
PxDefaultAllocator gAllocator;
|
||||
PxDefaultErrorCallback gErrorCallback;
|
||||
|
||||
PxFoundation* gFoundation = NULL;
|
||||
PxPhysics* gPhysics = NULL;
|
||||
|
||||
PxDefaultCpuDispatcher* gDispatcher = NULL;
|
||||
PxScene* gScene = NULL;
|
||||
|
||||
PxMaterial* gMaterial = NULL;
|
||||
|
||||
PxPvd* gPvd = NULL;
|
||||
|
||||
struct RaycastThread
|
||||
{
|
||||
SnippetUtils::Sync* mWorkReadySyncHandle;
|
||||
SnippetUtils::Thread* mThreadHandle;
|
||||
};
|
||||
const PxU32 gNumThreads = 1;
|
||||
RaycastThread gThreads[gNumThreads];
|
||||
|
||||
SnippetUtils::Sync* gWorkDoneSyncHandle;
|
||||
|
||||
const PxI32 gRayCount = 1024;
|
||||
volatile PxI32 gRaysAvailable;
|
||||
volatile PxI32 gRaysCompleted;
|
||||
|
||||
|
||||
static PxVec3 randVec3()
|
||||
{
|
||||
return (PxVec3(float(rand())/float(RAND_MAX),
|
||||
float(rand())/float(RAND_MAX),
|
||||
float(rand())/float(RAND_MAX))*2.0f - PxVec3(1.0f)).getNormalized();
|
||||
}
|
||||
|
||||
static void threadExecute(void* data)
|
||||
{
|
||||
RaycastThread* raycastThread = static_cast<RaycastThread*>(data);
|
||||
|
||||
// Perform random raycasts against the scene until stop.
|
||||
for(;;)
|
||||
{
|
||||
// Wait here for the sync to be set then reset the sync
|
||||
// to ensure that we only perform raycast work after the
|
||||
// sync has been set again.
|
||||
SnippetUtils::syncWait(raycastThread->mWorkReadySyncHandle);
|
||||
SnippetUtils::syncReset(raycastThread->mWorkReadySyncHandle);
|
||||
|
||||
// If the thread has been signaled to quit then exit this function.
|
||||
if (SnippetUtils::threadQuitIsSignalled(raycastThread->mThreadHandle))
|
||||
break;
|
||||
|
||||
// Perform a fixed number of random raycasts against the scene
|
||||
// and share the work between multiple threads.
|
||||
while (SnippetUtils::atomicDecrement(&gRaysAvailable) >= 0)
|
||||
{
|
||||
PxVec3 dir = randVec3();
|
||||
|
||||
PxRaycastBuffer buf;
|
||||
gScene->raycast(PxVec3(0.0f), dir.getNormalized(), 1000.0f, buf, PxHitFlag::eDEFAULT);
|
||||
|
||||
// If this is the last raycast then signal this to the main thread.
|
||||
if (SnippetUtils::atomicIncrement(&gRaysCompleted) == gRayCount)
|
||||
{
|
||||
SnippetUtils::syncSet(gWorkDoneSyncHandle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Quit the current thread.
|
||||
SnippetUtils::threadQuit(raycastThread->mThreadHandle);
|
||||
}
|
||||
|
||||
void createStack(const PxTransform& t, PxU32 size, PxReal halfExtent)
|
||||
{
|
||||
PxShape* shape = gPhysics->createShape(PxBoxGeometry(halfExtent, halfExtent, halfExtent), *gMaterial);
|
||||
for(PxU32 i=0; i<size;i++)
|
||||
{
|
||||
for(PxU32 j=0;j<size-i;j++)
|
||||
{
|
||||
PxTransform localTm(PxVec3(PxReal(j*2) - PxReal(size-i), PxReal(i*2+1), 0) * halfExtent);
|
||||
PxRigidDynamic* body = gPhysics->createRigidDynamic(t.transform(localTm));
|
||||
body->attachShape(*shape);
|
||||
PxRigidBodyExt::updateMassAndInertia(*body, 10.0f);
|
||||
gScene->addActor(*body);
|
||||
}
|
||||
}
|
||||
shape->release();
|
||||
}
|
||||
|
||||
void createPhysicsAndScene()
|
||||
{
|
||||
gFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gAllocator, gErrorCallback);
|
||||
|
||||
gPvd = PxCreatePvd(*gFoundation);
|
||||
PxPvdTransport* transport = PxDefaultPvdSocketTransportCreate(PVD_HOST, 5425, 10);
|
||||
gPvd->connect(*transport,PxPvdInstrumentationFlag::eALL);
|
||||
|
||||
gPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, PxTolerancesScale(),true,gPvd);
|
||||
gMaterial = gPhysics->createMaterial(0.5f, 0.5f, 0.6f);
|
||||
|
||||
PxSceneDesc sceneDesc(gPhysics->getTolerancesScale());
|
||||
sceneDesc.gravity = PxVec3(0.0f, -9.81f, 0.0f);
|
||||
|
||||
PxU32 numCores = SnippetUtils::getNbPhysicalCores();
|
||||
gDispatcher = PxDefaultCpuDispatcherCreate(numCores == 0 ? 0 : numCores - 1);
|
||||
sceneDesc.cpuDispatcher = gDispatcher;
|
||||
sceneDesc.filterShader = PxDefaultSimulationFilterShader;
|
||||
|
||||
gScene = gPhysics->createScene(sceneDesc);
|
||||
|
||||
PxRigidStatic* groundPlane = PxCreatePlane(*gPhysics, PxPlane(0,1,0,0), *gMaterial);
|
||||
gScene->addActor(*groundPlane);
|
||||
|
||||
for(PxU32 i=0;i<5;i++)
|
||||
createStack(PxTransform(PxVec3(0,0,i*10.0f)), 10, 2.0f);
|
||||
}
|
||||
|
||||
void createRaycastThreads()
|
||||
{
|
||||
// Create and start threads that will perform raycasts.
|
||||
// Create a sync for each thread so that a signal may be sent
|
||||
// from the main thread to the raycast thread that it can start
|
||||
// performing raycasts.
|
||||
for (PxU32 i=0; i < gNumThreads; ++i)
|
||||
{
|
||||
//Create a sync.
|
||||
gThreads[i].mWorkReadySyncHandle = SnippetUtils::syncCreate();
|
||||
|
||||
//Create and start a thread.
|
||||
gThreads[i].mThreadHandle = SnippetUtils::threadCreate(threadExecute, &gThreads[i]);
|
||||
}
|
||||
|
||||
// Create another sync so that the raycast threads can signal to the main
|
||||
// thread that they have finished performing their raycasts.
|
||||
gWorkDoneSyncHandle = SnippetUtils::syncCreate();
|
||||
}
|
||||
|
||||
void initPhysics()
|
||||
{
|
||||
createPhysicsAndScene();
|
||||
createRaycastThreads();
|
||||
}
|
||||
|
||||
void stepPhysics()
|
||||
{
|
||||
// Start simulation
|
||||
gScene->simulate(1.0f/60.0f);
|
||||
|
||||
// Start ray-cast threads
|
||||
gRaysAvailable = gRayCount;
|
||||
gRaysCompleted = 0;
|
||||
|
||||
// Signal to each raycast thread that they can start performing raycasts.
|
||||
for (PxU32 i=0; i < gNumThreads; ++i)
|
||||
{
|
||||
SnippetUtils::syncSet(gThreads[i].mWorkReadySyncHandle);
|
||||
}
|
||||
|
||||
// Wait for raycast threads to finish.
|
||||
SnippetUtils::syncWait(gWorkDoneSyncHandle);
|
||||
SnippetUtils::syncReset(gWorkDoneSyncHandle);
|
||||
|
||||
// Fetch simulation results
|
||||
gScene->fetchResults(true);
|
||||
}
|
||||
|
||||
void cleanupPhysics()
|
||||
{
|
||||
// Signal threads to quit.
|
||||
for (PxU32 i=0; i < gNumThreads; ++i)
|
||||
{
|
||||
SnippetUtils::threadSignalQuit(gThreads[i].mThreadHandle);
|
||||
SnippetUtils::syncSet(gThreads[i].mWorkReadySyncHandle);
|
||||
}
|
||||
|
||||
// Clean up raycast threads and syncs.
|
||||
for (PxU32 i=0; i < gNumThreads; ++i)
|
||||
{
|
||||
SnippetUtils::threadWaitForQuit(gThreads[i].mThreadHandle);
|
||||
SnippetUtils::threadRelease(gThreads[i].mThreadHandle);
|
||||
SnippetUtils::syncRelease(gThreads[i].mWorkReadySyncHandle);
|
||||
}
|
||||
|
||||
// Clean up the sync for the main thread.
|
||||
SnippetUtils::syncRelease(gWorkDoneSyncHandle);
|
||||
|
||||
PX_RELEASE(gScene);
|
||||
|
||||
PX_RELEASE(gDispatcher);
|
||||
|
||||
PX_RELEASE(gPhysics);
|
||||
if(gPvd)
|
||||
{
|
||||
PxPvdTransport* transport = gPvd->getTransport();
|
||||
gPvd->release(); gPvd = NULL;
|
||||
PX_RELEASE(transport);
|
||||
}
|
||||
|
||||
PX_RELEASE(gFoundation);
|
||||
|
||||
printf("SnippetMultiThreading done.\n");
|
||||
}
|
||||
|
||||
int snippetMain(int, const char*const*)
|
||||
{
|
||||
initPhysics();
|
||||
|
||||
for(PxU32 i=0; i<100; ++i)
|
||||
stepPhysics();
|
||||
|
||||
cleanupPhysics();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
248
physx/snippets/snippetnestedscene/NestedScene.h
Normal file
248
physx/snippets/snippetnestedscene/NestedScene.h
Normal file
@ -0,0 +1,248 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
|
||||
|
||||
extern PxPhysics* gPhysics;
|
||||
extern PxDefaultCpuDispatcher* gDispatcher;
|
||||
extern PxMaterial* gMaterial;
|
||||
|
||||
#ifdef RENDER_SNIPPET
|
||||
void renderScene(physx::PxScene *, physx::PxRigidActor * frame, const physx::PxVec3 & color);
|
||||
#endif
|
||||
|
||||
class NestedScene : public PxSimulationEventCallback
|
||||
{
|
||||
public:
|
||||
NestedScene(PxRigidDynamic* containingActor) : mContainingActor(containingActor), lastLVel(PxZero), lastAVel(PxZero)
|
||||
{
|
||||
//create contained scene
|
||||
PxSceneDesc sceneDesc(gPhysics->getTolerancesScale());
|
||||
sceneDesc.cpuDispatcher = gDispatcher;
|
||||
sceneDesc.filterShader = PxDefaultSimulationFilterShader;
|
||||
sceneDesc.simulationEventCallback = this;
|
||||
sceneDesc.gravity = PxVec3(0.0f, -9.81f, 0.0f);
|
||||
mScene = gPhysics->createScene(sceneDesc);
|
||||
|
||||
//create the static environment of the contained scene out of the containing actor's geometry
|
||||
//this could be any other arbitrary geometry too though
|
||||
|
||||
|
||||
{
|
||||
//the truck bed
|
||||
PxShape* shape = gPhysics->createShape(PxBoxGeometry(1.8f, 0.25f, 4.5f), *gMaterial);
|
||||
PxRigidStatic * staticActor = gPhysics->createRigidStatic(PxTransform(PxVec3(0.0f, 1.0f, 0.0f)));
|
||||
staticActor->attachShape(*shape);
|
||||
mScene->addActor(*staticActor);
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
//the cabin of the truck
|
||||
PxShape* shape = gPhysics->createShape(PxBoxGeometry(1.7f, 0.5f, 0.9f), *gMaterial);
|
||||
PxRigidStatic * staticActor = gPhysics->createRigidStatic(PxTransform(PxVec3(0.0f, 1.75f, 2.5f)));
|
||||
staticActor->attachShape(*shape);
|
||||
mScene->addActor(*staticActor);
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
//some detail thingie on the cabin
|
||||
PxShape* shape = gPhysics->createShape(PxSphereGeometry(0.5f), *gMaterial);
|
||||
PxRigidStatic * staticActor = gPhysics->createRigidStatic(PxTransform(PxVec3(0.6f, 2.25f, 2.75f)));
|
||||
staticActor->attachShape(*shape);
|
||||
mScene->addActor(*staticActor);
|
||||
}
|
||||
|
||||
{
|
||||
//a trigger shape around the truck bed. If shapes leave this, they move to the main scene.
|
||||
PxShape* shape = gPhysics->createShape(PxBoxGeometry(1.8f, 3.0f, 4.5f), *gMaterial);
|
||||
shape->setFlag(PxShapeFlag::eSIMULATION_SHAPE, false);
|
||||
shape->setFlag(PxShapeFlag::eTRIGGER_SHAPE, true);
|
||||
PxRigidStatic * staticActor = gPhysics->createRigidStatic(PxTransform(PxVec3(0.0f, 1.0f, 0.0f)));
|
||||
staticActor->attachShape(*shape);
|
||||
mScene->addActor(*staticActor);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
~NestedScene()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void createBoxStack()
|
||||
{
|
||||
//create a box stack inside the scene
|
||||
|
||||
createStack(PxTransform(PxVec3(0.0f, 3.0f, 0.0f)), 3, 0.4f);
|
||||
|
||||
//TODO
|
||||
}
|
||||
|
||||
void simulate(PxScene * , PxF32 timeStep)
|
||||
{
|
||||
//1) mirror reference actor accelerations into scene
|
||||
|
||||
if (!mContainingActor->isSleeping())
|
||||
{
|
||||
PxVec3 lvel = mContainingActor->getLinearVelocity();
|
||||
PxVec3 avel = mContainingActor->getAngularVelocity();
|
||||
|
||||
//note that this is actually -acc.
|
||||
PxVec3 lacc = lastLVel - lvel;
|
||||
//PxVec3 aacc = lastAVel - avel;
|
||||
|
||||
lastLVel = lvel;
|
||||
lastAVel = avel;
|
||||
|
||||
|
||||
//special sauce:
|
||||
//filter out vertical movement due to suspension travel, otherwise the ride is too bumpy
|
||||
lacc.y = 0.0f;
|
||||
//decrease the rest of the acceleration by a bit
|
||||
lacc *= 0.7f;
|
||||
|
||||
|
||||
if (lacc.magnitudeSquared() > 0.01f) //let things sleep if the accel is too small
|
||||
{
|
||||
PxU32 nbActors = mScene->getNbActors(PxActorTypeFlag::eRIGID_DYNAMIC);
|
||||
if(nbActors)
|
||||
{
|
||||
std::vector<PxActor*> actors(nbActors);
|
||||
mScene->getActors(PxActorTypeFlag::eRIGID_DYNAMIC, &actors[0], nbActors);
|
||||
|
||||
for(PxU32 i=0;i<nbActors;i++)
|
||||
{
|
||||
actors[i]->is<PxRigidBody>()->addForce(lacc, PxForceMode::eVELOCITY_CHANGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
lastLVel = PxVec3(PxZero);
|
||||
lastAVel = PxVec3(PxZero);
|
||||
}
|
||||
|
||||
//2) simulate scene
|
||||
mScene->simulate(timeStep);
|
||||
mScene->fetchResults(true);
|
||||
|
||||
//move actors that have dropped off the truck out into the main scene
|
||||
|
||||
for(PxU32 i=0;i<removalQueue.size();i++)
|
||||
{
|
||||
mScene->removeActor(*removalQueue[i]);
|
||||
|
||||
//transform to the parent frame:
|
||||
PxTransform localPose = removalQueue[i]->getGlobalPose();
|
||||
PxTransform parentFrame = mContainingActor->getGlobalPose();
|
||||
removalQueue[i]->setGlobalPose(parentFrame * localPose);
|
||||
mContainingActor->getScene()->addActor(*removalQueue[i]);
|
||||
|
||||
}
|
||||
removalQueue.clear();
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
void render()
|
||||
{
|
||||
#ifdef RENDER_SNIPPET
|
||||
renderScene(mScene, mContainingActor, PxVec3(0.54f, 0.85f, 0.1f));
|
||||
#endif
|
||||
}
|
||||
|
||||
//simulation event callback -- we only need trigger:
|
||||
void onConstraintBreak(PxConstraintInfo* , PxU32 ) { }
|
||||
void onWake(PxActor** , PxU32 ) { }
|
||||
void onSleep(PxActor** , PxU32 ) { }
|
||||
void onContact(const PxContactPairHeader& , const PxContactPair* , PxU32 ) { }
|
||||
void onTrigger(PxTriggerPair* pairs, PxU32 count)
|
||||
{
|
||||
for(PxU32 i=0; i < count; i++)
|
||||
{
|
||||
// ignore pairs when shapes have been deleted
|
||||
if (pairs[i].status & PxPairFlag::eNOTIFY_TOUCH_LOST)
|
||||
{
|
||||
//we're not allowed to make changes in the callback, so save it for later
|
||||
removalQueue.push_back(pairs[i].otherActor);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
void onAdvance(const PxRigidBody*const*, const PxTransform*, const PxU32) {}
|
||||
|
||||
private:
|
||||
|
||||
void createStack(const PxTransform& t, PxU32 size, PxReal halfExtent)
|
||||
{
|
||||
PxShape* shape = gPhysics->createShape(PxBoxGeometry(halfExtent, halfExtent, halfExtent), *gMaterial);
|
||||
|
||||
PxFilterData simFilterData;
|
||||
simFilterData.word0 = snippetvehicle::COLLISION_FLAG_OBSTACLE;
|
||||
simFilterData.word1 = snippetvehicle::COLLISION_FLAG_OBSTACLE_AGAINST;
|
||||
shape->setSimulationFilterData(simFilterData);
|
||||
|
||||
for(PxU32 i=0; i<size;i++)
|
||||
{
|
||||
for(PxU32 j=0;j<size-i;j++)
|
||||
{
|
||||
PxTransform localTm(PxVec3(PxReal(j*2) - PxReal(size-i), PxReal(i*2+1), 0) * halfExtent);
|
||||
PxRigidDynamic* body = gPhysics->createRigidDynamic(t.transform(localTm));
|
||||
body->attachShape(*shape);
|
||||
PxRigidBodyExt::updateMassAndInertia(*body, 10.0f);
|
||||
mScene->addActor(*body);
|
||||
}
|
||||
}
|
||||
shape->release();
|
||||
}
|
||||
|
||||
|
||||
|
||||
PxScene* mScene;
|
||||
PxRigidDynamic* mContainingActor;
|
||||
PxVec3 lastLVel;
|
||||
PxVec3 lastAVel;
|
||||
std::vector<PxRigidActor*> removalQueue;
|
||||
};
|
||||
|
||||
627
physx/snippets/snippetnestedscene/SnippetNestedScene.cpp
Normal file
627
physx/snippets/snippetnestedscene/SnippetNestedScene.cpp
Normal file
@ -0,0 +1,627 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
// ****************************************************************************
|
||||
// This snippet shows how to work with nested scenes.
|
||||
//
|
||||
// It is based on SnippetVehicleTank, which creates a tank-like vehicle
|
||||
// and drives it around.
|
||||
//
|
||||
// In this sample we add a cargo bed to the tank which contains a bunch of dynamic
|
||||
// crates. These crates have their own scene in order to reduce clutter in
|
||||
// the main scene and increase performance. The geometry of the cargo bed against
|
||||
// which the crates collide is also only in this 'nested scene' as static geometry.
|
||||
// Meanwhile the tank only uses a single dynamic box representation in the main scene.
|
||||
//
|
||||
// The objects in the tank's 'nested scene' are color coded green while the objects
|
||||
// in the main scene are colored red in order to visualize the distinction.
|
||||
//
|
||||
// In this sample the crates on the tank are tossed about by the motion of the tank
|
||||
// because we apply the velocity changes of the tank to the crates as external
|
||||
// impulses. These impulses can be scaled by the user to tune the precise
|
||||
// desired behavior.
|
||||
//
|
||||
// The crates can also fall off the truck bed and onto the ground. This is detected
|
||||
// by the sample by means of a trigger around the cargo bed. When crates leave
|
||||
// the cargo bed they are removed from the nested scene and added to the main scene.
|
||||
// There they collide with the ground plane and the tank's wheels as expected.
|
||||
//
|
||||
// In a real game one could additionally suspend simulation of the embedded scene if
|
||||
// the tank is far away from the player.
|
||||
//
|
||||
// ****************************************************************************
|
||||
|
||||
#include <vector>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
|
||||
#include "../snippetvehiclecommon/SnippetVehicleSceneQuery.h"
|
||||
#include "../snippetvehiclecommon/SnippetVehicleFilterShader.h"
|
||||
#include "../snippetvehiclecommon/SnippetVehicleTireFriction.h"
|
||||
#include "../snippetvehiclecommon/SnippetVehicleCreate.h"
|
||||
|
||||
#include "../snippetcommon/SnippetPrint.h"
|
||||
#include "../snippetcommon/SnippetPVD.h"
|
||||
#include "../snippetutils/SnippetUtils.h"
|
||||
|
||||
|
||||
using namespace physx;
|
||||
using namespace snippetvehicle;
|
||||
|
||||
|
||||
#include "NestedScene.h"
|
||||
|
||||
PxDefaultAllocator gAllocator;
|
||||
PxDefaultErrorCallback gErrorCallback;
|
||||
|
||||
PxFoundation* gFoundation = NULL;
|
||||
PxPhysics* gPhysics = NULL;
|
||||
|
||||
PxDefaultCpuDispatcher* gDispatcher = NULL;
|
||||
PxScene* gScene = NULL;
|
||||
|
||||
PxCooking* gCooking = NULL;
|
||||
|
||||
PxMaterial* gMaterial = NULL;
|
||||
|
||||
VehicleSceneQueryData* gVehicleSceneQueryData = NULL;
|
||||
PxBatchQuery* gBatchQuery = NULL;
|
||||
|
||||
PxVehicleDrivableSurfaceToTireFrictionPairs* gFrictionPairs = NULL;
|
||||
|
||||
PxRigidStatic* gGroundPlane = NULL;
|
||||
|
||||
PxPvd* gPvd = NULL;
|
||||
|
||||
PxF32 gTankModeLifetime = 4.0f;
|
||||
PxF32 gTankModeTimer = 0.0f;
|
||||
PxU32 gTankOrderProgress = 0;
|
||||
bool gTankOrderComplete = false;
|
||||
bool gMimicKeyInputs = false;
|
||||
|
||||
VehicleDesc initTankDesc();
|
||||
|
||||
class TankEntity
|
||||
{
|
||||
|
||||
public:
|
||||
TankEntity() : mVehicleDriveTank(NULL), mNestedScene(NULL)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
~TankEntity()
|
||||
{
|
||||
if (mNestedScene)
|
||||
{
|
||||
delete mNestedScene;
|
||||
mNestedScene = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void create()
|
||||
{
|
||||
PX_ASSERT(mVehicleDriveTank == NULL);
|
||||
PX_ASSERT(mNestedScene == NULL);
|
||||
|
||||
VehicleDesc tankDesc = initTankDesc();
|
||||
mVehicleDriveTank = createVehicleTank(tankDesc, gPhysics, gCooking);
|
||||
PxTransform startTransform(PxVec3(0, (tankDesc.chassisDims.y*0.5f + tankDesc.wheelRadius + 1.0f), 0), PxQuat(PxIdentity));
|
||||
mVehicleDriveTank->getRigidDynamicActor()->setGlobalPose(startTransform);
|
||||
gScene->addActor(*mVehicleDriveTank->getRigidDynamicActor());
|
||||
|
||||
//Set the tank to rest in first gear.
|
||||
//Set the tank to use auto-gears.
|
||||
//Set the tank to use the standard control model
|
||||
mVehicleDriveTank->setToRestState();
|
||||
mVehicleDriveTank->mDriveDynData.forceGearChange(PxVehicleGearsData::eFIRST);
|
||||
mVehicleDriveTank->mDriveDynData.setUseAutoGears(true);
|
||||
mVehicleDriveTank->setDriveModel(PxVehicleDriveTankControlModel::eSTANDARD);
|
||||
|
||||
mNestedScene = new NestedScene(mVehicleDriveTank->getRigidDynamicActor());
|
||||
|
||||
mNestedScene->createBoxStack(); //can create stuff inside that scene now ... let's say this is the cargo of the vehicle.
|
||||
|
||||
}
|
||||
|
||||
void simulate(PxScene * scene, PxF32 timeStep)
|
||||
{
|
||||
PX_ASSERT(mNestedScene != NULL);
|
||||
|
||||
mNestedScene->simulate(scene, timeStep);
|
||||
}
|
||||
|
||||
void render()
|
||||
{
|
||||
PX_ASSERT(mNestedScene != NULL);
|
||||
|
||||
mNestedScene->render();
|
||||
}
|
||||
|
||||
void reverse()
|
||||
{
|
||||
mVehicleDriveTank->mDriveDynData.forceGearChange(PxVehicleGearsData::eREVERSE);
|
||||
}
|
||||
|
||||
void forward()
|
||||
{
|
||||
mVehicleDriveTank->mDriveDynData.forceGearChange(PxVehicleGearsData::eFIRST);
|
||||
}
|
||||
|
||||
|
||||
PxVehicleDriveTank* getVehicleDriveTank() { return mVehicleDriveTank; }
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
||||
PxVehicleDriveTank* mVehicleDriveTank;
|
||||
NestedScene* mNestedScene;
|
||||
|
||||
} tankEntity;
|
||||
|
||||
|
||||
|
||||
PxVehicleKeySmoothingData gKeySmoothingData=
|
||||
{
|
||||
{
|
||||
6.0f, //rise rate eANALOG_INPUT_ACCEL=0,
|
||||
6.0f, //rise rate eANALOG_INPUT_BRAKE,
|
||||
6.0f, //rise rate eANALOG_INPUT_HANDBRAKE,
|
||||
2.5f, //rise rate eANALOG_INPUT_STEER_LEFT,
|
||||
2.5f, //rise rate eANALOG_INPUT_STEER_RIGHT,
|
||||
},
|
||||
{
|
||||
10.0f, //fall rate eANALOG_INPUT_ACCEL=0,
|
||||
10.0f, //fall rate eANALOG_INPUT_BRAKE,
|
||||
10.0f, //fall rate eANALOG_INPUT_HANDBRAKE,
|
||||
5.0f, //fall rate eANALOG_INPUT_STEER_LEFT,
|
||||
5.0f //fall rate eANALOG_INPUT_STEER_RIGHT,
|
||||
}
|
||||
};
|
||||
|
||||
PxVehiclePadSmoothingData gPadSmoothingData=
|
||||
{
|
||||
{
|
||||
6.0f, //rise rate eANALOG_INPUT_ACCEL=0,
|
||||
6.0f, //rise rate eANALOG_INPUT_BRAKE,
|
||||
6.0f, //rise rate eANALOG_INPUT_HANDBRAKE,
|
||||
2.5f, //rise rate eANALOG_INPUT_STEER_LEFT,
|
||||
2.5f, //rise rate eANALOG_INPUT_STEER_RIGHT,
|
||||
},
|
||||
{
|
||||
10.0f, //fall rate eANALOG_INPUT_ACCEL=0
|
||||
10.0f, //fall rate eANALOG_INPUT_BRAKE_LEFT
|
||||
10.0f, //fall rate eANALOG_INPUT_BRAKE_RIGHT
|
||||
5.0f, //fall rate eANALOG_INPUT_THRUST_LEFT
|
||||
5.0f //fall rate eANALOG_INPUT_THRUST_RIGHT
|
||||
}
|
||||
};
|
||||
|
||||
PxVehicleDriveTankRawInputData gVehicleInputData(PxVehicleDriveTankControlModel::eSTANDARD);
|
||||
|
||||
enum DriveMode
|
||||
{
|
||||
eDRIVE_MODE_ACCEL_FORWARDS=0,
|
||||
eDRIVE_MODE_ACCEL_REVERSE,
|
||||
eDRIVE_MODE_HARD_TURN_LEFT,
|
||||
eDRIVE_MODE_SOFT_TURN_LEFT,
|
||||
eDRIVE_MODE_HARD_TURN_RIGHT,
|
||||
eDRIVE_MODE_SOFT_TURN_RIGHT,
|
||||
eDRIVE_MODE_BRAKE,
|
||||
eDRIVE_MODE_NONE
|
||||
};
|
||||
|
||||
DriveMode gDriveModeOrder[] =
|
||||
{
|
||||
eDRIVE_MODE_BRAKE,
|
||||
eDRIVE_MODE_ACCEL_FORWARDS,
|
||||
eDRIVE_MODE_BRAKE,
|
||||
eDRIVE_MODE_ACCEL_REVERSE,
|
||||
eDRIVE_MODE_BRAKE,
|
||||
eDRIVE_MODE_HARD_TURN_LEFT,
|
||||
eDRIVE_MODE_BRAKE,
|
||||
eDRIVE_MODE_HARD_TURN_RIGHT,
|
||||
eDRIVE_MODE_BRAKE,
|
||||
eDRIVE_MODE_SOFT_TURN_LEFT,
|
||||
eDRIVE_MODE_BRAKE,
|
||||
eDRIVE_MODE_SOFT_TURN_RIGHT,
|
||||
eDRIVE_MODE_NONE
|
||||
};
|
||||
|
||||
VehicleDesc initTankDesc()
|
||||
{
|
||||
//Set up the chassis mass, dimensions, moment of inertia, and center of mass offset.
|
||||
//The moment of inertia is just the moment of inertia of a cuboid but modified for easier steering.
|
||||
//Center of mass offset is 0.65m above the base of the chassis and 0.25m towards the front.
|
||||
const PxF32 chassisMass = 1500.0f;
|
||||
const PxVec3 chassisDims(3.5f,2.0f,9.0f);
|
||||
const PxVec3 chassisMOI
|
||||
((chassisDims.y*chassisDims.y + chassisDims.z*chassisDims.z)*chassisMass/12.0f,
|
||||
(chassisDims.x*chassisDims.x + chassisDims.z*chassisDims.z)*0.8f*chassisMass/12.0f,
|
||||
(chassisDims.x*chassisDims.x + chassisDims.y*chassisDims.y)*chassisMass/12.0f);
|
||||
const PxVec3 chassisCMOffset(0.0f, -chassisDims.y*0.5f + 0.65f, 0.25f);
|
||||
|
||||
//Set up the wheel mass, radius, width, moment of inertia, and number of wheels.
|
||||
//Moment of inertia is just the moment of inertia of a cylinder.
|
||||
const PxF32 wheelMass = 20.0f;
|
||||
const PxF32 wheelRadius = 0.5f;
|
||||
const PxF32 wheelWidth = 0.4f;
|
||||
const PxF32 wheelMOI = 0.5f*wheelMass*wheelRadius*wheelRadius;
|
||||
const PxU32 nbWheels = 14;
|
||||
|
||||
VehicleDesc tankDesc;
|
||||
tankDesc.chassisMass = chassisMass;
|
||||
tankDesc.chassisDims = chassisDims;
|
||||
tankDesc.chassisMOI = chassisMOI;
|
||||
tankDesc.chassisCMOffset = chassisCMOffset;
|
||||
tankDesc.chassisMaterial = gMaterial;
|
||||
tankDesc.wheelMass = wheelMass;
|
||||
tankDesc.wheelRadius = wheelRadius;
|
||||
tankDesc.wheelWidth = wheelWidth;
|
||||
tankDesc.wheelMOI = wheelMOI;
|
||||
tankDesc.numWheels = nbWheels;
|
||||
tankDesc.wheelMaterial = gMaterial;
|
||||
return tankDesc;
|
||||
}
|
||||
|
||||
void startAccelerateForwardsMode()
|
||||
{
|
||||
if(gMimicKeyInputs)
|
||||
{
|
||||
gVehicleInputData.setDigitalAccel(true);
|
||||
gVehicleInputData.setDigitalLeftThrust(true);
|
||||
gVehicleInputData.setDigitalRightThrust(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
gVehicleInputData.setAnalogAccel(1.0f);
|
||||
gVehicleInputData.setAnalogLeftThrust(1.0f);
|
||||
gVehicleInputData.setAnalogRightThrust(1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void startAccelerateReverseMode()
|
||||
{
|
||||
tankEntity.reverse();
|
||||
|
||||
if(gMimicKeyInputs)
|
||||
{
|
||||
gVehicleInputData.setDigitalAccel(true);
|
||||
gVehicleInputData.setDigitalLeftThrust(true);
|
||||
gVehicleInputData.setDigitalRightThrust(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
gVehicleInputData.setAnalogAccel(1.0f);
|
||||
gVehicleInputData.setAnalogLeftThrust(1.0f);
|
||||
gVehicleInputData.setAnalogRightThrust(1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void startBrakeMode()
|
||||
{
|
||||
if(gMimicKeyInputs)
|
||||
{
|
||||
gVehicleInputData.setDigitalLeftBrake(true);
|
||||
gVehicleInputData.setDigitalRightBrake(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
gVehicleInputData.setAnalogLeftBrake(1.0f);
|
||||
gVehicleInputData.setAnalogRightBrake(1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void startTurnHardLeftMode()
|
||||
{
|
||||
if(gMimicKeyInputs)
|
||||
{
|
||||
gVehicleInputData.setDigitalAccel(true);
|
||||
gVehicleInputData.setDigitalLeftThrust(true);
|
||||
gVehicleInputData.setDigitalRightBrake(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
gVehicleInputData.setAnalogAccel(1.0f);
|
||||
gVehicleInputData.setAnalogLeftThrust(1.0f);
|
||||
gVehicleInputData.setAnalogRightBrake(1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void startTurnHardRightMode()
|
||||
{
|
||||
if(gMimicKeyInputs)
|
||||
{
|
||||
gVehicleInputData.setDigitalAccel(true);
|
||||
gVehicleInputData.setDigitalRightThrust(true);
|
||||
gVehicleInputData.setDigitalLeftBrake(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
gVehicleInputData.setAnalogAccel(1.0f);
|
||||
gVehicleInputData.setAnalogRightThrust(1.0f);
|
||||
gVehicleInputData.setAnalogLeftBrake(1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void startTurnSoftLeftMode()
|
||||
{
|
||||
if(gMimicKeyInputs)
|
||||
{
|
||||
gVehicleInputData.setDigitalAccel(true);
|
||||
gVehicleInputData.setDigitalLeftThrust(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
gVehicleInputData.setAnalogAccel(1.0f);
|
||||
gVehicleInputData.setAnalogLeftThrust(1.0f);
|
||||
gVehicleInputData.setAnalogRightThrust(0.3f);
|
||||
}
|
||||
}
|
||||
|
||||
void startTurnSoftRightMode()
|
||||
{
|
||||
if(gMimicKeyInputs)
|
||||
{
|
||||
gVehicleInputData.setDigitalAccel(true);
|
||||
gVehicleInputData.setDigitalRightThrust(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
gVehicleInputData.setAnalogAccel(1.0f);
|
||||
gVehicleInputData.setAnalogRightThrust(1.0f);
|
||||
gVehicleInputData.setAnalogLeftThrust(0.3f);
|
||||
}
|
||||
}
|
||||
|
||||
void releaseAllControls()
|
||||
{
|
||||
if(gMimicKeyInputs)
|
||||
{
|
||||
gVehicleInputData.setDigitalAccel(false);
|
||||
gVehicleInputData.setDigitalRightThrust(false);
|
||||
gVehicleInputData.setDigitalLeftThrust(false);
|
||||
gVehicleInputData.setDigitalRightBrake(false);
|
||||
gVehicleInputData.setDigitalLeftBrake(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
gVehicleInputData.setAnalogAccel(0.0f);
|
||||
gVehicleInputData.setAnalogRightThrust(0.0f);
|
||||
gVehicleInputData.setAnalogLeftThrust(0.0f);
|
||||
gVehicleInputData.setAnalogRightBrake(0.0f);
|
||||
gVehicleInputData.setAnalogLeftBrake(0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void initPhysics(bool /*interactive*/)
|
||||
{
|
||||
gFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gAllocator, gErrorCallback);
|
||||
|
||||
gPvd = PxCreatePvd(*gFoundation);
|
||||
PxPvdTransport* transport = PxDefaultPvdSocketTransportCreate(PVD_HOST, 5425, 10);
|
||||
gPvd->connect(*transport,PxPvdInstrumentationFlag::eALL);
|
||||
|
||||
gPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, PxTolerancesScale(),true, gPvd);
|
||||
PxSceneDesc sceneDesc(gPhysics->getTolerancesScale());
|
||||
sceneDesc.gravity = PxVec3(0.0f, -9.81f, 0.0f);
|
||||
|
||||
PxU32 numWorkers = 1;
|
||||
gDispatcher = PxDefaultCpuDispatcherCreate(numWorkers);
|
||||
sceneDesc.cpuDispatcher = gDispatcher;
|
||||
sceneDesc.filterShader = VehicleFilterShader;
|
||||
|
||||
gScene = gPhysics->createScene(sceneDesc);
|
||||
|
||||
PxPvdSceneClient* pvdClient = gScene->getScenePvdClient();
|
||||
if(pvdClient)
|
||||
{
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONSTRAINTS, true);
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONTACTS, true);
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_SCENEQUERIES, true);
|
||||
}
|
||||
|
||||
gMaterial = gPhysics->createMaterial(0.5f, 0.5f, 0.6f);
|
||||
|
||||
gCooking = PxCreateCooking(PX_PHYSICS_VERSION, *gFoundation, PxCookingParams(PxTolerancesScale()));
|
||||
|
||||
/////////////////////////////////////////////
|
||||
|
||||
PxInitVehicleSDK(*gPhysics);
|
||||
PxVehicleSetBasisVectors(PxVec3(0,1,0), PxVec3(0,0,1));
|
||||
PxVehicleSetUpdateMode(PxVehicleUpdateMode::eVELOCITY_CHANGE);
|
||||
|
||||
//Create the batched scene queries for the suspension raycasts.
|
||||
gVehicleSceneQueryData = VehicleSceneQueryData::allocate(1, PX_MAX_NB_WHEELS, 1, 1, WheelSceneQueryPreFilterBlocking, NULL, gAllocator);
|
||||
gBatchQuery = VehicleSceneQueryData::setUpBatchedSceneQuery(0, *gVehicleSceneQueryData, gScene);
|
||||
|
||||
//Create the friction table for each combination of tire and surface type.
|
||||
gFrictionPairs = createFrictionPairs(gMaterial);
|
||||
|
||||
//Create a plane to drive on.
|
||||
PxFilterData groundPlaneSimFilterData(COLLISION_FLAG_GROUND, COLLISION_FLAG_GROUND_AGAINST, 0, 0);
|
||||
gGroundPlane = createDrivablePlane(groundPlaneSimFilterData, gMaterial, gPhysics);
|
||||
gScene->addActor(*gGroundPlane);
|
||||
|
||||
//Create a tank that will drive on the plane.
|
||||
tankEntity.create();
|
||||
|
||||
|
||||
gTankModeTimer = 0.0f;
|
||||
gTankOrderProgress = 0;
|
||||
startBrakeMode();
|
||||
}
|
||||
|
||||
void incrementDrivingMode(const PxF32 timestep)
|
||||
{
|
||||
gTankModeTimer += timestep;
|
||||
if(gTankModeTimer > gTankModeLifetime)
|
||||
{
|
||||
//If the mode just completed was eDRIVE_MODE_ACCEL_REVERSE then switch back to forward gears.
|
||||
if(eDRIVE_MODE_ACCEL_REVERSE == gDriveModeOrder[gTankOrderProgress])
|
||||
{
|
||||
tankEntity.forward();
|
||||
}
|
||||
|
||||
//Increment to next driving mode.
|
||||
gTankModeTimer = 0.0f;
|
||||
gTankOrderProgress++;
|
||||
releaseAllControls();
|
||||
|
||||
//If we are at the end of the list of driving modes then start again.
|
||||
if(eDRIVE_MODE_NONE == gDriveModeOrder[gTankOrderProgress])
|
||||
{
|
||||
gTankOrderProgress = 0;
|
||||
gTankOrderComplete = true;
|
||||
}
|
||||
|
||||
//Start driving in the selected mode.
|
||||
DriveMode eDriveMode = gDriveModeOrder[gTankOrderProgress];
|
||||
switch(eDriveMode)
|
||||
{
|
||||
case eDRIVE_MODE_ACCEL_FORWARDS:
|
||||
startAccelerateForwardsMode();
|
||||
break;
|
||||
case eDRIVE_MODE_ACCEL_REVERSE:
|
||||
startAccelerateReverseMode();
|
||||
break;
|
||||
case eDRIVE_MODE_HARD_TURN_LEFT:
|
||||
startTurnHardLeftMode();
|
||||
break;
|
||||
case eDRIVE_MODE_SOFT_TURN_LEFT:
|
||||
startTurnSoftLeftMode();
|
||||
break;
|
||||
case eDRIVE_MODE_HARD_TURN_RIGHT:
|
||||
startTurnHardRightMode();
|
||||
break;
|
||||
case eDRIVE_MODE_SOFT_TURN_RIGHT:
|
||||
startTurnSoftRightMode();
|
||||
break;
|
||||
case eDRIVE_MODE_BRAKE:
|
||||
startBrakeMode();
|
||||
break;
|
||||
case eDRIVE_MODE_NONE:
|
||||
break;
|
||||
};
|
||||
|
||||
//If the mode about to start is eDRIVE_MODE_ACCEL_REVERSE then switch to reverse gears.
|
||||
if(eDRIVE_MODE_ACCEL_REVERSE == gDriveModeOrder[gTankOrderProgress])
|
||||
{
|
||||
tankEntity.reverse();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void stepPhysics(bool /*interactive*/)
|
||||
{
|
||||
const PxF32 timestep = 1.0f/60.0f;
|
||||
|
||||
//Cycle through the driving modes.
|
||||
incrementDrivingMode(timestep);
|
||||
|
||||
//Update the control inputs for the tank.
|
||||
if(gMimicKeyInputs)
|
||||
{
|
||||
PxVehicleDriveTankSmoothDigitalRawInputsAndSetAnalogInputs(gKeySmoothingData, gVehicleInputData, timestep, *tankEntity.getVehicleDriveTank());
|
||||
}
|
||||
else
|
||||
{
|
||||
PxVehicleDriveTankSmoothAnalogRawInputsAndSetAnalogInputs(gPadSmoothingData, gVehicleInputData, timestep, *tankEntity.getVehicleDriveTank());
|
||||
}
|
||||
|
||||
//Raycasts.
|
||||
PxVehicleWheels* vehicles[1] = {tankEntity.getVehicleDriveTank()};
|
||||
PxVehicleSuspensionRaycasts(gBatchQuery, 1, vehicles, gVehicleSceneQueryData->getQueryResultBufferSize(), gVehicleSceneQueryData->getRaycastQueryResultBuffer(0));
|
||||
|
||||
//Vehicle update.
|
||||
const PxVec3 grav = gScene->getGravity();
|
||||
PxWheelQueryResult wheelQueryResults[PX_MAX_NB_WHEELS];
|
||||
PxVehicleWheelQueryResult vehicleQueryResults[1] = {{wheelQueryResults, tankEntity.getVehicleDriveTank()->mWheelsSimData.getNbWheels()}};
|
||||
PxVehicleUpdates(timestep, grav, *gFrictionPairs, 1, vehicles, vehicleQueryResults);
|
||||
|
||||
//Scene update.
|
||||
gScene->simulate(timestep);
|
||||
gScene->fetchResults(true);
|
||||
tankEntity.simulate(gScene, timestep);
|
||||
}
|
||||
|
||||
void renderPhysics()
|
||||
{
|
||||
#ifdef RENDER_SNIPPET
|
||||
renderScene(gScene, NULL, PxVec3(0.94f, 0.25f, 0.5f));
|
||||
#endif
|
||||
tankEntity.render();
|
||||
}
|
||||
|
||||
void cleanupPhysics(bool /*interactive*/)
|
||||
{
|
||||
gVehicleSceneQueryData->free(gAllocator);
|
||||
PX_RELEASE(gFrictionPairs);
|
||||
PxCloseVehicleSDK();
|
||||
|
||||
PX_RELEASE(gScene);
|
||||
PX_RELEASE(gDispatcher);
|
||||
PX_RELEASE(gPhysics);
|
||||
PX_RELEASE(gCooking);
|
||||
if(gPvd)
|
||||
{
|
||||
PxPvdTransport* transport = gPvd->getTransport();
|
||||
gPvd->release(); gPvd = NULL;
|
||||
PX_RELEASE(transport);
|
||||
}
|
||||
PX_RELEASE(gFoundation);
|
||||
|
||||
printf("SnippetNestedScene done.\n");
|
||||
}
|
||||
|
||||
void keyPress(unsigned char key, const PxTransform& camera)
|
||||
{
|
||||
PX_UNUSED(camera);
|
||||
PX_UNUSED(key);
|
||||
}
|
||||
|
||||
int snippetMain(int, const char*const*)
|
||||
{
|
||||
#ifdef RENDER_SNIPPET
|
||||
extern void renderLoop();
|
||||
renderLoop();
|
||||
#else
|
||||
initPhysics(false);
|
||||
while(!gTankOrderComplete)
|
||||
{
|
||||
stepPhysics(false);
|
||||
}
|
||||
cleanupPhysics(false);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
134
physx/snippets/snippetnestedscene/SnippetNestedSceneRender.cpp
Normal file
134
physx/snippets/snippetnestedscene/SnippetNestedSceneRender.cpp
Normal file
@ -0,0 +1,134 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifdef RENDER_SNIPPET
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
|
||||
#include "../snippetrender/SnippetRender.h"
|
||||
#include "../snippetrender/SnippetCamera.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
extern void initPhysics(bool interactive);
|
||||
extern void stepPhysics(bool interactive);
|
||||
extern void renderPhysics();
|
||||
extern void cleanupPhysics(bool interactive);
|
||||
extern void keyPress(unsigned char key, const PxTransform& camera);
|
||||
|
||||
extern PxScene* gScene;
|
||||
|
||||
Snippets::Camera* sCamera;
|
||||
|
||||
void motionCallback(int x, int y)
|
||||
{
|
||||
sCamera->handleMotion(x, y);
|
||||
}
|
||||
|
||||
void keyboardCallback(unsigned char key, int x, int y)
|
||||
{
|
||||
if(key==27)
|
||||
exit(0);
|
||||
|
||||
if(!sCamera->handleKey(key, x, y))
|
||||
keyPress(key, sCamera->getTransform());
|
||||
}
|
||||
|
||||
void mouseCallback(int button, int state, int x, int y)
|
||||
{
|
||||
sCamera->handleMouse(button, state, x, y);
|
||||
}
|
||||
|
||||
void idleCallback()
|
||||
{
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
void renderScene(physx::PxScene * scene, physx::PxRigidActor * referenceFrame, const physx::PxVec3 & color)
|
||||
{
|
||||
PxU32 nbActors = scene->getNbActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC);
|
||||
if(nbActors)
|
||||
{
|
||||
std::vector<PxRigidActor*> actors(nbActors);
|
||||
scene->getActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC, reinterpret_cast<PxActor**>(&actors[0]), nbActors);
|
||||
|
||||
glPushMatrix();
|
||||
if (referenceFrame)
|
||||
{
|
||||
const PxMat44 actorPose( referenceFrame->getGlobalPose());
|
||||
glMultMatrixf(reinterpret_cast<const float*>(&actorPose));
|
||||
}
|
||||
|
||||
Snippets::renderActors(&actors[0], static_cast<PxU32>(actors.size()), referenceFrame == NULL, color);
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void renderCallback()
|
||||
{
|
||||
stepPhysics(true);
|
||||
|
||||
Snippets::startRender(sCamera->getEye(), sCamera->getDir());
|
||||
|
||||
renderPhysics();
|
||||
|
||||
Snippets::finishRender();
|
||||
}
|
||||
|
||||
void exitCallback(void)
|
||||
{
|
||||
delete sCamera;
|
||||
cleanupPhysics(true);
|
||||
}
|
||||
|
||||
void renderLoop()
|
||||
{
|
||||
sCamera = new Snippets::Camera(PxVec3(10.0f, 10.0f, 10.0f), PxVec3(-0.6f,-0.2f,-0.7f));
|
||||
|
||||
Snippets::setupDefaultWindow("PhysX Snippet Nested Scene");
|
||||
Snippets::setupDefaultRenderState();
|
||||
|
||||
glutIdleFunc(idleCallback);
|
||||
glutDisplayFunc(renderCallback);
|
||||
glutKeyboardFunc(keyboardCallback);
|
||||
glutMouseFunc(mouseCallback);
|
||||
glutMotionFunc(motionCallback);
|
||||
motionCallback(0,0);
|
||||
|
||||
atexit(exitCallback);
|
||||
|
||||
initPhysics(true);
|
||||
glutMainLoop();
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,268 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
// ****************************************************************************
|
||||
// This snippet illustrates the usage of PxPruningStructure.
|
||||
//
|
||||
// It creates a box stack, then prepares a pruning structure. This structure
|
||||
// together with the actors is serialized into a collection. When the collection
|
||||
// is added to the scene, the actor's scene query shape AABBs are directly merged
|
||||
// into the current scene query AABB tree through the precomputed pruning structure.
|
||||
// This may unbalance the AABB tree but should provide significant speedup in
|
||||
// case of large world scenarios where parts get streamed in on the fly.
|
||||
// ****************************************************************************
|
||||
|
||||
#include <ctype.h>
|
||||
#include <vector>
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
|
||||
#include "extensions/PxCollectionExt.h"
|
||||
|
||||
#include "../snippetcommon/SnippetPrint.h"
|
||||
#include "../snippetcommon/SnippetPVD.h"
|
||||
#include "../snippetutils/SnippetUtils.h"
|
||||
|
||||
|
||||
using namespace physx;
|
||||
|
||||
PxDefaultAllocator gAllocator;
|
||||
PxDefaultErrorCallback gErrorCallback;
|
||||
|
||||
PxFoundation* gFoundation = NULL;
|
||||
PxPhysics* gPhysics = NULL;
|
||||
|
||||
PxDefaultCpuDispatcher* gDispatcher = NULL;
|
||||
PxScene* gScene = NULL;
|
||||
|
||||
PxMaterial* gMaterial = NULL;
|
||||
|
||||
PxPvd* gPvd = NULL;
|
||||
|
||||
#define MAX_MEMBLOCKS 10
|
||||
PxU8* gMemBlocks[MAX_MEMBLOCKS];
|
||||
PxU32 gMemBlockCount = 0;
|
||||
|
||||
PxReal stackZ = 10.0f;
|
||||
|
||||
/**
|
||||
Allocates 128 byte aligned memory block for binary serialized data
|
||||
Stores pointer to memory in gMemBlocks for later deallocation
|
||||
*/
|
||||
void* createAlignedBlock(PxU32 size)
|
||||
{
|
||||
PX_ASSERT(gMemBlockCount < MAX_MEMBLOCKS);
|
||||
PxU8* baseAddr = static_cast<PxU8*>(malloc(size + PX_SERIAL_FILE_ALIGN - 1));
|
||||
gMemBlocks[gMemBlockCount++] = baseAddr;
|
||||
void* alignedBlock = reinterpret_cast<void*>((size_t(baseAddr) + PX_SERIAL_FILE_ALIGN - 1)&~(PX_SERIAL_FILE_ALIGN - 1));
|
||||
return alignedBlock;
|
||||
}
|
||||
|
||||
// Create a regular stack, with actors added directly into a scene.
|
||||
void createStack(const PxTransform& t, PxU32 size, PxReal halfExtent)
|
||||
{
|
||||
PxShape* shape = gPhysics->createShape(PxBoxGeometry(halfExtent, halfExtent, halfExtent), *gMaterial);
|
||||
for(PxU32 i=0; i<size;i++)
|
||||
{
|
||||
for(PxU32 j=0;j<size-i;j++)
|
||||
{
|
||||
PxTransform localTm(PxVec3(PxReal(j*2) - PxReal(size-i), PxReal(i*2+1), 0) * halfExtent);
|
||||
PxRigidDynamic* body = gPhysics->createRigidDynamic(t.transform(localTm));
|
||||
body->attachShape(*shape);
|
||||
PxRigidBodyExt::updateMassAndInertia(*body, 10.0f);
|
||||
gScene->addActor(*body);
|
||||
}
|
||||
}
|
||||
shape->release();
|
||||
}
|
||||
|
||||
// Create a stack where pruning structure is build in runtime and used to merge
|
||||
// the query shapes into the AABB tree.
|
||||
void createStackWithRuntimePrunerStructure(const PxTransform& t, PxU32 size, PxReal halfExtent)
|
||||
{
|
||||
std::vector<PxRigidActor*> actors;
|
||||
PxShape* shape = gPhysics->createShape(PxBoxGeometry(halfExtent, halfExtent, halfExtent), *gMaterial);
|
||||
for (PxU32 i = 0; i < size; i++)
|
||||
{
|
||||
for (PxU32 j = 0; j < size - i; j++)
|
||||
{
|
||||
PxTransform localTm(PxVec3(PxReal(j * 2) - PxReal(size - i), PxReal(i * 2 + 1), 0) * halfExtent);
|
||||
PxRigidDynamic* body = gPhysics->createRigidDynamic(t.transform(localTm));
|
||||
body->attachShape(*shape);
|
||||
PxRigidBodyExt::updateMassAndInertia(*body, 10.0f);
|
||||
// store the actors, will be added later
|
||||
actors.push_back(body);
|
||||
}
|
||||
}
|
||||
shape->release();
|
||||
|
||||
// Create pruning structure from given actors.
|
||||
PxPruningStructure* ps = gPhysics->createPruningStructure(&actors[0], PxU32(actors.size()));
|
||||
// Add actors into a scene together with the precomputed pruning structure.
|
||||
gScene->addActors(*ps);
|
||||
ps->release();
|
||||
}
|
||||
|
||||
// Create a stack where pruning structure is build in runtime and then stored into a collection.
|
||||
// The collection is stored into a stream and loaded into another stream. The loaded collection
|
||||
// is added to a scene. While the collection is added to the scene the pruning structure is used.
|
||||
void createStackWithSerializedPrunerStructure(const PxTransform& t, PxU32 size, PxReal halfExtent)
|
||||
{
|
||||
PxCollection* collection = PxCreateCollection(); // collection for all the objects
|
||||
PxSerializationRegistry* sr = PxSerialization::createSerializationRegistry(*gPhysics);
|
||||
|
||||
std::vector<PxRigidActor*> actors;
|
||||
PxShape* shape = gPhysics->createShape(PxBoxGeometry(halfExtent, halfExtent, halfExtent), *gMaterial);
|
||||
for (PxU32 i = 0; i < size; i++)
|
||||
{
|
||||
for (PxU32 j = 0; j < size - i; j++)
|
||||
{
|
||||
PxTransform localTm(PxVec3(PxReal(j * 2) - PxReal(size - i), PxReal(i * 2 + 1), 0) * halfExtent);
|
||||
PxRigidDynamic* body = gPhysics->createRigidDynamic(t.transform(localTm));
|
||||
body->attachShape(*shape);
|
||||
PxRigidBodyExt::updateMassAndInertia(*body, 10.0f);
|
||||
// store the actors, will be added later
|
||||
actors.push_back(body);
|
||||
}
|
||||
}
|
||||
collection->add(*shape);
|
||||
|
||||
// Create pruner structure from given actors.
|
||||
PxPruningStructure* ps = gPhysics->createPruningStructure(&actors[0], PxU32(actors.size()));
|
||||
// Add the pruning structure into the collection. Adding the pruning structure will automatically
|
||||
// add the actors from which the collection was build.
|
||||
collection->add(*ps);
|
||||
PxSerialization::complete(*collection, *sr);
|
||||
|
||||
// Store the collection into a stream.
|
||||
PxDefaultMemoryOutputStream outStream;
|
||||
PxSerialization::serializeCollectionToBinary(outStream, *collection, *sr);
|
||||
collection->release();
|
||||
|
||||
// Release the used items added to the collection.
|
||||
ps->release();
|
||||
for (size_t i = 0; i < actors.size(); i++)
|
||||
{
|
||||
actors[i]->release();
|
||||
}
|
||||
shape->release();
|
||||
|
||||
// Load collection from the stream into and input stream.
|
||||
PxDefaultMemoryInputData inputStream(outStream.getData(), outStream.getSize());
|
||||
void* alignedBlock = createAlignedBlock(inputStream.getLength());
|
||||
inputStream.read(alignedBlock, inputStream.getLength());
|
||||
PxCollection* collection1 = PxSerialization::createCollectionFromBinary(alignedBlock, *sr);
|
||||
|
||||
// Add collection to the scene.
|
||||
gScene->addCollection(*collection1);
|
||||
|
||||
// Release objects in collection, the pruning structure must be released before its actors
|
||||
// otherwise actors will still be part of pruning structure
|
||||
PxCollectionExt::releaseObjects(*collection1);
|
||||
|
||||
collection1->release();
|
||||
}
|
||||
|
||||
void initPhysics(bool )
|
||||
{
|
||||
gFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gAllocator, gErrorCallback);
|
||||
|
||||
gPvd = PxCreatePvd(*gFoundation);
|
||||
PxPvdTransport* transport = PxDefaultPvdSocketTransportCreate(PVD_HOST, 5425, 10);
|
||||
gPvd->connect(*transport, PxPvdInstrumentationFlag::eALL);
|
||||
|
||||
gPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, PxTolerancesScale(),true, gPvd);
|
||||
|
||||
PxSceneDesc sceneDesc(gPhysics->getTolerancesScale());
|
||||
sceneDesc.gravity = PxVec3(0.0f, -9.81f, 0.0f);
|
||||
gDispatcher = PxDefaultCpuDispatcherCreate(2);
|
||||
sceneDesc.cpuDispatcher = gDispatcher;
|
||||
sceneDesc.filterShader = PxDefaultSimulationFilterShader;
|
||||
gScene = gPhysics->createScene(sceneDesc);
|
||||
|
||||
PxPvdSceneClient* pvdClient = gScene->getScenePvdClient();
|
||||
if(pvdClient)
|
||||
{
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONSTRAINTS, true);
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONTACTS, true);
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_SCENEQUERIES, true);
|
||||
}
|
||||
gMaterial = gPhysics->createMaterial(0.5f, 0.5f, 0.6f);
|
||||
|
||||
PxRigidStatic* groundPlane = PxCreatePlane(*gPhysics, PxPlane(0,1,0,0), *gMaterial);
|
||||
gScene->addActor(*groundPlane);
|
||||
|
||||
// Create a regular stack.
|
||||
createStack(PxTransform(PxVec3(0,0,stackZ-=10.0f)), 3, 2.0f);
|
||||
// Create a stack using the runtime pruner structure usage.
|
||||
createStackWithRuntimePrunerStructure(PxTransform(PxVec3(0,0,stackZ-=10.0f)), 3, 2.0f);
|
||||
// Create a stack using the serialized pruner structure usage.
|
||||
createStackWithSerializedPrunerStructure(PxTransform(PxVec3(0,0,stackZ-=10.0f)), 3, 2.0f);
|
||||
}
|
||||
|
||||
void stepPhysics(bool /*interactive*/)
|
||||
{
|
||||
gScene->simulate(1.0f/60.0f);
|
||||
gScene->fetchResults(true);
|
||||
}
|
||||
|
||||
void cleanupPhysics(bool /*interactive*/)
|
||||
{
|
||||
PX_RELEASE(gScene);
|
||||
PX_RELEASE(gDispatcher);
|
||||
PX_RELEASE(gPhysics);
|
||||
if(gPvd)
|
||||
{
|
||||
PxPvdTransport* transport = gPvd->getTransport();
|
||||
gPvd->release(); gPvd = NULL;
|
||||
PX_RELEASE(transport);
|
||||
}
|
||||
|
||||
// Now that the objects have been released, it's safe to release the space they occupy.
|
||||
for (PxU32 i = 0; i < gMemBlockCount; i++)
|
||||
free(gMemBlocks[i]);
|
||||
|
||||
gMemBlockCount = 0;
|
||||
|
||||
PX_RELEASE(gFoundation);
|
||||
|
||||
printf("SnippetPrunerSerialization done.\n");
|
||||
}
|
||||
|
||||
|
||||
int snippetMain(int, const char*const*)
|
||||
{
|
||||
static const PxU32 frameCount = 100;
|
||||
initPhysics(false);
|
||||
for(PxU32 i=0; i<frameCount; i++)
|
||||
stepPhysics(false);
|
||||
cleanupPhysics(false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
186
physx/snippets/snippetraycastccd/SnippetRaycastCCD.cpp
Normal file
186
physx/snippets/snippetraycastccd/SnippetRaycastCCD.cpp
Normal file
@ -0,0 +1,186 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
// ****************************************************************************
|
||||
// This snippet illustrates how to use the raycast CCD extension.
|
||||
//
|
||||
// It creates a simple box stack and a fast moving sphere. Without CCD the
|
||||
// sphere goes through the box stack. With raycast CCD the sphere hits the
|
||||
// stack and the behavior is more convincing.
|
||||
// ****************************************************************************
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
#include "extensions/PxRaycastCCD.h"
|
||||
|
||||
#include "../snippetcommon/SnippetPrint.h"
|
||||
#include "../snippetcommon/SnippetPVD.h"
|
||||
#include "../snippetutils/SnippetUtils.h"
|
||||
|
||||
|
||||
using namespace physx;
|
||||
|
||||
static const bool gEnableRaycastCCD = true; // Switch to false to see the sphere go through the box stack without CCD.
|
||||
|
||||
PxDefaultAllocator gAllocator;
|
||||
PxDefaultErrorCallback gErrorCallback;
|
||||
|
||||
PxFoundation* gFoundation = NULL;
|
||||
PxPhysics* gPhysics = NULL;
|
||||
|
||||
PxDefaultCpuDispatcher* gDispatcher = NULL;
|
||||
PxScene* gScene = NULL;
|
||||
|
||||
PxMaterial* gMaterial = NULL;
|
||||
|
||||
PxPvd* gPvd = NULL;
|
||||
|
||||
RaycastCCDManager* gRaycastCCD = NULL;
|
||||
|
||||
PxReal stackZ = 10.0f;
|
||||
|
||||
PxRigidDynamic* createDynamic(const PxTransform& t, const PxGeometry& geometry, const PxVec3& velocity=PxVec3(0))
|
||||
{
|
||||
PxRigidDynamic* dynamic = PxCreateDynamic(*gPhysics, t, geometry, *gMaterial, 10.0f);
|
||||
dynamic->setAngularDamping(0.5f);
|
||||
dynamic->setLinearVelocity(velocity);
|
||||
gScene->addActor(*dynamic);
|
||||
return dynamic;
|
||||
}
|
||||
|
||||
void createStack(const PxTransform& t, PxU32 size, PxReal halfExtent)
|
||||
{
|
||||
PxShape* shape = gPhysics->createShape(PxBoxGeometry(halfExtent, halfExtent, halfExtent), *gMaterial);
|
||||
for(PxU32 i=0; i<size;i++)
|
||||
{
|
||||
for(PxU32 j=0;j<size-i;j++)
|
||||
{
|
||||
PxTransform localTm(PxVec3(PxReal(j*2) - PxReal(size-i), PxReal(i*2+1), 0) * halfExtent);
|
||||
PxRigidDynamic* body = gPhysics->createRigidDynamic(t.transform(localTm));
|
||||
body->attachShape(*shape);
|
||||
PxRigidBodyExt::updateMassAndInertia(*body, 10.0f);
|
||||
gScene->addActor(*body);
|
||||
}
|
||||
}
|
||||
shape->release();
|
||||
}
|
||||
|
||||
void initPhysics(bool /*interactive*/)
|
||||
{
|
||||
gFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gAllocator, gErrorCallback);
|
||||
|
||||
gPvd = PxCreatePvd(*gFoundation);
|
||||
PxPvdTransport* transport = PxDefaultPvdSocketTransportCreate(PVD_HOST, 5425, 10);
|
||||
gPvd->connect(*transport,PxPvdInstrumentationFlag::eALL);
|
||||
|
||||
gPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, PxTolerancesScale(),true,gPvd);
|
||||
|
||||
PxSceneDesc sceneDesc(gPhysics->getTolerancesScale());
|
||||
sceneDesc.gravity = PxVec3(0.0f, -9.81f, 0.0f);
|
||||
gDispatcher = PxDefaultCpuDispatcherCreate(2);
|
||||
sceneDesc.cpuDispatcher = gDispatcher;
|
||||
sceneDesc.filterShader = PxDefaultSimulationFilterShader;
|
||||
gScene = gPhysics->createScene(sceneDesc);
|
||||
|
||||
PxPvdSceneClient* pvdClient = gScene->getScenePvdClient();
|
||||
if(pvdClient)
|
||||
{
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONSTRAINTS, true);
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONTACTS, true);
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_SCENEQUERIES, true);
|
||||
}
|
||||
gMaterial = gPhysics->createMaterial(0.5f, 0.5f, 0.6f);
|
||||
|
||||
PxRigidStatic* groundPlane = PxCreatePlane(*gPhysics, PxPlane(0,1,0,0), *gMaterial);
|
||||
gScene->addActor(*groundPlane);
|
||||
|
||||
createStack(PxTransform(PxVec3(0,0,stackZ)), 10, 2.0f);
|
||||
|
||||
// Create a fast moving sphere which goes through the box stack without CCD.
|
||||
PxRigidDynamic* actor = createDynamic(PxTransform(PxVec3(0.0f, 20.0f, 100.0f)), PxSphereGeometry(2.0f), PxVec3(0.0f, 0.0f, -1000.0f));
|
||||
if(gEnableRaycastCCD)
|
||||
{
|
||||
PxShape* shape;
|
||||
actor->getShapes(&shape, 1);
|
||||
|
||||
gRaycastCCD = new RaycastCCDManager(gScene);
|
||||
// Register each object for which CCD should be enabled. In this snippet we only enable it for the sphere.
|
||||
gRaycastCCD->registerRaycastCCDObject(actor, shape);
|
||||
}
|
||||
}
|
||||
|
||||
void stepPhysics(bool /*interactive*/)
|
||||
{
|
||||
gScene->simulate(1.0f/60.0f);
|
||||
gScene->fetchResults(true);
|
||||
|
||||
// Simply call this after fetchResults to perform CCD raycasts.
|
||||
if(gRaycastCCD)
|
||||
gRaycastCCD->doRaycastCCD(true);
|
||||
}
|
||||
|
||||
void cleanupPhysics(bool /*interactive*/)
|
||||
{
|
||||
if(gRaycastCCD)
|
||||
delete gRaycastCCD;
|
||||
|
||||
PX_RELEASE(gScene);
|
||||
PX_RELEASE(gDispatcher);
|
||||
PX_RELEASE(gPhysics);
|
||||
if(gPvd)
|
||||
{
|
||||
PxPvdTransport* transport = gPvd->getTransport();
|
||||
gPvd->release(); gPvd = NULL;
|
||||
PX_RELEASE(transport);
|
||||
}
|
||||
PX_RELEASE(gFoundation);
|
||||
|
||||
printf("SnippetRaycastCCD done.\n");
|
||||
}
|
||||
|
||||
void keyPress(unsigned char /*key*/, const PxTransform& /*camera*/)
|
||||
{
|
||||
}
|
||||
|
||||
int snippetMain(int, const char*const*)
|
||||
{
|
||||
#ifdef RENDER_SNIPPET
|
||||
extern void renderLoop();
|
||||
renderLoop();
|
||||
#else
|
||||
static const PxU32 frameCount = 100;
|
||||
initPhysics(false);
|
||||
for(PxU32 i=0; i<frameCount; i++)
|
||||
stepPhysics(false);
|
||||
cleanupPhysics(false);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
120
physx/snippets/snippetraycastccd/SnippetRaycastCCDRender.cpp
Normal file
120
physx/snippets/snippetraycastccd/SnippetRaycastCCDRender.cpp
Normal file
@ -0,0 +1,120 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifdef RENDER_SNIPPET
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
|
||||
#include "../snippetrender/SnippetRender.h"
|
||||
#include "../snippetrender/SnippetCamera.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
extern void initPhysics(bool interactive);
|
||||
extern void stepPhysics(bool interactive);
|
||||
extern void cleanupPhysics(bool interactive);
|
||||
extern void keyPress(unsigned char key, const PxTransform& camera);
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
Snippets::Camera* sCamera;
|
||||
|
||||
void motionCallback(int x, int y)
|
||||
{
|
||||
sCamera->handleMotion(x, y);
|
||||
}
|
||||
|
||||
void keyboardCallback(unsigned char key, int x, int y)
|
||||
{
|
||||
if(key==27)
|
||||
exit(0);
|
||||
|
||||
if(!sCamera->handleKey(key, x, y))
|
||||
keyPress(key, sCamera->getTransform());
|
||||
}
|
||||
|
||||
void mouseCallback(int button, int state, int x, int y)
|
||||
{
|
||||
sCamera->handleMouse(button, state, x, y);
|
||||
}
|
||||
|
||||
void idleCallback()
|
||||
{
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
void renderCallback()
|
||||
{
|
||||
stepPhysics(true);
|
||||
|
||||
Snippets::startRender(sCamera->getEye(), sCamera->getDir());
|
||||
|
||||
PxScene* scene;
|
||||
PxGetPhysics().getScenes(&scene,1);
|
||||
PxU32 nbActors = scene->getNbActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC);
|
||||
if(nbActors)
|
||||
{
|
||||
std::vector<PxRigidActor*> actors(nbActors);
|
||||
scene->getActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC, reinterpret_cast<PxActor**>(&actors[0]), nbActors);
|
||||
Snippets::renderActors(&actors[0], static_cast<PxU32>(actors.size()), true);
|
||||
}
|
||||
|
||||
Snippets::finishRender();
|
||||
}
|
||||
|
||||
void exitCallback(void)
|
||||
{
|
||||
delete sCamera;
|
||||
cleanupPhysics(true);
|
||||
}
|
||||
}
|
||||
|
||||
void renderLoop()
|
||||
{
|
||||
sCamera = new Snippets::Camera(PxVec3(50.0f, 50.0f, 50.0f), PxVec3(-0.6f,-0.2f,-0.7f));
|
||||
|
||||
Snippets::setupDefaultWindow("PhysX Snippet RaycastCCD");
|
||||
Snippets::setupDefaultRenderState();
|
||||
|
||||
glutIdleFunc(idleCallback);
|
||||
glutDisplayFunc(renderCallback);
|
||||
glutKeyboardFunc(keyboardCallback);
|
||||
glutMouseFunc(mouseCallback);
|
||||
glutMotionFunc(motionCallback);
|
||||
motionCallback(0,0);
|
||||
|
||||
atexit(exitCallback);
|
||||
|
||||
initPhysics(true);
|
||||
glutMainLoop();
|
||||
}
|
||||
#endif
|
||||
122
physx/snippets/snippetrender/SnippetCamera.cpp
Normal file
122
physx/snippets/snippetrender/SnippetCamera.cpp
Normal file
@ -0,0 +1,122 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
|
||||
|
||||
#include "SnippetCamera.h"
|
||||
#include <ctype.h>
|
||||
#include "foundation/PxMat33.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
namespace Snippets
|
||||
{
|
||||
|
||||
Camera::Camera(const PxVec3& eye, const PxVec3& dir)
|
||||
{
|
||||
mEye = eye;
|
||||
mDir = dir.getNormalized();
|
||||
mMouseX = 0;
|
||||
mMouseY = 0;
|
||||
}
|
||||
|
||||
void Camera::handleMouse(int button, int state, int x, int y)
|
||||
{
|
||||
PX_UNUSED(state);
|
||||
PX_UNUSED(button);
|
||||
mMouseX = x;
|
||||
mMouseY = y;
|
||||
}
|
||||
|
||||
bool Camera::handleKey(unsigned char key, int x, int y, float speed)
|
||||
{
|
||||
PX_UNUSED(x);
|
||||
PX_UNUSED(y);
|
||||
|
||||
PxVec3 viewY = mDir.cross(PxVec3(0,1,0)).getNormalized();
|
||||
switch(toupper(key))
|
||||
{
|
||||
case 'W': mEye += mDir*2.0f*speed; break;
|
||||
case 'S': mEye -= mDir*2.0f*speed; break;
|
||||
case 'A': mEye -= viewY*2.0f*speed; break;
|
||||
case 'D': mEye += viewY*2.0f*speed; break;
|
||||
default: return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Camera::handleAnalogMove(float x, float y)
|
||||
{
|
||||
PxVec3 viewY = mDir.cross(PxVec3(0,1,0)).getNormalized();
|
||||
mEye += mDir*y;
|
||||
mEye += viewY*x;
|
||||
}
|
||||
|
||||
void Camera::handleMotion(int x, int y)
|
||||
{
|
||||
int dx = mMouseX - x;
|
||||
int dy = mMouseY - y;
|
||||
|
||||
PxVec3 viewY = mDir.cross(PxVec3(0,1,0)).getNormalized();
|
||||
|
||||
PxQuat qx(PxPi * dx / 180.0f, PxVec3(0,1,0));
|
||||
mDir = qx.rotate(mDir);
|
||||
PxQuat qy(PxPi * dy / 180.0f, viewY);
|
||||
mDir = qy.rotate(mDir);
|
||||
|
||||
mDir.normalize();
|
||||
|
||||
mMouseX = x;
|
||||
mMouseY = y;
|
||||
}
|
||||
|
||||
PxTransform Camera::getTransform() const
|
||||
{
|
||||
PxVec3 viewY = mDir.cross(PxVec3(0,1,0));
|
||||
|
||||
if(viewY.normalize()<1e-6f)
|
||||
return PxTransform(mEye);
|
||||
|
||||
PxMat33 m(mDir.cross(viewY), viewY, -mDir);
|
||||
return PxTransform(mEye, PxQuat(m));
|
||||
}
|
||||
|
||||
PxVec3 Camera::getEye() const
|
||||
{
|
||||
return mEye;
|
||||
}
|
||||
|
||||
PxVec3 Camera::getDir() const
|
||||
{
|
||||
return mDir;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
62
physx/snippets/snippetrender/SnippetCamera.h
Normal file
62
physx/snippets/snippetrender/SnippetCamera.h
Normal file
@ -0,0 +1,62 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
|
||||
#ifndef PHYSX_SNIPPET_CAMERA_H
|
||||
#define PHYSX_SNIPPET_CAMERA_H
|
||||
|
||||
#include "foundation/PxTransform.h"
|
||||
|
||||
namespace Snippets
|
||||
{
|
||||
class Camera
|
||||
{
|
||||
public:
|
||||
Camera(const physx::PxVec3 &eye, const physx::PxVec3& dir);
|
||||
|
||||
void handleMouse(int button, int state, int x, int y);
|
||||
bool handleKey(unsigned char key, int x, int y, float speed = 1.0f);
|
||||
void handleMotion(int x, int y);
|
||||
void handleAnalogMove(float x, float y);
|
||||
|
||||
physx::PxVec3 getEye() const;
|
||||
physx::PxVec3 getDir() const;
|
||||
physx::PxTransform getTransform() const;
|
||||
private:
|
||||
physx::PxVec3 mEye;
|
||||
physx::PxVec3 mDir;
|
||||
int mMouseX;
|
||||
int mMouseY;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif //PHYSX_SNIPPET_CAMERA_H
|
||||
441
physx/snippets/snippetrender/SnippetRender.cpp
Normal file
441
physx/snippets/snippetrender/SnippetRender.cpp
Normal file
@ -0,0 +1,441 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#include "SnippetRender.h"
|
||||
|
||||
#define MAX_NUM_ACTOR_SHAPES 128
|
||||
|
||||
using namespace physx;
|
||||
|
||||
static float gCylinderData[]={
|
||||
1.0f,0.0f,1.0f,1.0f,0.0f,1.0f,1.0f,0.0f,0.0f,1.0f,0.0f,0.0f,
|
||||
0.866025f,0.500000f,1.0f,0.866025f,0.500000f,1.0f,0.866025f,0.500000f,0.0f,0.866025f,0.500000f,0.0f,
|
||||
0.500000f,0.866025f,1.0f,0.500000f,0.866025f,1.0f,0.500000f,0.866025f,0.0f,0.500000f,0.866025f,0.0f,
|
||||
-0.0f,1.0f,1.0f,-0.0f,1.0f,1.0f,-0.0f,1.0f,0.0f,-0.0f,1.0f,0.0f,
|
||||
-0.500000f,0.866025f,1.0f,-0.500000f,0.866025f,1.0f,-0.500000f,0.866025f,0.0f,-0.500000f,0.866025f,0.0f,
|
||||
-0.866025f,0.500000f,1.0f,-0.866025f,0.500000f,1.0f,-0.866025f,0.500000f,0.0f,-0.866025f,0.500000f,0.0f,
|
||||
-1.0f,-0.0f,1.0f,-1.0f,-0.0f,1.0f,-1.0f,-0.0f,0.0f,-1.0f,-0.0f,0.0f,
|
||||
-0.866025f,-0.500000f,1.0f,-0.866025f,-0.500000f,1.0f,-0.866025f,-0.500000f,0.0f,-0.866025f,-0.500000f,0.0f,
|
||||
-0.500000f,-0.866025f,1.0f,-0.500000f,-0.866025f,1.0f,-0.500000f,-0.866025f,0.0f,-0.500000f,-0.866025f,0.0f,
|
||||
0.0f,-1.0f,1.0f,0.0f,-1.0f,1.0f,0.0f,-1.0f,0.0f,0.0f,-1.0f,0.0f,
|
||||
0.500000f,-0.866025f,1.0f,0.500000f,-0.866025f,1.0f,0.500000f,-0.866025f,0.0f,0.500000f,-0.866025f,0.0f,
|
||||
0.866026f,-0.500000f,1.0f,0.866026f,-0.500000f,1.0f,0.866026f,-0.500000f,0.0f,0.866026f,-0.500000f,0.0f,
|
||||
1.0f,0.0f,1.0f,1.0f,0.0f,1.0f,1.0f,0.0f,0.0f,1.0f,0.0f,0.0f
|
||||
};
|
||||
|
||||
#define MAX_NUM_MESH_VEC3S 1024
|
||||
static PxVec3 gVertexBuffer[MAX_NUM_MESH_VEC3S];
|
||||
|
||||
static void renderGeometry(const PxGeometry& geom)
|
||||
{
|
||||
switch(geom.getType())
|
||||
{
|
||||
case PxGeometryType::eBOX:
|
||||
{
|
||||
const PxBoxGeometry& boxGeom = static_cast<const PxBoxGeometry&>(geom);
|
||||
glScalef(boxGeom.halfExtents.x, boxGeom.halfExtents.y, boxGeom.halfExtents.z);
|
||||
glutSolidCube(2);
|
||||
}
|
||||
break;
|
||||
|
||||
case PxGeometryType::eSPHERE:
|
||||
{
|
||||
const PxSphereGeometry& sphereGeom = static_cast<const PxSphereGeometry&>(geom);
|
||||
glutSolidSphere(GLdouble(sphereGeom.radius), 10, 10);
|
||||
}
|
||||
break;
|
||||
|
||||
case PxGeometryType::eCAPSULE:
|
||||
{
|
||||
const PxCapsuleGeometry& capsuleGeom = static_cast<const PxCapsuleGeometry&>(geom);
|
||||
const PxF32 radius = capsuleGeom.radius;
|
||||
const PxF32 halfHeight = capsuleGeom.halfHeight;
|
||||
|
||||
//Sphere
|
||||
glPushMatrix();
|
||||
glTranslatef(halfHeight, 0.0f, 0.0f);
|
||||
glScalef(radius,radius,radius);
|
||||
glutSolidSphere(1, 10, 10);
|
||||
glPopMatrix();
|
||||
|
||||
//Sphere
|
||||
glPushMatrix();
|
||||
glTranslatef(-halfHeight, 0.0f, 0.0f);
|
||||
glScalef(radius,radius,radius);
|
||||
glutSolidSphere(1, 10, 10);
|
||||
glPopMatrix();
|
||||
|
||||
//Cylinder
|
||||
glPushMatrix();
|
||||
glTranslatef(-halfHeight, 0.0f, 0.0f);
|
||||
glScalef(2.0f*halfHeight, radius,radius);
|
||||
glRotatef(90.0f,0.0f,1.0f,0.0f);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
glVertexPointer(3, GL_FLOAT, 2*3*sizeof(float), gCylinderData);
|
||||
glNormalPointer(GL_FLOAT, 2*3*sizeof(float), gCylinderData+3);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 13*2);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
glPopMatrix();
|
||||
}
|
||||
break;
|
||||
|
||||
case PxGeometryType::eCONVEXMESH:
|
||||
{
|
||||
const PxConvexMeshGeometry& convexGeom = static_cast<const PxConvexMeshGeometry&>(geom);
|
||||
|
||||
//Compute triangles for each polygon.
|
||||
const PxVec3& scale = convexGeom.scale.scale;
|
||||
PxConvexMesh* mesh = convexGeom.convexMesh;
|
||||
const PxU32 nbPolys = mesh->getNbPolygons();
|
||||
const PxU8* polygons = mesh->getIndexBuffer();
|
||||
const PxVec3* verts = mesh->getVertices();
|
||||
PxU32 nbVerts = mesh->getNbVertices();
|
||||
PX_UNUSED(nbVerts);
|
||||
|
||||
PxU32 numTotalTriangles = 0;
|
||||
for(PxU32 i = 0; i < nbPolys; i++)
|
||||
{
|
||||
PxHullPolygon data;
|
||||
mesh->getPolygonData(i, data);
|
||||
|
||||
const PxU32 nbTris = PxU32(data.mNbVerts - 2);
|
||||
const PxU8 vref0 = polygons[data.mIndexBase + 0];
|
||||
PX_ASSERT(vref0 < nbVerts);
|
||||
for(PxU32 j=0;j<nbTris;j++)
|
||||
{
|
||||
const PxU32 vref1 = polygons[data.mIndexBase + 0 + j + 1];
|
||||
const PxU32 vref2 = polygons[data.mIndexBase + 0 + j + 2];
|
||||
|
||||
//generate face normal:
|
||||
PxVec3 e0 = verts[vref1] - verts[vref0];
|
||||
PxVec3 e1 = verts[vref2] - verts[vref0];
|
||||
|
||||
PX_ASSERT(vref1 < nbVerts);
|
||||
PX_ASSERT(vref2 < nbVerts);
|
||||
|
||||
PxVec3 fnormal = e0.cross(e1);
|
||||
fnormal.normalize();
|
||||
|
||||
if(numTotalTriangles*6 < MAX_NUM_MESH_VEC3S)
|
||||
{
|
||||
gVertexBuffer[numTotalTriangles*6 + 0] = fnormal;
|
||||
gVertexBuffer[numTotalTriangles*6 + 1] = verts[vref0];
|
||||
gVertexBuffer[numTotalTriangles*6 + 2] = fnormal;
|
||||
gVertexBuffer[numTotalTriangles*6 + 3] = verts[vref1];
|
||||
gVertexBuffer[numTotalTriangles*6 + 4] = fnormal;
|
||||
gVertexBuffer[numTotalTriangles*6 + 5] = verts[vref2];
|
||||
numTotalTriangles++;
|
||||
}
|
||||
}
|
||||
}
|
||||
glPushMatrix();
|
||||
glScalef(scale.x, scale.y, scale.z);
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glNormalPointer(GL_FLOAT, 2*3*sizeof(float), gVertexBuffer);
|
||||
glVertexPointer(3, GL_FLOAT, 2*3*sizeof(float), gVertexBuffer+1);
|
||||
glDrawArrays(GL_TRIANGLES, 0, int(numTotalTriangles * 3));
|
||||
glPopMatrix();
|
||||
}
|
||||
break;
|
||||
|
||||
case PxGeometryType::eTRIANGLEMESH:
|
||||
{
|
||||
const PxTriangleMeshGeometry& triGeom = static_cast<const PxTriangleMeshGeometry&>(geom);
|
||||
|
||||
const PxTriangleMesh& mesh = *triGeom.triangleMesh;
|
||||
const PxVec3 scale = triGeom.scale.scale;
|
||||
|
||||
const PxU32 triangleCount = mesh.getNbTriangles();
|
||||
const PxU32 has16BitIndices = mesh.getTriangleMeshFlags() & PxTriangleMeshFlag::e16_BIT_INDICES;
|
||||
const void* indexBuffer = mesh.getTriangles();
|
||||
|
||||
const PxVec3* vertexBuffer = mesh.getVertices();
|
||||
|
||||
const PxU32* intIndices = reinterpret_cast<const PxU32*>(indexBuffer);
|
||||
const PxU16* shortIndices = reinterpret_cast<const PxU16*>(indexBuffer);
|
||||
PxU32 numTotalTriangles = 0;
|
||||
for(PxU32 i=0; i < triangleCount; ++i)
|
||||
{
|
||||
PxVec3 triVert[3];
|
||||
|
||||
if(has16BitIndices)
|
||||
{
|
||||
triVert[0] = vertexBuffer[*shortIndices++];
|
||||
triVert[1] = vertexBuffer[*shortIndices++];
|
||||
triVert[2] = vertexBuffer[*shortIndices++];
|
||||
}
|
||||
else
|
||||
{
|
||||
triVert[0] = vertexBuffer[*intIndices++];
|
||||
triVert[1] = vertexBuffer[*intIndices++];
|
||||
triVert[2] = vertexBuffer[*intIndices++];
|
||||
}
|
||||
|
||||
PxVec3 fnormal = (triVert[1] - triVert[0]).cross(triVert[2] - triVert[0]);
|
||||
fnormal.normalize();
|
||||
|
||||
if(numTotalTriangles*6 < MAX_NUM_MESH_VEC3S)
|
||||
{
|
||||
gVertexBuffer[numTotalTriangles*6 + 0] = fnormal;
|
||||
gVertexBuffer[numTotalTriangles*6 + 1] = triVert[0];
|
||||
gVertexBuffer[numTotalTriangles*6 + 2] = fnormal;
|
||||
gVertexBuffer[numTotalTriangles*6 + 3] = triVert[1];
|
||||
gVertexBuffer[numTotalTriangles*6 + 4] = fnormal;
|
||||
gVertexBuffer[numTotalTriangles*6 + 5] = triVert[2];
|
||||
numTotalTriangles++;
|
||||
}
|
||||
}
|
||||
glPushMatrix();
|
||||
glScalef(scale.x, scale.y, scale.z);
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glNormalPointer(GL_FLOAT, 2*3*sizeof(float), gVertexBuffer);
|
||||
glVertexPointer(3, GL_FLOAT, 2*3*sizeof(float), gVertexBuffer+1);
|
||||
glDrawArrays(GL_TRIANGLES, 0, int(numTotalTriangles * 3));
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
glPopMatrix();
|
||||
}
|
||||
break;
|
||||
|
||||
case PxGeometryType::eINVALID:
|
||||
case PxGeometryType::eHEIGHTFIELD:
|
||||
case PxGeometryType::eGEOMETRY_COUNT:
|
||||
case PxGeometryType::ePLANE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static PX_FORCE_INLINE void renderGeometryHolder(const PxGeometryHolder& h)
|
||||
{
|
||||
renderGeometry(h.any());
|
||||
}
|
||||
|
||||
namespace Snippets
|
||||
{
|
||||
static void reshapeCallback(int width, int height)
|
||||
{
|
||||
glViewport(0, 0, width, height);
|
||||
}
|
||||
|
||||
void setupDefaultWindow(const char *name)
|
||||
{
|
||||
char* namestr = new char[strlen(name)+1];
|
||||
strcpy(namestr, name);
|
||||
int argc = 1;
|
||||
char* argv[1] = { namestr };
|
||||
|
||||
glutInit(&argc, argv);
|
||||
|
||||
glutInitWindowSize(512, 512);
|
||||
glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE|GLUT_DEPTH);
|
||||
int mainHandle = glutCreateWindow(name);
|
||||
glutSetWindow(mainHandle);
|
||||
glutReshapeFunc(reshapeCallback);
|
||||
|
||||
delete[] namestr;
|
||||
}
|
||||
|
||||
void setupDefaultRenderState()
|
||||
{
|
||||
// Setup default render states
|
||||
glClearColor(0.3f, 0.4f, 0.5f, 1.0);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_COLOR_MATERIAL);
|
||||
|
||||
// Setup lighting
|
||||
glEnable(GL_LIGHTING);
|
||||
PxReal ambientColor[] = { 0.0f, 0.1f, 0.2f, 0.0f };
|
||||
PxReal diffuseColor[] = { 1.0f, 1.0f, 1.0f, 0.0f };
|
||||
PxReal specularColor[] = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
PxReal position[] = { 100.0f, 100.0f, 400.0f, 1.0f };
|
||||
glLightfv(GL_LIGHT0, GL_AMBIENT, ambientColor);
|
||||
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseColor);
|
||||
glLightfv(GL_LIGHT0, GL_SPECULAR, specularColor);
|
||||
glLightfv(GL_LIGHT0, GL_POSITION, position);
|
||||
glEnable(GL_LIGHT0);
|
||||
}
|
||||
|
||||
void startRender(const PxVec3& cameraEye, const PxVec3& cameraDir, PxReal clipNear, PxReal clipFar)
|
||||
{
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// Setup camera
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
gluPerspective(60.0, GLdouble(glutGet(GLUT_WINDOW_WIDTH)) / GLdouble(glutGet(GLUT_WINDOW_HEIGHT)), GLdouble(clipNear), GLdouble(clipFar));
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
gluLookAt(GLdouble(cameraEye.x), GLdouble(cameraEye.y), GLdouble(cameraEye.z), GLdouble(cameraEye.x + cameraDir.x), GLdouble(cameraEye.y + cameraDir.y), GLdouble(cameraEye.z + cameraDir.z), 0.0, 1.0, 0.0);
|
||||
|
||||
glColor4f(0.4f, 0.4f, 0.4f, 1.0f);
|
||||
}
|
||||
|
||||
void finishRender()
|
||||
{
|
||||
glutSwapBuffers();
|
||||
}
|
||||
|
||||
void renderActors(PxRigidActor** actors, const PxU32 numActors, bool shadows, const PxVec3& color, TriggerRender* cb)
|
||||
{
|
||||
const PxVec3 shadowDir(0.0f, -0.7071067f, -0.7071067f);
|
||||
const PxReal shadowMat[]={ 1,0,0,0, -shadowDir.x/shadowDir.y,0,-shadowDir.z/shadowDir.y,0, 0,0,1,0, 0,0,0,1 };
|
||||
|
||||
PxShape* shapes[MAX_NUM_ACTOR_SHAPES];
|
||||
for(PxU32 i=0;i<numActors;i++)
|
||||
{
|
||||
const PxU32 nbShapes = actors[i]->getNbShapes();
|
||||
PX_ASSERT(nbShapes <= MAX_NUM_ACTOR_SHAPES);
|
||||
actors[i]->getShapes(shapes, nbShapes);
|
||||
const bool sleeping = actors[i]->is<PxRigidDynamic>() ? actors[i]->is<PxRigidDynamic>()->isSleeping() : false;
|
||||
|
||||
for(PxU32 j=0;j<nbShapes;j++)
|
||||
{
|
||||
const PxMat44 shapePose(PxShapeExt::getGlobalPose(*shapes[j], *actors[i]));
|
||||
const PxGeometryHolder h = shapes[j]->getGeometry();
|
||||
|
||||
const bool isTrigger = cb ? cb->isTrigger(shapes[j]) : shapes[j]->getFlags() & PxShapeFlag::eTRIGGER_SHAPE;
|
||||
if(isTrigger)
|
||||
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
|
||||
|
||||
// render object
|
||||
glPushMatrix();
|
||||
glMultMatrixf(&shapePose.column0.x);
|
||||
if(sleeping)
|
||||
{
|
||||
const PxVec3 darkColor = color * 0.25f;
|
||||
glColor4f(darkColor.x, darkColor.y, darkColor.z, 1.0f);
|
||||
}
|
||||
else
|
||||
glColor4f(color.x, color.y, color.z, 1.0f);
|
||||
renderGeometryHolder(h);
|
||||
glPopMatrix();
|
||||
|
||||
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
|
||||
|
||||
if(shadows)
|
||||
{
|
||||
glPushMatrix();
|
||||
glMultMatrixf(shadowMat);
|
||||
glMultMatrixf(&shapePose.column0.x);
|
||||
glDisable(GL_LIGHTING);
|
||||
glColor4f(0.1f, 0.2f, 0.3f, 1.0f);
|
||||
renderGeometryHolder(h);
|
||||
glEnable(GL_LIGHTING);
|
||||
glPopMatrix();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*static const PxU32 gGeomSizes[] = {
|
||||
sizeof(PxSphereGeometry),
|
||||
sizeof(PxPlaneGeometry),
|
||||
sizeof(PxCapsuleGeometry),
|
||||
sizeof(PxBoxGeometry),
|
||||
sizeof(PxConvexMeshGeometry),
|
||||
sizeof(PxTriangleMeshGeometry),
|
||||
sizeof(PxHeightFieldGeometry),
|
||||
};
|
||||
|
||||
void renderGeoms(const PxU32 nbGeoms, const PxGeometry* geoms, const PxTransform* poses, bool shadows, const PxVec3& color)
|
||||
{
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
const PxVec3 shadowDir(0.0f, -0.7071067f, -0.7071067f);
|
||||
const PxReal shadowMat[]={ 1,0,0,0, -shadowDir.x/shadowDir.y,0,-shadowDir.z/shadowDir.y,0, 0,0,1,0, 0,0,0,1 };
|
||||
|
||||
const PxU8* stream = reinterpret_cast<const PxU8*>(geoms);
|
||||
for(PxU32 j=0;j<nbGeoms;j++)
|
||||
{
|
||||
const PxMat44 shapePose(poses[j]);
|
||||
|
||||
const PxGeometry& geom = *reinterpret_cast<const PxGeometry*>(stream);
|
||||
stream += gGeomSizes[geom.getType()];
|
||||
|
||||
// render object
|
||||
glPushMatrix();
|
||||
glMultMatrixf(&shapePose.column0.x);
|
||||
glColor4f(color.x, color.y, color.z, 1.0f);
|
||||
renderGeometry(geom);
|
||||
glPopMatrix();
|
||||
|
||||
if(shadows)
|
||||
{
|
||||
glPushMatrix();
|
||||
glMultMatrixf(shadowMat);
|
||||
glMultMatrixf(&shapePose.column0.x);
|
||||
glDisable(GL_LIGHTING);
|
||||
glColor4f(0.1f, 0.2f, 0.3f, 1.0f);
|
||||
renderGeometry(geom);
|
||||
glEnable(GL_LIGHTING);
|
||||
glPopMatrix();
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
void renderGeoms(const PxU32 nbGeoms, const PxGeometryHolder* geoms, const PxTransform* poses, bool shadows, const PxVec3& color)
|
||||
{
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
// glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
|
||||
const PxVec3 shadowDir(0.0f, -0.7071067f, -0.7071067f);
|
||||
const PxReal shadowMat[]={ 1,0,0,0, -shadowDir.x/shadowDir.y,0,-shadowDir.z/shadowDir.y,0, 0,0,1,0, 0,0,0,1 };
|
||||
|
||||
for(PxU32 j=0;j<nbGeoms;j++)
|
||||
{
|
||||
const PxMat44 shapePose(poses[j]);
|
||||
|
||||
const PxGeometry& geom = geoms[j].any();
|
||||
|
||||
// render object
|
||||
glPushMatrix();
|
||||
glMultMatrixf(&shapePose.column0.x);
|
||||
glColor4f(color.x, color.y, color.z, 1.0f);
|
||||
renderGeometry(geom);
|
||||
glPopMatrix();
|
||||
|
||||
if(shadows)
|
||||
{
|
||||
glPushMatrix();
|
||||
glMultMatrixf(shadowMat);
|
||||
glMultMatrixf(&shapePose.column0.x);
|
||||
glDisable(GL_LIGHTING);
|
||||
glColor4f(0.1f, 0.2f, 0.3f, 1.0f);
|
||||
renderGeometry(geom);
|
||||
glEnable(GL_LIGHTING);
|
||||
glPopMatrix();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} //namespace Snippets
|
||||
|
||||
68
physx/snippets/snippetrender/SnippetRender.h
Normal file
68
physx/snippets/snippetrender/SnippetRender.h
Normal file
@ -0,0 +1,68 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
|
||||
#ifndef PHYSX_SNIPPET_RENDER_H
|
||||
#define PHYSX_SNIPPET_RENDER_H
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
#include "foundation/PxPreprocessor.h"
|
||||
|
||||
#if PX_WINDOWS
|
||||
#include <windows.h>
|
||||
#pragma warning(disable: 4505)
|
||||
#include <glut.h>
|
||||
#elif PX_LINUX_FAMILY
|
||||
#include <GL/glut.h>
|
||||
#elif PX_OSX
|
||||
#include <GLUT/glut.h>
|
||||
#else
|
||||
#error platform not supported.
|
||||
#endif
|
||||
|
||||
namespace Snippets
|
||||
{
|
||||
void setupDefaultWindow(const char* name);
|
||||
void setupDefaultRenderState();
|
||||
|
||||
void startRender(const physx::PxVec3& cameraEye, const physx::PxVec3& cameraDir, physx::PxReal nearClip = 1.f, physx::PxReal farClip = 10000.f);
|
||||
void finishRender();
|
||||
|
||||
class TriggerRender
|
||||
{
|
||||
public:
|
||||
virtual bool isTrigger(physx::PxShape*) const = 0;
|
||||
};
|
||||
|
||||
void renderActors(physx::PxRigidActor** actors, const physx::PxU32 numActors, bool shadows = false, const physx::PxVec3& color = physx::PxVec3(0.0f, 0.75f, 0.0f), TriggerRender* cb=nullptr);
|
||||
// void renderGeoms(const physx::PxU32 nbGeoms, const physx::PxGeometry* geoms, const physx::PxTransform* poses, bool shadows, const physx::PxVec3& color);
|
||||
void renderGeoms(const physx::PxU32 nbGeoms, const physx::PxGeometryHolder* geoms, const physx::PxTransform* poses, bool shadows, const physx::PxVec3& color);
|
||||
}
|
||||
|
||||
#endif //PHYSX_SNIPPET_RENDER_H
|
||||
312
physx/snippets/snippetserialization/SnippetSerialization.cpp
Normal file
312
physx/snippets/snippetserialization/SnippetSerialization.cpp
Normal file
@ -0,0 +1,312 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
// ****************************************************************************
|
||||
// This snippet illustrates the use of binary and xml serialization
|
||||
//
|
||||
// It creates a chain of boxes and serializes them as two collections:
|
||||
// a collection with shared objects and a collection with actors and joints
|
||||
// which can be instantiated multiple times.
|
||||
//
|
||||
// Then physics is setup based on the serialized data. The collection with the
|
||||
// actors and the joints is instantiated multiple times with different
|
||||
// transforms.
|
||||
//
|
||||
// Finally phyics is teared down again, including deallocation of memory
|
||||
// occupied by deserialized objects (in the case of binary serialization).
|
||||
//
|
||||
// ****************************************************************************
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
|
||||
#include "foundation/PxMemory.h"
|
||||
|
||||
#include "../snippetutils/SnippetUtils.h"
|
||||
#include "../snippetcommon/SnippetPrint.h"
|
||||
#include "../snippetcommon/SnippetPVD.h"
|
||||
|
||||
|
||||
using namespace physx;
|
||||
|
||||
bool gUseBinarySerialization = false;
|
||||
|
||||
PxDefaultAllocator gAllocator;
|
||||
PxDefaultErrorCallback gErrorCallback;
|
||||
|
||||
PxFoundation* gFoundation = NULL;
|
||||
PxPhysics* gPhysics = NULL;
|
||||
PxCooking* gCooking = NULL;
|
||||
|
||||
PxDefaultCpuDispatcher* gDispatcher = NULL;
|
||||
PxScene* gScene = NULL;
|
||||
|
||||
PxPvd* gPvd = NULL;
|
||||
#define MAX_MEMBLOCKS 10
|
||||
PxU8* gMemBlocks[MAX_MEMBLOCKS];
|
||||
PxU32 gMemBlockCount = 0;
|
||||
|
||||
/**
|
||||
Creates two example collections:
|
||||
- collection with actors and joints that can be instantiated multiple times in the scene
|
||||
- collection with shared objects
|
||||
*/
|
||||
void createCollections(PxCollection*& sharedCollection, PxCollection*& actorCollection, PxSerializationRegistry& sr)
|
||||
{
|
||||
PxMaterial* material = gPhysics->createMaterial(0.5f, 0.5f, 0.6f);
|
||||
|
||||
PxReal halfLength = 2.0f, height = 25.0f;
|
||||
PxVec3 offset(halfLength, 0, 0);
|
||||
PxRigidActor* prevActor = PxCreateStatic(*gPhysics, PxTransform(PxVec3(0,height,0)), PxSphereGeometry(halfLength), *material, PxTransform(offset));
|
||||
|
||||
PxShape* shape = gPhysics->createShape(PxBoxGeometry(halfLength, 1.0f, 1.0f), *material);
|
||||
for(PxU32 i=1; i<8;i++)
|
||||
{
|
||||
PxTransform tm(PxVec3(PxReal(i*2)* halfLength, height, 0));
|
||||
PxRigidDynamic* dynamic = gPhysics->createRigidDynamic(tm);
|
||||
dynamic->attachShape(*shape);
|
||||
PxRigidBodyExt::updateMassAndInertia(*dynamic, 10.0f);
|
||||
|
||||
PxSphericalJointCreate(*gPhysics, prevActor, PxTransform(offset), dynamic, PxTransform(-offset));
|
||||
prevActor = dynamic;
|
||||
}
|
||||
|
||||
sharedCollection = PxCreateCollection(); // collection for all the shared objects
|
||||
actorCollection = PxCreateCollection(); // collection for all the nonshared objects
|
||||
|
||||
sharedCollection->add(*shape);
|
||||
PxSerialization::complete(*sharedCollection, sr); // chases the pointer from shape to material, and adds it
|
||||
PxSerialization::createSerialObjectIds(*sharedCollection, PxSerialObjectId(77)); // arbitrary choice of base for references to shared objects
|
||||
|
||||
actorCollection->add(*prevActor);
|
||||
PxSerialization::complete(*actorCollection, sr, sharedCollection, true); // chases all pointers and recursively adds actors and joints
|
||||
}
|
||||
|
||||
/**
|
||||
Allocates 128 byte aligned memory block for binary serialized data
|
||||
Stores pointer to memory in gMemBlocks for later deallocation
|
||||
*/
|
||||
void* createAlignedBlock(PxU32 size)
|
||||
{
|
||||
PX_ASSERT(gMemBlockCount < MAX_MEMBLOCKS);
|
||||
PxU8* baseAddr = static_cast<PxU8*>(malloc(size+PX_SERIAL_FILE_ALIGN-1));
|
||||
gMemBlocks[gMemBlockCount++] = baseAddr;
|
||||
void* alignedBlock = reinterpret_cast<void*>((size_t(baseAddr)+PX_SERIAL_FILE_ALIGN-1)&~(PX_SERIAL_FILE_ALIGN-1));
|
||||
return alignedBlock;
|
||||
}
|
||||
|
||||
/**
|
||||
Create objects, add them to collections and serialize the collections to the steams gSharedStream and gActorStream
|
||||
This function doesn't setup the gPhysics global as the corresponding physics object is only used locally
|
||||
*/
|
||||
void serializeObjects(PxOutputStream& sharedStream, PxOutputStream& actorStream)
|
||||
{
|
||||
PxSerializationRegistry* sr = PxSerialization::createSerializationRegistry(*gPhysics);
|
||||
|
||||
PxCollection* sharedCollection = NULL;
|
||||
PxCollection* actorCollection = NULL;
|
||||
createCollections(sharedCollection, actorCollection, *sr);
|
||||
|
||||
// Alternatively to using PxDefaultMemoryOutputStream it would be possible to serialize to files using
|
||||
// PxDefaultFileOutputStream or a similar implementation of PxOutputStream.
|
||||
if (gUseBinarySerialization)
|
||||
{
|
||||
PxSerialization::serializeCollectionToBinary(sharedStream, *sharedCollection, *sr);
|
||||
PxSerialization::serializeCollectionToBinary(actorStream, *actorCollection, *sr, sharedCollection);
|
||||
}
|
||||
else
|
||||
{
|
||||
PxSerialization::serializeCollectionToXml(sharedStream, *sharedCollection, *sr);
|
||||
PxSerialization::serializeCollectionToXml(actorStream, *actorCollection, *sr, NULL, sharedCollection);
|
||||
}
|
||||
|
||||
actorCollection->release();
|
||||
sharedCollection->release();
|
||||
|
||||
sr->release();
|
||||
}
|
||||
|
||||
/**
|
||||
Deserialize shared data and use resulting collection to deserialize and instance actor collections
|
||||
*/
|
||||
void deserializeObjects(PxInputData& sharedData, PxInputData& actorData)
|
||||
{
|
||||
PxSerializationRegistry* sr = PxSerialization::createSerializationRegistry(*gPhysics);
|
||||
|
||||
PxCollection* sharedCollection = NULL;
|
||||
{
|
||||
if (gUseBinarySerialization)
|
||||
{
|
||||
void* alignedBlock = createAlignedBlock(sharedData.getLength());
|
||||
sharedData.read(alignedBlock, sharedData.getLength());
|
||||
sharedCollection = PxSerialization::createCollectionFromBinary(alignedBlock, *sr);
|
||||
}
|
||||
else
|
||||
{
|
||||
sharedCollection = PxSerialization::createCollectionFromXml(sharedData, *gCooking, *sr);
|
||||
}
|
||||
}
|
||||
|
||||
// Deserialize collection and instantiate objects twice, each time with a different transform
|
||||
PxTransform transforms[2] = { PxTransform(PxVec3(-5.0f, 0.0f, 0.0f)), PxTransform(PxVec3(5.0f, 0.0f, 0.0f)) };
|
||||
|
||||
for (PxU32 i = 0; i < 2; i++)
|
||||
{
|
||||
PxCollection* collection = NULL;
|
||||
|
||||
// If the PxInputData actorData would refer to a file, it would be better to avoid reading from it twice.
|
||||
// This could be achieved by reading the file once to memory, and then working with copies.
|
||||
// This is particulary practical when using binary serialization, where the data can be directly
|
||||
// converted to physics objects.
|
||||
actorData.seek(0);
|
||||
|
||||
if (gUseBinarySerialization)
|
||||
{
|
||||
void* alignedBlock = createAlignedBlock(actorData.getLength());
|
||||
actorData.read(alignedBlock, actorData.getLength());
|
||||
collection = PxSerialization::createCollectionFromBinary(alignedBlock, *sr, sharedCollection);
|
||||
}
|
||||
else
|
||||
{
|
||||
collection = PxSerialization::createCollectionFromXml(actorData, *gCooking, *sr, sharedCollection);
|
||||
}
|
||||
|
||||
for (PxU32 o = 0; o < collection->getNbObjects(); o++)
|
||||
{
|
||||
PxRigidActor* rigidActor = collection->getObject(o).is<PxRigidActor>();
|
||||
if (rigidActor)
|
||||
{
|
||||
PxTransform globalPose = rigidActor->getGlobalPose();
|
||||
globalPose = globalPose.transform(transforms[i]);
|
||||
rigidActor->setGlobalPose(globalPose);
|
||||
}
|
||||
}
|
||||
|
||||
gScene->addCollection(*collection);
|
||||
collection->release();
|
||||
}
|
||||
sharedCollection->release();
|
||||
|
||||
PxMaterial* material;
|
||||
gPhysics->getMaterials(&material,1);
|
||||
PxRigidStatic* groundPlane = PxCreatePlane(*gPhysics, PxPlane(0,1,0,0), *material);
|
||||
gScene->addActor(*groundPlane);
|
||||
sr->release();
|
||||
}
|
||||
|
||||
/**
|
||||
Initializes physics and creates a scene
|
||||
*/
|
||||
void initPhysics()
|
||||
{
|
||||
gFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gAllocator, gErrorCallback);
|
||||
gPvd = PxCreatePvd(*gFoundation);
|
||||
PxPvdTransport* transport = PxDefaultPvdSocketTransportCreate(PVD_HOST, 5425, 10);
|
||||
gPvd->connect(*transport,PxPvdInstrumentationFlag::eALL);
|
||||
|
||||
gPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, PxTolerancesScale(), true, gPvd);
|
||||
gCooking = PxCreateCooking(PX_PHYSICS_VERSION, *gFoundation, PxCookingParams(PxTolerancesScale()));
|
||||
PxInitExtensions(*gPhysics, gPvd);
|
||||
|
||||
PxU32 numCores = SnippetUtils::getNbPhysicalCores();
|
||||
gDispatcher = PxDefaultCpuDispatcherCreate(numCores == 0 ? 0 : numCores - 1);
|
||||
PxSceneDesc sceneDesc(gPhysics->getTolerancesScale());
|
||||
sceneDesc.gravity = PxVec3(0, -9.81f, 0);
|
||||
sceneDesc.cpuDispatcher = gDispatcher;
|
||||
sceneDesc.filterShader = PxDefaultSimulationFilterShader;
|
||||
gScene = gPhysics->createScene(sceneDesc);
|
||||
|
||||
PxPvdSceneClient* pvdClient = gScene->getScenePvdClient();
|
||||
if(pvdClient)
|
||||
{
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONSTRAINTS, true);
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONTACTS, true);
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_SCENEQUERIES, true);
|
||||
}
|
||||
}
|
||||
|
||||
void stepPhysics()
|
||||
{
|
||||
gScene->simulate(1.0f/60.0f);
|
||||
gScene->fetchResults(true);
|
||||
}
|
||||
|
||||
/**
|
||||
Releases all physics objects, including memory blocks containing deserialized data
|
||||
*/
|
||||
void cleanupPhysics()
|
||||
{
|
||||
PX_RELEASE(gScene);
|
||||
PX_RELEASE(gDispatcher);
|
||||
PxCloseExtensions();
|
||||
|
||||
PX_RELEASE(gPhysics); // releases all objects
|
||||
PX_RELEASE(gCooking);
|
||||
if(gPvd)
|
||||
{
|
||||
PxPvdTransport* transport = gPvd->getTransport();
|
||||
gPvd->release(); gPvd = NULL;
|
||||
PX_RELEASE(transport);
|
||||
}
|
||||
|
||||
// Now that the objects have been released, it's safe to release the space they occupy
|
||||
for (PxU32 i = 0; i < gMemBlockCount; i++)
|
||||
free(gMemBlocks[i]);
|
||||
|
||||
gMemBlockCount = 0;
|
||||
|
||||
PX_RELEASE(gFoundation);
|
||||
}
|
||||
|
||||
int snippetMain(int, const char*const*)
|
||||
{
|
||||
initPhysics();
|
||||
// Alternatively PxDefaultFileOutputStream could be used
|
||||
PxDefaultMemoryOutputStream sharedOutputStream;
|
||||
PxDefaultMemoryOutputStream actorOutputStream;
|
||||
serializeObjects(sharedOutputStream, actorOutputStream);
|
||||
cleanupPhysics();
|
||||
|
||||
initPhysics();
|
||||
// Alternatively PxDefaultFileInputData could be used
|
||||
PxDefaultMemoryInputData sharedInputStream(sharedOutputStream.getData(), sharedOutputStream.getSize());
|
||||
PxDefaultMemoryInputData actorInputStream(actorOutputStream.getData(), actorOutputStream.getSize());
|
||||
deserializeObjects(sharedInputStream, actorInputStream);
|
||||
#ifdef RENDER_SNIPPET
|
||||
extern void renderLoop();
|
||||
renderLoop();
|
||||
#else
|
||||
static const PxU32 frameCount = 250;
|
||||
for(PxU32 i=0; i<frameCount; i++)
|
||||
stepPhysics();
|
||||
cleanupPhysics();
|
||||
printf("SnippetSerialization done.\n");
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -0,0 +1,119 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifdef RENDER_SNIPPET
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
|
||||
#include "../snippetcommon/SnippetPrint.h"
|
||||
#include "../snippetrender/SnippetRender.h"
|
||||
#include "../snippetrender/SnippetCamera.h"
|
||||
|
||||
|
||||
using namespace physx;
|
||||
|
||||
extern void initPhysics();
|
||||
extern void stepPhysics();
|
||||
extern void cleanupPhysics();
|
||||
|
||||
namespace
|
||||
{
|
||||
Snippets::Camera* sCamera;
|
||||
|
||||
void motionCallback(int x, int y)
|
||||
{
|
||||
sCamera->handleMotion(x, y);
|
||||
}
|
||||
|
||||
void keyboardCallback(unsigned char key, int x, int y)
|
||||
{
|
||||
if(key==27)
|
||||
exit(0);
|
||||
|
||||
sCamera->handleKey(key, x, y);
|
||||
}
|
||||
|
||||
void mouseCallback(int button, int state, int x, int y)
|
||||
{
|
||||
sCamera->handleMouse(button, state, x, y);
|
||||
}
|
||||
|
||||
void idleCallback()
|
||||
{
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
void renderCallback()
|
||||
{
|
||||
Snippets::startRender(sCamera->getEye(), sCamera->getDir());
|
||||
|
||||
PxScene* scene;
|
||||
PxGetPhysics().getScenes(&scene,1);
|
||||
PxU32 nbActors = scene->getNbActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC);
|
||||
if(nbActors)
|
||||
{
|
||||
std::vector<PxRigidActor*> actors(nbActors);
|
||||
scene->getActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC, reinterpret_cast<PxActor**>(&actors[0]), nbActors);
|
||||
Snippets::renderActors(&actors[0], static_cast<PxU32>(actors.size()), true);
|
||||
}
|
||||
|
||||
Snippets::finishRender();
|
||||
|
||||
stepPhysics();
|
||||
}
|
||||
|
||||
void exitCallback(void)
|
||||
{
|
||||
delete sCamera;
|
||||
cleanupPhysics();
|
||||
printf("SnippetSerialization done.\n");
|
||||
}
|
||||
}
|
||||
|
||||
void renderLoop()
|
||||
{
|
||||
sCamera = new Snippets::Camera(PxVec3(50.0f, 50.0f, 50.0f), PxVec3(-0.6f,-0.2f,-0.7f));
|
||||
|
||||
Snippets::setupDefaultWindow("PhysX Snippet Serialization");
|
||||
Snippets::setupDefaultRenderState();
|
||||
|
||||
glutIdleFunc(idleCallback);
|
||||
glutDisplayFunc(renderCallback);
|
||||
glutKeyboardFunc(keyboardCallback);
|
||||
glutMouseFunc(mouseCallback);
|
||||
glutMotionFunc(motionCallback);
|
||||
motionCallback(0,0);
|
||||
|
||||
atexit(exitCallback);
|
||||
|
||||
glutMainLoop();
|
||||
}
|
||||
#endif
|
||||
@ -0,0 +1,276 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
// ****************************************************************************
|
||||
// This snippet illustrates the use of simple contact reports.
|
||||
//
|
||||
// It defines a filter shader function that requests touch reports for
|
||||
// all pairs, and a contact callback function that saves the contact points.
|
||||
// It configures the scene to use this filter and callback, and prints the
|
||||
// number of contact reports each frame. If rendering, it renders each
|
||||
// contact as a line whose length and direction are defined by the contact
|
||||
// impulse.
|
||||
//
|
||||
// ****************************************************************************
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
|
||||
#include "../snippetcommon/SnippetPrint.h"
|
||||
#include "../snippetcommon/SnippetPVD.h"
|
||||
#include "../snippetutils/SnippetUtils.h"
|
||||
#include "PsAtomic.h"
|
||||
#include "task/PxTask.h"
|
||||
|
||||
#define PARALLEL_CALLBACKS 1
|
||||
|
||||
|
||||
using namespace physx;
|
||||
|
||||
|
||||
PxDefaultAllocator gAllocator;
|
||||
PxDefaultErrorCallback gErrorCallback;
|
||||
|
||||
PxFoundation* gFoundation = NULL;
|
||||
PxPhysics* gPhysics = NULL;
|
||||
|
||||
PxDefaultCpuDispatcher* gDispatcher = NULL;
|
||||
PxScene* gScene = NULL;
|
||||
PxMaterial* gMaterial = NULL;
|
||||
PxPvd* gPvd = NULL;
|
||||
|
||||
const PxI32 maxCount = 10000;
|
||||
|
||||
PxI32 gSharedIndex = 0;
|
||||
|
||||
PxVec3* gContactPositions;
|
||||
PxVec3* gContactImpulses;
|
||||
PxVec3* gContactVertices;
|
||||
|
||||
class CallbackFinishTask : public PxLightCpuTask
|
||||
{
|
||||
SnippetUtils::Sync* mSync;
|
||||
public:
|
||||
CallbackFinishTask(){ mSync = SnippetUtils::syncCreate(); }
|
||||
|
||||
virtual void release()
|
||||
{
|
||||
PxLightCpuTask::release();
|
||||
SnippetUtils::syncSet(mSync);
|
||||
}
|
||||
|
||||
void reset() { SnippetUtils::syncReset(mSync); }
|
||||
|
||||
void wait() { SnippetUtils::syncWait(mSync); }
|
||||
|
||||
virtual void run() { /*Do nothing - release the sync in the release method for thread-safety*/}
|
||||
|
||||
virtual const char* getName() const { return "CallbackFinishTask"; }
|
||||
}
|
||||
callbackFinishTask;
|
||||
|
||||
|
||||
PxFilterFlags contactReportFilterShader(PxFilterObjectAttributes attributes0, PxFilterData filterData0,
|
||||
PxFilterObjectAttributes attributes1, PxFilterData filterData1,
|
||||
PxPairFlags& pairFlags, const void* constantBlock, PxU32 constantBlockSize)
|
||||
{
|
||||
PX_UNUSED(attributes0);
|
||||
PX_UNUSED(attributes1);
|
||||
PX_UNUSED(filterData0);
|
||||
PX_UNUSED(filterData1);
|
||||
PX_UNUSED(constantBlockSize);
|
||||
PX_UNUSED(constantBlock);
|
||||
|
||||
// all initial and persisting reports for everything, with per-point data
|
||||
pairFlags = PxPairFlag::eSOLVE_CONTACT | PxPairFlag::eDETECT_DISCRETE_CONTACT
|
||||
| PxPairFlag::eNOTIFY_TOUCH_FOUND
|
||||
| PxPairFlag::eNOTIFY_TOUCH_PERSISTS
|
||||
| PxPairFlag::eNOTIFY_CONTACT_POINTS;
|
||||
return PxFilterFlag::eDEFAULT;
|
||||
}
|
||||
|
||||
class ContactReportCallback : public PxSimulationEventCallback
|
||||
{
|
||||
void onConstraintBreak(PxConstraintInfo* constraints, PxU32 count) { PX_UNUSED(constraints); PX_UNUSED(count); }
|
||||
void onWake(PxActor** actors, PxU32 count) { PX_UNUSED(actors); PX_UNUSED(count); }
|
||||
void onSleep(PxActor** actors, PxU32 count) { PX_UNUSED(actors); PX_UNUSED(count); }
|
||||
void onTrigger(PxTriggerPair* pairs, PxU32 count) { PX_UNUSED(pairs); PX_UNUSED(count); }
|
||||
void onAdvance(const PxRigidBody*const*, const PxTransform*, const PxU32) {}
|
||||
void onContact(const PxContactPairHeader& pairHeader, const PxContactPair* pairs, PxU32 nbPairs)
|
||||
{
|
||||
PX_UNUSED((pairHeader));
|
||||
//Maximum of 64 vertices can be produced by contact gen
|
||||
PxContactPairPoint contactPoints[64];
|
||||
|
||||
for (PxU32 i = 0; i<nbPairs; i++)
|
||||
{
|
||||
PxU32 contactCount = pairs[i].contactCount;
|
||||
if (contactCount)
|
||||
{
|
||||
pairs[i].extractContacts(&contactPoints[0], contactCount);
|
||||
|
||||
PxI32 startIdx = physx::shdfnd::atomicAdd(&gSharedIndex, int32_t(contactCount));
|
||||
for (PxU32 j = 0; j<contactCount; j++)
|
||||
{
|
||||
gContactPositions[startIdx+j] = contactPoints[j].position;
|
||||
gContactImpulses[startIdx+j] = contactPoints[j].impulse;
|
||||
gContactVertices[2*(startIdx + j)] = contactPoints[j].position;
|
||||
gContactVertices[2*(startIdx + j) + 1] = contactPoints[j].position + contactPoints[j].impulse * 0.1f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ContactReportCallback gContactReportCallback;
|
||||
|
||||
void createStack(const PxTransform& t, PxU32 size, PxReal halfExtent)
|
||||
{
|
||||
PxShape* shape = gPhysics->createShape(PxBoxGeometry(halfExtent, halfExtent, halfExtent), *gMaterial);
|
||||
for (PxU32 i = 0; i<size; i++)
|
||||
{
|
||||
for (PxU32 j = 0; j<size - i; j++)
|
||||
{
|
||||
PxTransform localTm(PxVec3(PxReal(j * 2) - PxReal(size - i), PxReal(i * 2 + 1), 0) * halfExtent);
|
||||
PxRigidDynamic* body = gPhysics->createRigidDynamic(t.transform(localTm));
|
||||
body->attachShape(*shape);
|
||||
PxRigidBodyExt::updateMassAndInertia(*body, 10.0f);
|
||||
gScene->addActor(*body);
|
||||
}
|
||||
}
|
||||
shape->release();
|
||||
}
|
||||
|
||||
void initPhysics(bool /*interactive*/)
|
||||
{
|
||||
gContactPositions = new PxVec3[maxCount];
|
||||
gContactImpulses = new PxVec3[maxCount];
|
||||
gContactVertices = new PxVec3[2*maxCount];
|
||||
|
||||
gFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gAllocator, gErrorCallback);
|
||||
gPvd = PxCreatePvd(*gFoundation);
|
||||
PxPvdTransport* transport = PxDefaultPvdSocketTransportCreate(PVD_HOST, 5425, 10);
|
||||
gPvd->connect(*transport, PxPvdInstrumentationFlag::eALL);
|
||||
gPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, PxTolerancesScale(), true, gPvd);
|
||||
PxInitExtensions(*gPhysics, gPvd);
|
||||
PxU32 numCores = SnippetUtils::getNbPhysicalCores();
|
||||
gDispatcher = PxDefaultCpuDispatcherCreate(numCores == 0 ? 0 : numCores - 1);
|
||||
PxSceneDesc sceneDesc(gPhysics->getTolerancesScale());
|
||||
sceneDesc.cpuDispatcher = gDispatcher;
|
||||
sceneDesc.gravity = PxVec3(0, -9.81f, 0);
|
||||
sceneDesc.filterShader = contactReportFilterShader;
|
||||
sceneDesc.simulationEventCallback = &gContactReportCallback;
|
||||
gScene = gPhysics->createScene(sceneDesc);
|
||||
|
||||
PxPvdSceneClient* pvdClient = gScene->getScenePvdClient();
|
||||
if (pvdClient)
|
||||
{
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONSTRAINTS, true);
|
||||
}
|
||||
gMaterial = gPhysics->createMaterial(0.5f, 0.5f, 0.6f);
|
||||
|
||||
PxRigidStatic* groundPlane = PxCreatePlane(*gPhysics, PxPlane(0, 1, 0, 0), *gMaterial);
|
||||
gScene->addActor(*groundPlane);
|
||||
|
||||
const PxU32 nbStacks = 50;
|
||||
|
||||
for (PxU32 i = 0; i < nbStacks; ++i)
|
||||
{
|
||||
createStack(PxTransform(PxVec3(0, 3.0f, 10.f - 5.f*i)), 5, 2.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void stepPhysics(bool /*interactive*/)
|
||||
{
|
||||
gSharedIndex = 0;
|
||||
|
||||
gScene->simulate(1.0f / 60.0f);
|
||||
|
||||
#if !PARALLEL_CALLBACKS
|
||||
gScene->fetchResults(true);
|
||||
#else
|
||||
//Call fetchResultsStart. Get the set of pair headers
|
||||
const PxContactPairHeader* pairHeader;
|
||||
PxU32 nbContactPairs;
|
||||
gScene->fetchResultsStart(pairHeader, nbContactPairs, true);
|
||||
|
||||
//Set up continuation task to be run after callbacks have been processed in parallel
|
||||
callbackFinishTask.setContinuation(*gScene->getTaskManager(), NULL);
|
||||
callbackFinishTask.reset();
|
||||
|
||||
//process the callbacks
|
||||
gScene->processCallbacks(&callbackFinishTask);
|
||||
|
||||
callbackFinishTask.removeReference();
|
||||
|
||||
callbackFinishTask.wait();
|
||||
|
||||
gScene->fetchResultsFinish();
|
||||
#endif
|
||||
|
||||
printf("%d contact reports\n", PxU32(gSharedIndex));
|
||||
}
|
||||
|
||||
void cleanupPhysics(bool /*interactive*/)
|
||||
{
|
||||
PX_RELEASE(gScene);
|
||||
PX_RELEASE(gDispatcher);
|
||||
PxCloseExtensions();
|
||||
PX_RELEASE(gPhysics);
|
||||
if(gPvd)
|
||||
{
|
||||
PxPvdTransport* transport = gPvd->getTransport();
|
||||
gPvd->release(); gPvd = NULL;
|
||||
PX_RELEASE(transport);
|
||||
}
|
||||
PX_RELEASE(gFoundation);
|
||||
|
||||
delete gContactPositions;
|
||||
delete gContactImpulses;
|
||||
delete gContactVertices;
|
||||
|
||||
printf("SnippetSplitFetchResults done.\n");
|
||||
}
|
||||
|
||||
int snippetMain(int, const char*const*)
|
||||
{
|
||||
#ifdef RENDER_SNIPPET
|
||||
extern void renderLoop();
|
||||
renderLoop();
|
||||
#else
|
||||
initPhysics(false);
|
||||
for (PxU32 i = 0; i<250; i++)
|
||||
stepPhysics(false);
|
||||
cleanupPhysics(false);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -0,0 +1,131 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifdef RENDER_SNIPPET
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
#include "../snippetrender/SnippetRender.h"
|
||||
#include "../snippetrender/SnippetCamera.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
extern void initPhysics(bool interactive);
|
||||
extern void stepPhysics(bool interactive);
|
||||
extern void cleanupPhysics(bool interactive);
|
||||
|
||||
extern PxVec3* gContactPositions;
|
||||
extern PxVec3* gContactImpulses;
|
||||
extern PxI32 gSharedIndex;
|
||||
extern PxVec3* gContactVertices;
|
||||
|
||||
namespace
|
||||
{
|
||||
Snippets::Camera* sCamera;
|
||||
|
||||
void motionCallback(int x, int y)
|
||||
{
|
||||
sCamera->handleMotion(x, y);
|
||||
}
|
||||
|
||||
void keyboardCallback(unsigned char key, int x, int y)
|
||||
{
|
||||
if (key == 27)
|
||||
exit(0);
|
||||
|
||||
sCamera->handleKey(key, x, y);
|
||||
}
|
||||
|
||||
void mouseCallback(int button, int state, int x, int y)
|
||||
{
|
||||
sCamera->handleMouse(button, state, x, y);
|
||||
}
|
||||
|
||||
void idleCallback()
|
||||
{
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
void renderCallback()
|
||||
{
|
||||
stepPhysics(true);
|
||||
|
||||
Snippets::startRender(sCamera->getEye(), sCamera->getDir());
|
||||
|
||||
PxScene* scene;
|
||||
PxGetPhysics().getScenes(&scene, 1);
|
||||
PxU32 nbActors = scene->getNbActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC);
|
||||
if (nbActors)
|
||||
{
|
||||
std::vector<PxRigidActor*> actors(nbActors);
|
||||
scene->getActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC, reinterpret_cast<PxActor**>(&actors[0]), nbActors);
|
||||
Snippets::renderActors(&actors[0], static_cast<PxU32>(actors.size()), true);
|
||||
}
|
||||
|
||||
PxI32 count = gSharedIndex;
|
||||
if (count)
|
||||
{
|
||||
glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glVertexPointer(3, GL_FLOAT, 0, &gContactVertices[0]);
|
||||
glDrawArrays(GL_LINES, 0, GLint(count*2));
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
}
|
||||
|
||||
Snippets::finishRender();
|
||||
}
|
||||
|
||||
void exitCallback(void)
|
||||
{
|
||||
delete sCamera;
|
||||
cleanupPhysics(true);
|
||||
}
|
||||
}
|
||||
|
||||
void renderLoop()
|
||||
{
|
||||
sCamera = new Snippets::Camera(PxVec3(50.0f, 50.0f, 50.0f), PxVec3(-0.6f, -0.2f, -0.7f));
|
||||
|
||||
Snippets::setupDefaultWindow("PhysX Snippet Split fetchResults");
|
||||
Snippets::setupDefaultRenderState();
|
||||
|
||||
glutIdleFunc(idleCallback);
|
||||
glutDisplayFunc(renderCallback);
|
||||
glutKeyboardFunc(keyboardCallback);
|
||||
glutMouseFunc(mouseCallback);
|
||||
glutMotionFunc(motionCallback);
|
||||
motionCallback(0, 0);
|
||||
|
||||
atexit(exitCallback);
|
||||
|
||||
initPhysics(true);
|
||||
glutMainLoop();
|
||||
}
|
||||
#endif
|
||||
385
physx/snippets/snippetsplitsim/SnippetSplitSim.cpp
Normal file
385
physx/snippets/snippetsplitsim/SnippetSplitSim.cpp
Normal file
@ -0,0 +1,385 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
|
||||
// *******************************************************************************************************
|
||||
// In addition to the simulate() function, which performs both collision detection and dynamics update,
|
||||
// the PhysX SDK provides an api for separate execution of the collision detection and dynamics update steps.
|
||||
// We shall refer to this feature as "split sim". This snippet demonstrates two ways to use the split sim feature
|
||||
// so that application work can be performed concurrently with the collision detection step.
|
||||
|
||||
// The snippet creates a list of kinematic box actors along with a number of dynamic actors that
|
||||
// interact with the kinematic actors.
|
||||
|
||||
//The defines OVERLAP_COLLISION_AND_RENDER_WITH_NO_LAG and OVERLAP_COLLISION_AND_RENDER_WITH_ONE_FRAME_LAG
|
||||
//demonstrate two distinct modes of split sim operation:
|
||||
|
||||
// (1)Enabling OVERLAP_COLLISION_AND_RENDER_WITH_NO_LAG allows the collision detection step to run in parallel
|
||||
// with the renderer and with the update of the kinematic target poses without introducing any lag between
|
||||
// application time and physics time. This is equivalent to calling simulate() and fetchResults() with the key
|
||||
// difference being that the application can schedule work to run concurrently with the collision detection.
|
||||
// A consequence of this approach is that the first frame is more expensive than subsequent frames because it has to
|
||||
// perform blocking collision detection and dynamics update calls.
|
||||
|
||||
// (2)OVERLAP_COLLISION_AND_RENDER_WITH_ONE_FRAME_LAG also allows the collision to run in parallel with
|
||||
// the renderer and the update of the kinematic target poses but this time with a lag between physics time and
|
||||
// application time; that is, the physics is always a single timestep behind the application because the first
|
||||
// frame merely starts the collision detection for the subsequent frame. A consequence of this approach is that
|
||||
// the first frame is cheaper than subsequent frames.
|
||||
// ********************************************************************************************************
|
||||
|
||||
|
||||
#include <ctype.h>
|
||||
#include "PxPhysicsAPI.h"
|
||||
|
||||
#include "../snippetcommon/SnippetPrint.h"
|
||||
#include "../snippetcommon/SnippetPVD.h"
|
||||
#include "../snippetutils/SnippetUtils.h"
|
||||
|
||||
//This will allow the split sim to overlap collision and render and game logic.
|
||||
#define OVERLAP_COLLISION_AND_RENDER_WITH_NO_LAG 1
|
||||
#define OVERLAP_COLLISION_AND_RENDER_WITH_ONE_FRAME_LAG 0
|
||||
|
||||
using namespace physx;
|
||||
|
||||
PxDefaultAllocator gAllocator;
|
||||
PxDefaultErrorCallback gErrorCallback;
|
||||
|
||||
PxFoundation* gFoundation = NULL;
|
||||
PxPhysics* gPhysics = NULL;
|
||||
|
||||
PxDefaultCpuDispatcher* gDispatcher = NULL;
|
||||
PxScene* gScene = NULL;
|
||||
|
||||
PxMaterial* gMaterial = NULL;
|
||||
|
||||
PxPvd* gPvd = NULL;
|
||||
|
||||
#define NB_KINE_X 16
|
||||
#define NB_KINE_Y 16
|
||||
#define KINE_SCALE 3.1f
|
||||
|
||||
static bool isFirstFrame = true;
|
||||
|
||||
PxRigidDynamic* gKinematics[NB_KINE_Y][NB_KINE_X];
|
||||
|
||||
PxQuat setRotY(PxMat33& m, const PxReal angle)
|
||||
{
|
||||
m = PxMat33(PxIdentity);
|
||||
|
||||
const PxReal cos = cosf(angle);
|
||||
const PxReal sin = sinf(angle);
|
||||
|
||||
m[0][0] = m[2][2] = cos;
|
||||
m[0][2] = -sin;
|
||||
m[2][0] = sin;
|
||||
|
||||
return PxQuat(m);
|
||||
}
|
||||
|
||||
void createDynamics()
|
||||
{
|
||||
const PxU32 NbX = 8;
|
||||
const PxU32 NbY = 8;
|
||||
|
||||
const PxVec3 dims(0.2f, 0.1f, 0.2f);
|
||||
const PxReal sphereRadius = 0.2f;
|
||||
const PxReal capsuleRadius = 0.2f;
|
||||
const PxReal halfHeight = 0.5f;
|
||||
|
||||
const PxU32 NbLayers = 3;
|
||||
const float YScale = 0.4f;
|
||||
const float YStart = 6.0f;
|
||||
PxShape* boxShape = gPhysics->createShape(PxBoxGeometry(dims), *gMaterial);
|
||||
PxShape* sphereShape = gPhysics->createShape(PxSphereGeometry(sphereRadius), *gMaterial);
|
||||
PxShape* capsuleShape = gPhysics->createShape(PxCapsuleGeometry(capsuleRadius, halfHeight), *gMaterial);
|
||||
PX_UNUSED(boxShape);
|
||||
PX_UNUSED(sphereShape);
|
||||
PX_UNUSED(capsuleShape);
|
||||
PxMat33 m;
|
||||
for(PxU32 j=0;j<NbLayers;j++)
|
||||
{
|
||||
const float angle = float(j)*0.08f;
|
||||
const PxQuat rot = setRotY(m, angle);
|
||||
|
||||
const float ScaleX = 4.0f;
|
||||
const float ScaleY = 4.0f;
|
||||
|
||||
for(PxU32 y=0;y<NbY;y++)
|
||||
{
|
||||
for(PxU32 x=0;x<NbX;x++)
|
||||
{
|
||||
const float xf = (float(x)-float(NbX)*0.5f)*ScaleX;
|
||||
const float yf = (float(y)-float(NbY)*0.5f)*ScaleY;
|
||||
|
||||
PxRigidDynamic* dynamic = NULL;
|
||||
|
||||
PxU32 v = j&3;
|
||||
PxVec3 pos = PxVec3(xf, YStart + float(j)*YScale, yf);
|
||||
|
||||
switch(v)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
PxTransform pose(pos, rot);
|
||||
dynamic = gPhysics->createRigidDynamic(pose);
|
||||
dynamic->attachShape(*boxShape);
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
PxTransform pose(pos, PxQuat(PxIdentity));
|
||||
dynamic = gPhysics->createRigidDynamic(pose);
|
||||
dynamic->attachShape(*sphereShape);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
PxTransform pose(pos, rot);
|
||||
dynamic = gPhysics->createRigidDynamic(pose);
|
||||
dynamic->attachShape(*capsuleShape);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
PxRigidBodyExt::updateMassAndInertia(*dynamic, 10.f);
|
||||
|
||||
gScene->addActor(*dynamic);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void createGroudPlane()
|
||||
{
|
||||
PxTransform pose = PxTransform(PxVec3(0.0f, 0.0f, 0.0f),PxQuat(PxHalfPi, PxVec3(0.0f, 0.0f, 1.0f)));
|
||||
PxRigidStatic* actor = gPhysics->createRigidStatic(pose);
|
||||
PxShape* shape = PxRigidActorExt::createExclusiveShape(*actor, PxPlaneGeometry(), *gMaterial);
|
||||
PX_UNUSED(shape);
|
||||
gScene->addActor(*actor);
|
||||
}
|
||||
|
||||
void createKinematics()
|
||||
{
|
||||
const PxU32 NbX = NB_KINE_X;
|
||||
const PxU32 NbY = NB_KINE_Y;
|
||||
|
||||
const PxVec3 dims(1.5f, 0.2f, 1.5f);
|
||||
const PxQuat rot = PxQuat(PxIdentity);
|
||||
|
||||
const float YScale = 0.4f;
|
||||
|
||||
PxShape* shape = gPhysics->createShape(PxBoxGeometry(dims), *gMaterial);
|
||||
|
||||
|
||||
const float ScaleX = KINE_SCALE;
|
||||
const float ScaleY = KINE_SCALE;
|
||||
for(PxU32 y=0;y<NbY;y++)
|
||||
{
|
||||
for(PxU32 x=0;x<NbX;x++)
|
||||
{
|
||||
const float xf = (float(x)-float(NbX)*0.5f)*ScaleX;
|
||||
const float yf = (float(y)-float(NbY)*0.5f)*ScaleY;
|
||||
PxTransform pose(PxVec3(xf, 0.2f + YScale, yf), rot);
|
||||
PxRigidDynamic* body = gPhysics->createRigidDynamic(pose);
|
||||
body->attachShape(*shape);
|
||||
gScene->addActor(*body);
|
||||
body->setRigidBodyFlag(PxRigidBodyFlag::eKINEMATIC, true);
|
||||
|
||||
gKinematics[y][x] = body;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void updateKinematics(PxReal timeStep)
|
||||
{
|
||||
const float YScale = 0.4f;
|
||||
|
||||
PxTransform motion;
|
||||
motion.q = PxQuat(PxIdentity);
|
||||
|
||||
static float gTime = 0.0f;
|
||||
gTime += timeStep;
|
||||
|
||||
const PxU32 NbX = NB_KINE_X;
|
||||
const PxU32 NbY = NB_KINE_Y;
|
||||
|
||||
const float Coeff = 0.2f;
|
||||
|
||||
const float ScaleX = KINE_SCALE;
|
||||
const float ScaleY = KINE_SCALE;
|
||||
for(PxU32 y=0;y<NbY;y++)
|
||||
{
|
||||
for(PxU32 x=0;x<NbX;x++)
|
||||
{
|
||||
const float xf = (float(x)-float(NbX)*0.5f)*ScaleX;
|
||||
const float yf = (float(y)-float(NbY)*0.5f)*ScaleY;
|
||||
|
||||
const float h = sinf(gTime*2.0f + float(x)*Coeff + + float(y)*Coeff)*2.0f;
|
||||
motion.p = PxVec3(xf, h + 2.0f + YScale, yf);
|
||||
|
||||
PxRigidDynamic* kine = gKinematics[y][x];
|
||||
kine->setKinematicTarget(motion);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void initPhysics(bool /*interactive*/)
|
||||
{
|
||||
gFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gAllocator, gErrorCallback);
|
||||
gPvd = PxCreatePvd(*gFoundation);
|
||||
PxPvdTransport* transport = PxDefaultPvdSocketTransportCreate(PVD_HOST, 5425, 10);
|
||||
gPvd->connect(*transport,PxPvdInstrumentationFlag::eALL);
|
||||
|
||||
gPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, PxTolerancesScale(),true,gPvd);
|
||||
|
||||
PxSceneDesc sceneDesc(gPhysics->getTolerancesScale());
|
||||
sceneDesc.gravity = PxVec3(0.0f, -9.81f, 0.0f);
|
||||
gDispatcher = PxDefaultCpuDispatcherCreate(2);
|
||||
sceneDesc.cpuDispatcher = gDispatcher;
|
||||
sceneDesc.filterShader = PxDefaultSimulationFilterShader;
|
||||
gScene = gPhysics->createScene(sceneDesc);
|
||||
PxPvdSceneClient* pvdClient = gScene->getScenePvdClient();
|
||||
if(pvdClient)
|
||||
{
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONSTRAINTS, true);
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONTACTS, true);
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_SCENEQUERIES, true);
|
||||
}
|
||||
gMaterial = gPhysics->createMaterial(0.5f, 0.5f, 0.6f);
|
||||
|
||||
PxRigidStatic* groundPlane = PxCreatePlane(*gPhysics, PxPlane(0,1,0,0), *gMaterial);
|
||||
gScene->addActor(*groundPlane);
|
||||
|
||||
createKinematics();
|
||||
createDynamics();
|
||||
|
||||
}
|
||||
|
||||
#if OVERLAP_COLLISION_AND_RENDER_WITH_NO_LAG
|
||||
void stepPhysics(bool /*interactive*/)
|
||||
{
|
||||
const PxReal timeStep = 1.0f/60.0f;
|
||||
|
||||
if(isFirstFrame)
|
||||
{
|
||||
//Run the first frame's collision detection
|
||||
gScene->collide(timeStep);
|
||||
isFirstFrame = false;
|
||||
}
|
||||
//update the kinematice target pose in parallel with collision running
|
||||
updateKinematics(timeStep);
|
||||
gScene->fetchCollision(true);
|
||||
gScene->advance();
|
||||
gScene->fetchResults(true);
|
||||
|
||||
//Run the deferred collision detection for the next frame. This will run in parallel with render.
|
||||
gScene->collide(timeStep);
|
||||
}
|
||||
#elif OVERLAP_COLLISION_AND_RENDER_WITH_ONE_FRAME_LAG
|
||||
|
||||
void stepPhysics(bool /*interactive*/)
|
||||
{
|
||||
PxReal timeStep = 1.0/60.0f;
|
||||
|
||||
//update the kinematice target pose in parallel with collision running
|
||||
updateKinematics(timeStep);
|
||||
if(!isFirstFrame)
|
||||
{
|
||||
gScene->fetchCollision(true);
|
||||
gScene->advance();
|
||||
gScene->fetchResults(true);
|
||||
}
|
||||
|
||||
isFirstFrame = false;
|
||||
//Run the deferred collision detection for the next frame. This will run in parallel with render.
|
||||
gScene->collide(timeStep);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void stepPhysics(bool /*interactive*/)
|
||||
{
|
||||
PxReal timeStep = 1.0/60.0f;
|
||||
//update the kinematice target pose in parallel with collision running
|
||||
gScene->collide(timeStep);
|
||||
updateKinematics(timeStep);
|
||||
gScene->fetchCollision(true);
|
||||
gScene->advance();
|
||||
gScene->fetchResults(true);
|
||||
}
|
||||
#endif
|
||||
|
||||
void cleanupPhysics(bool /*interactive*/)
|
||||
{
|
||||
#if OVERLAP_COLLISION_AND_RENDER_WITH_NO_LAG || OVERLAP_COLLISION_AND_RENDER_WITH_ONE_FRAME_LAG
|
||||
//Close out remainder of previously running scene. If we don't do this, it will be implicitly done
|
||||
//in gScene->release() but a warning will be issued.
|
||||
gScene->fetchCollision(true);
|
||||
gScene->advance();
|
||||
gScene->fetchResults(true);
|
||||
#endif
|
||||
|
||||
PX_RELEASE(gScene);
|
||||
PX_RELEASE(gDispatcher);
|
||||
PX_RELEASE(gPhysics);
|
||||
if(gPvd)
|
||||
{
|
||||
PxPvdTransport* transport = gPvd->getTransport();
|
||||
gPvd->release(); gPvd = NULL;
|
||||
PX_RELEASE(transport);
|
||||
}
|
||||
PX_RELEASE(gFoundation);
|
||||
|
||||
printf("SnippetSplitSim done.\n");
|
||||
}
|
||||
|
||||
void keyPress(unsigned char key, const PxTransform& camer)
|
||||
{
|
||||
PX_UNUSED(key);
|
||||
PX_UNUSED(camer);
|
||||
}
|
||||
|
||||
int snippetMain(int, const char*const*)
|
||||
{
|
||||
#ifdef RENDER_SNIPPET
|
||||
extern void renderLoop();
|
||||
renderLoop();
|
||||
#else
|
||||
static const PxU32 frameCount = 100;
|
||||
initPhysics(false);
|
||||
for(PxU32 i=0; i<frameCount; i++)
|
||||
stepPhysics(false);
|
||||
cleanupPhysics(false);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
134
physx/snippets/snippetsplitsim/SnippetSplitSimRender.cpp
Normal file
134
physx/snippets/snippetsplitsim/SnippetSplitSimRender.cpp
Normal file
@ -0,0 +1,134 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifdef RENDER_SNIPPET
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
|
||||
#include "../snippetrender/SnippetRender.h"
|
||||
#include "../snippetrender/SnippetCamera.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
extern void initPhysics(bool interactive);
|
||||
extern void stepPhysics(bool interactive);
|
||||
extern void cleanupPhysics(bool interactive);
|
||||
extern void keyPress(unsigned char key, const PxTransform& camera);
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
Snippets::Camera* sCamera;
|
||||
|
||||
void motionCallback(int x, int y)
|
||||
{
|
||||
sCamera->handleMotion(x, y);
|
||||
}
|
||||
|
||||
void keyboardCallback(unsigned char key, int x, int y)
|
||||
{
|
||||
if(key==27)
|
||||
exit(0);
|
||||
|
||||
if(!sCamera->handleKey(key, x, y))
|
||||
keyPress(key, sCamera->getTransform());
|
||||
}
|
||||
|
||||
void mouseCallback(int button, int state, int x, int y)
|
||||
{
|
||||
sCamera->handleMouse(button, state, x, y);
|
||||
}
|
||||
|
||||
void idleCallback()
|
||||
{
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
void renderCallback()
|
||||
{
|
||||
stepPhysics(true);
|
||||
|
||||
|
||||
Snippets::startRender(sCamera->getEye(), sCamera->getDir());
|
||||
|
||||
PxScene* scene;
|
||||
PxGetPhysics().getScenes(&scene,1);
|
||||
PxU32 nbActors = scene->getNbActors(PxActorTypeFlag::eRIGID_DYNAMIC);
|
||||
if(nbActors)
|
||||
{
|
||||
PxVec3 dynColor(1.0f, 0.f, 1.f);
|
||||
PxVec3 kinematicColor(0.f, 1.f, 0.f);
|
||||
std::vector<PxRigidActor*> actors(nbActors);
|
||||
scene->getActors(PxActorTypeFlag::eRIGID_DYNAMIC, reinterpret_cast<PxActor**>(&actors[0]), nbActors);
|
||||
for(PxU32 i=0; i<nbActors; ++i)
|
||||
{
|
||||
PxRigidActor* actor = actors[i];
|
||||
PxRigidDynamic* dyn = actor->is<PxRigidDynamic>();
|
||||
if(dyn->getRigidBodyFlags() & PxRigidBodyFlag::eKINEMATIC)
|
||||
{
|
||||
Snippets::renderActors(&actor, 1, true, kinematicColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
Snippets::renderActors(&actor, 1, true, dynColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
Snippets::finishRender();
|
||||
}
|
||||
|
||||
void exitCallback(void)
|
||||
{
|
||||
delete sCamera;
|
||||
cleanupPhysics(true);
|
||||
}
|
||||
}
|
||||
|
||||
void renderLoop()
|
||||
{
|
||||
sCamera = new Snippets::Camera(PxVec3(50.0f, 50.0f, 50.0f), PxVec3(-0.6f,-0.2f,-0.7f));
|
||||
|
||||
Snippets::setupDefaultWindow("PhysX Snippet Split Sim");
|
||||
Snippets::setupDefaultRenderState();
|
||||
|
||||
glutIdleFunc(idleCallback);
|
||||
glutDisplayFunc(renderCallback);
|
||||
glutKeyboardFunc(keyboardCallback);
|
||||
glutMouseFunc(mouseCallback);
|
||||
glutMotionFunc(motionCallback);
|
||||
motionCallback(0,0);
|
||||
|
||||
atexit(exitCallback);
|
||||
|
||||
initPhysics(true);
|
||||
glutMainLoop();
|
||||
}
|
||||
#endif
|
||||
236
physx/snippets/snippetstepper/SnippetStepper.cpp
Normal file
236
physx/snippets/snippetstepper/SnippetStepper.cpp
Normal file
@ -0,0 +1,236 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
// ****************************************************************************
|
||||
// This snippet illustrates kinematic actor updates in a substepped simulation.
|
||||
//
|
||||
// It uses chained continuation tasks that call fetchResults and run simulation steps.
|
||||
// The scene consists of a kinematic platform interacting with a dynamic
|
||||
// sphere. The kinematic actor's target pose is updated before every substep.
|
||||
// ****************************************************************************
|
||||
|
||||
#include <new>
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
|
||||
#include "../snippetcommon/SnippetPrint.h"
|
||||
#include "../snippetcommon/SnippetPVD.h"
|
||||
#include "../snippetutils/SnippetUtils.h"
|
||||
|
||||
using namespace physx;
|
||||
using namespace SnippetUtils;
|
||||
|
||||
// The usual PhysX resources.
|
||||
PxDefaultAllocator gAllocator;
|
||||
PxDefaultErrorCallback gErrorCallback;
|
||||
|
||||
PxFoundation* gFoundation = NULL;
|
||||
PxPhysics* gPhysics = NULL;
|
||||
PxMaterial* gMaterial = NULL;
|
||||
|
||||
PxDefaultCpuDispatcher* gDispatcher = NULL;
|
||||
PxScene* gScene = NULL;
|
||||
PxRigidDynamic* gKinematic = NULL;
|
||||
|
||||
// A very simple substepping policy: just take 2 60Hz substeps per step.
|
||||
static const PxReal SUBSTEP_LENGTH = 1.0f/60.0f;
|
||||
static const PxU32 NUM_STEPS = 1000;
|
||||
static const PxI32 NUM_SUBSTEPS = 2;
|
||||
PxPvd* gPvd = NULL;
|
||||
// Context for keeping track of the stepper state.
|
||||
struct StepContext
|
||||
{
|
||||
class SubstepCompletionTask* taskPool;
|
||||
Sync* completionSync;
|
||||
PxI32 nbSubstepsFinished;
|
||||
volatile PxI32 nbTasksDestroyed;
|
||||
} gStepContext;
|
||||
|
||||
// Completion task for running a substep.
|
||||
|
||||
// The following sequencing is guaranteed:
|
||||
// * the section of the run() method up to the removeReference() in startNextSubstep() will execute prior
|
||||
// to the run() method of the task submitted by startNextSubstep()
|
||||
// * the run() method of a task will run before its release() method
|
||||
//
|
||||
// Any work done by a task after releasing the next task (via removeReference()) could end up running in
|
||||
// parallel with that task, if simulate() completes sufficiently quickly or there is a context switch. In order
|
||||
// to prevent races, it is therefore recommended that a completion task do no work after releasing the next.
|
||||
|
||||
class SubstepCompletionTask : public PxLightCpuTask
|
||||
{
|
||||
public:
|
||||
SubstepCompletionTask()
|
||||
{
|
||||
mTm = gScene->getTaskManager();
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
void startNextSubstep();
|
||||
|
||||
gScene->fetchResults(true);
|
||||
if(++gStepContext.nbSubstepsFinished < NUM_SUBSTEPS)
|
||||
startNextSubstep();
|
||||
}
|
||||
|
||||
void release()
|
||||
{
|
||||
this->~SubstepCompletionTask();
|
||||
|
||||
// If we're done with all the substeps , synchronize with the main thread. In a real application
|
||||
// we would most likely run dependent tasks instead.
|
||||
|
||||
// We can only signal completion once all substepping resources are cleaned up.
|
||||
// Release() calls may run concurrently or out of order, so we use an atomic counter.
|
||||
|
||||
if(atomicIncrement(&gStepContext.nbTasksDestroyed) == NUM_SUBSTEPS)
|
||||
syncSet(gStepContext.completionSync);
|
||||
}
|
||||
|
||||
const char* getName() const { return "Substep Completion Task"; }
|
||||
};
|
||||
|
||||
|
||||
// Update the sim inputs and start the next PhysX substep.
|
||||
|
||||
void startNextSubstep()
|
||||
{
|
||||
// Compute new target pose for the kinematic at the end of the substep.
|
||||
|
||||
static PxReal sTotalSeconds = 0.0f;
|
||||
sTotalSeconds += SUBSTEP_LENGTH;
|
||||
|
||||
const PxReal period = 4.0f;
|
||||
const PxReal amplitude = 10.0f;
|
||||
const PxReal angVel = PxTwoPi/period;
|
||||
|
||||
PxReal yPos = PxSin(angVel * sTotalSeconds) * amplitude;
|
||||
gKinematic->setKinematicTarget(PxTransform(0.0f, yPos, 0.0f));
|
||||
|
||||
// Create a completion task and set its reference count to 1. This way we can safely submit it to simulate()
|
||||
// and, even if we get context-switched and simulate() completes before we get back, the task's run()
|
||||
// method will not execute until we're ready.
|
||||
|
||||
SubstepCompletionTask* nextCompletion = new (gStepContext.taskPool+gStepContext.nbSubstepsFinished) SubstepCompletionTask();
|
||||
nextCompletion->addReference();
|
||||
|
||||
// Kick off the sim with the new completion task. Once this call returns, worker threads will update the PhysX
|
||||
// state in parallel with the rest of this function.
|
||||
|
||||
gScene->simulate(SUBSTEP_LENGTH, nextCompletion);
|
||||
|
||||
// We can do things here that can run in parallel with the simulation, but must happen before the next task's
|
||||
// run method executes. In this snippet, there's nothing to do...
|
||||
|
||||
// Finally, remove the reference that prevents the next completion task running.
|
||||
|
||||
nextCompletion->removeReference();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void runPhysics()
|
||||
{
|
||||
// Initialize the substepping context.
|
||||
syncReset(gStepContext.completionSync);
|
||||
gStepContext.nbSubstepsFinished = 0;
|
||||
gStepContext.nbTasksDestroyed = 0;
|
||||
|
||||
// Start the first substep, then wait for the last one to finish.
|
||||
startNextSubstep();
|
||||
syncWait(gStepContext.completionSync);
|
||||
}
|
||||
|
||||
void initPhysics()
|
||||
{
|
||||
gFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gAllocator, gErrorCallback);
|
||||
|
||||
gPvd = PxCreatePvd(*gFoundation);
|
||||
PxPvdTransport* transport = PxDefaultPvdSocketTransportCreate(PVD_HOST, 5425, 10);
|
||||
gPvd->connect(*transport,PxPvdInstrumentationFlag::eALL);
|
||||
|
||||
gPhysics = PxCreateBasePhysics(PX_PHYSICS_VERSION, *gFoundation, PxTolerancesScale(), true, gPvd);
|
||||
|
||||
gMaterial = gPhysics->createMaterial(0.5f, 0.5f, 0.2f);
|
||||
|
||||
PxSceneDesc desc(gPhysics->getTolerancesScale());
|
||||
desc.filterShader = PxDefaultSimulationFilterShader;
|
||||
desc.cpuDispatcher = gDispatcher = PxDefaultCpuDispatcherCreate(2);
|
||||
desc.gravity = PxVec3(0.0f, -9.81f, 0.0f);
|
||||
gScene = gPhysics->createScene(desc);
|
||||
|
||||
PxPvdSceneClient* pvdClient = gScene->getScenePvdClient();
|
||||
if(pvdClient)
|
||||
{
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONSTRAINTS, true);
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONTACTS, true);
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_SCENEQUERIES, true);
|
||||
}
|
||||
gKinematic = PxCreateKinematic(*gPhysics, PxTransform(PxIdentity), PxBoxGeometry(5.0f, 1.0f, 5.0f), *gMaterial, 1.0f);
|
||||
gScene->addActor(*gKinematic);
|
||||
|
||||
PxRigidDynamic* sphere = PxCreateDynamic(*gPhysics, PxTransform(0.0f, 5.0f, 0.0f), PxSphereGeometry(1.0f), *gMaterial, 1.0f);
|
||||
gScene->addActor(*sphere);
|
||||
}
|
||||
|
||||
void cleanupPhysics()
|
||||
{
|
||||
PX_RELEASE(gDispatcher);
|
||||
PX_RELEASE(gPhysics);
|
||||
|
||||
if(gPvd)
|
||||
{
|
||||
PxPvdTransport* transport = gPvd->getTransport();
|
||||
gPvd->release(); gPvd = NULL;
|
||||
PX_RELEASE(transport);
|
||||
}
|
||||
PX_RELEASE(gFoundation);
|
||||
}
|
||||
|
||||
int snippetMain(int, const char*const*)
|
||||
{
|
||||
initPhysics();
|
||||
|
||||
// Storage and synchronization for substepping.
|
||||
gStepContext.taskPool = reinterpret_cast<SubstepCompletionTask*>(malloc(NUM_SUBSTEPS * sizeof(SubstepCompletionTask)));
|
||||
gStepContext.completionSync = syncCreate();
|
||||
|
||||
for(PxU32 i=0; i<NUM_STEPS; i++)
|
||||
runPhysics();
|
||||
|
||||
syncRelease(gStepContext.completionSync);
|
||||
free(gStepContext.taskPool);
|
||||
|
||||
cleanupPhysics();
|
||||
|
||||
printf("SnippetStepper done.\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
178
physx/snippets/snippettolerancescale/SnippetToleranceScale.cpp
Normal file
178
physx/snippets/snippettolerancescale/SnippetToleranceScale.cpp
Normal file
@ -0,0 +1,178 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
// ********************************************************************************
|
||||
// This snippet illustrates the concept of PxToleranceScale.
|
||||
//
|
||||
// It creates 2 scenes using different units for length and mass.
|
||||
// Use PVD to replay the scene and see how scaling affects the simulation.
|
||||
// ********************************************************************************
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
|
||||
#include "../snippetcommon/SnippetPrint.h"
|
||||
#include "../snippetcommon/SnippetPVD.h"
|
||||
#include "../snippetutils/SnippetUtils.h"
|
||||
|
||||
|
||||
using namespace physx;
|
||||
|
||||
PxDefaultAllocator gAllocator;
|
||||
PxDefaultErrorCallback gErrorCallback;
|
||||
|
||||
PxFoundation* gFoundation = NULL;
|
||||
PxPhysics* gPhysics = NULL;
|
||||
|
||||
PxDefaultCpuDispatcher* gDispatcher = NULL;
|
||||
PxScene* gScene = NULL;
|
||||
|
||||
PxMaterial* gMaterial = NULL;
|
||||
|
||||
PxPvd* gPvd = NULL;
|
||||
|
||||
PxReal gStackZ = 10.0f;
|
||||
|
||||
PxRigidDynamic* createDynamic(const PxTransform& t, const PxGeometry& geometry, const PxReal& mass, const PxVec3& velocity=PxVec3(0))
|
||||
{
|
||||
PxRigidDynamic* dynamic = PxCreateDynamic(*gPhysics, t, geometry, *gMaterial, 10.0f);
|
||||
dynamic->setAngularDamping(0.5f);
|
||||
dynamic->setLinearVelocity(velocity);
|
||||
PxRigidBodyExt::setMassAndUpdateInertia(*dynamic, mass);
|
||||
gScene->addActor(*dynamic);
|
||||
return dynamic;
|
||||
}
|
||||
|
||||
void createStack(const PxTransform& t, PxU32 size, PxReal halfExtent, const PxReal& mass)
|
||||
{
|
||||
PxShape* shape = gPhysics->createShape(PxBoxGeometry(halfExtent, halfExtent, halfExtent), *gMaterial);
|
||||
for(PxU32 i=0; i<size;i++)
|
||||
{
|
||||
for(PxU32 j=0;j<size-i;j++)
|
||||
{
|
||||
PxTransform localTm(PxVec3(PxReal(j*2) - PxReal(size-i), PxReal(i*2+1), 0) * halfExtent);
|
||||
PxRigidDynamic* body = gPhysics->createRigidDynamic(t.transform(localTm));
|
||||
body->attachShape(*shape);
|
||||
PxRigidBodyExt::setMassAndUpdateInertia(*body, mass);
|
||||
gScene->addActor(*body);
|
||||
}
|
||||
}
|
||||
shape->release();
|
||||
}
|
||||
|
||||
void initPhysics(bool interactive, const PxTolerancesScale& scale, PxReal scaleMass)
|
||||
{
|
||||
gFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gAllocator, gErrorCallback);
|
||||
|
||||
gPvd = PxCreatePvd(*gFoundation);
|
||||
PxPvdTransport* transport = PxDefaultPvdSocketTransportCreate(PVD_HOST, 5425, 10);
|
||||
gPvd->connect(*transport,PxPvdInstrumentationFlag::eALL);
|
||||
|
||||
gPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, scale, true, gPvd);
|
||||
|
||||
PxReal scaleLength = scale.length;
|
||||
|
||||
PxSceneDesc sceneDesc(scale);
|
||||
sceneDesc.gravity = PxVec3(0.0f, -9.81f, 0.0f) * scaleLength;
|
||||
gDispatcher = PxDefaultCpuDispatcherCreate(2);
|
||||
sceneDesc.cpuDispatcher = gDispatcher;
|
||||
sceneDesc.filterShader = PxDefaultSimulationFilterShader;
|
||||
gScene = gPhysics->createScene(sceneDesc);
|
||||
|
||||
PxPvdSceneClient* pvdClient = gScene->getScenePvdClient();
|
||||
if(pvdClient)
|
||||
{
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONSTRAINTS, true);
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONTACTS, true);
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_SCENEQUERIES, true);
|
||||
}
|
||||
|
||||
gMaterial = gPhysics->createMaterial(0.5f, 0.5f, 0.6f);
|
||||
|
||||
PxRigidStatic* groundPlane = PxCreatePlane(*gPhysics, PxPlane(0,1,0,0), *gMaterial);
|
||||
gScene->addActor(*groundPlane);
|
||||
|
||||
for(PxU32 i=0;i<5;i++)
|
||||
createStack(PxTransform(PxVec3(0,0,gStackZ-=10.0f) * scaleLength), 10, 2.0f * scaleLength, 1.0f * scaleMass);
|
||||
|
||||
if(!interactive)
|
||||
createDynamic(PxTransform(PxVec3(0,40,100) * scaleLength), PxSphereGeometry(10 * scaleLength), 100.0f * scaleMass, PxVec3(0,-50,-100) * scaleLength);
|
||||
}
|
||||
|
||||
void stepPhysics(bool /*interactive*/)
|
||||
{
|
||||
gScene->simulate(1.0f/60.0f);
|
||||
gScene->fetchResults(true);
|
||||
}
|
||||
|
||||
void cleanupPhysics(bool /*interactive*/)
|
||||
{
|
||||
PX_RELEASE(gScene);
|
||||
PX_RELEASE(gDispatcher);
|
||||
PX_RELEASE(gPhysics);
|
||||
if(gPvd)
|
||||
{
|
||||
PxPvdTransport* transport = gPvd->getTransport();
|
||||
gPvd->release(); gPvd = NULL;
|
||||
PX_RELEASE(transport);
|
||||
}
|
||||
PX_RELEASE(gFoundation);
|
||||
}
|
||||
|
||||
void runSim(const PxTolerancesScale& scale, PxReal scaleMass)
|
||||
{
|
||||
static const PxU32 frameCount = 150;
|
||||
initPhysics(false, scale, scaleMass);
|
||||
for(PxU32 i=0; i<frameCount; i++)
|
||||
stepPhysics(false);
|
||||
cleanupPhysics(false);
|
||||
}
|
||||
|
||||
int snippetMain(int, const char*const*)
|
||||
{
|
||||
PxTolerancesScale scale;
|
||||
|
||||
// Default
|
||||
printf("PxToleranceScale (Default).\n");
|
||||
runSim(scale, 1000.0f);
|
||||
|
||||
// Reset position of pyramid stack z coordinate to default
|
||||
gStackZ = 10.0f;
|
||||
|
||||
// Scaled assets
|
||||
printf("PxToleranceScale (Scaled).\n");
|
||||
scale.length = 100; // length in cm
|
||||
scale.speed *= scale.length; // speed in cm/s
|
||||
runSim(scale, 1.0f);
|
||||
|
||||
printf("SnippetToleranceScale done.\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -0,0 +1,394 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
// ****************************************************************************
|
||||
// This snippet demonstrates the possibilities of triangle mesh creation.
|
||||
//
|
||||
// The snippet creates triangle mesh with a different cooking settings
|
||||
// and shows how these settings affect the triangle mesh creation speed.
|
||||
// ****************************************************************************
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
|
||||
#include "../snippetutils/SnippetUtils.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
PxDefaultAllocator gAllocator;
|
||||
PxDefaultErrorCallback gErrorCallback;
|
||||
|
||||
PxFoundation* gFoundation = NULL;
|
||||
PxPhysics* gPhysics = NULL;
|
||||
PxCooking* gCooking = NULL;
|
||||
|
||||
float rand(float loVal, float hiVal)
|
||||
{
|
||||
return loVal + float(rand()/float(RAND_MAX))*(hiVal - loVal);
|
||||
}
|
||||
|
||||
PxU32 rand(PxU32 loVal, PxU32 hiVal)
|
||||
{
|
||||
return loVal + PxU32(rand()%(hiVal - loVal));
|
||||
}
|
||||
|
||||
void indexToCoord(PxU32& x, PxU32& z, PxU32 index, PxU32 w)
|
||||
{
|
||||
x = index % w;
|
||||
z = index / w;
|
||||
}
|
||||
|
||||
// Creates a random terrain data.
|
||||
void createRandomTerrain(const PxVec3& origin, PxU32 numRows, PxU32 numColumns,
|
||||
PxReal cellSizeRow, PxReal cellSizeCol, PxReal heightScale,
|
||||
PxVec3*& vertices, PxU32*& indices)
|
||||
{
|
||||
PxU32 numX = (numColumns + 1);
|
||||
PxU32 numZ = (numRows + 1);
|
||||
PxU32 numVertices = numX*numZ;
|
||||
PxU32 numTriangles = numRows*numColumns * 2;
|
||||
|
||||
if (vertices == NULL)
|
||||
vertices = new PxVec3[numVertices];
|
||||
if (indices == NULL)
|
||||
indices = new PxU32[numTriangles * 3];
|
||||
|
||||
PxU32 currentIdx = 0;
|
||||
for (PxU32 i = 0; i <= numRows; i++)
|
||||
{
|
||||
for (PxU32 j = 0; j <= numColumns; j++)
|
||||
{
|
||||
PxVec3 v(origin.x + PxReal(j)*cellSizeRow, origin.y, origin.z + PxReal(i)*cellSizeCol);
|
||||
vertices[currentIdx++] = v;
|
||||
}
|
||||
}
|
||||
|
||||
currentIdx = 0;
|
||||
for (PxU32 i = 0; i < numRows; i++)
|
||||
{
|
||||
for (PxU32 j = 0; j < numColumns; j++)
|
||||
{
|
||||
PxU32 base = (numColumns + 1)*i + j;
|
||||
indices[currentIdx++] = base + 1;
|
||||
indices[currentIdx++] = base;
|
||||
indices[currentIdx++] = base + numColumns + 1;
|
||||
indices[currentIdx++] = base + numColumns + 2;
|
||||
indices[currentIdx++] = base + 1;
|
||||
indices[currentIdx++] = base + numColumns + 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (PxU32 i = 0; i < numVertices; i++)
|
||||
{
|
||||
PxVec3& v = vertices[i];
|
||||
v.y += heightScale * rand(-1.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
// Setup common cooking params
|
||||
void setupCommonCookingParams(PxCookingParams& params, bool skipMeshCleanup, bool skipEdgeData)
|
||||
{
|
||||
// we suppress the triangle mesh remap table computation to gain some speed, as we will not need it
|
||||
// in this snippet
|
||||
params.suppressTriangleMeshRemapTable = true;
|
||||
|
||||
// If DISABLE_CLEAN_MESH is set, the mesh is not cleaned during the cooking. The input mesh must be valid.
|
||||
// The following conditions are true for a valid triangle mesh :
|
||||
// 1. There are no duplicate vertices(within specified vertexWeldTolerance.See PxCookingParams::meshWeldTolerance)
|
||||
// 2. There are no large triangles(within specified PxTolerancesScale.)
|
||||
// It is recommended to run a separate validation check in debug/checked builds, see below.
|
||||
|
||||
if (!skipMeshCleanup)
|
||||
params.meshPreprocessParams &= ~static_cast<PxMeshPreprocessingFlags>(PxMeshPreprocessingFlag::eDISABLE_CLEAN_MESH);
|
||||
else
|
||||
params.meshPreprocessParams |= PxMeshPreprocessingFlag::eDISABLE_CLEAN_MESH;
|
||||
|
||||
// If DISABLE_ACTIVE_EDGES_PREDOCOMPUTE is set, the cooking does not compute the active (convex) edges, and instead
|
||||
// marks all edges as active. This makes cooking faster but can slow down contact generation. This flag may change
|
||||
// the collision behavior, as all edges of the triangle mesh will now be considered active.
|
||||
if (!skipEdgeData)
|
||||
params.meshPreprocessParams &= ~static_cast<PxMeshPreprocessingFlags>(PxMeshPreprocessingFlag::eDISABLE_ACTIVE_EDGES_PRECOMPUTE);
|
||||
else
|
||||
params.meshPreprocessParams |= PxMeshPreprocessingFlag::eDISABLE_ACTIVE_EDGES_PRECOMPUTE;
|
||||
}
|
||||
|
||||
// Creates a triangle mesh using BVH33 midphase with different settings.
|
||||
void createBV33TriangleMesh(PxU32 numVertices, const PxVec3* vertices, PxU32 numTriangles, const PxU32* indices,
|
||||
bool skipMeshCleanup, bool skipEdgeData, bool inserted, bool cookingPerformance, bool meshSizePerfTradeoff)
|
||||
{
|
||||
PxU64 startTime = SnippetUtils::getCurrentTimeCounterValue();
|
||||
|
||||
PxTriangleMeshDesc meshDesc;
|
||||
meshDesc.points.count = numVertices;
|
||||
meshDesc.points.data = vertices;
|
||||
meshDesc.points.stride = sizeof(PxVec3);
|
||||
meshDesc.triangles.count = numTriangles;
|
||||
meshDesc.triangles.data = indices;
|
||||
meshDesc.triangles.stride = 3 * sizeof(PxU32);
|
||||
|
||||
PxCookingParams params = gCooking->getParams();
|
||||
|
||||
// Create BVH33 midphase
|
||||
params.midphaseDesc = PxMeshMidPhase::eBVH33;
|
||||
|
||||
// setup common cooking params
|
||||
setupCommonCookingParams(params, skipMeshCleanup, skipEdgeData);
|
||||
|
||||
// The COOKING_PERFORMANCE flag for BVH33 midphase enables a fast cooking path at the expense of somewhat lower quality BVH construction.
|
||||
if (cookingPerformance)
|
||||
params.midphaseDesc.mBVH33Desc.meshCookingHint = PxMeshCookingHint::eCOOKING_PERFORMANCE;
|
||||
else
|
||||
params.midphaseDesc.mBVH33Desc.meshCookingHint = PxMeshCookingHint::eSIM_PERFORMANCE;
|
||||
|
||||
// If meshSizePerfTradeoff is set to true, smaller mesh cooked mesh is produced. The mesh size/performance trade-off
|
||||
// is controlled by setting the meshSizePerformanceTradeOff from 0.0f (smaller mesh) to 1.0f (larger mesh).
|
||||
if(meshSizePerfTradeoff)
|
||||
{
|
||||
params.midphaseDesc.mBVH33Desc.meshSizePerformanceTradeOff = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
// using the default value
|
||||
params.midphaseDesc.mBVH33Desc.meshSizePerformanceTradeOff = 0.55f;
|
||||
}
|
||||
|
||||
gCooking->setParams(params);
|
||||
|
||||
#if defined(PX_CHECKED) || defined(PX_DEBUG)
|
||||
// If DISABLE_CLEAN_MESH is set, the mesh is not cleaned during the cooking.
|
||||
// We should check the validity of provided triangles in debug/checked builds though.
|
||||
if (skipMeshCleanup)
|
||||
{
|
||||
PX_ASSERT(gCooking->validateTriangleMesh(meshDesc));
|
||||
}
|
||||
#endif // DEBUG
|
||||
|
||||
|
||||
PxTriangleMesh* triMesh = NULL;
|
||||
PxU32 meshSize = 0;
|
||||
|
||||
// The cooked mesh may either be saved to a stream for later loading, or inserted directly into PxPhysics.
|
||||
if (inserted)
|
||||
{
|
||||
triMesh = gCooking->createTriangleMesh(meshDesc, gPhysics->getPhysicsInsertionCallback());
|
||||
}
|
||||
else
|
||||
{
|
||||
PxDefaultMemoryOutputStream outBuffer;
|
||||
gCooking->cookTriangleMesh(meshDesc, outBuffer);
|
||||
|
||||
PxDefaultMemoryInputData stream(outBuffer.getData(), outBuffer.getSize());
|
||||
triMesh = gPhysics->createTriangleMesh(stream);
|
||||
|
||||
meshSize = outBuffer.getSize();
|
||||
}
|
||||
|
||||
// Print the elapsed time for comparison
|
||||
PxU64 stopTime = SnippetUtils::getCurrentTimeCounterValue();
|
||||
float elapsedTime = SnippetUtils::getElapsedTimeInMilliseconds(stopTime - startTime);
|
||||
printf("\t -----------------------------------------------\n");
|
||||
printf("\t Create triangle mesh with %d triangles: \n",numTriangles);
|
||||
cookingPerformance ? printf("\t\t Cooking performance on\n") : printf("\t\t Cooking performance off\n");
|
||||
inserted ? printf("\t\t Mesh inserted on\n") : printf("\t\t Mesh inserted off\n");
|
||||
!skipEdgeData ? printf("\t\t Precompute edge data on\n") : printf("\t\t Precompute edge data off\n");
|
||||
!skipMeshCleanup ? printf("\t\t Mesh cleanup on\n") : printf("\t\t Mesh cleanup off\n");
|
||||
printf("\t\t Mesh size/performance trade-off: %f \n", double(params.midphaseDesc.mBVH33Desc.meshSizePerformanceTradeOff));
|
||||
printf("\t Elapsed time in ms: %f \n", double(elapsedTime));
|
||||
if(!inserted)
|
||||
{
|
||||
printf("\t Mesh size: %d \n", meshSize);
|
||||
}
|
||||
|
||||
triMesh->release();
|
||||
}
|
||||
|
||||
// Creates a triangle mesh using BVH34 midphase with different settings.
|
||||
void createBV34TriangleMesh(PxU32 numVertices, const PxVec3* vertices, PxU32 numTriangles, const PxU32* indices,
|
||||
bool skipMeshCleanup, bool skipEdgeData, bool inserted, const PxU32 numTrisPerLeaf)
|
||||
{
|
||||
PxU64 startTime = SnippetUtils::getCurrentTimeCounterValue();
|
||||
|
||||
PxTriangleMeshDesc meshDesc;
|
||||
meshDesc.points.count = numVertices;
|
||||
meshDesc.points.data = vertices;
|
||||
meshDesc.points.stride = sizeof(PxVec3);
|
||||
meshDesc.triangles.count = numTriangles;
|
||||
meshDesc.triangles.data = indices;
|
||||
meshDesc.triangles.stride = 3 * sizeof(PxU32);
|
||||
|
||||
PxCookingParams params = gCooking->getParams();
|
||||
|
||||
// Create BVH34 midphase
|
||||
params.midphaseDesc = PxMeshMidPhase::eBVH34;
|
||||
|
||||
// setup common cooking params
|
||||
setupCommonCookingParams(params, skipMeshCleanup, skipEdgeData);
|
||||
|
||||
// Cooking mesh with less triangles per leaf produces larger meshes with better runtime performance
|
||||
// and worse cooking performance. Cooking time is better when more triangles per leaf are used.
|
||||
params.midphaseDesc.mBVH34Desc.numPrimsPerLeaf = numTrisPerLeaf;
|
||||
|
||||
gCooking->setParams(params);
|
||||
|
||||
#if defined(PX_CHECKED) || defined(PX_DEBUG)
|
||||
// If DISABLE_CLEAN_MESH is set, the mesh is not cleaned during the cooking.
|
||||
// We should check the validity of provided triangles in debug/checked builds though.
|
||||
if (skipMeshCleanup)
|
||||
{
|
||||
PX_ASSERT(gCooking->validateTriangleMesh(meshDesc));
|
||||
}
|
||||
#endif // DEBUG
|
||||
|
||||
|
||||
PxTriangleMesh* triMesh = NULL;
|
||||
PxU32 meshSize = 0;
|
||||
|
||||
// The cooked mesh may either be saved to a stream for later loading, or inserted directly into PxPhysics.
|
||||
if (inserted)
|
||||
{
|
||||
triMesh = gCooking->createTriangleMesh(meshDesc, gPhysics->getPhysicsInsertionCallback());
|
||||
}
|
||||
else
|
||||
{
|
||||
PxDefaultMemoryOutputStream outBuffer;
|
||||
gCooking->cookTriangleMesh(meshDesc, outBuffer);
|
||||
|
||||
PxDefaultMemoryInputData stream(outBuffer.getData(), outBuffer.getSize());
|
||||
triMesh = gPhysics->createTriangleMesh(stream);
|
||||
|
||||
meshSize = outBuffer.getSize();
|
||||
}
|
||||
|
||||
// Print the elapsed time for comparison
|
||||
PxU64 stopTime = SnippetUtils::getCurrentTimeCounterValue();
|
||||
float elapsedTime = SnippetUtils::getElapsedTimeInMilliseconds(stopTime - startTime);
|
||||
printf("\t -----------------------------------------------\n");
|
||||
printf("\t Create triangle mesh with %d triangles: \n", numTriangles);
|
||||
inserted ? printf("\t\t Mesh inserted on\n") : printf("\t\t Mesh inserted off\n");
|
||||
!skipEdgeData ? printf("\t\t Precompute edge data on\n") : printf("\t\t Precompute edge data off\n");
|
||||
!skipMeshCleanup ? printf("\t\t Mesh cleanup on\n") : printf("\t\t Mesh cleanup off\n");
|
||||
printf("\t\t Num triangles per leaf: %d \n", numTrisPerLeaf);
|
||||
printf("\t Elapsed time in ms: %f \n", double(elapsedTime));
|
||||
if (!inserted)
|
||||
{
|
||||
printf("\t Mesh size: %d \n", meshSize);
|
||||
}
|
||||
|
||||
triMesh->release();
|
||||
}
|
||||
|
||||
void createTriangleMeshes()
|
||||
{
|
||||
const PxU32 numColumns = 128;
|
||||
const PxU32 numRows = 128;
|
||||
const PxU32 numVertices = (numColumns + 1)*(numRows + 1);
|
||||
const PxU32 numTriangles = numColumns*numRows * 2;
|
||||
|
||||
PxVec3* vertices = new PxVec3[numVertices];
|
||||
PxU32* indices = new PxU32[numTriangles * 3];
|
||||
|
||||
srand(50);
|
||||
|
||||
createRandomTerrain(PxVec3(0.0f, 0.0f, 0.0f), numRows, numColumns, 1.0f, 1.0f, 1.f, vertices, indices);
|
||||
|
||||
// Create triangle mesh using BVH33 midphase with different settings
|
||||
printf("-----------------------------------------------\n");
|
||||
printf("Create triangles mesh using BVH33 midphase: \n\n");
|
||||
|
||||
// Favor runtime speed, cleaning the mesh and precomputing active edges. Store the mesh in a stream.
|
||||
// These are the default settings, suitable for offline cooking.
|
||||
createBV33TriangleMesh(numVertices,vertices,numTriangles,indices, false, false, false, false, false);
|
||||
|
||||
// Favor mesh size, cleaning the mesh and precomputing active edges. Store the mesh in a stream.
|
||||
createBV33TriangleMesh(numVertices, vertices, numTriangles, indices, false, false, false, false, true);
|
||||
|
||||
// Favor cooking speed, skip mesh cleanup, but precompute active edges. Insert into PxPhysics.
|
||||
// These settings are suitable for runtime cooking, although selecting fast cooking may reduce
|
||||
// runtime performance of simulation and queries. We still need to ensure the triangles
|
||||
// are valid, so we perform a validation check in debug/checked builds.
|
||||
createBV33TriangleMesh(numVertices,vertices,numTriangles,indices, true, false, true, true, false);
|
||||
|
||||
// Favor cooking speed, skip mesh cleanup, and don't precompute the active edges. Insert into PxPhysics.
|
||||
// This is the fastest possible solution for runtime cooking, but all edges are marked as active, which can
|
||||
// further reduce runtime performance, and also affect behavior.
|
||||
createBV33TriangleMesh(numVertices,vertices,numTriangles,indices, false, true, true, true, false);
|
||||
|
||||
// Create triangle mesh using BVH34 midphase with different settings
|
||||
printf("-----------------------------------------------\n");
|
||||
printf("Create triangles mesh using BVH34 midphase: \n\n");
|
||||
|
||||
// Favor runtime speed, cleaning the mesh and precomputing active edges. Store the mesh in a stream.
|
||||
// These are the default settings, suitable for offline cooking.
|
||||
createBV34TriangleMesh(numVertices, vertices, numTriangles, indices, false, false, false, 4);
|
||||
|
||||
// Favor mesh size, cleaning the mesh and precomputing active edges. Store the mesh in a stream.
|
||||
createBV34TriangleMesh(numVertices, vertices, numTriangles, indices, false, false, false, 15);
|
||||
|
||||
// Favor cooking speed, skip mesh cleanup, but precompute active edges. Insert into PxPhysics.
|
||||
// These settings are suitable for runtime cooking, although selecting more triangles per leaf may reduce
|
||||
// runtime performance of simulation and queries. We still need to ensure the triangles
|
||||
// are valid, so we perform a validation check in debug/checked builds.
|
||||
createBV34TriangleMesh(numVertices, vertices, numTriangles, indices, true, false, true, 15);
|
||||
|
||||
// Favor cooking speed, skip mesh cleanup, and don't precompute the active edges. Insert into PxPhysics.
|
||||
// This is the fastest possible solution for runtime cooking, but all edges are marked as active, which can
|
||||
// further reduce runtime performance, and also affect behavior.
|
||||
createBV34TriangleMesh(numVertices, vertices, numTriangles, indices, false, true, true, 15);
|
||||
|
||||
delete [] vertices;
|
||||
delete [] indices;
|
||||
}
|
||||
|
||||
void initPhysics()
|
||||
{
|
||||
gFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gAllocator, gErrorCallback);
|
||||
gPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, PxTolerancesScale(),true);
|
||||
gCooking = PxCreateCooking(PX_PHYSICS_VERSION, *gFoundation, PxCookingParams(PxTolerancesScale()));
|
||||
|
||||
createTriangleMeshes();
|
||||
}
|
||||
|
||||
void cleanupPhysics()
|
||||
{
|
||||
gPhysics->release();
|
||||
gCooking->release();
|
||||
gFoundation->release();
|
||||
|
||||
printf("SnippetTriangleMeshCreate done.\n");
|
||||
}
|
||||
|
||||
|
||||
int snippetMain(int, const char*const*)
|
||||
{
|
||||
initPhysics();
|
||||
cleanupPhysics();
|
||||
|
||||
return 0;
|
||||
}
|
||||
528
physx/snippets/snippettriggers/SnippetTriggers.cpp
Normal file
528
physx/snippets/snippettriggers/SnippetTriggers.cpp
Normal file
@ -0,0 +1,528 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
// ****************************************************************************
|
||||
// This snippet illustrates the use of built-in triggers, and how to emulate
|
||||
// them with regular shapes if you need CCD or trigger-trigger notifications.
|
||||
//
|
||||
// ****************************************************************************
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
|
||||
#include "../snippetutils/SnippetUtils.h"
|
||||
#include "../snippetcommon/SnippetPrint.h"
|
||||
#include "../snippetcommon/SnippetPVD.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
enum TriggerImpl
|
||||
{
|
||||
// Uses built-in triggers (PxShapeFlag::eTRIGGER_SHAPE).
|
||||
REAL_TRIGGERS,
|
||||
|
||||
// Emulates triggers using a filter shader. Needs one reserved value in PxFilterData.
|
||||
FILTER_SHADER,
|
||||
|
||||
// Emulates triggers using a filter callback. Doesn't use PxFilterData but needs user-defined way to mark a shape as a trigger.
|
||||
FILTER_CALLBACK,
|
||||
};
|
||||
|
||||
struct ScenarioData
|
||||
{
|
||||
TriggerImpl mImpl;
|
||||
bool mCCD;
|
||||
bool mTriggerTrigger;
|
||||
};
|
||||
|
||||
#define SCENARIO_COUNT 9
|
||||
|
||||
static ScenarioData gData[SCENARIO_COUNT] = {
|
||||
{REAL_TRIGGERS, false, false},
|
||||
{FILTER_SHADER, false, false},
|
||||
{FILTER_CALLBACK, false, false},
|
||||
{REAL_TRIGGERS, true, false},
|
||||
{FILTER_SHADER, true, false},
|
||||
{FILTER_CALLBACK, true, false},
|
||||
{REAL_TRIGGERS, false, true},
|
||||
{FILTER_SHADER, false, true},
|
||||
{FILTER_CALLBACK, false, true},
|
||||
};
|
||||
|
||||
static PxU32 gScenario = 0;
|
||||
|
||||
static PX_FORCE_INLINE TriggerImpl getImpl() { return gData[gScenario].mImpl; }
|
||||
static PX_FORCE_INLINE bool usesCCD() { return gData[gScenario].mCCD; }
|
||||
static PX_FORCE_INLINE bool usesTriggerTrigger() { return gData[gScenario].mTriggerTrigger; }
|
||||
|
||||
static PxDefaultAllocator gAllocator;
|
||||
static PxDefaultErrorCallback gErrorCallback;
|
||||
|
||||
static PxFoundation* gFoundation = NULL;
|
||||
static PxPhysics* gPhysics = NULL;
|
||||
|
||||
static PxDefaultCpuDispatcher* gDispatcher = NULL;
|
||||
static PxScene* gScene = NULL;
|
||||
static PxMaterial* gMaterial = NULL;
|
||||
static PxPvd* gPvd = NULL;
|
||||
|
||||
static bool gPause = false;
|
||||
static bool gOneFrame = false;
|
||||
|
||||
// Detects a trigger using the shape's simulation filter data. See createTriggerShape() function.
|
||||
bool isTrigger(const PxFilterData& data)
|
||||
{
|
||||
if(data.word0!=0xffffffff)
|
||||
return false;
|
||||
if(data.word1!=0xffffffff)
|
||||
return false;
|
||||
if(data.word2!=0xffffffff)
|
||||
return false;
|
||||
if(data.word3!=0xffffffff)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isTriggerShape(PxShape* shape)
|
||||
{
|
||||
const TriggerImpl impl = getImpl();
|
||||
|
||||
// Detects native built-in triggers.
|
||||
if(impl==REAL_TRIGGERS && (shape->getFlags() & PxShapeFlag::eTRIGGER_SHAPE))
|
||||
return true;
|
||||
|
||||
// Detects our emulated triggers using the simulation filter data. See createTriggerShape() function.
|
||||
if(impl==FILTER_SHADER && ::isTrigger(shape->getSimulationFilterData()))
|
||||
return true;
|
||||
|
||||
// Detects our emulated triggers using the simulation filter callback. See createTriggerShape() function.
|
||||
if(impl==FILTER_CALLBACK && shape->userData)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static PxFilterFlags triggersUsingFilterShader(PxFilterObjectAttributes /*attributes0*/, PxFilterData filterData0,
|
||||
PxFilterObjectAttributes /*attributes1*/, PxFilterData filterData1,
|
||||
PxPairFlags& pairFlags, const void* /*constantBlock*/, PxU32 /*constantBlockSize*/)
|
||||
{
|
||||
// printf("contactReportFilterShader\n");
|
||||
|
||||
PX_ASSERT(getImpl()==FILTER_SHADER);
|
||||
|
||||
// We need to detect whether one of the shapes is a trigger.
|
||||
const bool isTriggerPair = isTrigger(filterData0) || isTrigger(filterData1);
|
||||
|
||||
// If we have a trigger, replicate the trigger codepath from PxDefaultSimulationFilterShader
|
||||
if(isTriggerPair)
|
||||
{
|
||||
pairFlags = PxPairFlag::eTRIGGER_DEFAULT;
|
||||
|
||||
if(usesCCD())
|
||||
pairFlags |= PxPairFlag::eDETECT_CCD_CONTACT;
|
||||
|
||||
return PxFilterFlag::eDEFAULT;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise use the default flags for regular pairs
|
||||
pairFlags = PxPairFlag::eCONTACT_DEFAULT;
|
||||
return PxFilterFlag::eDEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
static PxFilterFlags triggersUsingFilterCallback(PxFilterObjectAttributes /*attributes0*/, PxFilterData /*filterData0*/,
|
||||
PxFilterObjectAttributes /*attributes1*/, PxFilterData /*filterData1*/,
|
||||
PxPairFlags& pairFlags, const void* /*constantBlock*/, PxU32 /*constantBlockSize*/)
|
||||
{
|
||||
// printf("contactReportFilterShader\n");
|
||||
|
||||
PX_ASSERT(getImpl()==FILTER_CALLBACK);
|
||||
|
||||
pairFlags = PxPairFlag::eCONTACT_DEFAULT;
|
||||
|
||||
if(usesCCD())
|
||||
pairFlags |= PxPairFlag::eDETECT_CCD_CONTACT|PxPairFlag::eNOTIFY_TOUCH_CCD;
|
||||
|
||||
return PxFilterFlag::eCALLBACK;
|
||||
}
|
||||
|
||||
class TriggersFilterCallback : public PxSimulationFilterCallback
|
||||
{
|
||||
virtual PxFilterFlags pairFound(PxU32 /*pairID*/,
|
||||
PxFilterObjectAttributes /*attributes0*/, PxFilterData /*filterData0*/, const PxActor* /*a0*/, const PxShape* s0,
|
||||
PxFilterObjectAttributes /*attributes1*/, PxFilterData /*filterData1*/, const PxActor* /*a1*/, const PxShape* s1,
|
||||
PxPairFlags& pairFlags)
|
||||
{
|
||||
// printf("pairFound\n");
|
||||
|
||||
if(s0->userData || s1->userData) // See createTriggerShape() function
|
||||
{
|
||||
pairFlags = PxPairFlag::eTRIGGER_DEFAULT;
|
||||
|
||||
if(usesCCD())
|
||||
pairFlags |= PxPairFlag::eDETECT_CCD_CONTACT|PxPairFlag::eNOTIFY_TOUCH_CCD;
|
||||
}
|
||||
else
|
||||
pairFlags = PxPairFlag::eCONTACT_DEFAULT;
|
||||
|
||||
return PxFilterFlags();
|
||||
}
|
||||
|
||||
virtual void pairLost(PxU32 /*pairID*/,
|
||||
PxFilterObjectAttributes /*attributes0*/,
|
||||
PxFilterData /*filterData0*/,
|
||||
PxFilterObjectAttributes /*attributes1*/,
|
||||
PxFilterData /*filterData1*/,
|
||||
bool /*objectRemoved*/)
|
||||
{
|
||||
// printf("pairLost\n");
|
||||
}
|
||||
|
||||
virtual bool statusChange(PxU32& /*pairID*/, PxPairFlags& /*pairFlags*/, PxFilterFlags& /*filterFlags*/)
|
||||
{
|
||||
// printf("statusChange\n");
|
||||
return false;
|
||||
}
|
||||
}gTriggersFilterCallback;
|
||||
|
||||
class ContactReportCallback: public PxSimulationEventCallback
|
||||
{
|
||||
void onConstraintBreak(PxConstraintInfo* /*constraints*/, PxU32 /*count*/)
|
||||
{
|
||||
printf("onConstraintBreak\n");
|
||||
}
|
||||
|
||||
void onWake(PxActor** /*actors*/, PxU32 /*count*/)
|
||||
{
|
||||
printf("onWake\n");
|
||||
}
|
||||
|
||||
void onSleep(PxActor** /*actors*/, PxU32 /*count*/)
|
||||
{
|
||||
printf("onSleep\n");
|
||||
}
|
||||
|
||||
void onTrigger(PxTriggerPair* pairs, PxU32 count)
|
||||
{
|
||||
// printf("onTrigger: %d trigger pairs\n", count);
|
||||
while(count--)
|
||||
{
|
||||
const PxTriggerPair& current = *pairs++;
|
||||
if(current.status & PxPairFlag::eNOTIFY_TOUCH_FOUND)
|
||||
printf("Shape is entering trigger volume\n");
|
||||
if(current.status & PxPairFlag::eNOTIFY_TOUCH_LOST)
|
||||
printf("Shape is leaving trigger volume\n");
|
||||
}
|
||||
}
|
||||
|
||||
void onAdvance(const PxRigidBody*const*, const PxTransform*, const PxU32)
|
||||
{
|
||||
printf("onAdvance\n");
|
||||
}
|
||||
|
||||
void onContact(const PxContactPairHeader& /*pairHeader*/, const PxContactPair* pairs, PxU32 count)
|
||||
{
|
||||
// printf("onContact: %d pairs\n", count);
|
||||
|
||||
while(count--)
|
||||
{
|
||||
const PxContactPair& current = *pairs++;
|
||||
|
||||
// The reported pairs can be trigger pairs or not. We only enabled contact reports for
|
||||
// trigger pairs in the filter shader, so we don't need to do further checks here. In a
|
||||
// real-world scenario you would probably need a way to tell whether one of the shapes
|
||||
// is a trigger or not. You could e.g. reuse the PxFilterData like we did in the filter
|
||||
// shader, or maybe use the shape's userData to identify triggers, or maybe put triggers
|
||||
// in a hash-set and test the reported shape pointers against it. Many options here.
|
||||
|
||||
if(current.events & (PxPairFlag::eNOTIFY_TOUCH_FOUND|PxPairFlag::eNOTIFY_TOUCH_CCD))
|
||||
printf("Shape is entering trigger volume\n");
|
||||
if(current.events & PxPairFlag::eNOTIFY_TOUCH_LOST)
|
||||
printf("Shape is leaving trigger volume\n");
|
||||
|
||||
if(isTriggerShape(current.shapes[0]) && isTriggerShape(current.shapes[1]))
|
||||
printf("Trigger-trigger overlap detected\n");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static ContactReportCallback gContactReportCallback;
|
||||
|
||||
static PxShape* createTriggerShape(const PxGeometry& geom, bool isExclusive)
|
||||
{
|
||||
const TriggerImpl impl = getImpl();
|
||||
|
||||
PxShape* shape = nullptr;
|
||||
if(impl==REAL_TRIGGERS)
|
||||
{
|
||||
const PxShapeFlags shapeFlags = PxShapeFlag::eVISUALIZATION | PxShapeFlag::eTRIGGER_SHAPE;
|
||||
shape = gPhysics->createShape(geom, *gMaterial, isExclusive, shapeFlags);
|
||||
}
|
||||
else if(impl==FILTER_SHADER)
|
||||
{
|
||||
PxShapeFlags shapeFlags = PxShapeFlag::eVISUALIZATION | PxShapeFlag::eSIMULATION_SHAPE;
|
||||
shape = gPhysics->createShape(geom, *gMaterial, isExclusive, shapeFlags);
|
||||
|
||||
// For this method to work, you need a way to mark shapes as triggers without using PxShapeFlag::eTRIGGER_SHAPE
|
||||
// (so that trigger-trigger pairs are reported), and without calling a PxShape function (so that the data is
|
||||
// available in a filter shader).
|
||||
//
|
||||
// One way is to reserve a special PxFilterData value/mask for triggers. It may not always be possible depending
|
||||
// on how you otherwise use the filter data).
|
||||
const PxFilterData triggerFilterData(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff);
|
||||
shape->setSimulationFilterData(triggerFilterData);
|
||||
}
|
||||
else if(impl==FILTER_CALLBACK)
|
||||
{
|
||||
// We will have access to shape pointers in the filter callback so we just mark triggers in an arbitrary way here,
|
||||
// for example using the shape's userData.
|
||||
shape = gPhysics->createShape(geom, *gMaterial, isExclusive);
|
||||
shape->userData = shape; // Arbitrary rule: it's a trigger if non null
|
||||
}
|
||||
return shape;
|
||||
}
|
||||
|
||||
static void createDefaultScene()
|
||||
{
|
||||
const bool ccd = usesCCD();
|
||||
|
||||
// Create trigger shape
|
||||
{
|
||||
const PxVec3 halfExtent(10.0f, ccd ? 0.01f : 1.0f, 10.0f);
|
||||
PxShape* shape = createTriggerShape(PxBoxGeometry(halfExtent), false);
|
||||
|
||||
if(shape)
|
||||
{
|
||||
PxRigidStatic* body = gPhysics->createRigidStatic(PxTransform(0.0f, 10.0f, 0.0f));
|
||||
body->attachShape(*shape);
|
||||
gScene->addActor(*body);
|
||||
shape->release();
|
||||
}
|
||||
}
|
||||
|
||||
// Create falling rigid body
|
||||
{
|
||||
const PxVec3 halfExtent(ccd ? 0.1f : 1.0f);
|
||||
|
||||
PxShape* shape = gPhysics->createShape(PxBoxGeometry(halfExtent), *gMaterial);
|
||||
|
||||
PxRigidDynamic* body = gPhysics->createRigidDynamic(PxTransform(0.0f, ccd ? 30.0f : 20.0f, 0.0f));
|
||||
body->attachShape(*shape);
|
||||
|
||||
PxRigidBodyExt::updateMassAndInertia(*body, 1.0f);
|
||||
gScene->addActor(*body);
|
||||
shape->release();
|
||||
|
||||
if(ccd)
|
||||
{
|
||||
body->setRigidBodyFlag(PxRigidBodyFlag::eENABLE_CCD, true);
|
||||
body->setLinearVelocity(PxVec3(0.0f, -140.0f, 0.0f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void createTriggerTriggerScene()
|
||||
{
|
||||
struct Local
|
||||
{
|
||||
static void createSphereActor(const PxVec3& pos, const PxVec3& linVel)
|
||||
{
|
||||
PxShape* sphereShape = gPhysics->createShape(PxSphereGeometry(1.0f), *gMaterial, false);
|
||||
|
||||
PxRigidDynamic* body = gPhysics->createRigidDynamic(PxTransform(pos));
|
||||
body->attachShape(*sphereShape);
|
||||
|
||||
PxShape* triggerShape = createTriggerShape(PxSphereGeometry(4.0f), true);
|
||||
body->attachShape(*triggerShape);
|
||||
|
||||
const bool isTriggershape = triggerShape->getFlags() & PxShapeFlag::eTRIGGER_SHAPE;
|
||||
if(!isTriggershape)
|
||||
triggerShape->setFlag(PxShapeFlag::eSIMULATION_SHAPE, false);
|
||||
PxRigidBodyExt::updateMassAndInertia(*body, 1.0f);
|
||||
if(!isTriggershape)
|
||||
triggerShape->setFlag(PxShapeFlag::eSIMULATION_SHAPE, true);
|
||||
gScene->addActor(*body);
|
||||
sphereShape->release();
|
||||
triggerShape->release();
|
||||
|
||||
body->setLinearVelocity(linVel);
|
||||
}
|
||||
};
|
||||
|
||||
Local::createSphereActor(PxVec3(-5.0f, 1.0f, 0.0f), PxVec3( 1.0f, 0.0f, 0.0f));
|
||||
Local::createSphereActor(PxVec3( 5.0f, 1.0f, 0.0f), PxVec3(-1.0f, 0.0f, 0.0f));
|
||||
}
|
||||
|
||||
static void initScene()
|
||||
{
|
||||
const TriggerImpl impl = getImpl();
|
||||
|
||||
PxSceneDesc sceneDesc(gPhysics->getTolerancesScale());
|
||||
// sceneDesc.flags &= ~PxSceneFlag::eENABLE_PCM;
|
||||
sceneDesc.cpuDispatcher = gDispatcher;
|
||||
sceneDesc.gravity = PxVec3(0, -9.81f, 0);
|
||||
sceneDesc.simulationEventCallback = &gContactReportCallback;
|
||||
if(impl==REAL_TRIGGERS)
|
||||
{
|
||||
sceneDesc.filterShader = PxDefaultSimulationFilterShader;
|
||||
printf("- Using built-in triggers.\n");
|
||||
}
|
||||
else if(impl==FILTER_SHADER)
|
||||
{
|
||||
sceneDesc.filterShader = triggersUsingFilterShader;
|
||||
printf("- Using regular shapes emulating triggers with a filter shader.\n");
|
||||
}
|
||||
else if(impl==FILTER_CALLBACK)
|
||||
{
|
||||
sceneDesc.filterShader = triggersUsingFilterCallback;
|
||||
sceneDesc.filterCallback = &gTriggersFilterCallback;
|
||||
printf("- Using regular shapes emulating triggers with a filter callback.\n");
|
||||
}
|
||||
|
||||
if(usesCCD())
|
||||
{
|
||||
sceneDesc.flags |= PxSceneFlag::eENABLE_CCD;
|
||||
printf("- Using CCD.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("- Using no CCD.\n");
|
||||
}
|
||||
|
||||
gScene = gPhysics->createScene(sceneDesc);
|
||||
|
||||
PxPvdSceneClient* pvdClient = gScene->getScenePvdClient();
|
||||
if(pvdClient)
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONTACTS, true);
|
||||
|
||||
PxRigidStatic* groundPlane = PxCreatePlane(*gPhysics, PxPlane(0,1,0,0), *gMaterial);
|
||||
gScene->addActor(*groundPlane);
|
||||
|
||||
if(usesTriggerTrigger())
|
||||
createTriggerTriggerScene();
|
||||
else
|
||||
createDefaultScene();
|
||||
}
|
||||
|
||||
static void releaseScene()
|
||||
{
|
||||
PX_RELEASE(gScene);
|
||||
}
|
||||
|
||||
void stepPhysics(bool /*interactive*/)
|
||||
{
|
||||
if(gPause && !gOneFrame)
|
||||
return;
|
||||
gOneFrame = false;
|
||||
|
||||
if(gScene)
|
||||
{
|
||||
gScene->simulate(1.0f/60.0f);
|
||||
gScene->fetchResults(true);
|
||||
}
|
||||
}
|
||||
|
||||
void initPhysics(bool /*interactive*/)
|
||||
{
|
||||
printf("Press keys F1 to F9 to select a scenario.\n");
|
||||
|
||||
gFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gAllocator, gErrorCallback);
|
||||
gPvd = PxCreatePvd(*gFoundation);
|
||||
PxPvdTransport* transport = PxDefaultPvdSocketTransportCreate(PVD_HOST, 5425, 10);
|
||||
gPvd->connect(*transport,PxPvdInstrumentationFlag::eALL);
|
||||
gPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, PxTolerancesScale(),true,gPvd);
|
||||
PxInitExtensions(*gPhysics,gPvd);
|
||||
const PxU32 numCores = SnippetUtils::getNbPhysicalCores();
|
||||
gDispatcher = PxDefaultCpuDispatcherCreate(numCores == 0 ? 0 : numCores - 1);
|
||||
gMaterial = gPhysics->createMaterial(1.0f, 1.0f, 0.0f);
|
||||
|
||||
initScene();
|
||||
}
|
||||
|
||||
void cleanupPhysics(bool /*interactive*/)
|
||||
{
|
||||
releaseScene();
|
||||
|
||||
PX_RELEASE(gDispatcher);
|
||||
PxCloseExtensions();
|
||||
PX_RELEASE(gPhysics);
|
||||
if(gPvd)
|
||||
{
|
||||
PxPvdTransport* transport = gPvd->getTransport();
|
||||
PX_RELEASE(gPvd);
|
||||
PX_RELEASE(transport);
|
||||
}
|
||||
PX_RELEASE(gFoundation);
|
||||
|
||||
printf("SnippetTriggers done.\n");
|
||||
}
|
||||
|
||||
void keyPress(unsigned char key, const PxTransform& /*camera*/)
|
||||
{
|
||||
if(key=='p' || key=='P')
|
||||
gPause = !gPause;
|
||||
|
||||
if(key=='o' || key=='O')
|
||||
{
|
||||
gPause = true;
|
||||
gOneFrame = true;
|
||||
}
|
||||
|
||||
if(gScene)
|
||||
{
|
||||
if(key>=1 && key<=SCENARIO_COUNT)
|
||||
{
|
||||
gScenario = key-1;
|
||||
releaseScene();
|
||||
initScene();
|
||||
}
|
||||
|
||||
if(key=='r' || key=='R')
|
||||
{
|
||||
releaseScene();
|
||||
initScene();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int snippetMain(int, const char*const*)
|
||||
{
|
||||
#ifdef RENDER_SNIPPET
|
||||
extern void renderLoop();
|
||||
renderLoop();
|
||||
#else
|
||||
initPhysics(false);
|
||||
for(PxU32 i=0; i<250; i++)
|
||||
stepPhysics(false);
|
||||
cleanupPhysics(false);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
198
physx/snippets/snippettriggers/SnippetTriggersRender.cpp
Normal file
198
physx/snippets/snippettriggers/SnippetTriggersRender.cpp
Normal file
@ -0,0 +1,198 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifdef RENDER_SNIPPET
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
#include "../snippetrender/SnippetRender.h"
|
||||
#include "../snippetrender/SnippetCamera.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
extern void initPhysics(bool interactive);
|
||||
extern void stepPhysics(bool interactive);
|
||||
extern void cleanupPhysics(bool interactive);
|
||||
extern void keyPress(unsigned char key, const PxTransform& camera);
|
||||
bool isTrigger(const PxFilterData& data);
|
||||
bool isTriggerShape(PxShape* shape);
|
||||
|
||||
namespace
|
||||
{
|
||||
Snippets::Camera* sCamera;
|
||||
|
||||
void motionCallback(int x, int y)
|
||||
{
|
||||
sCamera->handleMotion(x, y);
|
||||
}
|
||||
|
||||
void keyboardCallback(unsigned char key, int x, int y)
|
||||
{
|
||||
if(key==27)
|
||||
exit(0);
|
||||
|
||||
if(!sCamera->handleKey(key, x, y))
|
||||
keyPress(key, sCamera->getTransform());
|
||||
}
|
||||
|
||||
void keyboardCallback2(int key, int /*x*/, int /*y*/)
|
||||
{
|
||||
keyPress(key, sCamera->getTransform());
|
||||
}
|
||||
|
||||
void mouseCallback(int button, int state, int x, int y)
|
||||
{
|
||||
sCamera->handleMouse(button, state, x, y);
|
||||
}
|
||||
|
||||
void idleCallback()
|
||||
{
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
static void InitLighting()
|
||||
{
|
||||
glEnable(GL_COLOR_MATERIAL);
|
||||
|
||||
const float zero[] = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, zero);
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, zero);
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, zero);
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, zero);
|
||||
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0f);
|
||||
|
||||
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, zero);
|
||||
|
||||
glEnable(GL_LIGHTING);
|
||||
PxVec3 Dir(-1.0f, 1.0f, 0.5f);
|
||||
// PxVec3 Dir(0.0f, 1.0f, 0.0f);
|
||||
Dir.normalize();
|
||||
|
||||
const float AmbientValue = 0.3f;
|
||||
const float ambientColor0[] = { AmbientValue, AmbientValue, AmbientValue, 0.0f };
|
||||
glLightfv(GL_LIGHT0, GL_AMBIENT, ambientColor0);
|
||||
|
||||
const float specularColor0[] = { 0.0f, 0.0f, 0.0f, 0.0f };
|
||||
glLightfv(GL_LIGHT0, GL_SPECULAR, specularColor0);
|
||||
|
||||
const float diffuseColor0[] = { 0.7f, 0.7f, 0.7f, 0.0f };
|
||||
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseColor0);
|
||||
|
||||
const float position0[] = { Dir.x, Dir.y, Dir.z, 0.0f };
|
||||
glLightfv(GL_LIGHT0, GL_POSITION, position0);
|
||||
|
||||
glEnable(GL_LIGHT0);
|
||||
|
||||
// glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
// glColor4f(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
if(0)
|
||||
{
|
||||
glEnable(GL_FOG);
|
||||
glFogi(GL_FOG_MODE,GL_LINEAR);
|
||||
//glFogi(GL_FOG_MODE,GL_EXP);
|
||||
//glFogi(GL_FOG_MODE,GL_EXP2);
|
||||
glFogf(GL_FOG_START, 0.0f);
|
||||
glFogf(GL_FOG_END, 100.0f);
|
||||
glFogf(GL_FOG_DENSITY, 0.005f);
|
||||
// glClearColor(0.2f, 0.2f, 0.2f, 1.0);
|
||||
// const PxVec3 FogColor(0.2f, 0.2f, 0.2f);
|
||||
const PxVec3 FogColor(1.0f);
|
||||
glFogfv(GL_FOG_COLOR, &FogColor.x);
|
||||
}
|
||||
}
|
||||
|
||||
class MyTriggerRender : public Snippets::TriggerRender
|
||||
{
|
||||
public:
|
||||
virtual bool isTrigger(physx::PxShape* shape) const
|
||||
{
|
||||
return ::isTriggerShape(shape);
|
||||
}
|
||||
};
|
||||
|
||||
void renderCallback()
|
||||
{
|
||||
stepPhysics(true);
|
||||
|
||||
if(0)
|
||||
{
|
||||
PxVec3 camPos = sCamera->getEye();
|
||||
PxVec3 camDir = sCamera->getDir();
|
||||
printf("camPos: (%ff, %ff, %ff)\n", double(camPos.x), double(camPos.y), double(camPos.z));
|
||||
printf("camDir: (%ff, %ff, %ff)\n", double(camDir.x), double(camDir.y), double(camDir.z));
|
||||
}
|
||||
|
||||
Snippets::startRender(sCamera->getEye(), sCamera->getDir());
|
||||
InitLighting();
|
||||
|
||||
PxScene* scene;
|
||||
PxGetPhysics().getScenes(&scene,1);
|
||||
PxU32 nbActors = scene->getNbActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC);
|
||||
if(nbActors)
|
||||
{
|
||||
std::vector<PxRigidActor*> actors(nbActors);
|
||||
scene->getActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC, reinterpret_cast<PxActor**>(&actors[0]), nbActors);
|
||||
|
||||
MyTriggerRender tr;
|
||||
Snippets::renderActors(&actors[0], static_cast<PxU32>(actors.size()), true, PxVec3(0.0f, 0.75f, 0.0f), &tr);
|
||||
}
|
||||
|
||||
Snippets::finishRender();
|
||||
}
|
||||
|
||||
void exitCallback(void)
|
||||
{
|
||||
delete sCamera;
|
||||
cleanupPhysics(true);
|
||||
}
|
||||
}
|
||||
|
||||
void renderLoop()
|
||||
{
|
||||
sCamera = new Snippets::Camera(PxVec3(8.757190f, 12.367847f, 23.541956f), PxVec3(-0.407947f, -0.042438f, -0.912019f));
|
||||
|
||||
Snippets::setupDefaultWindow("PhysX Snippet Triggers");
|
||||
Snippets::setupDefaultRenderState();
|
||||
|
||||
glutIdleFunc(idleCallback);
|
||||
glutDisplayFunc(renderCallback);
|
||||
glutKeyboardFunc(keyboardCallback);
|
||||
glutSpecialFunc(keyboardCallback2);
|
||||
glutMouseFunc(mouseCallback);
|
||||
glutMotionFunc(motionCallback);
|
||||
motionCallback(0,0);
|
||||
|
||||
atexit(exitCallback);
|
||||
|
||||
initPhysics(true);
|
||||
glutMainLoop();
|
||||
}
|
||||
#endif
|
||||
214
physx/snippets/snippetutils/SnippetUtils.cpp
Normal file
214
physx/snippets/snippetutils/SnippetUtils.cpp
Normal file
@ -0,0 +1,214 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#include "SnippetUtils.h"
|
||||
|
||||
#include "foundation/PxSimpleTypes.h"
|
||||
|
||||
#include "CmPhysXCommon.h"
|
||||
|
||||
#include "PsAtomic.h"
|
||||
#include "PsString.h"
|
||||
#include "PsSync.h"
|
||||
#include "PsThread.h"
|
||||
#include "PsTime.h"
|
||||
#include "PsMutex.h"
|
||||
#include "PsAllocator.h"
|
||||
#include "extensions/PxDefaultAllocator.h"
|
||||
|
||||
|
||||
namespace physx
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
PxDefaultAllocator gUtilAllocator;
|
||||
|
||||
struct UtilAllocator // since we're allocating internal classes here, make sure we align properly
|
||||
{
|
||||
void* allocate(size_t size,const char* file, PxU32 line) { return gUtilAllocator.allocate(size, NULL, file, int(line)); }
|
||||
void deallocate(void* ptr) { gUtilAllocator.deallocate(ptr); }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
namespace SnippetUtils
|
||||
{
|
||||
|
||||
PxI32 atomicIncrement(volatile PxI32* val)
|
||||
{
|
||||
return Ps::atomicIncrement(val);
|
||||
}
|
||||
|
||||
PxI32 atomicDecrement(volatile PxI32* val)
|
||||
{
|
||||
return Ps::atomicDecrement(val);
|
||||
}
|
||||
|
||||
//******************************************************************************//
|
||||
|
||||
PxU32 getNbPhysicalCores()
|
||||
{
|
||||
return Ps::Thread::getNbPhysicalCores();
|
||||
}
|
||||
|
||||
//******************************************************************************//
|
||||
|
||||
PxU32 getThreadId()
|
||||
{
|
||||
return static_cast<PxU32>(Ps::Thread::getId());
|
||||
}
|
||||
|
||||
//******************************************************************************//
|
||||
|
||||
PxU64 getCurrentTimeCounterValue()
|
||||
{
|
||||
return Ps::Time::getCurrentCounterValue();
|
||||
}
|
||||
|
||||
PxReal getElapsedTimeInMilliseconds(const PxU64 elapsedTime)
|
||||
{
|
||||
return Ps::Time::getCounterFrequency().toTensOfNanos(elapsedTime)/(100.0f * 1000.0f);
|
||||
}
|
||||
|
||||
PxReal getElapsedTimeInMicroSeconds(const PxU64 elapsedTime)
|
||||
{
|
||||
return Ps::Time::getCounterFrequency().toTensOfNanos(elapsedTime)/(100.0f);
|
||||
}
|
||||
|
||||
//******************************************************************************//
|
||||
|
||||
struct Sync: public Ps::SyncT<UtilAllocator> {};
|
||||
|
||||
Sync* syncCreate()
|
||||
{
|
||||
return new(gUtilAllocator.allocate(sizeof(Sync), 0, 0, 0)) Sync();
|
||||
}
|
||||
|
||||
void syncWait(Sync* sync)
|
||||
{
|
||||
sync->wait();
|
||||
}
|
||||
|
||||
void syncSet(Sync* sync)
|
||||
{
|
||||
sync->set();
|
||||
}
|
||||
|
||||
void syncReset(Sync* sync)
|
||||
{
|
||||
sync->reset();
|
||||
}
|
||||
|
||||
void syncRelease(Sync* sync)
|
||||
{
|
||||
sync->~Sync();
|
||||
gUtilAllocator.deallocate(sync);
|
||||
}
|
||||
|
||||
//******************************************************************************//
|
||||
|
||||
struct Thread: public Ps::ThreadT<UtilAllocator>
|
||||
{
|
||||
Thread(ThreadEntryPoint entryPoint, void* data):
|
||||
Ps::ThreadT<UtilAllocator>(),
|
||||
mEntryPoint(entryPoint),
|
||||
mData(data)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void execute(void)
|
||||
{
|
||||
mEntryPoint(mData);
|
||||
}
|
||||
|
||||
ThreadEntryPoint mEntryPoint;
|
||||
void* mData;
|
||||
};
|
||||
|
||||
Thread* threadCreate(ThreadEntryPoint entryPoint, void* data)
|
||||
{
|
||||
Thread* createThread = static_cast<Thread*>(gUtilAllocator.allocate(sizeof(Thread), 0, 0, 0));
|
||||
PX_PLACEMENT_NEW(createThread, Thread(entryPoint, data));
|
||||
createThread->start();
|
||||
return createThread;
|
||||
}
|
||||
|
||||
void threadQuit(Thread* thread)
|
||||
{
|
||||
thread->quit();
|
||||
}
|
||||
|
||||
void threadSignalQuit(Thread* thread)
|
||||
{
|
||||
thread->signalQuit();
|
||||
}
|
||||
|
||||
bool threadWaitForQuit(Thread* thread)
|
||||
{
|
||||
return thread->waitForQuit();
|
||||
}
|
||||
|
||||
bool threadQuitIsSignalled(Thread* thread)
|
||||
{
|
||||
return thread->quitIsSignalled();
|
||||
}
|
||||
|
||||
void threadRelease(Thread* thread)
|
||||
{
|
||||
thread->~Thread();
|
||||
gUtilAllocator.deallocate(thread);
|
||||
}
|
||||
|
||||
//******************************************************************************//
|
||||
|
||||
struct Mutex: public Ps::MutexT<UtilAllocator> {};
|
||||
|
||||
Mutex* mutexCreate()
|
||||
{
|
||||
return new(gUtilAllocator.allocate(sizeof(Mutex), 0, 0, 0)) Mutex();
|
||||
}
|
||||
|
||||
void mutexLock(Mutex* mutex)
|
||||
{
|
||||
mutex->lock();
|
||||
}
|
||||
|
||||
void mutexUnlock(Mutex* mutex)
|
||||
{
|
||||
mutex->unlock();
|
||||
}
|
||||
|
||||
void mutexRelease(Mutex* mutex)
|
||||
{
|
||||
mutex->~Mutex();
|
||||
gUtilAllocator.deallocate(mutex);
|
||||
}
|
||||
|
||||
|
||||
} // namespace physXUtils
|
||||
} // namespace physx
|
||||
127
physx/snippets/snippetutils/SnippetUtils.h
Normal file
127
physx/snippets/snippetutils/SnippetUtils.h
Normal file
@ -0,0 +1,127 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
|
||||
#include "foundation/PxSimpleTypes.h"
|
||||
|
||||
#define PX_RELEASE(x) if(x) { x->release(); x = NULL; }
|
||||
|
||||
namespace physx
|
||||
{
|
||||
namespace SnippetUtils
|
||||
{
|
||||
/* Increment the specified location. Return the incremented value. */
|
||||
PxI32 atomicIncrement(volatile PxI32* val);
|
||||
|
||||
/* Decrement the specified location. Return the decremented value. */
|
||||
PxI32 atomicDecrement(volatile PxI32* val);
|
||||
|
||||
//******************************************************************************//
|
||||
|
||||
/* Return the number of physical cores (does not include hyper-threaded cores), returns 0 on failure. */
|
||||
PxU32 getNbPhysicalCores();
|
||||
|
||||
//******************************************************************************//
|
||||
|
||||
/* Return the id of a thread. */
|
||||
PxU32 getThreadId();
|
||||
|
||||
//******************************************************************************//
|
||||
|
||||
/* Return the current time */
|
||||
PxU64 getCurrentTimeCounterValue();
|
||||
|
||||
/* Convert to milliseconds an elapsed time computed from the difference of the times returned from two calls to getCurrentTimeCounterValue. */
|
||||
PxReal getElapsedTimeInMilliseconds(const PxU64 elapsedTime);
|
||||
|
||||
/* Convert to microseconds an elapsed time computed from the difference of the times returned from two calls to getCurrentTimeCounterValue. */
|
||||
PxReal getElapsedTimeInMicroSeconds(const PxU64 elapsedTime);
|
||||
|
||||
//******************************************************************************//
|
||||
|
||||
struct Sync;
|
||||
|
||||
/* Create a sync object. Returns a unique handle to the sync object so that it may be addressed through syncWait etc. */
|
||||
Sync* syncCreate();
|
||||
|
||||
/* Wait indefinitely until the specified sync object is signaled. */
|
||||
void syncWait(Sync* sync);
|
||||
|
||||
/* Signal the specified synchronization object, waking all threads waiting on it. */
|
||||
void syncSet(Sync* sync);
|
||||
|
||||
/** Reset the specified synchronization object. */
|
||||
void syncReset(Sync* sync);
|
||||
|
||||
/* Release the specified sync object so that it may be reused with syncCreate. */
|
||||
void syncRelease(Sync* sync);
|
||||
|
||||
//******************************************************************************//
|
||||
|
||||
struct Thread;
|
||||
|
||||
/* Prototype of callback passed to threadCreate. */
|
||||
typedef void (*ThreadEntryPoint)(void*);
|
||||
|
||||
/* Create a thread object and return a unique handle to the thread object so that it may be addressed through threadStart etc.
|
||||
entryPoint implements ThreadEntryPoint and data will be passed as a function argument, POSIX-style. */
|
||||
Thread* threadCreate(ThreadEntryPoint entryPoint, void* data);
|
||||
|
||||
/* Cleanly shut down the specified thread. Called in the context of the spawned thread. */
|
||||
void threadQuit(Thread* thread);
|
||||
|
||||
/* Stop the specified thread. Signals the spawned thread that it should stop, so the
|
||||
thread should check regularly. */
|
||||
void threadSignalQuit(Thread* thread);
|
||||
|
||||
/* Wait for the specified thread to stop. Should be called in the context of the spawning
|
||||
thread. Returns false if the thread has not been started.*/
|
||||
bool threadWaitForQuit(Thread* thread);
|
||||
|
||||
/* Check whether the thread is signalled to quit. Called in the context of the
|
||||
spawned thread. */
|
||||
bool threadQuitIsSignalled(Thread* thread);
|
||||
|
||||
/* Release the specified thread object so that it may be reused with threadCreate. */
|
||||
void threadRelease(Thread* thread);
|
||||
|
||||
//******************************************************************************//
|
||||
|
||||
struct Mutex;
|
||||
|
||||
/* Create a mutex object and return a unique handle to the mutex object so that it may be addressed through mutexLock etc. */
|
||||
Mutex* mutexCreate();
|
||||
|
||||
/* Acquire (lock) the specified mutex. If the mutex is already locked by another thread, this method blocks until the mutex is unlocked.*/
|
||||
void mutexLock(Mutex* mutex);
|
||||
|
||||
/* Release (unlock) the specified mutex, the calling thread must have previously called lock() or method will error. */
|
||||
void mutexUnlock(Mutex* mutex);
|
||||
|
||||
/* Release the specified mutex so that it may be reused with mutexCreate. */
|
||||
void mutexRelease(Mutex* mutex);
|
||||
}
|
||||
}
|
||||
531
physx/snippets/snippetvehicle4w/SnippetVehicle4W.cpp
Normal file
531
physx/snippets/snippetvehicle4w/SnippetVehicle4W.cpp
Normal file
@ -0,0 +1,531 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
// ****************************************************************************
|
||||
// This snippet illustrates simple use of PxVehicleDrive4W.
|
||||
//
|
||||
// It creates a vehicle on a plane and then controls the vehicle so that it performs a
|
||||
// number of choreographed manoeuvres such as accelerate, reverse, brake, handbrake, and turn.
|
||||
|
||||
// It is a good idea to record and playback with pvd (PhysX Visual Debugger).
|
||||
// ****************************************************************************
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
|
||||
#include "vehicle/PxVehicleUtil.h"
|
||||
#include "../snippetvehiclecommon/SnippetVehicleSceneQuery.h"
|
||||
#include "../snippetvehiclecommon/SnippetVehicleFilterShader.h"
|
||||
#include "../snippetvehiclecommon/SnippetVehicleTireFriction.h"
|
||||
#include "../snippetvehiclecommon/SnippetVehicleCreate.h"
|
||||
|
||||
#include "../snippetcommon/SnippetPrint.h"
|
||||
#include "../snippetcommon/SnippetPVD.h"
|
||||
#include "../snippetutils/SnippetUtils.h"
|
||||
|
||||
|
||||
using namespace physx;
|
||||
using namespace snippetvehicle;
|
||||
|
||||
PxDefaultAllocator gAllocator;
|
||||
PxDefaultErrorCallback gErrorCallback;
|
||||
|
||||
PxFoundation* gFoundation = NULL;
|
||||
PxPhysics* gPhysics = NULL;
|
||||
|
||||
PxDefaultCpuDispatcher* gDispatcher = NULL;
|
||||
PxScene* gScene = NULL;
|
||||
|
||||
PxCooking* gCooking = NULL;
|
||||
|
||||
PxMaterial* gMaterial = NULL;
|
||||
|
||||
PxPvd* gPvd = NULL;
|
||||
|
||||
VehicleSceneQueryData* gVehicleSceneQueryData = NULL;
|
||||
PxBatchQuery* gBatchQuery = NULL;
|
||||
|
||||
PxVehicleDrivableSurfaceToTireFrictionPairs* gFrictionPairs = NULL;
|
||||
|
||||
PxRigidStatic* gGroundPlane = NULL;
|
||||
PxVehicleDrive4W* gVehicle4W = NULL;
|
||||
|
||||
bool gIsVehicleInAir = true;
|
||||
|
||||
PxF32 gSteerVsForwardSpeedData[2*8]=
|
||||
{
|
||||
0.0f, 0.75f,
|
||||
5.0f, 0.75f,
|
||||
30.0f, 0.125f,
|
||||
120.0f, 0.1f,
|
||||
PX_MAX_F32, PX_MAX_F32,
|
||||
PX_MAX_F32, PX_MAX_F32,
|
||||
PX_MAX_F32, PX_MAX_F32,
|
||||
PX_MAX_F32, PX_MAX_F32
|
||||
};
|
||||
PxFixedSizeLookupTable<8> gSteerVsForwardSpeedTable(gSteerVsForwardSpeedData,4);
|
||||
|
||||
PxVehicleKeySmoothingData gKeySmoothingData=
|
||||
{
|
||||
{
|
||||
6.0f, //rise rate eANALOG_INPUT_ACCEL
|
||||
6.0f, //rise rate eANALOG_INPUT_BRAKE
|
||||
6.0f, //rise rate eANALOG_INPUT_HANDBRAKE
|
||||
2.5f, //rise rate eANALOG_INPUT_STEER_LEFT
|
||||
2.5f, //rise rate eANALOG_INPUT_STEER_RIGHT
|
||||
},
|
||||
{
|
||||
10.0f, //fall rate eANALOG_INPUT_ACCEL
|
||||
10.0f, //fall rate eANALOG_INPUT_BRAKE
|
||||
10.0f, //fall rate eANALOG_INPUT_HANDBRAKE
|
||||
5.0f, //fall rate eANALOG_INPUT_STEER_LEFT
|
||||
5.0f //fall rate eANALOG_INPUT_STEER_RIGHT
|
||||
}
|
||||
};
|
||||
|
||||
PxVehiclePadSmoothingData gPadSmoothingData=
|
||||
{
|
||||
{
|
||||
6.0f, //rise rate eANALOG_INPUT_ACCEL
|
||||
6.0f, //rise rate eANALOG_INPUT_BRAKE
|
||||
6.0f, //rise rate eANALOG_INPUT_HANDBRAKE
|
||||
2.5f, //rise rate eANALOG_INPUT_STEER_LEFT
|
||||
2.5f, //rise rate eANALOG_INPUT_STEER_RIGHT
|
||||
},
|
||||
{
|
||||
10.0f, //fall rate eANALOG_INPUT_ACCEL
|
||||
10.0f, //fall rate eANALOG_INPUT_BRAKE
|
||||
10.0f, //fall rate eANALOG_INPUT_HANDBRAKE
|
||||
5.0f, //fall rate eANALOG_INPUT_STEER_LEFT
|
||||
5.0f //fall rate eANALOG_INPUT_STEER_RIGHT
|
||||
}
|
||||
};
|
||||
|
||||
PxVehicleDrive4WRawInputData gVehicleInputData;
|
||||
|
||||
enum DriveMode
|
||||
{
|
||||
eDRIVE_MODE_ACCEL_FORWARDS=0,
|
||||
eDRIVE_MODE_ACCEL_REVERSE,
|
||||
eDRIVE_MODE_HARD_TURN_LEFT,
|
||||
eDRIVE_MODE_HANDBRAKE_TURN_LEFT,
|
||||
eDRIVE_MODE_HARD_TURN_RIGHT,
|
||||
eDRIVE_MODE_HANDBRAKE_TURN_RIGHT,
|
||||
eDRIVE_MODE_BRAKE,
|
||||
eDRIVE_MODE_NONE
|
||||
};
|
||||
|
||||
DriveMode gDriveModeOrder[] =
|
||||
{
|
||||
eDRIVE_MODE_BRAKE,
|
||||
eDRIVE_MODE_ACCEL_FORWARDS,
|
||||
eDRIVE_MODE_BRAKE,
|
||||
eDRIVE_MODE_ACCEL_REVERSE,
|
||||
eDRIVE_MODE_BRAKE,
|
||||
eDRIVE_MODE_HARD_TURN_LEFT,
|
||||
eDRIVE_MODE_BRAKE,
|
||||
eDRIVE_MODE_HARD_TURN_RIGHT,
|
||||
eDRIVE_MODE_ACCEL_FORWARDS,
|
||||
eDRIVE_MODE_HANDBRAKE_TURN_LEFT,
|
||||
eDRIVE_MODE_ACCEL_FORWARDS,
|
||||
eDRIVE_MODE_HANDBRAKE_TURN_RIGHT,
|
||||
eDRIVE_MODE_NONE
|
||||
};
|
||||
|
||||
PxF32 gVehicleModeLifetime = 4.0f;
|
||||
PxF32 gVehicleModeTimer = 0.0f;
|
||||
PxU32 gVehicleOrderProgress = 0;
|
||||
bool gVehicleOrderComplete = false;
|
||||
bool gMimicKeyInputs = false;
|
||||
|
||||
VehicleDesc initVehicleDesc()
|
||||
{
|
||||
//Set up the chassis mass, dimensions, moment of inertia, and center of mass offset.
|
||||
//The moment of inertia is just the moment of inertia of a cuboid but modified for easier steering.
|
||||
//Center of mass offset is 0.65m above the base of the chassis and 0.25m towards the front.
|
||||
const PxF32 chassisMass = 1500.0f;
|
||||
const PxVec3 chassisDims(2.5f,2.0f,5.0f);
|
||||
const PxVec3 chassisMOI
|
||||
((chassisDims.y*chassisDims.y + chassisDims.z*chassisDims.z)*chassisMass/12.0f,
|
||||
(chassisDims.x*chassisDims.x + chassisDims.z*chassisDims.z)*0.8f*chassisMass/12.0f,
|
||||
(chassisDims.x*chassisDims.x + chassisDims.y*chassisDims.y)*chassisMass/12.0f);
|
||||
const PxVec3 chassisCMOffset(0.0f, -chassisDims.y*0.5f + 0.65f, 0.25f);
|
||||
|
||||
//Set up the wheel mass, radius, width, moment of inertia, and number of wheels.
|
||||
//Moment of inertia is just the moment of inertia of a cylinder.
|
||||
const PxF32 wheelMass = 20.0f;
|
||||
const PxF32 wheelRadius = 0.5f;
|
||||
const PxF32 wheelWidth = 0.4f;
|
||||
const PxF32 wheelMOI = 0.5f*wheelMass*wheelRadius*wheelRadius;
|
||||
const PxU32 nbWheels = 6;
|
||||
|
||||
VehicleDesc vehicleDesc;
|
||||
|
||||
vehicleDesc.chassisMass = chassisMass;
|
||||
vehicleDesc.chassisDims = chassisDims;
|
||||
vehicleDesc.chassisMOI = chassisMOI;
|
||||
vehicleDesc.chassisCMOffset = chassisCMOffset;
|
||||
vehicleDesc.chassisMaterial = gMaterial;
|
||||
vehicleDesc.chassisSimFilterData = PxFilterData(COLLISION_FLAG_CHASSIS, COLLISION_FLAG_CHASSIS_AGAINST, 0, 0);
|
||||
|
||||
vehicleDesc.wheelMass = wheelMass;
|
||||
vehicleDesc.wheelRadius = wheelRadius;
|
||||
vehicleDesc.wheelWidth = wheelWidth;
|
||||
vehicleDesc.wheelMOI = wheelMOI;
|
||||
vehicleDesc.numWheels = nbWheels;
|
||||
vehicleDesc.wheelMaterial = gMaterial;
|
||||
vehicleDesc.chassisSimFilterData = PxFilterData(COLLISION_FLAG_WHEEL, COLLISION_FLAG_WHEEL_AGAINST, 0, 0);
|
||||
|
||||
return vehicleDesc;
|
||||
}
|
||||
|
||||
void startAccelerateForwardsMode()
|
||||
{
|
||||
if(gMimicKeyInputs)
|
||||
{
|
||||
gVehicleInputData.setDigitalAccel(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
gVehicleInputData.setAnalogAccel(1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void startAccelerateReverseMode()
|
||||
{
|
||||
gVehicle4W->mDriveDynData.forceGearChange(PxVehicleGearsData::eREVERSE);
|
||||
|
||||
if(gMimicKeyInputs)
|
||||
{
|
||||
gVehicleInputData.setDigitalAccel(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
gVehicleInputData.setAnalogAccel(1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void startBrakeMode()
|
||||
{
|
||||
if(gMimicKeyInputs)
|
||||
{
|
||||
gVehicleInputData.setDigitalBrake(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
gVehicleInputData.setAnalogBrake(1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void startTurnHardLeftMode()
|
||||
{
|
||||
if(gMimicKeyInputs)
|
||||
{
|
||||
gVehicleInputData.setDigitalAccel(true);
|
||||
gVehicleInputData.setDigitalSteerLeft(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
gVehicleInputData.setAnalogAccel(true);
|
||||
gVehicleInputData.setAnalogSteer(-1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void startTurnHardRightMode()
|
||||
{
|
||||
if(gMimicKeyInputs)
|
||||
{
|
||||
gVehicleInputData.setDigitalAccel(true);
|
||||
gVehicleInputData.setDigitalSteerRight(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
gVehicleInputData.setAnalogAccel(1.0f);
|
||||
gVehicleInputData.setAnalogSteer(1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void startHandbrakeTurnLeftMode()
|
||||
{
|
||||
if(gMimicKeyInputs)
|
||||
{
|
||||
gVehicleInputData.setDigitalSteerLeft(true);
|
||||
gVehicleInputData.setDigitalHandbrake(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
gVehicleInputData.setAnalogSteer(-1.0f);
|
||||
gVehicleInputData.setAnalogHandbrake(1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void startHandbrakeTurnRightMode()
|
||||
{
|
||||
if(gMimicKeyInputs)
|
||||
{
|
||||
gVehicleInputData.setDigitalSteerRight(true);
|
||||
gVehicleInputData.setDigitalHandbrake(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
gVehicleInputData.setAnalogSteer(1.0f);
|
||||
gVehicleInputData.setAnalogHandbrake(1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void releaseAllControls()
|
||||
{
|
||||
if(gMimicKeyInputs)
|
||||
{
|
||||
gVehicleInputData.setDigitalAccel(false);
|
||||
gVehicleInputData.setDigitalSteerLeft(false);
|
||||
gVehicleInputData.setDigitalSteerRight(false);
|
||||
gVehicleInputData.setDigitalBrake(false);
|
||||
gVehicleInputData.setDigitalHandbrake(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
gVehicleInputData.setAnalogAccel(0.0f);
|
||||
gVehicleInputData.setAnalogSteer(0.0f);
|
||||
gVehicleInputData.setAnalogBrake(0.0f);
|
||||
gVehicleInputData.setAnalogHandbrake(0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void initPhysics()
|
||||
{
|
||||
gFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gAllocator, gErrorCallback);
|
||||
gPvd = PxCreatePvd(*gFoundation);
|
||||
PxPvdTransport* transport = PxDefaultPvdSocketTransportCreate(PVD_HOST, 5425, 10);
|
||||
gPvd->connect(*transport,PxPvdInstrumentationFlag::eALL);
|
||||
gPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, PxTolerancesScale(), true, gPvd);
|
||||
|
||||
PxSceneDesc sceneDesc(gPhysics->getTolerancesScale());
|
||||
sceneDesc.gravity = PxVec3(0.0f, -9.81f, 0.0f);
|
||||
|
||||
PxU32 numWorkers = 1;
|
||||
gDispatcher = PxDefaultCpuDispatcherCreate(numWorkers);
|
||||
sceneDesc.cpuDispatcher = gDispatcher;
|
||||
sceneDesc.filterShader = VehicleFilterShader;
|
||||
|
||||
gScene = gPhysics->createScene(sceneDesc);
|
||||
PxPvdSceneClient* pvdClient = gScene->getScenePvdClient();
|
||||
if(pvdClient)
|
||||
{
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONSTRAINTS, true);
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_CONTACTS, true);
|
||||
pvdClient->setScenePvdFlag(PxPvdSceneFlag::eTRANSMIT_SCENEQUERIES, true);
|
||||
}
|
||||
gMaterial = gPhysics->createMaterial(0.5f, 0.5f, 0.6f);
|
||||
|
||||
gCooking = PxCreateCooking(PX_PHYSICS_VERSION, *gFoundation, PxCookingParams(PxTolerancesScale()));
|
||||
|
||||
/////////////////////////////////////////////
|
||||
|
||||
PxInitVehicleSDK(*gPhysics);
|
||||
PxVehicleSetBasisVectors(PxVec3(0,1,0), PxVec3(0,0,1));
|
||||
PxVehicleSetUpdateMode(PxVehicleUpdateMode::eVELOCITY_CHANGE);
|
||||
|
||||
//Create the batched scene queries for the suspension raycasts.
|
||||
gVehicleSceneQueryData = VehicleSceneQueryData::allocate(1, PX_MAX_NB_WHEELS, 1, 1, WheelSceneQueryPreFilterBlocking, NULL, gAllocator);
|
||||
gBatchQuery = VehicleSceneQueryData::setUpBatchedSceneQuery(0, *gVehicleSceneQueryData, gScene);
|
||||
|
||||
//Create the friction table for each combination of tire and surface type.
|
||||
gFrictionPairs = createFrictionPairs(gMaterial);
|
||||
|
||||
//Create a plane to drive on.
|
||||
PxFilterData groundPlaneSimFilterData(COLLISION_FLAG_GROUND, COLLISION_FLAG_GROUND_AGAINST, 0, 0);
|
||||
gGroundPlane = createDrivablePlane(groundPlaneSimFilterData, gMaterial, gPhysics);
|
||||
gScene->addActor(*gGroundPlane);
|
||||
|
||||
//Create a vehicle that will drive on the plane.
|
||||
VehicleDesc vehicleDesc = initVehicleDesc();
|
||||
gVehicle4W = createVehicle4W(vehicleDesc, gPhysics, gCooking);
|
||||
PxTransform startTransform(PxVec3(0, (vehicleDesc.chassisDims.y*0.5f + vehicleDesc.wheelRadius + 1.0f), 0), PxQuat(PxIdentity));
|
||||
gVehicle4W->getRigidDynamicActor()->setGlobalPose(startTransform);
|
||||
gScene->addActor(*gVehicle4W->getRigidDynamicActor());
|
||||
|
||||
//Set the vehicle to rest in first gear.
|
||||
//Set the vehicle to use auto-gears.
|
||||
gVehicle4W->setToRestState();
|
||||
gVehicle4W->mDriveDynData.forceGearChange(PxVehicleGearsData::eFIRST);
|
||||
gVehicle4W->mDriveDynData.setUseAutoGears(true);
|
||||
|
||||
gVehicleModeTimer = 0.0f;
|
||||
gVehicleOrderProgress = 0;
|
||||
startBrakeMode();
|
||||
}
|
||||
|
||||
void incrementDrivingMode(const PxF32 timestep)
|
||||
{
|
||||
gVehicleModeTimer += timestep;
|
||||
if(gVehicleModeTimer > gVehicleModeLifetime)
|
||||
{
|
||||
//If the mode just completed was eDRIVE_MODE_ACCEL_REVERSE then switch back to forward gears.
|
||||
if(eDRIVE_MODE_ACCEL_REVERSE == gDriveModeOrder[gVehicleOrderProgress])
|
||||
{
|
||||
gVehicle4W->mDriveDynData.forceGearChange(PxVehicleGearsData::eFIRST);
|
||||
}
|
||||
|
||||
//Increment to next driving mode.
|
||||
gVehicleModeTimer = 0.0f;
|
||||
gVehicleOrderProgress++;
|
||||
releaseAllControls();
|
||||
|
||||
//If we are at the end of the list of driving modes then start again.
|
||||
if(eDRIVE_MODE_NONE == gDriveModeOrder[gVehicleOrderProgress])
|
||||
{
|
||||
gVehicleOrderProgress = 0;
|
||||
gVehicleOrderComplete = true;
|
||||
}
|
||||
|
||||
//Start driving in the selected mode.
|
||||
DriveMode eDriveMode = gDriveModeOrder[gVehicleOrderProgress];
|
||||
switch(eDriveMode)
|
||||
{
|
||||
case eDRIVE_MODE_ACCEL_FORWARDS:
|
||||
startAccelerateForwardsMode();
|
||||
break;
|
||||
case eDRIVE_MODE_ACCEL_REVERSE:
|
||||
startAccelerateReverseMode();
|
||||
break;
|
||||
case eDRIVE_MODE_HARD_TURN_LEFT:
|
||||
startTurnHardLeftMode();
|
||||
break;
|
||||
case eDRIVE_MODE_HANDBRAKE_TURN_LEFT:
|
||||
startHandbrakeTurnLeftMode();
|
||||
break;
|
||||
case eDRIVE_MODE_HARD_TURN_RIGHT:
|
||||
startTurnHardRightMode();
|
||||
break;
|
||||
case eDRIVE_MODE_HANDBRAKE_TURN_RIGHT:
|
||||
startHandbrakeTurnRightMode();
|
||||
break;
|
||||
case eDRIVE_MODE_BRAKE:
|
||||
startBrakeMode();
|
||||
break;
|
||||
case eDRIVE_MODE_NONE:
|
||||
break;
|
||||
};
|
||||
|
||||
//If the mode about to start is eDRIVE_MODE_ACCEL_REVERSE then switch to reverse gears.
|
||||
if(eDRIVE_MODE_ACCEL_REVERSE == gDriveModeOrder[gVehicleOrderProgress])
|
||||
{
|
||||
gVehicle4W->mDriveDynData.forceGearChange(PxVehicleGearsData::eREVERSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void stepPhysics()
|
||||
{
|
||||
const PxF32 timestep = 1.0f/60.0f;
|
||||
|
||||
//Cycle through the driving modes to demonstrate how to accelerate/reverse/brake/turn etc.
|
||||
incrementDrivingMode(timestep);
|
||||
|
||||
//Update the control inputs for the vehicle.
|
||||
if(gMimicKeyInputs)
|
||||
{
|
||||
PxVehicleDrive4WSmoothDigitalRawInputsAndSetAnalogInputs(gKeySmoothingData, gSteerVsForwardSpeedTable, gVehicleInputData, timestep, gIsVehicleInAir, *gVehicle4W);
|
||||
}
|
||||
else
|
||||
{
|
||||
PxVehicleDrive4WSmoothAnalogRawInputsAndSetAnalogInputs(gPadSmoothingData, gSteerVsForwardSpeedTable, gVehicleInputData, timestep, gIsVehicleInAir, *gVehicle4W);
|
||||
}
|
||||
|
||||
//Raycasts.
|
||||
PxVehicleWheels* vehicles[1] = {gVehicle4W};
|
||||
PxRaycastQueryResult* raycastResults = gVehicleSceneQueryData->getRaycastQueryResultBuffer(0);
|
||||
const PxU32 raycastResultsSize = gVehicleSceneQueryData->getQueryResultBufferSize();
|
||||
PxVehicleSuspensionRaycasts(gBatchQuery, 1, vehicles, raycastResultsSize, raycastResults);
|
||||
|
||||
//Vehicle update.
|
||||
const PxVec3 grav = gScene->getGravity();
|
||||
PxWheelQueryResult wheelQueryResults[PX_MAX_NB_WHEELS];
|
||||
PxVehicleWheelQueryResult vehicleQueryResults[1] = {{wheelQueryResults, gVehicle4W->mWheelsSimData.getNbWheels()}};
|
||||
PxVehicleUpdates(timestep, grav, *gFrictionPairs, 1, vehicles, vehicleQueryResults);
|
||||
|
||||
//Work out if the vehicle is in the air.
|
||||
gIsVehicleInAir = gVehicle4W->getRigidDynamicActor()->isSleeping() ? false : PxVehicleIsInAir(vehicleQueryResults[0]);
|
||||
|
||||
//Scene update.
|
||||
gScene->simulate(timestep);
|
||||
gScene->fetchResults(true);
|
||||
}
|
||||
|
||||
void cleanupPhysics()
|
||||
{
|
||||
gVehicle4W->getRigidDynamicActor()->release();
|
||||
gVehicle4W->free();
|
||||
PX_RELEASE(gGroundPlane);
|
||||
PX_RELEASE(gBatchQuery);
|
||||
gVehicleSceneQueryData->free(gAllocator);
|
||||
PX_RELEASE(gFrictionPairs);
|
||||
PxCloseVehicleSDK();
|
||||
|
||||
PX_RELEASE(gMaterial);
|
||||
PX_RELEASE(gCooking);
|
||||
PX_RELEASE(gScene);
|
||||
PX_RELEASE(gDispatcher);
|
||||
PX_RELEASE(gPhysics);
|
||||
if(gPvd)
|
||||
{
|
||||
PxPvdTransport* transport = gPvd->getTransport();
|
||||
gPvd->release(); gPvd = NULL;
|
||||
PX_RELEASE(transport);
|
||||
}
|
||||
PX_RELEASE(gFoundation);
|
||||
|
||||
printf("SnippetVehicle4W done.\n");
|
||||
}
|
||||
|
||||
void keyPress(unsigned char key, const PxTransform& camera)
|
||||
{
|
||||
PX_UNUSED(camera);
|
||||
PX_UNUSED(key);
|
||||
}
|
||||
|
||||
int snippetMain(int, const char*const*)
|
||||
{
|
||||
#ifdef RENDER_SNIPPET
|
||||
extern void renderLoop();
|
||||
renderLoop();
|
||||
#else
|
||||
initPhysics();
|
||||
while(!gVehicleOrderComplete)
|
||||
{
|
||||
stepPhysics();
|
||||
}
|
||||
cleanupPhysics();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
120
physx/snippets/snippetvehicle4w/SnippetVehicle4WRender.cpp
Normal file
120
physx/snippets/snippetvehicle4w/SnippetVehicle4WRender.cpp
Normal file
@ -0,0 +1,120 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifdef RENDER_SNIPPET
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
|
||||
#include "../snippetrender/SnippetRender.h"
|
||||
#include "../snippetrender/SnippetCamera.h"
|
||||
|
||||
using namespace physx;
|
||||
|
||||
extern void initPhysics();
|
||||
extern void stepPhysics();
|
||||
extern void cleanupPhysics();
|
||||
extern void keyPress(unsigned char key, const PxTransform& camera);
|
||||
|
||||
extern PxScene* gScene;
|
||||
|
||||
namespace
|
||||
{
|
||||
Snippets::Camera* sCamera;
|
||||
|
||||
void motionCallback(int x, int y)
|
||||
{
|
||||
sCamera->handleMotion(x, y);
|
||||
}
|
||||
|
||||
void keyboardCallback(unsigned char key, int x, int y)
|
||||
{
|
||||
if(key==27)
|
||||
exit(0);
|
||||
|
||||
if(!sCamera->handleKey(key, x, y))
|
||||
keyPress(key, sCamera->getTransform());
|
||||
}
|
||||
|
||||
void mouseCallback(int button, int state, int x, int y)
|
||||
{
|
||||
sCamera->handleMouse(button, state, x, y);
|
||||
}
|
||||
|
||||
void idleCallback()
|
||||
{
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
void renderCallback()
|
||||
{
|
||||
stepPhysics();
|
||||
|
||||
Snippets::startRender(sCamera->getEye(), sCamera->getDir());
|
||||
|
||||
PxU32 nbActors = gScene->getNbActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC);
|
||||
if(nbActors)
|
||||
{
|
||||
std::vector<PxRigidActor*> actors(nbActors);
|
||||
gScene->getActors(PxActorTypeFlag::eRIGID_DYNAMIC | PxActorTypeFlag::eRIGID_STATIC, reinterpret_cast<PxActor**>(&actors[0]), nbActors);
|
||||
Snippets::renderActors(&actors[0], static_cast<PxU32>(actors.size()), true);
|
||||
}
|
||||
|
||||
Snippets::finishRender();
|
||||
}
|
||||
|
||||
void exitCallback(void)
|
||||
{
|
||||
delete sCamera;
|
||||
cleanupPhysics();
|
||||
}
|
||||
}
|
||||
|
||||
void renderLoop()
|
||||
{
|
||||
sCamera = new Snippets::Camera(PxVec3(10.0f, 10.0f, 10.0f), PxVec3(-0.6f,-0.2f,-0.7f));
|
||||
|
||||
Snippets::setupDefaultWindow("PhysX Snippet Vehicle4W");
|
||||
Snippets::setupDefaultRenderState();
|
||||
|
||||
glutIdleFunc(idleCallback);
|
||||
glutDisplayFunc(renderCallback);
|
||||
glutKeyboardFunc(keyboardCallback);
|
||||
glutMouseFunc(mouseCallback);
|
||||
glutMotionFunc(motionCallback);
|
||||
motionCallback(0,0);
|
||||
|
||||
atexit(exitCallback);
|
||||
|
||||
initPhysics();
|
||||
glutMainLoop();
|
||||
}
|
||||
|
||||
#endif
|
||||
321
physx/snippets/snippetvehiclecommon/SnippetVehicle4WCreate.cpp
Normal file
321
physx/snippets/snippetvehiclecommon/SnippetVehicle4WCreate.cpp
Normal file
@ -0,0 +1,321 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#include "SnippetVehicleCreate.h"
|
||||
#include "SnippetVehicleTireFriction.h"
|
||||
#include "SnippetVehicleSceneQuery.h"
|
||||
|
||||
|
||||
namespace snippetvehicle
|
||||
{
|
||||
|
||||
using namespace physx;
|
||||
|
||||
namespace fourwheel
|
||||
{
|
||||
|
||||
void computeWheelCenterActorOffsets4W(const PxF32 wheelFrontZ, const PxF32 wheelRearZ, const PxVec3& chassisDims, const PxF32 wheelWidth, const PxF32 wheelRadius, const PxU32 numWheels, PxVec3* wheelCentreOffsets)
|
||||
{
|
||||
//chassisDims.z is the distance from the rear of the chassis to the front of the chassis.
|
||||
//The front has z = 0.5*chassisDims.z and the rear has z = -0.5*chassisDims.z.
|
||||
//Compute a position for the front wheel and the rear wheel along the z-axis.
|
||||
//Compute the separation between each wheel along the z-axis.
|
||||
const PxF32 numLeftWheels = numWheels/2.0f;
|
||||
const PxF32 deltaZ = (wheelFrontZ - wheelRearZ)/(numLeftWheels-1.0f);
|
||||
//Set the outside of the left and right wheels to be flush with the chassis.
|
||||
//Set the top of the wheel to be just touching the underside of the chassis.
|
||||
//Begin by setting the rear-left/rear-right/front-left,front-right wheels.
|
||||
wheelCentreOffsets[PxVehicleDrive4WWheelOrder::eREAR_LEFT] = PxVec3((-chassisDims.x + wheelWidth)*0.5f, -(chassisDims.y/2 + wheelRadius), wheelRearZ + 0*deltaZ*0.5f);
|
||||
wheelCentreOffsets[PxVehicleDrive4WWheelOrder::eREAR_RIGHT] = PxVec3((+chassisDims.x - wheelWidth)*0.5f, -(chassisDims.y/2 + wheelRadius), wheelRearZ + 0*deltaZ*0.5f);
|
||||
wheelCentreOffsets[PxVehicleDrive4WWheelOrder::eFRONT_LEFT] = PxVec3((-chassisDims.x + wheelWidth)*0.5f, -(chassisDims.y/2 + wheelRadius), wheelRearZ + (numLeftWheels-1)*deltaZ);
|
||||
wheelCentreOffsets[PxVehicleDrive4WWheelOrder::eFRONT_RIGHT] = PxVec3((+chassisDims.x - wheelWidth)*0.5f, -(chassisDims.y/2 + wheelRadius), wheelRearZ + (numLeftWheels-1)*deltaZ);
|
||||
//Set the remaining wheels.
|
||||
for(PxU32 i = 2, wheelCount = 4; i < numWheels-2; i+=2, wheelCount+=2)
|
||||
{
|
||||
wheelCentreOffsets[wheelCount + 0] = PxVec3((-chassisDims.x + wheelWidth)*0.5f, -(chassisDims.y/2 + wheelRadius), wheelRearZ + i*deltaZ*0.5f);
|
||||
wheelCentreOffsets[wheelCount + 1] = PxVec3((+chassisDims.x - wheelWidth)*0.5f, -(chassisDims.y/2 + wheelRadius), wheelRearZ + i*deltaZ*0.5f);
|
||||
}
|
||||
}
|
||||
|
||||
void setupWheelsSimulationData
|
||||
(const PxF32 wheelMass, const PxF32 wheelMOI, const PxF32 wheelRadius, const PxF32 wheelWidth,
|
||||
const PxU32 numWheels, const PxVec3* wheelCenterActorOffsets,
|
||||
const PxVec3& chassisCMOffset, const PxF32 chassisMass,
|
||||
PxVehicleWheelsSimData* wheelsSimData)
|
||||
{
|
||||
//Set up the wheels.
|
||||
PxVehicleWheelData wheels[PX_MAX_NB_WHEELS];
|
||||
{
|
||||
//Set up the wheel data structures with mass, moi, radius, width.
|
||||
for(PxU32 i = 0; i < numWheels; i++)
|
||||
{
|
||||
wheels[i].mMass = wheelMass;
|
||||
wheels[i].mMOI = wheelMOI;
|
||||
wheels[i].mRadius = wheelRadius;
|
||||
wheels[i].mWidth = wheelWidth;
|
||||
}
|
||||
|
||||
//Enable the handbrake for the rear wheels only.
|
||||
wheels[PxVehicleDrive4WWheelOrder::eREAR_LEFT].mMaxHandBrakeTorque=4000.0f;
|
||||
wheels[PxVehicleDrive4WWheelOrder::eREAR_RIGHT].mMaxHandBrakeTorque=4000.0f;
|
||||
//Enable steering for the front wheels only.
|
||||
wheels[PxVehicleDrive4WWheelOrder::eFRONT_LEFT].mMaxSteer=PxPi*0.3333f;
|
||||
wheels[PxVehicleDrive4WWheelOrder::eFRONT_RIGHT].mMaxSteer=PxPi*0.3333f;
|
||||
}
|
||||
|
||||
//Set up the tires.
|
||||
PxVehicleTireData tires[PX_MAX_NB_WHEELS];
|
||||
{
|
||||
//Set up the tires.
|
||||
for(PxU32 i = 0; i < numWheels; i++)
|
||||
{
|
||||
tires[i].mType = TIRE_TYPE_NORMAL;
|
||||
}
|
||||
}
|
||||
|
||||
//Set up the suspensions
|
||||
PxVehicleSuspensionData suspensions[PX_MAX_NB_WHEELS];
|
||||
{
|
||||
//Compute the mass supported by each suspension spring.
|
||||
PxF32 suspSprungMasses[PX_MAX_NB_WHEELS];
|
||||
PxVehicleComputeSprungMasses
|
||||
(numWheels, wheelCenterActorOffsets,
|
||||
chassisCMOffset, chassisMass, 1, suspSprungMasses);
|
||||
|
||||
//Set the suspension data.
|
||||
for(PxU32 i = 0; i < numWheels; i++)
|
||||
{
|
||||
suspensions[i].mMaxCompression = 0.3f;
|
||||
suspensions[i].mMaxDroop = 0.1f;
|
||||
suspensions[i].mSpringStrength = 35000.0f;
|
||||
suspensions[i].mSpringDamperRate = 4500.0f;
|
||||
suspensions[i].mSprungMass = suspSprungMasses[i];
|
||||
}
|
||||
|
||||
//Set the camber angles.
|
||||
const PxF32 camberAngleAtRest=0.0;
|
||||
const PxF32 camberAngleAtMaxDroop=0.01f;
|
||||
const PxF32 camberAngleAtMaxCompression=-0.01f;
|
||||
for(PxU32 i = 0; i < numWheels; i+=2)
|
||||
{
|
||||
suspensions[i + 0].mCamberAtRest = camberAngleAtRest;
|
||||
suspensions[i + 1].mCamberAtRest = -camberAngleAtRest;
|
||||
suspensions[i + 0].mCamberAtMaxDroop = camberAngleAtMaxDroop;
|
||||
suspensions[i + 1].mCamberAtMaxDroop = -camberAngleAtMaxDroop;
|
||||
suspensions[i + 0].mCamberAtMaxCompression = camberAngleAtMaxCompression;
|
||||
suspensions[i + 1].mCamberAtMaxCompression = -camberAngleAtMaxCompression;
|
||||
}
|
||||
}
|
||||
|
||||
//Set up the wheel geometry.
|
||||
PxVec3 suspTravelDirections[PX_MAX_NB_WHEELS];
|
||||
PxVec3 wheelCentreCMOffsets[PX_MAX_NB_WHEELS];
|
||||
PxVec3 suspForceAppCMOffsets[PX_MAX_NB_WHEELS];
|
||||
PxVec3 tireForceAppCMOffsets[PX_MAX_NB_WHEELS];
|
||||
{
|
||||
//Set the geometry data.
|
||||
for(PxU32 i = 0; i < numWheels; i++)
|
||||
{
|
||||
//Vertical suspension travel.
|
||||
suspTravelDirections[i] = PxVec3(0,-1,0);
|
||||
|
||||
//Wheel center offset is offset from rigid body center of mass.
|
||||
wheelCentreCMOffsets[i] =
|
||||
wheelCenterActorOffsets[i] - chassisCMOffset;
|
||||
|
||||
//Suspension force application point 0.3 metres below
|
||||
//rigid body center of mass.
|
||||
suspForceAppCMOffsets[i] =
|
||||
PxVec3(wheelCentreCMOffsets[i].x,-0.3f,wheelCentreCMOffsets[i].z);
|
||||
|
||||
//Tire force application point 0.3 metres below
|
||||
//rigid body center of mass.
|
||||
tireForceAppCMOffsets[i] =
|
||||
PxVec3(wheelCentreCMOffsets[i].x,-0.3f,wheelCentreCMOffsets[i].z);
|
||||
}
|
||||
}
|
||||
|
||||
//Set up the filter data of the raycast that will be issued by each suspension.
|
||||
PxFilterData qryFilterData;
|
||||
setupNonDrivableSurface(qryFilterData);
|
||||
|
||||
//Set the wheel, tire and suspension data.
|
||||
//Set the geometry data.
|
||||
//Set the query filter data
|
||||
for(PxU32 i = 0; i < numWheels; i++)
|
||||
{
|
||||
wheelsSimData->setWheelData(i, wheels[i]);
|
||||
wheelsSimData->setTireData(i, tires[i]);
|
||||
wheelsSimData->setSuspensionData(i, suspensions[i]);
|
||||
wheelsSimData->setSuspTravelDirection(i, suspTravelDirections[i]);
|
||||
wheelsSimData->setWheelCentreOffset(i, wheelCentreCMOffsets[i]);
|
||||
wheelsSimData->setSuspForceAppPointOffset(i, suspForceAppCMOffsets[i]);
|
||||
wheelsSimData->setTireForceAppPointOffset(i, tireForceAppCMOffsets[i]);
|
||||
wheelsSimData->setSceneQueryFilterData(i, qryFilterData);
|
||||
wheelsSimData->setWheelShapeMapping(i, PxI32(i));
|
||||
}
|
||||
|
||||
//Add a front and rear anti-roll bar
|
||||
PxVehicleAntiRollBarData barFront;
|
||||
barFront.mWheel0 = PxVehicleDrive4WWheelOrder::eFRONT_LEFT;
|
||||
barFront.mWheel1 = PxVehicleDrive4WWheelOrder::eFRONT_RIGHT;
|
||||
barFront.mStiffness = 10000.0f;
|
||||
wheelsSimData->addAntiRollBarData(barFront);
|
||||
PxVehicleAntiRollBarData barRear;
|
||||
barRear.mWheel0 = PxVehicleDrive4WWheelOrder::eREAR_LEFT;
|
||||
barRear.mWheel1 = PxVehicleDrive4WWheelOrder::eREAR_RIGHT;
|
||||
barRear.mStiffness = 10000.0f;
|
||||
wheelsSimData->addAntiRollBarData(barRear);
|
||||
}
|
||||
|
||||
} //namespace fourwheel
|
||||
|
||||
PxVehicleDrive4W* createVehicle4W(const VehicleDesc& vehicle4WDesc, PxPhysics* physics, PxCooking* cooking)
|
||||
{
|
||||
const PxVec3 chassisDims = vehicle4WDesc.chassisDims;
|
||||
const PxF32 wheelWidth = vehicle4WDesc.wheelWidth;
|
||||
const PxF32 wheelRadius = vehicle4WDesc.wheelRadius;
|
||||
const PxU32 numWheels = vehicle4WDesc.numWheels;
|
||||
|
||||
const PxFilterData& chassisSimFilterData = vehicle4WDesc.chassisSimFilterData;
|
||||
const PxFilterData& wheelSimFilterData = vehicle4WDesc.wheelSimFilterData;
|
||||
|
||||
//Construct a physx actor with shapes for the chassis and wheels.
|
||||
//Set the rigid body mass, moment of inertia, and center of mass offset.
|
||||
PxRigidDynamic* veh4WActor = NULL;
|
||||
{
|
||||
//Construct a convex mesh for a cylindrical wheel.
|
||||
PxConvexMesh* wheelMesh = createWheelMesh(wheelWidth, wheelRadius, *physics, *cooking);
|
||||
//Assume all wheels are identical for simplicity.
|
||||
PxConvexMesh* wheelConvexMeshes[PX_MAX_NB_WHEELS];
|
||||
PxMaterial* wheelMaterials[PX_MAX_NB_WHEELS];
|
||||
|
||||
//Set the meshes and materials for the driven wheels.
|
||||
for(PxU32 i = PxVehicleDrive4WWheelOrder::eFRONT_LEFT; i <= PxVehicleDrive4WWheelOrder::eREAR_RIGHT; i++)
|
||||
{
|
||||
wheelConvexMeshes[i] = wheelMesh;
|
||||
wheelMaterials[i] = vehicle4WDesc.wheelMaterial;
|
||||
}
|
||||
//Set the meshes and materials for the non-driven wheels
|
||||
for(PxU32 i = PxVehicleDrive4WWheelOrder::eREAR_RIGHT + 1; i < numWheels; i++)
|
||||
{
|
||||
wheelConvexMeshes[i] = wheelMesh;
|
||||
wheelMaterials[i] = vehicle4WDesc.wheelMaterial;
|
||||
}
|
||||
|
||||
//Chassis just has a single convex shape for simplicity.
|
||||
PxConvexMesh* chassisConvexMesh = createChassisMesh(chassisDims, *physics, *cooking);
|
||||
PxConvexMesh* chassisConvexMeshes[1] = {chassisConvexMesh};
|
||||
PxMaterial* chassisMaterials[1] = {vehicle4WDesc.chassisMaterial};
|
||||
|
||||
//Rigid body data.
|
||||
PxVehicleChassisData rigidBodyData;
|
||||
rigidBodyData.mMOI = vehicle4WDesc.chassisMOI;
|
||||
rigidBodyData.mMass = vehicle4WDesc.chassisMass;
|
||||
rigidBodyData.mCMOffset = vehicle4WDesc.chassisCMOffset;
|
||||
|
||||
veh4WActor = createVehicleActor
|
||||
(rigidBodyData,
|
||||
wheelMaterials, wheelConvexMeshes, numWheels, wheelSimFilterData,
|
||||
chassisMaterials, chassisConvexMeshes, 1, chassisSimFilterData,
|
||||
*physics);
|
||||
}
|
||||
|
||||
//Set up the sim data for the wheels.
|
||||
PxVehicleWheelsSimData* wheelsSimData = PxVehicleWheelsSimData::allocate(numWheels);
|
||||
{
|
||||
//Compute the wheel center offsets from the origin.
|
||||
PxVec3 wheelCenterActorOffsets[PX_MAX_NB_WHEELS];
|
||||
const PxF32 frontZ = chassisDims.z*0.3f;
|
||||
const PxF32 rearZ = -chassisDims.z*0.3f;
|
||||
fourwheel::computeWheelCenterActorOffsets4W(frontZ, rearZ, chassisDims, wheelWidth, wheelRadius, numWheels, wheelCenterActorOffsets);
|
||||
|
||||
//Set up the simulation data for all wheels.
|
||||
fourwheel::setupWheelsSimulationData
|
||||
(vehicle4WDesc.wheelMass, vehicle4WDesc.wheelMOI, wheelRadius, wheelWidth,
|
||||
numWheels, wheelCenterActorOffsets,
|
||||
vehicle4WDesc.chassisCMOffset, vehicle4WDesc.chassisMass,
|
||||
wheelsSimData);
|
||||
}
|
||||
|
||||
//Set up the sim data for the vehicle drive model.
|
||||
PxVehicleDriveSimData4W driveSimData;
|
||||
{
|
||||
//Diff
|
||||
PxVehicleDifferential4WData diff;
|
||||
diff.mType=PxVehicleDifferential4WData::eDIFF_TYPE_LS_4WD;
|
||||
driveSimData.setDiffData(diff);
|
||||
|
||||
//Engine
|
||||
PxVehicleEngineData engine;
|
||||
engine.mPeakTorque=500.0f;
|
||||
engine.mMaxOmega=600.0f;//approx 6000 rpm
|
||||
driveSimData.setEngineData(engine);
|
||||
|
||||
//Gears
|
||||
PxVehicleGearsData gears;
|
||||
gears.mSwitchTime=0.5f;
|
||||
driveSimData.setGearsData(gears);
|
||||
|
||||
//Clutch
|
||||
PxVehicleClutchData clutch;
|
||||
clutch.mStrength=10.0f;
|
||||
driveSimData.setClutchData(clutch);
|
||||
|
||||
//Ackermann steer accuracy
|
||||
PxVehicleAckermannGeometryData ackermann;
|
||||
ackermann.mAccuracy=1.0f;
|
||||
ackermann.mAxleSeparation=
|
||||
wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eFRONT_LEFT).z-
|
||||
wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eREAR_LEFT).z;
|
||||
ackermann.mFrontWidth=
|
||||
wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eFRONT_RIGHT).x-
|
||||
wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eFRONT_LEFT).x;
|
||||
ackermann.mRearWidth=
|
||||
wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eREAR_RIGHT).x -
|
||||
wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eREAR_LEFT).x;
|
||||
driveSimData.setAckermannGeometryData(ackermann);
|
||||
}
|
||||
|
||||
//Create a vehicle from the wheels and drive sim data.
|
||||
PxVehicleDrive4W* vehDrive4W = PxVehicleDrive4W::allocate(numWheels);
|
||||
vehDrive4W->setup(physics, veh4WActor, *wheelsSimData, driveSimData, numWheels - 4);
|
||||
|
||||
//Configure the userdata
|
||||
configureUserData(vehDrive4W, vehicle4WDesc.actorUserData, vehicle4WDesc.shapeUserDatas);
|
||||
|
||||
//Free the sim data because we don't need that any more.
|
||||
wheelsSimData->free();
|
||||
|
||||
return vehDrive4W;
|
||||
}
|
||||
|
||||
} //namespace snippetvehicle
|
||||
|
||||
|
||||
122
physx/snippets/snippetvehiclecommon/SnippetVehicleConcurrency.h
Normal file
122
physx/snippets/snippetvehiclecommon/SnippetVehicleConcurrency.h
Normal file
@ -0,0 +1,122 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#ifndef SNIPPET_VEHICLE_CONCURRENCY_H
|
||||
#define SNIPPET_VEHICLE_CONCURRENCY_H
|
||||
|
||||
#include "PxPhysicsAPI.h"
|
||||
#include <new>
|
||||
|
||||
namespace snippetvehicle
|
||||
{
|
||||
using namespace physx;
|
||||
|
||||
//Data structure for quick setup of wheel query data structures.
|
||||
class VehicleConcurrency
|
||||
{
|
||||
public:
|
||||
|
||||
VehicleConcurrency()
|
||||
: mMaxNumVehicles(0),
|
||||
mMaxNumWheelsPerVehicle(0),
|
||||
mVehicleConcurrentUpdates(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
~VehicleConcurrency()
|
||||
{
|
||||
}
|
||||
|
||||
static VehicleConcurrency* allocate(const PxU32 maxNumVehicles, const PxU32 maxNumWheelsPerVehicle, PxAllocatorCallback& allocator)
|
||||
{
|
||||
const PxU32 byteSize =
|
||||
sizeof(VehicleConcurrency) +
|
||||
sizeof(PxVehicleConcurrentUpdateData)*maxNumVehicles +
|
||||
sizeof(PxVehicleWheelConcurrentUpdateData)*maxNumWheelsPerVehicle*maxNumVehicles;
|
||||
|
||||
PxU8* buffer = static_cast<PxU8*>(allocator.allocate(byteSize, NULL, NULL, 0));
|
||||
|
||||
VehicleConcurrency* vc = reinterpret_cast<VehicleConcurrency*>(buffer);
|
||||
new(vc) VehicleConcurrency();
|
||||
buffer += sizeof(VehicleConcurrency);
|
||||
|
||||
vc->mMaxNumVehicles = maxNumVehicles;
|
||||
vc->mMaxNumWheelsPerVehicle = maxNumWheelsPerVehicle;
|
||||
|
||||
vc->mVehicleConcurrentUpdates = reinterpret_cast<PxVehicleConcurrentUpdateData*>(buffer);
|
||||
buffer += sizeof(PxVehicleConcurrentUpdateData)*maxNumVehicles;
|
||||
|
||||
for(PxU32 i=0;i<maxNumVehicles;i++)
|
||||
{
|
||||
new(vc->mVehicleConcurrentUpdates + i) PxVehicleConcurrentUpdateData();
|
||||
|
||||
vc->mVehicleConcurrentUpdates[i].nbConcurrentWheelUpdates = maxNumWheelsPerVehicle;
|
||||
|
||||
vc->mVehicleConcurrentUpdates[i].concurrentWheelUpdates = reinterpret_cast<PxVehicleWheelConcurrentUpdateData*>(buffer);
|
||||
buffer += sizeof(PxVehicleWheelConcurrentUpdateData)*maxNumWheelsPerVehicle;
|
||||
|
||||
for(PxU32 j = 0; j < maxNumWheelsPerVehicle; j++)
|
||||
{
|
||||
new(vc->mVehicleConcurrentUpdates[i].concurrentWheelUpdates + j) PxVehicleWheelConcurrentUpdateData();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
return vc;
|
||||
}
|
||||
|
||||
//Free allocated buffer for scene queries of suspension raycasts.
|
||||
void free(PxAllocatorCallback& allocator)
|
||||
{
|
||||
allocator.deallocate(this);
|
||||
}
|
||||
|
||||
//Return the PxVehicleConcurrentUpdate for a vehicle specified by an index.
|
||||
PxVehicleConcurrentUpdateData* getVehicleConcurrentUpdate(const PxU32 id)
|
||||
{
|
||||
return (mVehicleConcurrentUpdates + id);
|
||||
}
|
||||
|
||||
//Return the entire array of PxVehicleConcurrentUpdates
|
||||
PxVehicleConcurrentUpdateData* getVehicleConcurrentUpdateBuffer()
|
||||
{
|
||||
return mVehicleConcurrentUpdates;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
PxU32 mMaxNumVehicles;
|
||||
PxU32 mMaxNumWheelsPerVehicle;
|
||||
PxVehicleConcurrentUpdateData* mVehicleConcurrentUpdates;
|
||||
};
|
||||
|
||||
} // namespace snippetvehicle
|
||||
|
||||
#endif //SNIPPET_VEHICLE_CONCURRENCY_H
|
||||
339
physx/snippets/snippetvehiclecommon/SnippetVehicleCreate.cpp
Normal file
339
physx/snippets/snippetvehiclecommon/SnippetVehicleCreate.cpp
Normal file
@ -0,0 +1,339 @@
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above copyright
|
||||
// notice, this list of conditions and the following disclaimer in the
|
||||
// documentation and/or other materials provided with the distribution.
|
||||
// * Neither the name of NVIDIA CORPORATION nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Copyright (c) 2008-2021 NVIDIA Corporation. All rights reserved.
|
||||
// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
|
||||
// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
|
||||
|
||||
#include <new>
|
||||
#include "SnippetVehicleCreate.h"
|
||||
#include "SnippetVehicleSceneQuery.h"
|
||||
#include "SnippetVehicleFilterShader.h"
|
||||
#include "SnippetVehicleTireFriction.h"
|
||||
#include "PxPhysicsAPI.h"
|
||||
|
||||
namespace snippetvehicle
|
||||
{
|
||||
|
||||
using namespace physx;
|
||||
|
||||
PxRigidStatic* createDrivablePlane(const PxFilterData& simFilterData, PxMaterial* material, PxPhysics* physics)
|
||||
{
|
||||
//Add a plane to the scene.
|
||||
PxRigidStatic* groundPlane = PxCreatePlane(*physics, PxPlane(0,1,0,0), *material);
|
||||
|
||||
//Get the plane shape so we can set query and simulation filter data.
|
||||
PxShape* shapes[1];
|
||||
groundPlane->getShapes(shapes, 1);
|
||||
|
||||
//Set the query filter data of the ground plane so that the vehicle raycasts can hit the ground.
|
||||
PxFilterData qryFilterData;
|
||||
setupDrivableSurface(qryFilterData);
|
||||
shapes[0]->setQueryFilterData(qryFilterData);
|
||||
|
||||
//Set the simulation filter data of the ground plane so that it collides with the chassis of a vehicle but not the wheels.
|
||||
shapes[0]->setSimulationFilterData(simFilterData);
|
||||
|
||||
return groundPlane;
|
||||
}
|
||||
|
||||
static PxConvexMesh* createConvexMesh(const PxVec3* verts, const PxU32 numVerts, PxPhysics& physics, PxCooking& cooking)
|
||||
{
|
||||
// Create descriptor for convex mesh
|
||||
PxConvexMeshDesc convexDesc;
|
||||
convexDesc.points.count = numVerts;
|
||||
convexDesc.points.stride = sizeof(PxVec3);
|
||||
convexDesc.points.data = verts;
|
||||
convexDesc.flags = PxConvexFlag::eCOMPUTE_CONVEX;
|
||||
|
||||
PxConvexMesh* convexMesh = NULL;
|
||||
PxDefaultMemoryOutputStream buf;
|
||||
if(cooking.cookConvexMesh(convexDesc, buf))
|
||||
{
|
||||
PxDefaultMemoryInputData id(buf.getData(), buf.getSize());
|
||||
convexMesh = physics.createConvexMesh(id);
|
||||
}
|
||||
|
||||
return convexMesh;
|
||||
}
|
||||
|
||||
PxConvexMesh* createChassisMesh(const PxVec3 dims, PxPhysics& physics, PxCooking& cooking)
|
||||
{
|
||||
const PxF32 x = dims.x*0.5f;
|
||||
const PxF32 y = dims.y*0.5f;
|
||||
const PxF32 z = dims.z*0.5f;
|
||||
PxVec3 verts[8] =
|
||||
{
|
||||
PxVec3(x,y,-z),
|
||||
PxVec3(x,y,z),
|
||||
PxVec3(x,-y,z),
|
||||
PxVec3(x,-y,-z),
|
||||
PxVec3(-x,y,-z),
|
||||
PxVec3(-x,y,z),
|
||||
PxVec3(-x,-y,z),
|
||||
PxVec3(-x,-y,-z)
|
||||
};
|
||||
|
||||
return createConvexMesh(verts,8,physics,cooking);
|
||||
}
|
||||
|
||||
PxConvexMesh* createWheelMesh(const PxF32 width, const PxF32 radius, PxPhysics& physics, PxCooking& cooking)
|
||||
{
|
||||
PxVec3 points[2*16];
|
||||
for(PxU32 i = 0; i < 16; i++)
|
||||
{
|
||||
const PxF32 cosTheta = PxCos(i*PxPi*2.0f/16.0f);
|
||||
const PxF32 sinTheta = PxSin(i*PxPi*2.0f/16.0f);
|
||||
const PxF32 y = radius*cosTheta;
|
||||
const PxF32 z = radius*sinTheta;
|
||||
points[2*i+0] = PxVec3(-width/2.0f, y, z);
|
||||
points[2*i+1] = PxVec3(+width/2.0f, y, z);
|
||||
}
|
||||
|
||||
return createConvexMesh(points,32,physics,cooking);
|
||||
}
|
||||
|
||||
PxRigidDynamic* createVehicleActor
|
||||
(const PxVehicleChassisData& chassisData,
|
||||
PxMaterial** wheelMaterials, PxConvexMesh** wheelConvexMeshes, const PxU32 numWheels, const PxFilterData& wheelSimFilterData,
|
||||
PxMaterial** chassisMaterials, PxConvexMesh** chassisConvexMeshes, const PxU32 numChassisMeshes, const PxFilterData& chassisSimFilterData,
|
||||
PxPhysics& physics)
|
||||
{
|
||||
//We need a rigid body actor for the vehicle.
|
||||
//Don't forget to add the actor to the scene after setting up the associated vehicle.
|
||||
PxRigidDynamic* vehActor = physics.createRigidDynamic(PxTransform(PxIdentity));
|
||||
|
||||
//Wheel and chassis query filter data.
|
||||
//Optional: cars don't drive on other cars.
|
||||
PxFilterData wheelQryFilterData;
|
||||
setupNonDrivableSurface(wheelQryFilterData);
|
||||
PxFilterData chassisQryFilterData;
|
||||
setupNonDrivableSurface(chassisQryFilterData);
|
||||
|
||||
//Add all the wheel shapes to the actor.
|
||||
for(PxU32 i = 0; i < numWheels; i++)
|
||||
{
|
||||
PxConvexMeshGeometry geom(wheelConvexMeshes[i]);
|
||||
PxShape* wheelShape=PxRigidActorExt::createExclusiveShape(*vehActor, geom, *wheelMaterials[i]);
|
||||
wheelShape->setQueryFilterData(wheelQryFilterData);
|
||||
wheelShape->setSimulationFilterData(wheelSimFilterData);
|
||||
wheelShape->setLocalPose(PxTransform(PxIdentity));
|
||||
}
|
||||
|
||||
//Add the chassis shapes to the actor.
|
||||
for(PxU32 i = 0; i < numChassisMeshes; i++)
|
||||
{
|
||||
PxShape* chassisShape=PxRigidActorExt::createExclusiveShape(*vehActor, PxConvexMeshGeometry(chassisConvexMeshes[i]), *chassisMaterials[i]);
|
||||
chassisShape->setQueryFilterData(chassisQryFilterData);
|
||||
chassisShape->setSimulationFilterData(chassisSimFilterData);
|
||||
chassisShape->setLocalPose(PxTransform(PxIdentity));
|
||||
}
|
||||
|
||||
vehActor->setMass(chassisData.mMass);
|
||||
vehActor->setMassSpaceInertiaTensor(chassisData.mMOI);
|
||||
vehActor->setCMassLocalPose(PxTransform(chassisData.mCMOffset,PxQuat(PxIdentity)));
|
||||
|
||||
return vehActor;
|
||||
}
|
||||
|
||||
void configureUserData(PxVehicleWheels* vehicle, ActorUserData* actorUserData, ShapeUserData* shapeUserDatas)
|
||||
{
|
||||
if(actorUserData)
|
||||
{
|
||||
vehicle->getRigidDynamicActor()->userData = actorUserData;
|
||||
actorUserData->vehicle = vehicle;
|
||||
}
|
||||
|
||||
if(shapeUserDatas)
|
||||
{
|
||||
PxShape* shapes[PX_MAX_NB_WHEELS + 1];
|
||||
vehicle->getRigidDynamicActor()->getShapes(shapes, PX_MAX_NB_WHEELS + 1);
|
||||
for(PxU32 i = 0; i < vehicle->mWheelsSimData.getNbWheels(); i++)
|
||||
{
|
||||
const PxI32 shapeId = vehicle->mWheelsSimData.getWheelShapeMapping(i);
|
||||
shapes[shapeId]->userData = &shapeUserDatas[i];
|
||||
shapeUserDatas[i].isWheel = true;
|
||||
shapeUserDatas[i].wheelId = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void customizeVehicleToLengthScale(const PxReal lengthScale, PxRigidDynamic* rigidDynamic, PxVehicleWheelsSimData* wheelsSimData, PxVehicleDriveSimData* driveSimData)
|
||||
{
|
||||
//Rigid body center of mass and moment of inertia.
|
||||
{
|
||||
PxTransform t = rigidDynamic->getCMassLocalPose();
|
||||
t.p *= lengthScale;
|
||||
rigidDynamic->setCMassLocalPose(t);
|
||||
|
||||
PxVec3 moi = rigidDynamic->getMassSpaceInertiaTensor();
|
||||
moi *= (lengthScale*lengthScale);
|
||||
rigidDynamic->setMassSpaceInertiaTensor(moi);
|
||||
}
|
||||
|
||||
//Wheels, suspensions, wheel centers, tire/susp force application points.
|
||||
{
|
||||
for(PxU32 i = 0; i < wheelsSimData->getNbWheels(); i++)
|
||||
{
|
||||
PxVehicleWheelData wheelData = wheelsSimData->getWheelData(i);
|
||||
wheelData.mRadius *= lengthScale;
|
||||
wheelData.mWidth *= lengthScale;
|
||||
wheelData.mDampingRate *= lengthScale*lengthScale;
|
||||
wheelData.mMaxBrakeTorque *= lengthScale*lengthScale;
|
||||
wheelData.mMaxHandBrakeTorque *= lengthScale*lengthScale;
|
||||
wheelData.mMOI *= lengthScale*lengthScale;
|
||||
wheelsSimData->setWheelData(i, wheelData);
|
||||
|
||||
PxVehicleSuspensionData suspData = wheelsSimData->getSuspensionData(i);
|
||||
suspData.mMaxCompression *= lengthScale;
|
||||
suspData.mMaxDroop *= lengthScale;
|
||||
wheelsSimData->setSuspensionData(i, suspData);
|
||||
|
||||
PxVec3 v = wheelsSimData->getWheelCentreOffset(i);
|
||||
v *= lengthScale;
|
||||
wheelsSimData->setWheelCentreOffset(i,v);
|
||||
|
||||
v = wheelsSimData->getSuspForceAppPointOffset(i);
|
||||
v *= lengthScale;
|
||||
wheelsSimData->setSuspForceAppPointOffset(i,v);
|
||||
|
||||
v = wheelsSimData->getTireForceAppPointOffset(i);
|
||||
v *= lengthScale;
|
||||
wheelsSimData->setTireForceAppPointOffset(i,v);
|
||||
}
|
||||
}
|
||||
|
||||
//Slow forward speed correction.
|
||||
{
|
||||
wheelsSimData->setSubStepCount(5.0f*lengthScale, 3, 1);
|
||||
wheelsSimData->setMinLongSlipDenominator(4.0f*lengthScale);
|
||||
}
|
||||
|
||||
//Engine
|
||||
if(driveSimData)
|
||||
{
|
||||
PxVehicleEngineData engineData = driveSimData->getEngineData();
|
||||
engineData.mMOI *= lengthScale*lengthScale;
|
||||
engineData.mPeakTorque *= lengthScale*lengthScale;
|
||||
engineData.mDampingRateFullThrottle *= lengthScale*lengthScale;
|
||||
engineData.mDampingRateZeroThrottleClutchEngaged *= lengthScale*lengthScale;
|
||||
engineData.mDampingRateZeroThrottleClutchDisengaged *= lengthScale*lengthScale;
|
||||
driveSimData->setEngineData(engineData);
|
||||
}
|
||||
|
||||
//Clutch.
|
||||
if(driveSimData)
|
||||
{
|
||||
PxVehicleClutchData clutchData = driveSimData->getClutchData();
|
||||
clutchData.mStrength *= lengthScale*lengthScale;
|
||||
driveSimData->setClutchData(clutchData);
|
||||
}
|
||||
|
||||
//Scale the collision meshes too.
|
||||
{
|
||||
PxShape* shapes[16];
|
||||
const PxU32 nbShapes = rigidDynamic->getShapes(shapes, 16);
|
||||
for(PxU32 i = 0; i < nbShapes; i++)
|
||||
{
|
||||
switch(shapes[i]->getGeometryType())
|
||||
{
|
||||
case PxGeometryType::eSPHERE:
|
||||
{
|
||||
PxSphereGeometry sphere;
|
||||
shapes[i]->getSphereGeometry(sphere);
|
||||
sphere.radius *= lengthScale;
|
||||
shapes[i]->setGeometry(sphere);
|
||||
}
|
||||
break;
|
||||
case PxGeometryType::ePLANE:
|
||||
PX_ASSERT(false);
|
||||
break;
|
||||
case PxGeometryType::eCAPSULE:
|
||||
{
|
||||
PxCapsuleGeometry capsule;
|
||||
shapes[i]->getCapsuleGeometry(capsule);
|
||||
capsule.radius *= lengthScale;
|
||||
capsule.halfHeight*= lengthScale;
|
||||
shapes[i]->setGeometry(capsule);
|
||||
}
|
||||
break;
|
||||
case PxGeometryType::eBOX:
|
||||
{
|
||||
PxBoxGeometry box;
|
||||
shapes[i]->getBoxGeometry(box);
|
||||
box.halfExtents *= lengthScale;
|
||||
shapes[i]->setGeometry(box);
|
||||
}
|
||||
break;
|
||||
case PxGeometryType::eCONVEXMESH:
|
||||
{
|
||||
PxConvexMeshGeometry convexMesh;
|
||||
shapes[i]->getConvexMeshGeometry(convexMesh);
|
||||
convexMesh.scale.scale *= lengthScale;
|
||||
shapes[i]->setGeometry(convexMesh);
|
||||
}
|
||||
break;
|
||||
case PxGeometryType::eTRIANGLEMESH:
|
||||
{
|
||||
PxTriangleMeshGeometry triMesh;
|
||||
shapes[i]->getTriangleMeshGeometry(triMesh);
|
||||
triMesh.scale.scale *= lengthScale;
|
||||
shapes[i]->setGeometry(triMesh);
|
||||
}
|
||||
break;
|
||||
case PxGeometryType::eHEIGHTFIELD:
|
||||
{
|
||||
PxHeightFieldGeometry hf;
|
||||
shapes[i]->getHeightFieldGeometry(hf);
|
||||
hf.columnScale *= lengthScale;
|
||||
hf.heightScale *= lengthScale;
|
||||
hf.rowScale *= lengthScale;
|
||||
shapes[i]->setGeometry(hf);
|
||||
}
|
||||
break;
|
||||
case PxGeometryType::eINVALID:
|
||||
case PxGeometryType::eGEOMETRY_COUNT:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void customizeVehicleToLengthScale(const PxReal lengthScale, PxRigidDynamic* rigidDynamic, PxVehicleWheelsSimData* wheelsSimData, PxVehicleDriveSimData4W* driveSimData)
|
||||
{
|
||||
customizeVehicleToLengthScale(lengthScale, rigidDynamic, wheelsSimData, static_cast<PxVehicleDriveSimData*>(driveSimData));
|
||||
|
||||
//Ackermann geometry.
|
||||
if(driveSimData)
|
||||
{
|
||||
PxVehicleAckermannGeometryData ackermannData = driveSimData->getAckermannGeometryData();
|
||||
ackermannData.mAxleSeparation *= lengthScale;
|
||||
ackermannData.mFrontWidth *= lengthScale;
|
||||
ackermannData.mRearWidth *= lengthScale;
|
||||
driveSimData->setAckermannGeometryData(ackermannData);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace snippetvehicle
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user