diff options
| author | Marijn Tamis <[email protected]> | 2018-09-12 14:12:47 +0200 |
|---|---|---|
| committer | Marijn Tamis <[email protected]> | 2018-09-12 14:12:47 +0200 |
| commit | 7bceea80d4a04649f495f4f4331d7e3bdcdb05ca (patch) | |
| tree | 824767cccf7b516a8c0b32467c6314eaa802f58d /NvCloth/Tools | |
| parent | Added missing GenerateProjectsIOS.sh file (diff) | |
| download | nvcloth-7bceea80d4a04649f495f4f4331d7e3bdcdb05ca.tar.xz nvcloth-7bceea80d4a04649f495f4f4331d7e3bdcdb05ca.zip | |
1.1.5 Release (24934621)
Diffstat (limited to 'NvCloth/Tools')
13 files changed, 1707 insertions, 0 deletions
diff --git a/NvCloth/Tools/AuthoringLibrary/CMakeLists.txt b/NvCloth/Tools/AuthoringLibrary/CMakeLists.txt new file mode 100644 index 0000000..e9702e3 --- /dev/null +++ b/NvCloth/Tools/AuthoringLibrary/CMakeLists.txt @@ -0,0 +1,84 @@ +cmake_minimum_required(VERSION 3.3) + +project(NvClothAuthoringLibrary CXX) + +CMAKE_POLICY(SET CMP0057 NEW) # Enable IN_LIST + +IF(NOT DEFINED AUTHORINGLIBRARY_ROOT_DIR) + + STRING(REPLACE "\\" "/" BRD_TEMP $ENV{AUTHORINGLIBRARY_ROOT_DIR}) + + # This env variable is set by GenerateProjects.bat, and is no longer available when CMake rebuilds, so this stores it in the cache + SET(AUTHORINGLIBRARY_ROOT_DIR ${BRD_TEMP} CACHE INTERNAL "Root of the AuthoringLibrary source tree") + +ENDIF() + +IF(NOT EXISTS ${AUTHORINGLIBRARY_ROOT_DIR}) + MESSAGE(FATAL_ERROR "AUTHORINGLIBRARY_ROOT_DIR environment variable wasn't set or was invalid.") +ENDIF() + +SET(GW_DEPS_ROOT "${AUTHORINGLIBRARY_ROOT_DIR}/external") + +SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${GW_DEPS_ROOT}/CMakeModules") + +MESSAGE("AUTHORINGLIBRARY_ROOT_DIR:" ${AUTHORINGLIBRARY_ROOT_DIR}) +MESSAGE("GW_DEPS_ROOT:" ${GW_DEPS_ROOT}) +MESSAGE("Module path:" ${CMAKE_MODULE_PATH}) + + +IF(CMAKE_CONFIGURATION_TYPES) + SET(CMAKE_CONFIGURATION_TYPES debug profile checked release) + SET(CMAKE_CONFIGURATION_TYPES "${CMAKE_CONFIGURATION_TYPES}" CACHE STRING + "Reset config to what we need" + FORCE) + + SET(CMAKE_SHARED_LINKER_FLAGS_CHECKED "") + SET(CMAKE_SHARED_LINKER_FLAGS_PROFILE "") + + SET(CMAKE_EXE_LINKER_FLAGS_CHECKED "") + SET(CMAKE_EXE_LINKER_FLAGS_PROFILE "") + +ENDIF() + +# Default to appending "DEBUG", "PROFILE", etc to produced artifacts +IF(NOT DEFINED APPEND_CONFIG_NAME) + SET(APPEND_CONFIG_NAME ON) +ENDIF() + +IF (APPEND_CONFIG_NAME) + MESSAGE("Appending config to output names") + + SET(CMAKE_DEBUG_POSTFIX "DEBUG") + SET(CMAKE_PROFILE_POSTFIX "PROFILE") + SET(CMAKE_CHECKED_POSTFIX "CHECKED") + SET(CMAKE_RELEASE_POSTFIX "") +ENDIF() + +INCLUDE(SetOutputPaths) + +# Either have to define a single output path, or each one. + +IF(NOT DEFINED BL_OUTPUT_DIR) + IF (NOT DEFINED BL_LIB_OUTPUT_DIR) + MESSAGE(FATAL_ERROR "BL_LIB_OUTPUT_DIR not defined - Define either BL_OUTPUT_DIR or BL_LIB_OUTPUT_DIR and BL_DLL_OUTPUT_DIR and BL_EXE_OUTPUT_DIR") + ENDIF() + + IF (NOT DEFINED BL_DLL_OUTPUT_DIR) + MESSAGE(FATAL_ERROR "BL_DLL_OUTPUT_DIR not defined - Define either BL_OUTPUT_DIR or BL_LIB_OUTPUT_DIR and BL_DLL_OUTPUT_DIR and BL_EXE_OUTPUT_DIR") + ENDIF() + + IF (NOT DEFINED BL_EXE_OUTPUT_DIR) + MESSAGE(FATAL_ERROR "BL_EXE_OUTPUT_DIR not defined - Define either BL_OUTPUT_DIR or BL_LIB_OUTPUT_DIR and BL_DLL_OUTPUT_DIR and BL_EXE_OUTPUT_DIR") + ENDIF() + + SetLibOutputPath(${BL_LIB_OUTPUT_DIR}) + SetDllOutputPath(${BL_DLL_OUTPUT_DIR}) + SetExeOutputPath(${BL_EXE_OUTPUT_DIR}) +ELSE() + SetSingleOutputPath(${BL_OUTPUT_DIR}) +ENDIF() + +SET(PROJECT_CMAKE_FILES_DIR compiler/cmake/) + +# Include the platform specific configuration +INCLUDE(${PROJECT_CMAKE_FILES_DIR}${TARGET_BUILD_PLATFORM}/CMakeLists.txt OPTIONAL) diff --git a/NvCloth/Tools/AuthoringLibrary/CmakeGenerateProjects.bat b/NvCloth/Tools/AuthoringLibrary/CmakeGenerateProjects.bat new file mode 100644 index 0000000..e3a297c --- /dev/null +++ b/NvCloth/Tools/AuthoringLibrary/CmakeGenerateProjects.bat @@ -0,0 +1,37 @@ +CD /D %~dp0 +echo "Note: You need to run this with admin rights for the first time to set GW_DEPS_ROOT globally." +call "../../scripts/locate_gw_root.bat" GW_DEPS_ROOT_F +@echo on +setx GW_DEPS_ROOT "%GW_DEPS_ROOT_F% +echo GW_DEPS_ROOT = %GW_DEPS_ROOT% + +REM Install cmake using packman +set PACKMAN=call ../../scripts/packman/packman.cmd +%PACKMAN% pull -p windows "../../scripts/packman/packages/cmake.packman.xml" +IF %ERRORLEVEL% NEQ 0 ( + set EXIT_CODE=%ERRORLEVEL% + goto End +) +set CMAKE=%PM_cmake_PATH%/bin/cmake.exe + +set PX_OUTPUT_ROOT=%~dp0 + +set OUTPUT_ROOT=%~dp0 +set AUTHORINGLIBRARY_ROOT_DIR=%~dp0 + + +rmdir /s /q compiler\vc14win64-cmake\ +mkdir compiler\vc14win64-cmake\ +pushd compiler\vc14win64-cmake\ +%CMAKE% ..\.. -G "Visual Studio 14 2015" -Ax64 -DTARGET_BUILD_PLATFORM=windows -DSTATIC_WINCRT=0 -DBL_DLL_OUTPUT_DIR=%OUTPUT_ROOT%\bin\vc14win64-cmake -DBL_LIB_OUTPUT_DIR=%OUTPUT_ROOT%\lib\vc14win64-cmake -DBL_EXE_OUTPUT_DIR=%OUTPUT_ROOT%\bin\vc14win64-cmake + +popd + +rmdir /s /q compiler\vc14win32-cmake\ +mkdir compiler\vc14win32-cmake\ +pushd compiler\vc14win32-cmake\ +%CMAKE% ..\.. -G "Visual Studio 14 2015" -AWin32 -DTARGET_BUILD_PLATFORM=windows -DSTATIC_WINCRT=0 -DBL_DLL_OUTPUT_DIR=%OUTPUT_ROOT%\bin\vc14win32-cmake -DBL_LIB_OUTPUT_DIR=%OUTPUT_ROOT%\lib\vc14win32-cmake -DBL_EXE_OUTPUT_DIR=%OUTPUT_ROOT%\bin\vc14win32-cmake + +popd + +pause diff --git a/NvCloth/Tools/AuthoringLibrary/compiler/cmake/AuthoringLibrary.cmake b/NvCloth/Tools/AuthoringLibrary/compiler/cmake/AuthoringLibrary.cmake new file mode 100644 index 0000000..e649116 --- /dev/null +++ b/NvCloth/Tools/AuthoringLibrary/compiler/cmake/AuthoringLibrary.cmake @@ -0,0 +1,73 @@ +# +# Build AUTHORINGLIBRARY Common +# + +MESSAGE("AuthoringLibrary.cmake [begin]") + +MESSAGE("CMAKE_MODULE_PATH: " ${CMAKE_MODULE_PATH}) + +#SET(SB_SOURCE_DIR ${PROJECT_SOURCE_DIR}/..) + + +FIND_PACKAGE(PxShared "1.0.21467209.1" REQUIRED) + + +# Include here after the directories are defined so that the platform specific file can use the variables. +include(${PROJECT_CMAKE_FILES_DIR}/${TARGET_BUILD_PLATFORM}/AuthoringLibrary.cmake) + + +SET(HEADERS + ${PROJECT_SOURCE_DIR}/include/NvClothAuthoringLibrary/Parameters.h + ${PROJECT_SOURCE_DIR}/include/NvClothAuthoringLibrary/DebugVisualization.h + ${PROJECT_SOURCE_DIR}/include/NvClothAuthoringLibrary/CollisionVisualization.h +) + +SET(SOURCE + ${PROJECT_SOURCE_DIR}/src/Parameters.cpp + ${PROJECT_SOURCE_DIR}/src/DebugVisualization.cpp + ${PROJECT_SOURCE_DIR}/src/CollisionVisualization.cpp +) + +ADD_LIBRARY(NvClothAuthoringLibrary + ${HEADERS} + ${SOURCE} +) + +SOURCE_GROUP("include\\NvClothAuthoringLibrary" FILES ${HEADERS}) +SOURCE_GROUP("src" FILES ${SOURCE}) + + +# Target specific compile options + +TARGET_INCLUDE_DIRECTORIES(NvClothAuthoringLibrary + PRIVATE ${AUTHORINGLIBRARY_PLATFORM_INCLUDES} + + PRIVATE ${PXSHARED_ROOT_DIR}/include/foundation + PRIVATE ${PXSHARED_ROOT_DIR}/include + PRIVATE ${PXSHARED_ROOT_DIR}/src/foundation/include + + PRIVATE ${NVCLOTH_ROOT_DIR}/include + PRIVATE ${NVCLOTH_ROOT_DIR}/extensions/include + + PRIVATE ${PROJECT_SOURCE_DIR}/include +) + +TARGET_COMPILE_DEFINITIONS(NvClothAuthoringLibrary + PRIVATE ${AUTHORINGLIBRARY_COMPILE_DEFS} +) + +SET_TARGET_PROPERTIES(NvClothAuthoringLibrary PROPERTIES + COMPILE_PDB_NAME_DEBUG "NvClothAuthoringLibrary${CMAKE_DEBUG_POSTFIX}" + COMPILE_PDB_NAME_CHECKED "NvClothAuthoringLibrary${CMAKE_CHECKED_POSTFIX}" + COMPILE_PDB_NAME_PROFILE "NvClothAuthoringLibrary${CMAKE_PROFILE_POSTFIX}" + COMPILE_PDB_NAME_RELEASE "NvClothAuthoringLibrary${CMAKE_RELEASE_POSTFIX}" +) + +TARGET_COMPILE_OPTIONS(NvClothAuthoringLibrary PRIVATE /wd4005 /wd4244) + +TARGET_LINK_LIBRARIES(NvClothAuthoringLibrary PUBLIC PxFoundation) +TARGET_LINK_LIBRARIES(NvClothAuthoringLibrary PUBLIC NvCloth) + +SET_TARGET_PROPERTIES(NvClothAuthoringLibrary PROPERTIES LINK_FLAGS ${AUTHORINGLIBRARY_LINK_FLAGS}) + +MESSAGE("AUTHORINGLIBRARY.cmake [end]")
\ No newline at end of file diff --git a/NvCloth/Tools/AuthoringLibrary/compiler/cmake/windows/AuthoringLibrary.cmake b/NvCloth/Tools/AuthoringLibrary/compiler/cmake/windows/AuthoringLibrary.cmake new file mode 100644 index 0000000..88a3dd5 --- /dev/null +++ b/NvCloth/Tools/AuthoringLibrary/compiler/cmake/windows/AuthoringLibrary.cmake @@ -0,0 +1,44 @@ +# +# Build AuthoringLibrary Windows +# + +SET(AUTHORINGLIBRARY_PLATFORM_COMMON_FILES +) + +SET(AUTHORINGLIBRARY_COMPILE_DEFS + # Common to all configurations + ${SAMPLES_SLN_COMPILE_DEFS} + + $<$<CONFIG:debug>:${SAMPLES_SLN_DEBUG_COMPILE_DEFS}> + $<$<CONFIG:checked>:${SAMPLES_SLN_CHECKED_COMPILE_DEFS}> + $<$<CONFIG:profile>:${SAMPLES_SLN_PROFILE_COMPILE_DEFS}> + $<$<CONFIG:release>:${SAMPLES_SLN_RELEASE_COMPILE_DEFS}> +) + +SET(AUTHORINGLIBRARY_LINK_FLAGS "/SUBSYSTEM:WINDOWS") + +SET(AUTHORINGLIBRARY_ADDITIONAL_DLLS "") + +#TODO: Move this to an external dep +if (CMAKE_CL_64) + SET(SHADOW_LIB ${NVCLOTH_ROOT_DIR}/samples/external/shadow_lib/GFSDK_ShadowLib_DX11.win64.lib) + SET(SHADOW_DLLS ${NVCLOTH_ROOT_DIR}/samples/external/shadow_lib/GFSDK_ShadowLib_DX11.win64.dll) + + SET(HBAO_LIB ${NVCLOTH_ROOT_DIR}/samples/external/hbao/GFSDK_SSAO_D3D11.win64.lib) + SET(HBAO_DLLS ${NVCLOTH_ROOT_DIR}/samples/external/hbao/GFSDK_SSAO_D3D11.win64.dll) + + SET(D3DCOMPILER_DLL "\"$(VC_ExecutablePath_x64_x64)/d3dcompiler_47.dll\"") + + SET(ASSIMP_DLLS ${ASSIMP_DLL_PATH}/Release/assimp-vc140-mt.dll) +else() + SET(SHADOW_LIB ${NVCLOTH_ROOT_DIR}/samples/external/shadow_lib/GFSDK_ShadowLib_DX11.win32.lib) + SET(SHADOW_DLLS ${NVCLOTH_ROOT_DIR}/samples/external/shadow_lib/GFSDK_ShadowLib_DX11.win32.dll) + + SET(HBAO_LIB ${NVCLOTH_ROOT_DIR}/samples/external/hbao/GFSDK_SSAO_D3D11.win32.lib) + SET(HBAO_DLLS ${NVCLOTH_ROOT_DIR}/samples/external/hbao/GFSDK_SSAO_D3D11.win32.dll) + + SET(D3DCOMPILER_DLL "\"$(VC_ExecutablePath_x86_x86)/d3dcompiler_47.dll\"") + + SET(ASSIMP_DLLS ${ASSIMP_DLL_PATH}/Release/assimp-vc140-mt.dll) +endif() + diff --git a/NvCloth/Tools/AuthoringLibrary/compiler/cmake/windows/CMakeLists.txt b/NvCloth/Tools/AuthoringLibrary/compiler/cmake/windows/CMakeLists.txt new file mode 100644 index 0000000..fd9d4bd --- /dev/null +++ b/NvCloth/Tools/AuthoringLibrary/compiler/cmake/windows/CMakeLists.txt @@ -0,0 +1,82 @@ +#Platform specific compile flags and project includes + +SET(GW_DEPS_ROOT $ENV{GW_DEPS_ROOT}) + +SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}; $ENV{GW_DEPS_ROOT}/sw/physx/tools/CMakeModules) + +IF(EXISTS $ENV{GW_DEPS_ROOT}/Externals/CMakeModules) + SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}; $ENV{GW_DEPS_ROOT}/Externals/CMakeModules) +ENDIF() + + +IF(EXISTS $ENV{GW_DEPS_ROOT}/Externals/CMakeModules) + SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}; $ENV{GW_DEPS_ROOT}/Externals/CMakeModules) +ENDIF() + +SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}; "${CMAKE_CURRENT_SOURCE_DIR}/../..") +SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}; "${CMAKE_CURRENT_SOURCE_DIR}/external/CMakeModules") +MESSAGE("CMAKE_MODULE_PATH: " ${CMAKE_MODULE_PATH}) + +#NOTE: Warnings lowered on the sample projects as it's got a lot of warnings. Defines below hide more. +SET(CMAKE_CXX_FLAGS "/GR- /GF /MP /Gy /EHsc /d2Zi+ /errorReport:prompt /fp:fast /Gd /Gm- /GS- /nologo /W3 /WX /Zc:forScope /Zc:inline /Zc:wchar_t /Zi") + +# Are we using the static or dynamic RT library? Whatever we use, it needs to be the same in any dependencies +# we pull in or we're potentially having mismatch issues. +IF(STATIC_WINCRT) + SET(WINCRT_NDEBUG "/MT") + SET(WINCRT_DEBUG "/MTd") +ELSE() + SET(WINCRT_NDEBUG "/MD") + SET(WINCRT_DEBUG "/MDd") +ENDIF() + +SET(CMAKE_CXX_FLAGS_DEBUG "/Od /RTCsu ${WINCRT_DEBUG}") +SET(CMAKE_CXX_FLAGS_CHECKED "/Ox ${WINCRT_NDEBUG}") +SET(CMAKE_CXX_FLAGS_PROFILE "/Ox ${WINCRT_NDEBUG}") +SET(CMAKE_CXX_FLAGS_RELEASE "/Ox ${WINCRT_NDEBUG}") + +# Build PDBs for all configurations +SET(CMAKE_SHARED_LINKER_FLAGS "/DEBUG") + +IF(CMAKE_CL_64) + ADD_DEFINITIONS(-DWIN64) +ENDIF(CMAKE_CL_64) + +SET(SAMPLES_SLN_COMPILE_DEFS _UNICODE;UNICODE;WIN32;WIN64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH;_ALLOW_RUNTIME_LIBRARY_MISMATCH;__GFSDK_DX11__;) +#NvBlastExt doesn't have the _CONSOLE flag + +SET(SAMPLES_SLN_DEBUG_COMPILE_DEFS _DEBUG;NV_DEBUG=1;) +SET(SAMPLES_SLN_CHECKED_COMPILE_DEFS NDEBUG;NV_CHECKED=1;) +SET(SAMPLES_SLN_PROFILE_COMPILE_DEFS NDEBUG;NV_PROFILE=1;) +SET(SAMPLES_SLN_RELEASE_COMPILE_DEFS NDEBUG;) + +IF(CMAKE_CL_64) + SET(LIBPATH_SUFFIX "x64") +ELSE(CMAKE_CL_64) + SET(LIBPATH_SUFFIX "x86") +ENDIF(CMAKE_CL_64) + +SET(CMAKE_DEBUG_POSTFIX "${CMAKE_DEBUG_POSTFIX}_${LIBPATH_SUFFIX}") +SET(CMAKE_PROFILE_POSTFIX "${CMAKE_PROFILE_POSTFIX}_${LIBPATH_SUFFIX}") +SET(CMAKE_CHECKED_POSTFIX "${CMAKE_CHECKED_POSTFIX}_${LIBPATH_SUFFIX}") +SET(CMAKE_RELEASE_POSTFIX "${CMAKE_RELEASE_POSTFIX}_${LIBPATH_SUFFIX}") + +SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}; "${CMAKE_CURRENT_SOURCE_DIR}/../../../..") + +SET(PX_SELECT_COMPONENTS PxFoundation) +FIND_PACKAGE(PxShared REQUIRED) +FIND_PACKAGE(NvCloth REQUIRED) + +# Include the PxShared-exports.cmake file that PxShared created. There's other ways to do this, but there's a bunch of issues with it in a CI environment +# such as - we don't want to be installing any built artifacts on this server, etc. So for now we hack it. + +# Add PxShared as a dependency so that we can use project references +#ADD_SUBDIRECTORY(${PXSHARED_ROOT_DIR}/src/compiler/cmake/windows "${CMAKE_CURRENT_BINARY_DIR}/pxshared_bin") +#MESSAGE("NVCLOTH_ROOT_DIR = ${NVCLOTH_ROOT_DIR}") +ADD_SUBDIRECTORY(${NVCLOTH_ROOT_DIR}/compiler/cmake/windows "${CMAKE_CURRENT_BINARY_DIR}/NvCloth_bin") + + +# Include all of the projects +INCLUDE(${PROJECT_CMAKE_FILES_DIR}/AuthoringLibrary.cmake) + + diff --git a/NvCloth/Tools/AuthoringLibrary/external/CMakeModules/FindPxShared.cmake b/NvCloth/Tools/AuthoringLibrary/external/CMakeModules/FindPxShared.cmake new file mode 100644 index 0000000..c094676 --- /dev/null +++ b/NvCloth/Tools/AuthoringLibrary/external/CMakeModules/FindPxShared.cmake @@ -0,0 +1,20 @@ +# - Try to find PxShared +# Once done this will define +# PXSHARED_FOUND - System has PxShared +# PXSHARED_ROOT_DIR - The root of PxShared + +# NOTE: We're including a version in this, but the first hint is without one - we should use that! +FIND_PATH( PXSHARED_ROOT_DIR include/cudamanager/PxGpuCopyDesc.h + HINTS + ${GW_DEPS_ROOT}/PxShared/${PxShared_FIND_VERSION} + ${GW_DEPS_ROOT}/sw/physx/PxShared/1.0/trunk + + ) + + + + +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(PxShared DEFAULT_MSG PXSHARED_ROOT_DIR) + +mark_as_advanced(PXSHARED_ROOT_DIR) diff --git a/NvCloth/Tools/AuthoringLibrary/external/CMakeModules/SetOutputPaths.cmake b/NvCloth/Tools/AuthoringLibrary/external/CMakeModules/SetOutputPaths.cmake new file mode 100644 index 0000000..a1be9f4 --- /dev/null +++ b/NvCloth/Tools/AuthoringLibrary/external/CMakeModules/SetOutputPaths.cmake @@ -0,0 +1,95 @@ +FUNCTION(SetOutputPaths + OUTPUT_EXE_DIR + OUTPUT_DLL_DIR + OUTPUT_LIB_DIR) + + SET(EXE_DIR ${OUTPUT_EXE_DIR}) + SET(DLL_DIR ${OUTPUT_DLL_DIR}) + SET(LIB_DIR ${OUTPUT_LIB_DIR}) + + # Override the default output directories for all configurations. + SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${EXE_DIR} PARENT_SCOPE) + SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${DLL_DIR} PARENT_SCOPE) + SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${LIB_DIR} PARENT_SCOPE) + + SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_CHECKED ${EXE_DIR} PARENT_SCOPE) + SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY_CHECKED ${DLL_DIR} PARENT_SCOPE) + SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_CHECKED ${LIB_DIR} PARENT_SCOPE) + + SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_PROFILE ${EXE_DIR} PARENT_SCOPE) + SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY_PROFILE ${DLL_DIR} PARENT_SCOPE) + SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_PROFILE ${LIB_DIR} PARENT_SCOPE) + + SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${EXE_DIR} PARENT_SCOPE) + SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${DLL_DIR} PARENT_SCOPE) + SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${LIB_DIR} PARENT_SCOPE) + + SET(CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY ${LIB_DIR}) + +ENDFUNCTION(SetOutputPaths) + +FUNCTION(SetExeOutputPath OUTPUT_EXE_DIR) + + SET(EXE_DIR ${OUTPUT_EXE_DIR}) + + # Override the default output directories for all configurations. + SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${EXE_DIR} PARENT_SCOPE) + SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_CHECKED ${EXE_DIR} PARENT_SCOPE) + SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_PROFILE ${EXE_DIR} PARENT_SCOPE) + SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${EXE_DIR} PARENT_SCOPE) + +ENDFUNCTION(SetExeOutputPath) + +FUNCTION(SetDllOutputPath OUTPUT_DLL_DIR) + + SET(DLL_DIR ${OUTPUT_DLL_DIR}) + + # Override the default output directories for all configurations. + SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${DLL_DIR}/${ARGV1} PARENT_SCOPE) + SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY_PROFILE ${DLL_DIR}/${ARGV2} PARENT_SCOPE) + SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY_CHECKED ${DLL_DIR}/${ARGV3} PARENT_SCOPE) + SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${DLL_DIR}/${ARGV4} PARENT_SCOPE) + +ENDFUNCTION(SetDllOutputPath) + +FUNCTION(SetLibOutputPath OUTPUT_LIB_DIR) + + SET(LIB_DIR ${OUTPUT_LIB_DIR}) + + # Override the default output directories for all configurations. + SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${LIB_DIR}/${ARGV1} PARENT_SCOPE) + SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_PROFILE ${LIB_DIR}/${ARGV2} PARENT_SCOPE) + SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_CHECKED ${LIB_DIR}/${ARGV3} PARENT_SCOPE) + SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${LIB_DIR}/${ARGV4} PARENT_SCOPE) + + SET(CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY ${LIB_DIR}) + +ENDFUNCTION(SetLibOutputPath) + +FUNCTION(SetSingleOutputPath OUTPUT_ALL_DIR) + + SET(EXE_DIR ${OUTPUT_ALL_DIR}) + SET(DLL_DIR ${OUTPUT_ALL_DIR}) + SET(LIB_DIR ${OUTPUT_ALL_DIR}) + + # Override the default output directories for all configurations. + SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${EXE_DIR} PARENT_SCOPE) + SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${DLL_DIR} PARENT_SCOPE) + SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${LIB_DIR} PARENT_SCOPE) + + SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_CHECKED ${EXE_DIR} PARENT_SCOPE) + SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY_CHECKED ${DLL_DIR} PARENT_SCOPE) + SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_CHECKED ${LIB_DIR} PARENT_SCOPE) + + SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_PROFILE ${EXE_DIR} PARENT_SCOPE) + SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY_PROFILE ${DLL_DIR} PARENT_SCOPE) + SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_PROFILE ${LIB_DIR} PARENT_SCOPE) + + SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${EXE_DIR} PARENT_SCOPE) + SET(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${DLL_DIR} PARENT_SCOPE) + SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${LIB_DIR} PARENT_SCOPE) + + SET(CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY ${LIB_DIR}) + +ENDFUNCTION(SetSingleOutputPath) + diff --git a/NvCloth/Tools/AuthoringLibrary/include/NvClothAuthoringLibrary/CollisionVisualization.h b/NvCloth/Tools/AuthoringLibrary/include/NvClothAuthoringLibrary/CollisionVisualization.h new file mode 100644 index 0000000..4adab40 --- /dev/null +++ b/NvCloth/Tools/AuthoringLibrary/include/NvClothAuthoringLibrary/CollisionVisualization.h @@ -0,0 +1,98 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once +#include <foundation/PxVec2.h> +#include <foundation/PxVec3.h> +#include <foundation/PxVec4.h> +#include <foundation/PxMat44.h> +#include <foundation/PxStrideIterator.h> +#include <vector> +#include <algorithm> + +namespace nv +{ +namespace cloth +{ + +class Cloth; + +namespace collisionVisualization +{ + +// struct used to store cashed meshes in +// the initialize and ~destructor methods use nv::cloth::(de)allocate() +struct SimpleMesh +{ + SimpleMesh(); + ~SimpleMesh(); + void initialize(int vertexCount, int indexCount); + physx::PxVec3* mPositions; + physx::PxVec3* mNormals; + physx::PxVec2* mUvs; + unsigned int* mIndices; + + int mVertexCount; + int mIndexCount; + + physx::PxStrideIterator<physx::PxVec3> GetPositionIterator() { return physx::PxStrideIterator<physx::PxVec3>(mPositions); } + physx::PxStrideIterator<physx::PxVec3> GetNormalIterator() { return physx::PxStrideIterator<physx::PxVec3>(mNormals); } + physx::PxStrideIterator<physx::PxVec2> GetUvIterator() { return physx::PxStrideIterator<physx::PxVec2>(mUvs); } + physx::PxStrideIterator<unsigned int> GetIndexIterator() { return physx::PxStrideIterator<unsigned int>(mIndices); } + +}; + +//Generates simple meshes with smooth shading +//Use the Get*MemorySize to calculate how much memory the generate* function needs +//outNormals and outUvs are optional, they can be left nullptr + +//Spheres +void getSphereMemorySize(int segmentsX, int segmentsY, int* outVertexCount, int* outIndexCount); +void generateSphere(int segmentsX, int segmentY, physx::PxMat44 transform, + physx::PxStrideIterator<unsigned int> outIndices, int indexOffset, + physx::PxStrideIterator<physx::PxVec3> outPositions, physx::PxStrideIterator<physx::PxVec3> outNormals = physx::PxStrideIterator<physx::PxVec3>(), physx::PxStrideIterator<physx::PxVec2> outUvs = physx::PxStrideIterator<physx::PxVec2>()); + +//Cylinders without caps +void getCylinderMemorySize(int segmentsX, int segmentsY, int* outVertexCount, int* outIndexCount); +void generateCylinder(int segmentsX, int segmentsY, physx::PxMat44 transform, + physx::PxStrideIterator<unsigned int> outIndices, int indexOffset, + physx::PxStrideIterator<physx::PxVec3> outPositions, physx::PxStrideIterator<physx::PxVec3> outNormals = physx::PxStrideIterator<physx::PxVec3>(), physx::PxStrideIterator<physx::PxVec2> outUvs = physx::PxStrideIterator<physx::PxVec2>()); + + +//Combines cashed spheres and cylinders to generate the capsules +void getCollisionCapsuleMemorySize(int sphereCount, int indexCount, SimpleMesh const& cachedSphere, SimpleMesh const& cachedCylinder, int* outVertexCount, int* outIndexCount); +void generateCollisionCapsules(physx::PxVec4 const* spheres, int sphereCount, uint32_t const* indices, int indexCount, float grow, + SimpleMesh const& cachedSphere, SimpleMesh const& cachedCylinder, + physx::PxStrideIterator<unsigned int> outIndices, int indexOffset, + physx::PxStrideIterator<physx::PxVec3> outPositions, physx::PxStrideIterator<physx::PxVec3> outNormals = physx::PxStrideIterator<physx::PxVec3>(), physx::PxStrideIterator<physx::PxVec2> outUvs = physx::PxStrideIterator<physx::PxVec2>()); +void getCollisionCapsuleSubmeshOffsets(int sphereCount, int indexCount, SimpleMesh const& cachedSphere, SimpleMesh const& cachedCylinder, physx::PxStrideIterator<unsigned int> submehsOffsets); + +} +} +}
\ No newline at end of file diff --git a/NvCloth/Tools/AuthoringLibrary/include/NvClothAuthoringLibrary/DebugVisualization.h b/NvCloth/Tools/AuthoringLibrary/include/NvClothAuthoringLibrary/DebugVisualization.h new file mode 100644 index 0000000..e67ddbf --- /dev/null +++ b/NvCloth/Tools/AuthoringLibrary/include/NvClothAuthoringLibrary/DebugVisualization.h @@ -0,0 +1,58 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once +#include <foundation/PxVec3.h> +#include <foundation/PxVec4.h> +#include <vector> +#include <algorithm> + +namespace nv +{ +namespace cloth +{ + +class Cloth; + +namespace debugVisualization +{ + +typedef void(*AddLineCallback)(physx::PxVec3 posA, physx::PxVec4 colA, physx::PxVec3 posB, physx::PxVec4 colB); + +void VisualizeDistanceConstraints(Cloth* cloth, AddLineCallback addLineCallback); +void VisualizeTethers(Cloth* cloth_, AddLineCallback addLineCallback); +void VisualizeConstraints(Cloth* cloth_, AddLineCallback addLineCallback, int visiblePhaseRangeBegin = 0, int visiblePhaseRangeEnd = 0); +void VisualizeConstraintStiffness(Cloth* cloth_, AddLineCallback addLineCallback); +void VisualizeConstraintError(Cloth* cloth_, AddLineCallback addLineCallback); +void VisualizePositionDelta(Cloth* cloth_, AddLineCallback addLineCallback, float lengthScale = 2.0f); +void VisualizeBoundingBox(Cloth* cloth_, AddLineCallback addLineCallback); + +} +} +}
\ No newline at end of file diff --git a/NvCloth/Tools/AuthoringLibrary/include/NvClothAuthoringLibrary/Parameters.h b/NvCloth/Tools/AuthoringLibrary/include/NvClothAuthoringLibrary/Parameters.h new file mode 100644 index 0000000..38b098f --- /dev/null +++ b/NvCloth/Tools/AuthoringLibrary/include/NvClothAuthoringLibrary/Parameters.h @@ -0,0 +1,114 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2017 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once +#include "NvCloth/Cloth.h" + +namespace nv +{ +namespace cloth +{ +namespace authoring +{ + +enum class ParameterType +{ + NONE, + FLOAT, + VEC3, + VEC3_NORMALIZED, + VEC3_SLIDER1MAX, +}; + +//Parameter set callback types +typedef void(*SetFloatParamType)(Cloth* cloth, float value); +typedef void(*SetVec3ParamType)(Cloth* cloth, physx::PxVec3 value); + +//Parameter get callback types +typedef float(*GetFloatParamType)(Cloth* cloth); +typedef physx::PxVec3(*GetVec3ParamType)(Cloth* cloth); + +struct Parameter +{ + Parameter() {} + Parameter(Parameter const & other) + { + memcpy(this, &other, sizeof(Parameter)); + } + Parameter& operator=(Parameter const & other) + { + memcpy(this, &other, sizeof(Parameter)); + } + + int mParameterId; + int mCatagoryId; + const char* mName; + const char* mDescription; + ParameterType mType; + + //Setters + union + { + void* SetFunctionPointer; + SetFloatParamType SetFloat; + SetVec3ParamType SetVec3; + }; + + //Getters + union + { + void* GetFunctionPointer; + GetFloatParamType GetFloat; + GetVec3ParamType GetVec3; + }; + + union + { + float mMinFloat; + physx::PxVec3 mMinVec3; + }; + + union + { + float mMaxFloat; + physx::PxVec3 mMaxVec3; + }; + bool mHardMinLimit; //true if the mMax* limit should be respected, false if they are just guide lines + bool mHardMaxLimit; //true if the mMax* limit should be respected, false if they are just guide lines +}; + +int GetClothNumParameters(); +Parameter const& GetClothParameterInfo(int id); +int GetClothNumParameterCatagories(); +const char* GetClothParameterCatagorieInfo(int id); + + +} +} +}
\ No newline at end of file diff --git a/NvCloth/Tools/AuthoringLibrary/src/CollisionVisualization.cpp b/NvCloth/Tools/AuthoringLibrary/src/CollisionVisualization.cpp new file mode 100644 index 0000000..ceee90f --- /dev/null +++ b/NvCloth/Tools/AuthoringLibrary/src/CollisionVisualization.cpp @@ -0,0 +1,432 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2017 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 "NvClothAuthoringLibrary/CollisionVisualization.h" +#include "NvCloth/Cloth.h" +#include "NvCloth/Fabric.h" +#include "NvCloth/Factory.h" +#include <assert.h> +#include <algorithm> +#include "NvCloth/Allocator.h" +#include "NvCloth/Callbacks.h" + +namespace nv +{ +namespace cloth +{ +namespace collisionVisualization +{ + +SimpleMesh::SimpleMesh() + : +mPositions(nullptr), +mNormals(nullptr), +mUvs(nullptr), +mIndices(nullptr), +mVertexCount(0), +mIndexCount(0) +{ + +} +SimpleMesh::~SimpleMesh() +{ + auto& allocator = *GetNvClothAllocator(); + allocator.deallocate(mPositions); + allocator.deallocate(mNormals); + allocator.deallocate(mUvs); + allocator.deallocate(mIndices); +} +void SimpleMesh::initialize(int vertexCount, int indexCount) +{ + mVertexCount = vertexCount; + mIndexCount = indexCount; + + auto& allocator = *GetNvClothAllocator(); + + mPositions = static_cast<physx::PxVec3*>( + allocator.allocate(sizeof(physx::PxVec3)*vertexCount, "nv::cloth::collisionVisualization::SimpleMesh::mPositions", __FILE__, __LINE__) + ); + mNormals = static_cast<physx::PxVec3*>( + allocator.allocate(sizeof(physx::PxVec3)*vertexCount, "nv::cloth::collisionVisualization::SimpleMesh::mNormals", __FILE__, __LINE__) + ); + mUvs = static_cast<physx::PxVec2*>( + allocator.allocate(sizeof(physx::PxVec2)*vertexCount, "nv::cloth::collisionVisualization::SimpleMesh::mUvs", __FILE__, __LINE__) + ); + mIndices = static_cast<unsigned int*>( + allocator.allocate(sizeof(unsigned int)*indexCount, "nv::cloth::collisionVisualization::SimpleMesh::mIndices", __FILE__, __LINE__) + ); +} + +void getSphereMemorySize(int segmentsX, int segmentsY, int* outVertexCount, int* outIndexCount) +{ + const int xSegments = segmentsX; + const int ySegments = segmentsY; + + *outVertexCount = 1 + (xSegments * (ySegments - 1)) + 1; + *outIndexCount = xSegments * 3 + 6 * (xSegments * (ySegments - 2)) + xSegments * 3; +} + +void generateSphere(int segmentsX, int segmentY, physx::PxMat44 transform, + physx::PxStrideIterator<unsigned int> outIndices, int indexOffset, + physx::PxStrideIterator<physx::PxVec3> outPositions, physx::PxStrideIterator<physx::PxVec3> outNormals, physx::PxStrideIterator<physx::PxVec2> outUvs) +{ + const int xSegments = segmentsX; + const int ySegments = segmentY; + + physx::PxStrideIterator<physx::PxVec3> vertexIteratorPos = outPositions; + physx::PxStrideIterator<physx::PxVec3> vertexIteratorNormal = outNormals; + physx::PxStrideIterator<physx::PxVec2> vertexIteratorUv = outUvs; + + { + //bottom + physx::PxVec3 pos = physx::PxVec3(0.0f, -1.0f, 0.0f); + *vertexIteratorPos++ = transform.transform(pos); + if(outNormals.ptr()) *vertexIteratorNormal++ = transform.rotate(physx::PxVec4(pos, 0.0f)).getXYZ(); + if(outUvs.ptr()) *vertexIteratorUv++ = physx::PxVec2(0.0f, 0.0f); + } + + //middle + for(int y = 1; y < ySegments; y++) + { + for(int x = 0; x < xSegments; x++) + { + float xf = (float)x / (xSegments - 1.0f); + float yaw = xf*physx::PxTwoPi; + float yf = (float)y / (ySegments); + float pitch = (yf - 0.5f)*physx::PxPi; + + physx::PxVec3 pos = physx::PxVec3(cos(yaw)*cos(pitch), sin(pitch), sin(yaw)*cos(pitch));; + *vertexIteratorPos++ = transform.transform(pos); + if(outNormals.ptr()) *vertexIteratorNormal++ = transform.rotate(physx::PxVec4(pos, 0.0f)).getXYZ(); + if(outUvs.ptr()) *vertexIteratorUv++ = physx::PxVec2(xf, yf); + } + } + + { + //top + physx::PxVec3 pos = physx::PxVec3(0.0f, 1.0f, 0.0f); + *vertexIteratorPos++ = transform.transform(pos); + if(outNormals.ptr()) *vertexIteratorNormal++ = transform.rotate(physx::PxVec4(pos, 0.0f)).getXYZ(); + if(outUvs.ptr()) *vertexIteratorUv++ = physx::PxVec2(0.0f, 0.0f); + } + + physx::PxStrideIterator<unsigned int> indexIterator = outIndices; + + //bottom cap + for(int x = 0; x < xSegments; x++) + { + *indexIterator++ = indexOffset; + *indexIterator++ = 1 + x + indexOffset; + *indexIterator++ = 1 + (x + 1) % xSegments + indexOffset; + } + + const auto RingVertex = [xSegments, ySegments](int x, int y) + { + return 1 + y*xSegments + x%xSegments; + }; + + //middle + for(int y = 0; y < ySegments - 2; y++) + { + for(int x = 0; x < xSegments; x++) + { + *indexIterator++ = RingVertex(x, y) + indexOffset; + *indexIterator++ = RingVertex(x + 1, y) + indexOffset; + *indexIterator++ = RingVertex(x, y + 1) + indexOffset; + + *indexIterator++ = RingVertex(x + 1, y) + indexOffset; + *indexIterator++ = RingVertex(x + 1, y + 1) + indexOffset; + *indexIterator++ = RingVertex(x, y + 1) + indexOffset; + } + } + + int numVertices = vertexIteratorPos - outPositions; + + //bottom cap + for(int x = 0; x < xSegments; x++) + { + *indexIterator++ = numVertices - 1 + indexOffset; + *indexIterator++ = RingVertex(x, ySegments - 2) + indexOffset; + *indexIterator++ = RingVertex(x + 1, ySegments - 2) + indexOffset; + } +} + +void getCylinderMemorySize(int segmentsX, int segmentsY, int* outVertexCount, int* outIndexCount) +{ + const int xSegments = segmentsX; + const int ySegments = segmentsY; + + *outVertexCount = xSegments * (ySegments + 1); + *outIndexCount = xSegments * ySegments * 6; +} + + + + +void generateCylinder(int segmentsX, int segmentsY, physx::PxMat44 transform, + physx::PxStrideIterator<unsigned int> outIndices, int indexOffset, + physx::PxStrideIterator<physx::PxVec3> outPositions, physx::PxStrideIterator<physx::PxVec3> outNormals, physx::PxStrideIterator<physx::PxVec2> outUvs) +{ + const int xSegments = segmentsX; + const int ySegments = segmentsY; + + physx::PxStrideIterator<physx::PxVec3> vertexIteratorPos = outPositions; + physx::PxStrideIterator<physx::PxVec3> vertexIteratorNormal = outNormals; + physx::PxStrideIterator<physx::PxVec2> vertexIteratorUv = outUvs; + + //middle + for(int y = 0; y < ySegments + 1; y++) + { + for(int x = 0; x < xSegments; x++) + { + float xf = (float)x / (xSegments - 1.0f); + float yaw = xf*physx::PxTwoPi; + float yf = (float)y / (ySegments) * 2.0f - 1.0f; + + physx::PxVec3 pos = physx::PxVec3(cos(yaw), yf, sin(yaw)); + *vertexIteratorPos++ = transform.transform(pos); + if(outNormals.ptr()) *vertexIteratorNormal++ = transform.rotate(physx::PxVec4(physx::PxVec3(cos(yaw), 0.0f, sin(yaw)), 0.0f)).getXYZ(); + if(outUvs.ptr()) *vertexIteratorUv++ = physx::PxVec2(xf, yf); + } + } + + physx::PxStrideIterator<unsigned int> indexIterator = outIndices; + + + const auto RingVertex = [xSegments, ySegments](int x, int y) + { + return y*xSegments + x%xSegments; + }; + + //middle + for(int y = 0; y < ySegments; y++) + { + for(int x = 0; x < xSegments; x++) + { + *indexIterator++ = RingVertex(x, y) + indexOffset; + *indexIterator++ = RingVertex(x + 1, y) + indexOffset; + *indexIterator++ = RingVertex(x, y + 1) + indexOffset; + + *indexIterator++ = RingVertex(x + 1, y) + indexOffset; + *indexIterator++ = RingVertex(x + 1, y + 1) + indexOffset; + *indexIterator++ = RingVertex(x, y + 1) + indexOffset; + } + } +} + +void getCollisionCapsuleMemorySize(int sphereCount, int indexCount, SimpleMesh const& cachedSphere, SimpleMesh const& cachedCylinder, int* outVertexCount, int* outIndexCount) +{ + *outVertexCount = cachedSphere.mVertexCount*sphereCount + cachedCylinder.mVertexCount*(indexCount / 2); + *outIndexCount = cachedSphere.mIndexCount*sphereCount + cachedCylinder.mIndexCount*(indexCount / 2); +} + +namespace +{ + /** returns two vectors in b and c so that [a b c] form a basis. + * a needs to be a unit vector. + */ + inline void computeBasis(const physx::PxVec3& a, physx::PxVec3* b, physx::PxVec3* c) + { + if(fabsf(a.x) >= 0.57735f) + *b = physx::PxVec3(a.y, -a.x, 0.0f); + else + *b = physx::PxVec3(0.0f, a.z, -a.y); + + *b = b->getNormalized(); + *c = a.cross(*b); + } + + physx::PxVec3 IntersectSpheres(float* circleRadius, physx::PxVec3 aCenter, float aRadius, physx::PxVec3 bCenter, float bRadius) + { + //Intersect spheres in 2d (http://paulbourke.net/geometry/circlesphere/ Intersection of two circles) + float d = (aCenter - bCenter).magnitude(); + float a = (aRadius*aRadius - bRadius*bRadius + d*d) / (2.0f*d); + float h = sqrtf(aRadius*aRadius - a*a); + physx::PxVec3 P3 = aCenter + a * (bCenter - aCenter) / d; + if(circleRadius) *circleRadius = h; + return P3; + } +} + +void generateCollisionCapsules(physx::PxVec4 const* spheres, int sphereCount, uint32_t const* indices, int indexCount, float grow, + SimpleMesh const& cachedSphere, SimpleMesh const& cachedCylinder, + physx::PxStrideIterator<unsigned int> outIndices, int indexOffset, + physx::PxStrideIterator<physx::PxVec3> outPositions, physx::PxStrideIterator<physx::PxVec3> outNormals, physx::PxStrideIterator<physx::PxVec2> outUvs) +{ + physx::PxStrideIterator<physx::PxVec3> vertexIteratorPos = outPositions; + physx::PxStrideIterator<physx::PxVec3> vertexIteratorNormal = outNormals; + physx::PxStrideIterator<physx::PxVec2> vertexIteratorUv = outUvs; + + physx::PxStrideIterator<unsigned int> indexIterator = outIndices; + + int nextVertex = 0; + int nextIndex = 0; + for(int i = 0; i < sphereCount; i++) + { + int baseIndex = nextVertex; + physx::PxMat44 transform = + physx::PxMat44(physx::PxMat33(physx::PxIdentity), spheres[i].getXYZ()) + * physx::PxMat44(physx::PxVec4(spheres[i].w + grow, spheres[i].w + grow, spheres[i].w + grow, 1.0f)); + + for(int vi = 0; vi<cachedSphere.mVertexCount; vi++) + { + physx::PxVec3 pos = cachedSphere.mPositions[vi]; + *vertexIteratorPos++ = transform.transform(pos); + if(outNormals.ptr()) *vertexIteratorNormal++ = transform.rotate(physx::PxVec4(cachedSphere.mNormals[vi], 0.0f)).getXYZ(); + if(outUvs.ptr()) *vertexIteratorUv++ = cachedSphere.mUvs[vi]; + } + + for(int ii = 0; ii < cachedSphere.mIndexCount; ii++) + { + *indexIterator++ = cachedSphere.mIndices[ii] + baseIndex + indexOffset; + } + nextVertex += cachedSphere.mVertexCount; + } + + for(int i = 0; i < indexCount; i += 2) + { + int baseIndex = nextVertex; + + physx::PxVec3 spherePosA = spheres[indices[i]].getXYZ(); + physx::PxVec3 spherePosB = spheres[indices[i + 1]].getXYZ(); + float sphereRadiusA = spheres[indices[i]].w + grow; + float sphereRadiusB = spheres[indices[i + 1]].w + grow; + + if(sphereRadiusA < sphereRadiusB) + { + std::swap(sphereRadiusA, sphereRadiusB); + std::swap(spherePosA, spherePosB); + } + + { + //http://jwilson.coe.uga.edu/emt669/Student.Folders/Kertscher.Jeff/Essay.3/Tangents.html + + //sphere a with smaller radius + float cRadius = sphereRadiusA - sphereRadiusB; + if(cRadius > 0.00001) + { + physx::PxVec3 basis[3]; + basis[2] = spherePosB - spherePosA; + basis[2].normalize(); + computeBasis(basis[2], &basis[0], &basis[1]); + + physx::PxVec3 cCenter = spherePosA; + + //sphere in between the a and b + physx::PxVec3 dCenter = (spherePosA + spherePosB)*0.5f; + float dRadius = (spherePosA - spherePosB).magnitude()*0.5f; + + //intersection between c and d to get tangent point + float iRadius; + physx::PxVec3 iCenter = IntersectSpheres(&iRadius, dCenter, dRadius, cCenter, cRadius); + physx::PxVec3 iPoint = iCenter + basis[0] * iRadius; //tangent point on c + physx::PxVec3 offset = (iPoint - spherePosA).getNormalized(); //offset direction + + physx::PxVec3 aPoint = spherePosA + offset*sphereRadiusA; + spherePosA = (aPoint - spherePosA).dot(basis[2])*basis[2] + spherePosA; + sphereRadiusA = (aPoint - spherePosA).magnitude(); + physx::PxVec3 bPoint = spherePosB + offset*sphereRadiusB; + spherePosB = (bPoint - spherePosA).dot(basis[2])*basis[2] + spherePosA; + sphereRadiusB = (bPoint - spherePosB).magnitude(); + } + } + + float length = (spherePosB - spherePosA).magnitude(); + + + physx::PxMat44 scaleA = physx::PxMat44(physx::PxVec4(sphereRadiusA, length / 2.0f, sphereRadiusA + grow, 1.0f)); + physx::PxMat44 scaleB = physx::PxMat44(physx::PxVec4(sphereRadiusB, length / 2.0f, sphereRadiusB, 1.0f)); + + physx::PxQuat orientation; + { + physx::PxVec3 u = physx::PxVec3(0.0f, 1.0f, 0.0f); + physx::PxVec3 v = spherePosB - spherePosA; + v.normalize(); + + if(u.dot(v) < -0.9999 || u.dot(v) > 0.9999) + { + physx::PxVec3 orth, tmp; + computeBasis(u, &orth, &tmp); + orientation = physx::PxQuat(orth.x, orth.y, orth.z, 0.0f); + } + else + { + physx::PxVec3 half = u + v; + half.normalize(); + physx::PxVec3 imaginary = u.cross(half); + orientation = physx::PxQuat(imaginary.x, imaginary.y, imaginary.z, u.dot(half)); + } + } + + physx::PxMat44 transform = physx::PxMat44(physx::PxTransform(spherePosA, orientation))*scaleA; + + int firstRing = cachedCylinder.mVertexCount / 2; + for(int vi = 0; vi<firstRing; vi++) + { + physx::PxVec3 pos = cachedCylinder.mPositions[vi]; + *vertexIteratorPos++ = transform.transform(pos); + if(outNormals.ptr()) *vertexIteratorNormal++ = transform.rotate(physx::PxVec4(cachedCylinder.mNormals[vi], 0.0f)).getXYZ(); + if(outUvs.ptr()) *vertexIteratorUv++ = cachedCylinder.mUvs[vi]; + } + transform = physx::PxMat44(physx::PxTransform(spherePosA, orientation))*scaleB; + for(int vi = firstRing; vi<cachedCylinder.mVertexCount; vi++) + { + physx::PxVec3 pos = cachedCylinder.mPositions[vi]; + *vertexIteratorPos++ = transform.transform(pos); + if(outNormals.ptr()) *vertexIteratorNormal++ = transform.rotate(physx::PxVec4(cachedCylinder.mNormals[vi], 0.0f)).getXYZ(); + if(outUvs.ptr()) *vertexIteratorUv++ = cachedCylinder.mUvs[vi]; + } + + nextVertex += cachedCylinder.mVertexCount; + + for(int ii = 0; ii < cachedCylinder.mIndexCount; ii++) + { + *indexIterator++ = cachedCylinder.mIndices[ii] + baseIndex + indexOffset; + } + } +} + +void getCollisionCapsuleSubmeshOffsets(int sphereCount, int indexCount, SimpleMesh const& cachedSphere, SimpleMesh const& cachedCylinder, physx::PxStrideIterator<unsigned int> submehsOffsets) +{ + int nextOffset = 0; + for(int i = 0; i < sphereCount; i++) + { + *submehsOffsets++ = nextOffset; + nextOffset += cachedSphere.mIndexCount; + } + for(int i = 0; i < indexCount; i+=2) + { + *submehsOffsets++ = nextOffset; + nextOffset += cachedCylinder.mIndexCount; + } +} + + +} +} +}
\ No newline at end of file diff --git a/NvCloth/Tools/AuthoringLibrary/src/DebugVisualization.cpp b/NvCloth/Tools/AuthoringLibrary/src/DebugVisualization.cpp new file mode 100644 index 0000000..c7e4601 --- /dev/null +++ b/NvCloth/Tools/AuthoringLibrary/src/DebugVisualization.cpp @@ -0,0 +1,323 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2017 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 "NvClothAuthoringLibrary/DebugVisualization.h" +#include <foundation/PxMat44.h> +#include "NvCloth/Cloth.h" +#include "NvCloth/Fabric.h" +#include "NvCloth/Factory.h" +#include <assert.h> +#include <algorithm> + +namespace nv +{ +namespace cloth +{ +namespace debugVisualization +{ + +void VisualizeDistanceConstraints(Cloth* cloth_, AddLineCallback addLineCallback) +{ + nv::cloth::Cloth& cloth = *cloth_; + if(cloth.getNumMotionConstraints() == 0) + return; + + nv::cloth::Factory& factory = cloth.getFactory(); + + nv::cloth::MappedRange<physx::PxVec4> particles = cloth.getCurrentParticles(); + std::vector<physx::PxVec4> motionConstraints; + motionConstraints.reserve(cloth.getNumMotionConstraints() * 2); + motionConstraints.resize(cloth.getNumMotionConstraints()); + factory.extractMotionConstraints(cloth, nv::cloth::Range<physx::PxVec4>(&motionConstraints[0], &motionConstraints[0] + motionConstraints.size())); + motionConstraints.resize(cloth.getNumMotionConstraints() * 2); + + nv::cloth::MappedRange<physx::PxVec4> positions = cloth.getCurrentParticles(); + + assert(positions.size() == cloth.getNumMotionConstraints()); + + + //Set to 1 to color code lines based on distance constraint length (as % of max constraint distance in cloth) + //Set to 0 to color code lines based on how close the particle is to the distance constraint (as % of max distance per constraint) +#define SHOW_DISTANCE_COLOR 0 +#if SHOW_DISTANCE_COLOR + float maxDist = 0.0f; + for(int i = (int)(motionConstraints.size() >> 1) - 1; i >= 0; i--) + { + maxDist = max(maxDist, motionConstraints[i].w); + } +#endif + + for(int i = ((int)motionConstraints.size() >> 1) - 1; i >= 0; i--) + { + float l = motionConstraints[i].w; + physx::PxVec3 a = motionConstraints[i].getXYZ(); + physx::PxVec3 b = positions[i].getXYZ(); + physx::PxVec3 d = b - a; + float currentDist = d.magnitude(); + if(d.magnitudeSquared() < 0.00001f) + { + d = physx::PxVec3(0.0f, 0.0f, 1.0f); + } + else + { + d.normalize(); + } + +#if SHOW_DISTANCE_COLOR + physx::PxVec4 color(0.0f, 1.0f-std::max(0.0f, std::min(1.0f, (l / maxDist))), 0.0f, 1.0f); +#else + physx::PxVec4 color(0.0f, 1.0f-std::max(0.0f,std::min(1.0f, (currentDist / l))), 0.0f, 1.0f); +#endif + + addLineCallback(a, color, b, color); + } +} + +void VisualizeTethers(Cloth* cloth_, AddLineCallback addLineCallback) +{ + nv::cloth::Cloth& cloth = *cloth_; + nv::cloth::Fabric& fabric = cloth.getFabric(); + if(fabric.getNumTethers() == 0) + return; + + nv::cloth::Factory& factory = cloth.getFactory(); + nv::cloth::MappedRange<physx::PxVec4> particles = cloth.getCurrentParticles(); + + std::vector<float> tetherLengths; + tetherLengths.resize(fabric.getNumTethers()); + std::vector<uint32_t> anchors; + anchors.resize(fabric.getNumTethers()); + + factory.extractFabricData(fabric, nv::cloth::Range<uint32_t>(0, 0), nv::cloth::Range<uint32_t>(0, 0), nv::cloth::Range<float>(0, 0), nv::cloth::Range<float>(0, 0), nv::cloth::Range<uint32_t>(0, 0), + nv::cloth::Range<uint32_t>(&anchors[0], &anchors[0] + anchors.size()), nv::cloth::Range<float>(&tetherLengths[0], &tetherLengths[0] + tetherLengths.size()), nv::cloth::Range<uint32_t>(0, 0)); + + int particleCount = fabric.getNumParticles(); + + for(int i = 0; i < (int)anchors.size(); i++) + { + float lengthDiff = (particles[anchors[i]].getXYZ() - particles[i%particleCount].getXYZ()).magnitude() - tetherLengths[i]; + physx::PxVec4 color = lengthDiff > 0.0f ? physx::PxVec4(1.0f, 0.0, 0.0, 1.0f) : physx::PxVec4(1.0f, 0.0, 1.0, 1.0f); + addLineCallback(particles[anchors[i]].getXYZ(), color, particles[i%particleCount].getXYZ(), color); + } +} + +void VisualizeConstraints(Cloth* cloth_, AddLineCallback addLineCallback, int visiblePhaseRangeBegin, int visiblePhaseRangeEnd) +{ + nv::cloth::Cloth& cloth = *cloth_; + nv::cloth::Fabric& fabric = cloth.getFabric(); + if(fabric.getNumIndices() == 0) + return; + + nv::cloth::Factory& factory = cloth.getFactory(); + + nv::cloth::MappedRange<physx::PxVec4> particles = cloth.getCurrentParticles(); + + if(visiblePhaseRangeBegin >= visiblePhaseRangeEnd) + { + //then simply render all constraints in one go + std::vector<uint32_t> indices; + indices.resize(fabric.getNumIndices()); + + factory.extractFabricData(fabric, nv::cloth::Range<uint32_t>(0, 0), nv::cloth::Range<uint32_t>(0, 0), nv::cloth::Range<float>(0, 0), nv::cloth::Range<float>(0, 0), nv::cloth::Range<uint32_t>(&indices[0], &indices[0] + indices.size()), + nv::cloth::Range<uint32_t>(0, 0), nv::cloth::Range<float>(0, 0), nv::cloth::Range<uint32_t>(0, 0)); + + physx::PxVec4 color(0.098, 0.098, 0.6, 1.0f); + + for(int i = 1; i < (int)indices.size(); i += 2) + { + addLineCallback(particles[indices[i]].getXYZ(), color, particles[indices[i - 1]].getXYZ(), color); + } + } + else + { + //otherwise we render individual phases + std::vector<uint32_t> indices; + indices.resize(fabric.getNumIndices()); + std::vector<uint32_t> phases; + phases.resize(fabric.getNumPhases()); + std::vector<uint32_t> sets; + sets.resize(fabric.getNumSets()); + + factory.extractFabricData(fabric, nv::cloth::Range<uint32_t>(&phases[0], &phases[0] + phases.size()), nv::cloth::Range<uint32_t>(&sets[0], &sets[0] + sets.size()), nv::cloth::Range<float>(0, 0), nv::cloth::Range<float>(0, 0), nv::cloth::Range<uint32_t>(&indices[0], &indices[0] + indices.size()), + nv::cloth::Range<uint32_t>(0, 0), nv::cloth::Range<float>(0, 0), nv::cloth::Range<uint32_t>(0, 0)); + + uint32_t* iIt = &indices[0]; + for(int phaseIndex = 0; phaseIndex < (int)fabric.getNumPhases(); phaseIndex++) + { + uint32_t* sIt = &sets[phases[phaseIndex]]; + uint32_t* iEnd = &indices[0] + (sIt[0] * 2); + uint32_t* iStart = iIt; + + if(!(phaseIndex >= visiblePhaseRangeBegin && phaseIndex < visiblePhaseRangeEnd)) + { + iIt = iEnd; + continue; + } + + for(iIt; iIt < iEnd; iIt += 2) + { + float c = (float)(iIt - iStart) / (float)(iEnd - iStart); + + physx::PxVec4 colorTable[3] + { + physx::PxVec4(1.0f, 0.0f, 0.0f, 1.0f), + physx::PxVec4(0.0f, 1.0f, 0.0f, 1.0f), + physx::PxVec4(0.0f, 0.0f, 1.0f, 1.0f) + }; + + physx::PxVec4 shiftTable[3] + { + physx::PxVec4(0.0f, 1.0f, 0.0f, 0.0f), + physx::PxVec4(1.0f, 0.0f, 0.0f, 0.0f), + physx::PxVec4(0.0f, 0.0f, 1.0f, 0.0f) + }; + + physx::PxVec4 color = colorTable[phaseIndex % 3] + shiftTable[phaseIndex % 3] * c; + + addLineCallback(particles[*iIt].getXYZ(), color, particles[*(iIt + 1)].getXYZ(), color); + } + } + } +} + +void VisualizeConstraintStiffness(Cloth* cloth_, AddLineCallback addLineCallback) +{ + nv::cloth::Cloth& cloth = *cloth_; + nv::cloth::Fabric& fabric = cloth.getFabric(); + if(fabric.getNumIndices() == 0) + return; + + if(!fabric.getNumStiffnessValues()) + return; + + nv::cloth::Factory& factory = cloth.getFactory(); + + nv::cloth::MappedRange<physx::PxVec4> particles = cloth.getCurrentParticles(); + + std::vector<uint32_t> indices; + indices.resize(fabric.getNumIndices()); + std::vector<float> stiffness; + stiffness.resize(fabric.getNumRestvalues()); + + factory.extractFabricData(fabric, nv::cloth::Range<uint32_t>(0, 0), nv::cloth::Range<uint32_t>(0, 0), nv::cloth::Range<float>(0, 0), nv::cloth::Range<float>(&stiffness[0], &stiffness[0] + stiffness.size()), nv::cloth::Range<uint32_t>(&indices[0], &indices[0] + indices.size()), + nv::cloth::Range<uint32_t>(0, 0), nv::cloth::Range<float>(0, 0), nv::cloth::Range<uint32_t>(0, 0)); + + for(int i = 1; i < (int)indices.size(); i += 2) + { + float c = 1.0f - exp2f(stiffness[i >> 1]); + + physx::PxVec4 color(0.8f * (1.0f - c), c * 0.8f, 0.0f, 1.0f); + addLineCallback(particles[indices[i - 1]].getXYZ(), color, particles[indices[i]].getXYZ(), color); + } +} + +void VisualizeConstraintError(Cloth* cloth_, AddLineCallback addLineCallback) +{ + nv::cloth::Cloth& cloth = *cloth_; + nv::cloth::Fabric& fabric = cloth.getFabric(); + if(fabric.getNumRestvalues() == 0) { return; } + nv::cloth::Factory& factory = cloth.getFactory(); + + nv::cloth::MappedRange<physx::PxVec4> particles = cloth.getCurrentParticles(); + + std::vector<uint32_t> indices; + indices.resize(fabric.getNumIndices()); + std::vector<float> restLengths; + restLengths.resize(fabric.getNumRestvalues()); + + factory.extractFabricData(fabric, nv::cloth::Range<uint32_t>(0, 0), nv::cloth::Range<uint32_t>(0, 0), nv::cloth::Range<float>(&restLengths[0], &restLengths[0] + restLengths.size()), nv::cloth::Range<float>(0, 0), nv::cloth::Range<uint32_t>(&indices[0], &indices[0] + indices.size()), + nv::cloth::Range<uint32_t>(0, 0), nv::cloth::Range<float>(0, 0), nv::cloth::Range<uint32_t>(0, 0)); + + for(int i = 0; i < (int)indices.size(); i += 2) + { + physx::PxVec4 p0 = particles[indices[i]]; + physx::PxVec4 p1 = particles[indices[i + 1]]; + float restLength = restLengths[i >> 1]; + float length = (p0 - p1).magnitude(); + const float scale = 2.0f; + float error = (length / restLength * 0.5f - 0.5f) * scale + 0.5f; + error = std::max(0.0f, std::min(1.0f, error)); + physx::PxVec4 color(error * 0.8f, 1.0f - error*0.8f, 0.0f, 1.0f); + addLineCallback(p0.getXYZ(), color, p1.getXYZ(), color); + } +} + +void VisualizePositionDelta(Cloth* cloth_, AddLineCallback addLineCallback, float lengthScale) +{ + nv::cloth::Cloth& cloth = *cloth_; + + nv::cloth::MappedRange<physx::PxVec4> particles1 = cloth.getCurrentParticles(); + nv::cloth::MappedRange<physx::PxVec4> particles0 = cloth.getPreviousParticles(); + + //scale so that the solver frequency doesn't affect the position delta length assuming 60fps + float iterationsPerFrame = std::max(1, int(1.0f / 60.0f * cloth.getSolverFrequency() + 0.5f)); + + physx::PxVec4 color(0.0f, 1.0f, 1.0f, 1.0f); + + for(int i = 0; i < (int)particles1.size(); i++) + { + addLineCallback(particles1[i].getXYZ(), color, particles1[i].getXYZ() + (particles1[i] - particles0[i]).getXYZ()*iterationsPerFrame * lengthScale, color); + } +} + +void VisualizeBoundingBox(Cloth* cloth_, AddLineCallback addLineCallback) +{ + nv::cloth::Cloth& cloth = *cloth_; + + physx::PxVec3 c = cloth.getBoundingBoxCenter(); + physx::PxVec3 d = cloth.getBoundingBoxScale(); + physx::PxVec3 dx = physx::PxVec3(d.x, 0.0f, 0.0f); + physx::PxVec3 dy = physx::PxVec3(0.0f, d.y, 0.0f); + physx::PxVec3 dz = physx::PxVec3(0.0f, 0.0f, d.z); + + physx::PxVec4 color(1.0f, 1.0f, 0.0f, 1.0f); + + addLineCallback(c + dy + dz - dx, color, c + dy + dz + dx, color); + addLineCallback(c + dy - dz - dx, color, c + dy - dz + dx, color); + addLineCallback(c - dy + dz - dx, color, c - dy + dz + dx, color); + addLineCallback(c - dy - dz - dx, color, c - dy - dz + dx, color); + addLineCallback(c + dy + dx - dz, color, c + dy + dx + dz, color); + addLineCallback(c + dy - dx - dz, color, c + dy - dx + dz, color); + addLineCallback(c - dy + dx - dz, color, c - dy + dx + dz, color); + addLineCallback(c - dy - dx - dz, color, c - dy - dx + dz, color); + addLineCallback(c + dz + dx - dy, color, c + dz + dx + dy, color); + addLineCallback(c + dz - dx - dy, color, c + dz - dx + dy, color); + addLineCallback(c - dz + dx - dy, color, c - dz + dx + dy, color); + addLineCallback(c - dz - dx - dy, color, c - dz - dx + dy, color); + + color = physx::PxVec4(0.467f, 0.467f, 0.0f, 1.0f); + + addLineCallback(c + dy + dz + dx, color, c - dy - dz - dx, color); + addLineCallback(c + dy + dz - dx, color, c - dy - dz + dx, color); + addLineCallback(c - dy + dz + dx, color, c + dy - dz - dx, color); + addLineCallback(c - dy + dz - dx, color, c + dy - dz + dx, color); +} + +} +} +}
\ No newline at end of file diff --git a/NvCloth/Tools/AuthoringLibrary/src/Parameters.cpp b/NvCloth/Tools/AuthoringLibrary/src/Parameters.cpp new file mode 100644 index 0000000..69dbcdc --- /dev/null +++ b/NvCloth/Tools/AuthoringLibrary/src/Parameters.cpp @@ -0,0 +1,247 @@ +// This code contains NVIDIA Confidential Information and is disclosed to you +// under a form of NVIDIA software license agreement provided separately to you. +// +// Notice +// NVIDIA Corporation and its licensors retain all intellectual property and +// proprietary rights in and to this software and related documentation and +// any modifications thereto. Any use, reproduction, disclosure, or +// distribution of this software and related documentation without an express +// license agreement from NVIDIA Corporation is strictly prohibited. +// +// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES +// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO +// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, +// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. +// +// Information and code furnished is believed to be accurate and reliable. +// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such +// information or for any infringement of patents or other rights of third parties that may +// result from its use. No license is granted by implication or otherwise under any patent +// or patent rights of NVIDIA Corporation. Details are subject to change without notice. +// This code supersedes and replaces all information previously supplied. +// NVIDIA Corporation products are not authorized for use as critical +// components in life support devices or systems without express written approval of +// NVIDIA Corporation. +// +// Copyright (c) 2008-2017 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 "NvClothAuthoringLibrary/Parameters.h" + +namespace nv +{ +namespace cloth +{ +namespace authoring +{ + +Parameter InitParameter(ParameterType type, int catagoryId, const char* name, const char* description, void* set, void* get) +{ + Parameter p; + static int nextId = 0; + p.mCatagoryId = catagoryId; + p.mParameterId = nextId++; + p.mName = name; + p.mDescription = description; + p.mType = type; + p.SetFunctionPointer = set; + p.GetFunctionPointer = get; + p.mHardMinLimit = false; + p.mHardMaxLimit = false; + return p; +} + +Parameter InitParameter(int catagoryId, const char* name, const char* description, SetFloatParamType set, GetFloatParamType get, float minV, float maxV, bool hardMin = false, bool hardMax = false) +{ + Parameter p = InitParameter(ParameterType::FLOAT, catagoryId, name, description, set, get); + p.mMinFloat = minV; + p.mMaxFloat = maxV; + p.mHardMinLimit = hardMin; + p.mHardMaxLimit = hardMax; + return p; +} + +Parameter InitParameter(int catagoryId, const char* name, const char* description, SetVec3ParamType set, GetVec3ParamType get, physx::PxVec3 minV, physx::PxVec3 maxV, ParameterType parameterType = ParameterType::VEC3, bool hardMin = false, bool hardMax = false) +{ + Parameter p = InitParameter(parameterType, catagoryId, name, description, set, get); + p.mMinVec3 = minV; + p.mMaxVec3 = maxV; + p.mHardMaxLimit = hardMax; + p.mHardMinLimit = hardMin; + return p; +} + +static const char* sParameterCatagories[] = +{ + /* 0 */ "Basics", + /* 1 */ "Air simulation", + /* 2 */ "Local space simulation", + /* 3 */ "Tethers", + /* 4 */ "Collision", + /* 5 */ "Misc", + /* 6 */ "Airmeshes" + /* 7 */ + /* 8 */ +}; + +static Parameter sParameterList[] = +{ + InitParameter(0, "Damping", "", + [](Cloth* cloth, physx::PxVec3 value) {cloth->setDamping(value); }, + [](Cloth* cloth) {return cloth->getDamping(); }, + physx::PxVec3(0.0f), physx::PxVec3(1.0f), + ParameterType::VEC3_SLIDER1MAX, true, true + ), + InitParameter(0, "Gravity", "", + [](Cloth* cloth, physx::PxVec3 value) {cloth->setGravity(value); }, + [](Cloth* cloth) {return cloth->getGravity(); }, + physx::PxVec3(-50.0f,-50.0f,-50.0f), physx::PxVec3(50.0f,50.0f,50.0f) + ), + InitParameter(0, "Solver frequency", "Number of solver iterations per second", + [](Cloth* cloth, float value) {cloth->setSolverFrequency(value); }, + [](Cloth* cloth) {return cloth->getSolverFrequency(); }, + 0.0f, 600.0f, true, false + ), + + InitParameter(1, "Drag coefficient", "For the advanced wind model (non zero enables this feature which is expensive)", + [](Cloth* cloth, float value) {cloth->setDragCoefficient(value); }, + [](Cloth* cloth) {return cloth->getDragCoefficient(); }, + 0.0f, 1.0f, true, true + ), + InitParameter(1, "Lift coefficient", "For the advanced wind model (non zero enables this feature which is expensive)", + [](Cloth* cloth, float value) {cloth->setLiftCoefficient(value); }, + [](Cloth* cloth) {return cloth->getLiftCoefficient(); }, + 0.0f, 1.0f, true, true + ), + InitParameter(1, "Fluid density", "For the advanced wind model, can be used to", + [](Cloth* cloth, float value) {cloth->setLiftCoefficient(value); }, + [](Cloth* cloth) {return cloth->getLiftCoefficient(); }, + 0.0f, 10.0f, true, false + ), + + InitParameter(2, "Linear inertia", "Amount of linear force from moving the local space to be applied", + [](Cloth* cloth, physx::PxVec3 value) {cloth->setLinearInertia(value); }, + [](Cloth* cloth) {return cloth->getLinearInertia(); }, + physx::PxVec3(0.0f), physx::PxVec3(1.0f), + ParameterType::VEC3_SLIDER1MAX + ), + InitParameter(2, "Angular inertia", "Amount of angular force from moving the local space to be applied", + [](Cloth* cloth, physx::PxVec3 value) {cloth->setAngularInertia(value); }, + [](Cloth* cloth) {return cloth->getAngularInertia(); }, + physx::PxVec3(0.0f), physx::PxVec3(1.0f), + ParameterType::VEC3_SLIDER1MAX + ), + InitParameter(2, "Centrifugal inertia", "Amount of centrifugal force from moving the local space to be applied", + [](Cloth* cloth, physx::PxVec3 value) {cloth->setCentrifugalInertia(value); }, + [](Cloth* cloth) {return cloth->getCentrifugalInertia(); }, + physx::PxVec3(0.0f), physx::PxVec3(1.0f), + ParameterType::VEC3_SLIDER1MAX + ), + InitParameter(2, "Linear drag", "Amount of drag form moving the local space to be applied", + [](Cloth* cloth, physx::PxVec3 value) {cloth->setLinearDrag(value); }, + [](Cloth* cloth) {return cloth->getLinearDrag(); }, + physx::PxVec3(0.0f), physx::PxVec3(1.0f), + ParameterType::VEC3_SLIDER1MAX, true, true + ), + InitParameter(2, "Angular drag", "Amount of drag form moving the local space to be applied", + [](Cloth* cloth, physx::PxVec3 value) {cloth->setAngularDrag(value); }, + [](Cloth* cloth) {return cloth->getAngularDrag(); }, + physx::PxVec3(0.0f), physx::PxVec3(1.0f), + ParameterType::VEC3_SLIDER1MAX, true, true + ), + + InitParameter(3, "Scale", "Scale factor for tether length", + [](Cloth* cloth, float value) {cloth->setTetherConstraintScale(value); }, + [](Cloth* cloth) {return cloth->getTetherConstraintScale(); }, + 0.0f, 4.0f, true, false + ), + InitParameter(3, "Stiffness", "", + [](Cloth* cloth, float value) {cloth->setTetherConstraintStiffness(value); }, + [](Cloth* cloth) {return cloth->getTetherConstraintStiffness(); }, + 0.0f, 1.0f, true, true + ), + + InitParameter(4, "Friction", "Friction on collision contacts with collision shapes", + [](Cloth* cloth, float value) {cloth->setFriction(value); }, + [](Cloth* cloth) {return cloth->getFriction(); }, + 0.0f, 2.0f + ), + + InitParameter(4, "Motion constraint scale", "Scale factor for the length of the motion/distance constraints", + [](Cloth* cloth, float value) {cloth->setMotionConstraintScaleBias(value,cloth->getMotionConstraintBias()); }, + [](Cloth* cloth) {return cloth->getMotionConstraintScale(); }, + 0.0f, 4.0f, true, false + ), + InitParameter(4, "Motion constraint bias", "Additional length for the length of the motion/distance constraints", + [](Cloth* cloth, float value) {cloth->setMotionConstraintScaleBias(cloth->getMotionConstraintScale(), value); }, + [](Cloth* cloth) {return cloth->getMotionConstraintBias(); }, + 0.0f, 8.0f, false, false + ), + InitParameter(4, "Motion constraint stiffness", "How hard the constraint is enforced", + [](Cloth* cloth, float value) {cloth->setMotionConstraintStiffness(value); }, + [](Cloth* cloth) {return cloth->getMotionConstraintStiffness(); }, + 0.0f, 1.0f, true, true + ), + + InitParameter(4, "Self collision radius", "Min distance between two particles within this cloth (expensive when set > 0)", + [](Cloth* cloth, float value) {cloth->setSelfCollisionDistance(value); }, + [](Cloth* cloth) {return cloth->getSelfCollisionDistance(); }, + 0.0f, 1.0f, true, false + ), + InitParameter(4, "Self collision stiffness", "How hard the constraint is enforced", + [](Cloth* cloth, float value) {cloth->setSelfCollisionStiffness(value); }, + [](Cloth* cloth) {return cloth->getSelfCollisionStiffness(); }, + 0.0f, 1.0f, true, true + ), + + InitParameter(5, "Sleep threshold", "Maximum movement allowed for cloth to go to sleep", + [](Cloth* cloth, float value) {cloth->setSleepThreshold(value); }, + [](Cloth* cloth) {return cloth->getSleepThreshold(); }, + 0.0f, 1.0f + ), + InitParameter(5, "Stiffness frequency", "", + [](Cloth* cloth, float value) {cloth->setStiffnessFrequency(value); }, + [](Cloth* cloth) {return cloth->getStiffnessFrequency(); }, + 0.0f, 100.0f, true, false + ), + +/* + InitParameter(6, "Rest volume scale", "", + [](Cloth* cloth, float value) {cloth->setRestVolumesScale(value); }, + [](Cloth* cloth) {return cloth->getRestVolumesScale(); }, + 0.0f, 10.0f + ), + InitParameter(6, "Compression stiffness", "", + [](Cloth* cloth, float value) {cloth->setCompressionStiffness(value); }, + [](Cloth* cloth) {return cloth->getCompressionStiffness(); }, + 0.0f, 1.0f + ), + InitParameter(6, "Expansion stiffness", "", + [](Cloth* cloth, float value) {cloth->setExpansionStiffness(value); }, + [](Cloth* cloth) {return cloth->getExpansionStiffness(); }, + 0.0f, 1.0f + ), +*/ +}; + +int GetClothNumParameters() +{ + return (sizeof(sParameterList) / sizeof(Parameter)); +} +Parameter const& GetClothParameterInfo(int id) +{ + return sParameterList[id]; +} + +int GetClothNumParameterCatagories() +{ + return (sizeof(sParameterCatagories) / sizeof(const char*)); +} +const char* GetClothParameterCatagorieInfo(int id) +{ + return sParameterCatagories[id]; +} + +} +} +}
\ No newline at end of file |