mirror of
https://github.com/copyrighttxt/watrbx-game-engine.git
synced 2026-09-05 13:17:49 +00:00
GEEKING
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/src
|
||||
${AMD_OPENCL_INCLUDES}
|
||||
)
|
||||
|
||||
ADD_DEFINITIONS(-DUSE_AMD_OPENCL)
|
||||
ADD_DEFINITIONS(-DCL_PLATFORM_AMD)
|
||||
|
||||
|
||||
|
||||
SET(BulletSoftBodyOpenCLSolvers_SRCS
|
||||
../btSoftBodySolver_OpenCL.cpp
|
||||
../btSoftBodySolver_OpenCLSIMDAware.cpp
|
||||
../btSoftBodySolverOutputCLtoGL.cpp
|
||||
)
|
||||
|
||||
SET(BulletSoftBodyOpenCLSolvers_HDRS
|
||||
../btSoftBodySolver_OpenCL.h
|
||||
../btSoftBodySolver_OpenCLSIMDAware.h
|
||||
../../Shared/btSoftBodySolverData.h
|
||||
../btSoftBodySolverVertexData_OpenCL.h
|
||||
../btSoftBodySolverTriangleData_OpenCL.h
|
||||
../btSoftBodySolverLinkData_OpenCL.h
|
||||
../btSoftBodySolverLinkData_OpenCLSIMDAware.h
|
||||
../btSoftBodySolverBuffer_OpenCL.h
|
||||
../btSoftBodySolverVertexBuffer_OpenGL.h
|
||||
../btSoftBodySolverOutputCLtoGL.h
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
ADD_LIBRARY(BulletSoftBodySolvers_OpenCL_AMD
|
||||
${BulletSoftBodyOpenCLSolvers_SRCS}
|
||||
${BulletSoftBodyOpenCLSolvers_HDRS}
|
||||
)
|
||||
|
||||
SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_AMD PROPERTIES VERSION ${BULLET_VERSION})
|
||||
SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_AMD PROPERTIES SOVERSION ${BULLET_VERSION})
|
||||
IF (BUILD_SHARED_LIBS)
|
||||
TARGET_LINK_LIBRARIES(BulletSoftBodySolvers_OpenCL_AMD BulletSoftBody)
|
||||
ENDIF (BUILD_SHARED_LIBS)
|
||||
|
||||
|
||||
IF (INSTALL_LIBS)
|
||||
IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES)
|
||||
IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5)
|
||||
IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
INSTALL(TARGETS BulletSoftBodySolvers_OpenCL_AMD DESTINATION .)
|
||||
ELSE (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
INSTALL(TARGETS BulletSoftBodySolvers_OpenCL_AMD
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION lib${LIB_SUFFIX}
|
||||
ARCHIVE DESTINATION lib${LIB_SUFFIX})
|
||||
#headers are already installed by BulletMultiThreaded library
|
||||
ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5)
|
||||
|
||||
IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_AMD PROPERTIES FRAMEWORK true)
|
||||
SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_AMD PROPERTIES PUBLIC_HEADER "${BulletSoftBodyOpenCLSolvers_HDRS}")
|
||||
ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES)
|
||||
ENDIF (INSTALL_LIBS)
|
||||
@@ -0,0 +1,27 @@
|
||||
|
||||
hasCL = findOpenCL_AMD()
|
||||
|
||||
if (hasCL) then
|
||||
|
||||
project "BulletSoftBodySolvers_OpenCL_AMD"
|
||||
|
||||
defines { "USE_AMD_OPENCL","CL_PLATFORM_AMD"}
|
||||
|
||||
initOpenCL_AMD()
|
||||
|
||||
kind "StaticLib"
|
||||
|
||||
targetdir "../../../../../lib"
|
||||
|
||||
includedirs {
|
||||
".",
|
||||
"../../../..",
|
||||
"../../../../../Glut"
|
||||
}
|
||||
files {
|
||||
"../btSoftBodySolver_OpenCL.cpp",
|
||||
"../btSoftBodySolver_OpenCLSIMDAware.cpp",
|
||||
"../btSoftBodySolverOutputCLtoGL.cpp"
|
||||
}
|
||||
|
||||
end
|
||||
@@ -0,0 +1,80 @@
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/src
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
SET(BulletSoftBodyOpenCLSolvers_SRCS
|
||||
../btSoftBodySolver_OpenCL.cpp
|
||||
../btSoftBodySolver_OpenCLSIMDAware.cpp
|
||||
)
|
||||
|
||||
SET(BulletSoftBodyOpenCLSolvers_HDRS
|
||||
../btSoftBodySolver_OpenCL.h
|
||||
../../Shared/btSoftBodySolverData.h
|
||||
../btSoftBodySolverVertexData_OpenCL.h
|
||||
../btSoftBodySolverTriangleData_OpenCL.h
|
||||
../btSoftBodySolverLinkData_OpenCL.h
|
||||
../btSoftBodySolverBuffer_OpenCL.h
|
||||
)
|
||||
|
||||
# OpenCL and HLSL Shaders.
|
||||
# Build rules generated to stringify these into headers
|
||||
# which are needed by some of the sources
|
||||
SET(BulletSoftBodyOpenCLSolvers_Shaders
|
||||
# OutputToVertexArray
|
||||
UpdateNormals
|
||||
Integrate
|
||||
UpdatePositions
|
||||
UpdateNodes
|
||||
SolvePositions
|
||||
UpdatePositionsFromVelocities
|
||||
ApplyForces
|
||||
PrepareLinks
|
||||
VSolveLinks
|
||||
)
|
||||
|
||||
foreach(f ${BulletSoftBodyOpenCLSolvers_Shaders})
|
||||
LIST(APPEND BulletSoftBodyOpenCLSolvers_OpenCLC "../OpenCLC10/${f}.cl")
|
||||
endforeach(f)
|
||||
|
||||
|
||||
|
||||
ADD_LIBRARY(BulletSoftBodySolvers_OpenCL_Apple
|
||||
${BulletSoftBodyOpenCLSolvers_SRCS}
|
||||
${BulletSoftBodyOpenCLSolvers_HDRS}
|
||||
${BulletSoftBodyOpenCLSolvers_OpenCLC}
|
||||
)
|
||||
|
||||
SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_Apple PROPERTIES VERSION ${BULLET_VERSION})
|
||||
SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_Apple PROPERTIES SOVERSION ${BULLET_VERSION})
|
||||
IF (BUILD_SHARED_LIBS)
|
||||
IF (APPLE AND (BUILD_SHARED_LIBS OR FRAMEWORK) )
|
||||
SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_Apple PROPERTIES LINK_FLAGS "-framework OpenCL")
|
||||
ENDIF (APPLE AND (BUILD_SHARED_LIBS OR FRAMEWORK) )
|
||||
TARGET_LINK_LIBRARIES(BulletSoftBodySolvers_OpenCL_Apple BulletSoftBody)
|
||||
ENDIF (BUILD_SHARED_LIBS)
|
||||
|
||||
|
||||
IF (INSTALL_LIBS)
|
||||
IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES)
|
||||
IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5)
|
||||
IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
INSTALL(TARGETS BulletSoftBodySolvers_OpenCL_Apple DESTINATION .)
|
||||
ELSE (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
INSTALL(TARGETS BulletSoftBodySolvers_OpenCL_Apple
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION lib${LIB_SUFFIX}
|
||||
ARCHIVE DESTINATION lib${LIB_SUFFIX})
|
||||
#headers are already installed by BulletMultiThreaded library
|
||||
ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5)
|
||||
|
||||
IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_Apple PROPERTIES FRAMEWORK true)
|
||||
SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_Apple PROPERTIES PUBLIC_HEADER "${BulletSoftBodyOpenCLSolvers_HDRS}")
|
||||
ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES)
|
||||
ENDIF (INSTALL_LIBS)
|
||||
@@ -0,0 +1,17 @@
|
||||
SUBDIRS( MiniCL )
|
||||
|
||||
IF(BUILD_INTEL_OPENCL_DEMOS)
|
||||
SUBDIRS(Intel)
|
||||
ENDIF()
|
||||
|
||||
IF(BUILD_AMD_OPENCL_DEMOS)
|
||||
SUBDIRS(AMD)
|
||||
ENDIF()
|
||||
|
||||
IF(BUILD_NVIDIA_OPENCL_DEMOS)
|
||||
SUBDIRS(NVidia)
|
||||
ENDIF()
|
||||
|
||||
IF(APPLE AND OPENCL_LIBRARY)
|
||||
SUBDIRS(Apple)
|
||||
ENDIF()
|
||||
@@ -0,0 +1,85 @@
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/src
|
||||
${INTEL_OPENCL_INCLUDES}
|
||||
)
|
||||
|
||||
ADD_DEFINITIONS(-DUSE_INTEL_OPENCL)
|
||||
ADD_DEFINITIONS(-DCL_PLATFORM_INTEL)
|
||||
|
||||
|
||||
|
||||
SET(BulletSoftBodyOpenCLSolvers_SRCS
|
||||
../btSoftBodySolver_OpenCL.cpp
|
||||
../btSoftBodySolver_OpenCLSIMDAware.cpp
|
||||
../btSoftBodySolverOutputCLtoGL.cpp
|
||||
)
|
||||
|
||||
SET(BulletSoftBodyOpenCLSolvers_HDRS
|
||||
../btSoftBodySolver_OpenCL.h
|
||||
../btSoftBodySolver_OpenCLSIMDAware.h
|
||||
../../Shared/btSoftBodySolverData.h
|
||||
../btSoftBodySolverVertexData_OpenCL.h
|
||||
../btSoftBodySolverTriangleData_OpenCL.h
|
||||
../btSoftBodySolverLinkData_OpenCL.h
|
||||
../btSoftBodySolverLinkData_OpenCLSIMDAware.h
|
||||
../btSoftBodySolverBuffer_OpenCL.h
|
||||
../btSoftBodySolverVertexBuffer_OpenGL.h
|
||||
../btSoftBodySolverOutputCLtoGL.h
|
||||
)
|
||||
|
||||
# OpenCL and HLSL Shaders.
|
||||
# Build rules generated to stringify these into headers
|
||||
# which are needed by some of the sources
|
||||
SET(BulletSoftBodyOpenCLSolvers_Shaders
|
||||
# OutputToVertexArray
|
||||
UpdateNormals
|
||||
Integrate
|
||||
UpdatePositions
|
||||
UpdateNodes
|
||||
SolvePositions
|
||||
UpdatePositionsFromVelocities
|
||||
ApplyForces
|
||||
PrepareLinks
|
||||
VSolveLinks
|
||||
)
|
||||
|
||||
foreach(f ${BulletSoftBodyOpenCLSolvers_Shaders})
|
||||
LIST(APPEND BulletSoftBodyOpenCLSolvers_OpenCLC "../OpenCLC10/${f}.cl")
|
||||
endforeach(f)
|
||||
|
||||
|
||||
|
||||
ADD_LIBRARY(BulletSoftBodySolvers_OpenCL_Intel
|
||||
${BulletSoftBodyOpenCLSolvers_SRCS}
|
||||
${BulletSoftBodyOpenCLSolvers_HDRS}
|
||||
${BulletSoftBodyOpenCLSolvers_OpenCLC}
|
||||
)
|
||||
|
||||
SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_Intel PROPERTIES VERSION ${BULLET_VERSION})
|
||||
SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_Intel PROPERTIES SOVERSION ${BULLET_VERSION})
|
||||
IF (BUILD_SHARED_LIBS)
|
||||
TARGET_LINK_LIBRARIES(BulletSoftBodySolvers_OpenCL_Intel BulletSoftBody)
|
||||
ENDIF (BUILD_SHARED_LIBS)
|
||||
|
||||
|
||||
IF (INSTALL_LIBS)
|
||||
IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES)
|
||||
IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5)
|
||||
IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
INSTALL(TARGETS BulletSoftBodySolvers_OpenCL_Intel DESTINATION .)
|
||||
ELSE (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
INSTALL(TARGETS BulletSoftBodySolvers_OpenCL_Intel
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION lib${LIB_SUFFIX}
|
||||
ARCHIVE DESTINATION lib${LIB_SUFFIX})
|
||||
#headers are already installed by BulletMultiThreaded library
|
||||
ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5)
|
||||
|
||||
IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_Intel PROPERTIES FRAMEWORK true)
|
||||
SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_Intel PROPERTIES PUBLIC_HEADER "${BulletSoftBodyOpenCLSolvers_HDRS}")
|
||||
ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES)
|
||||
ENDIF (INSTALL_LIBS)
|
||||
@@ -0,0 +1,27 @@
|
||||
|
||||
hasCL = findOpenCL_Intel()
|
||||
|
||||
if (hasCL) then
|
||||
|
||||
project "BulletSoftBodySolvers_OpenCL_Intel"
|
||||
|
||||
defines { "USE_INTEL_OPENCL","CL_PLATFORM_INTEL"}
|
||||
|
||||
initOpenCL_Intel()
|
||||
|
||||
kind "StaticLib"
|
||||
|
||||
targetdir "../../../../../lib"
|
||||
|
||||
includedirs {
|
||||
".",
|
||||
"../../../..",
|
||||
"../../../../../Glut"
|
||||
}
|
||||
files {
|
||||
"../btSoftBodySolver_OpenCL.cpp",
|
||||
"../btSoftBodySolver_OpenCLSIMDAware.cpp",
|
||||
"../btSoftBodySolverOutputCLtoGL.cpp"
|
||||
}
|
||||
|
||||
end
|
||||
@@ -0,0 +1,78 @@
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/src
|
||||
)
|
||||
|
||||
ADD_DEFINITIONS(-DUSE_MINICL)
|
||||
|
||||
|
||||
|
||||
|
||||
SET(BulletSoftBodyOpenCLSolvers_SRCS
|
||||
../btSoftBodySolver_OpenCL.cpp
|
||||
)
|
||||
|
||||
SET(BulletSoftBodyOpenCLSolvers_HDRS
|
||||
../btSoftBodySolver_OpenCL.h
|
||||
../../Shared/btSoftBodySolverData.h
|
||||
../btSoftBodySolverVertexData_OpenCL.h
|
||||
../btSoftBodySolverTriangleData_OpenCL.h
|
||||
../btSoftBodySolverLinkData_OpenCL.h
|
||||
../btSoftBodySolverBuffer_OpenCL.h
|
||||
)
|
||||
|
||||
# OpenCL and HLSL Shaders.
|
||||
# Build rules generated to stringify these into headers
|
||||
# which are needed by some of the sources
|
||||
SET(BulletSoftBodyOpenCLSolvers_Shaders
|
||||
# OutputToVertexArray
|
||||
UpdateNormals
|
||||
Integrate
|
||||
UpdatePositions
|
||||
UpdateNodes
|
||||
SolvePositions
|
||||
UpdatePositionsFromVelocities
|
||||
ApplyForces
|
||||
PrepareLinks
|
||||
VSolveLinks
|
||||
)
|
||||
|
||||
foreach(f ${BulletSoftBodyOpenCLSolvers_Shaders})
|
||||
LIST(APPEND BulletSoftBodyOpenCLSolvers_OpenCLC "../OpenCLC10/${f}.cl")
|
||||
endforeach(f)
|
||||
|
||||
|
||||
|
||||
ADD_LIBRARY(BulletSoftBodySolvers_OpenCL_Mini
|
||||
${BulletSoftBodyOpenCLSolvers_SRCS}
|
||||
${BulletSoftBodyOpenCLSolvers_HDRS}
|
||||
${BulletSoftBodyOpenCLSolvers_OpenCLC}
|
||||
)
|
||||
|
||||
SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_Mini PROPERTIES VERSION ${BULLET_VERSION})
|
||||
SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_Mini PROPERTIES SOVERSION ${BULLET_VERSION})
|
||||
IF (BUILD_SHARED_LIBS)
|
||||
TARGET_LINK_LIBRARIES(BulletSoftBodySolvers_OpenCL_Mini MiniCL BulletMultiThreaded BulletSoftBody)
|
||||
ENDIF (BUILD_SHARED_LIBS)
|
||||
|
||||
|
||||
IF (INSTALL_LIBS)
|
||||
IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES)
|
||||
IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5)
|
||||
IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
INSTALL(TARGETS BulletSoftBodySolvers_OpenCL_Mini DESTINATION .)
|
||||
ELSE (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
INSTALL(TARGETS BulletSoftBodySolvers_OpenCL_Mini
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION lib${LIB_SUFFIX}
|
||||
ARCHIVE DESTINATION lib${LIB_SUFFIX})
|
||||
#headers are already installed by BulletMultiThreaded library
|
||||
ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5)
|
||||
|
||||
IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_Mini PROPERTIES FRAMEWORK true)
|
||||
SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_Mini PROPERTIES PUBLIC_HEADER "${BulletSoftBodyOpenCLSolvers_HDRS}")
|
||||
ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES)
|
||||
ENDIF (INSTALL_LIBS)
|
||||
+249
@@ -0,0 +1,249 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include <MiniCL/cl_MiniCL_Defs.h>
|
||||
|
||||
#define MSTRINGIFY(A) A
|
||||
#include "../OpenCLC10/ApplyForces.cl"
|
||||
#include "../OpenCLC10/Integrate.cl"
|
||||
#include "../OpenCLC10/PrepareLinks.cl"
|
||||
#include "../OpenCLC10/SolvePositions.cl"
|
||||
#include "../OpenCLC10/UpdateNodes.cl"
|
||||
#include "../OpenCLC10/UpdateNormals.cl"
|
||||
#include "../OpenCLC10/UpdatePositions.cl"
|
||||
#include "../OpenCLC10/UpdatePositionsFromVelocities.cl"
|
||||
#include "../OpenCLC10/VSolveLinks.cl"
|
||||
#include "../OpenCLC10/UpdateFixedVertexPositions.cl"
|
||||
//#include "../OpenCLC10/SolveCollisionsAndUpdateVelocities.cl"
|
||||
|
||||
|
||||
MINICL_REGISTER(PrepareLinksKernel)
|
||||
MINICL_REGISTER(VSolveLinksKernel)
|
||||
MINICL_REGISTER(UpdatePositionsFromVelocitiesKernel)
|
||||
MINICL_REGISTER(SolvePositionsFromLinksKernel)
|
||||
MINICL_REGISTER(updateVelocitiesFromPositionsWithVelocitiesKernel)
|
||||
MINICL_REGISTER(updateVelocitiesFromPositionsWithoutVelocitiesKernel)
|
||||
MINICL_REGISTER(IntegrateKernel)
|
||||
MINICL_REGISTER(ApplyForcesKernel)
|
||||
MINICL_REGISTER(ResetNormalsAndAreasKernel)
|
||||
MINICL_REGISTER(NormalizeNormalsAndAreasKernel)
|
||||
MINICL_REGISTER(UpdateSoftBodiesKernel)
|
||||
MINICL_REGISTER(UpdateFixedVertexPositions)
|
||||
|
||||
float mydot3a(float4 a, float4 b)
|
||||
{
|
||||
return a.x*b.x + a.y*b.y + a.z*b.z;
|
||||
}
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int firstObject;
|
||||
int endObject;
|
||||
} CollisionObjectIndices;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float4 shapeTransform[4]; // column major 4x4 matrix
|
||||
float4 linearVelocity;
|
||||
float4 angularVelocity;
|
||||
|
||||
int softBodyIdentifier;
|
||||
int collisionShapeType;
|
||||
|
||||
|
||||
// Shape information
|
||||
// Compressed from the union
|
||||
float radius;
|
||||
float halfHeight;
|
||||
int upAxis;
|
||||
|
||||
float margin;
|
||||
float friction;
|
||||
|
||||
int padding0;
|
||||
|
||||
} CollisionShapeDescription;
|
||||
|
||||
// From btBroadphaseProxy.h
|
||||
__constant int CAPSULE_SHAPE_PROXYTYPE = 10;
|
||||
|
||||
// Multiply column-major matrix against vector
|
||||
float4 matrixVectorMul( float4 matrix[4], float4 vector )
|
||||
{
|
||||
float4 returnVector;
|
||||
float4 row0 = float4(matrix[0].x, matrix[1].x, matrix[2].x, matrix[3].x);
|
||||
float4 row1 = float4(matrix[0].y, matrix[1].y, matrix[2].y, matrix[3].y);
|
||||
float4 row2 = float4(matrix[0].z, matrix[1].z, matrix[2].z, matrix[3].z);
|
||||
float4 row3 = float4(matrix[0].w, matrix[1].w, matrix[2].w, matrix[3].w);
|
||||
returnVector.x = dot(row0, vector);
|
||||
returnVector.y = dot(row1, vector);
|
||||
returnVector.z = dot(row2, vector);
|
||||
returnVector.w = dot(row3, vector);
|
||||
return returnVector;
|
||||
}
|
||||
|
||||
__kernel void
|
||||
SolveCollisionsAndUpdateVelocitiesKernel(
|
||||
const int numNodes,
|
||||
const float isolverdt,
|
||||
__global int *g_vertexClothIdentifier,
|
||||
__global float4 *g_vertexPreviousPositions,
|
||||
__global float * g_perClothFriction,
|
||||
__global float * g_clothDampingFactor,
|
||||
__global CollisionObjectIndices * g_perClothCollisionObjectIndices,
|
||||
__global CollisionShapeDescription * g_collisionObjectDetails,
|
||||
__global float4 * g_vertexForces,
|
||||
__global float4 *g_vertexVelocities,
|
||||
__global float4 *g_vertexPositions GUID_ARG)
|
||||
{
|
||||
int nodeID = get_global_id(0);
|
||||
float4 forceOnVertex = (float4)(0.f, 0.f, 0.f, 0.f);
|
||||
|
||||
if( get_global_id(0) < numNodes )
|
||||
{
|
||||
int clothIdentifier = g_vertexClothIdentifier[nodeID];
|
||||
|
||||
// Abort if this is not a valid cloth
|
||||
if( clothIdentifier < 0 )
|
||||
return;
|
||||
|
||||
|
||||
float4 position (g_vertexPositions[nodeID].xyz, 1.f);
|
||||
float4 previousPosition (g_vertexPreviousPositions[nodeID].xyz, 1.f);
|
||||
|
||||
float clothFriction = g_perClothFriction[clothIdentifier];
|
||||
float dampingFactor = g_clothDampingFactor[clothIdentifier];
|
||||
float velocityCoefficient = (1.f - dampingFactor);
|
||||
float4 difference = position - previousPosition;
|
||||
float4 velocity = difference*velocityCoefficient*isolverdt;
|
||||
|
||||
CollisionObjectIndices collisionObjectIndices = g_perClothCollisionObjectIndices[clothIdentifier];
|
||||
|
||||
int numObjects = collisionObjectIndices.endObject - collisionObjectIndices.firstObject;
|
||||
|
||||
if( numObjects > 0 )
|
||||
{
|
||||
// We have some possible collisions to deal with
|
||||
for( int collision = collisionObjectIndices.firstObject; collision < collisionObjectIndices.endObject; ++collision )
|
||||
{
|
||||
CollisionShapeDescription shapeDescription = g_collisionObjectDetails[collision];
|
||||
float colliderFriction = shapeDescription.friction;
|
||||
|
||||
if( shapeDescription.collisionShapeType == CAPSULE_SHAPE_PROXYTYPE )
|
||||
{
|
||||
// Colliding with a capsule
|
||||
|
||||
float capsuleHalfHeight = shapeDescription.halfHeight;
|
||||
float capsuleRadius = shapeDescription.radius;
|
||||
float capsuleMargin = shapeDescription.margin;
|
||||
int capsuleupAxis = shapeDescription.upAxis;
|
||||
|
||||
// Four columns of worldTransform matrix
|
||||
float4 worldTransform[4];
|
||||
worldTransform[0] = shapeDescription.shapeTransform[0];
|
||||
worldTransform[1] = shapeDescription.shapeTransform[1];
|
||||
worldTransform[2] = shapeDescription.shapeTransform[2];
|
||||
worldTransform[3] = shapeDescription.shapeTransform[3];
|
||||
|
||||
// Correctly define capsule centerline vector
|
||||
float4 c1 (0.f, 0.f, 0.f, 1.f);
|
||||
float4 c2 (0.f, 0.f, 0.f, 1.f);
|
||||
c1.x = select( 0.f, -capsuleHalfHeight, capsuleupAxis == 0 );
|
||||
c1.y = select( 0.f, -capsuleHalfHeight, capsuleupAxis == 1 );
|
||||
c1.z = select( 0.f, -capsuleHalfHeight, capsuleupAxis == 2 );
|
||||
c2.x = -c1.x;
|
||||
c2.y = -c1.y;
|
||||
c2.z = -c1.z;
|
||||
|
||||
|
||||
float4 worldC1 = matrixVectorMul(worldTransform, c1);
|
||||
float4 worldC2 = matrixVectorMul(worldTransform, c2);
|
||||
float4 segment = (worldC2 - worldC1);
|
||||
|
||||
// compute distance of tangent to vertex along line segment in capsule
|
||||
float distanceAlongSegment = -( mydot3a( (worldC1 - position), segment ) / mydot3a(segment, segment) );
|
||||
|
||||
float4 closestPoint = (worldC1 + (segment * distanceAlongSegment));
|
||||
float distanceFromLine = length(position - closestPoint);
|
||||
float distanceFromC1 = length(worldC1 - position);
|
||||
float distanceFromC2 = length(worldC2 - position);
|
||||
|
||||
// Final distance from collision, point to push from, direction to push in
|
||||
// for impulse force
|
||||
float dist;
|
||||
float4 normalVector;
|
||||
if( distanceAlongSegment < 0 )
|
||||
{
|
||||
dist = distanceFromC1;
|
||||
normalVector = float4(normalize(position - worldC1).xyz, 0.f);
|
||||
} else if( distanceAlongSegment > 1.f ) {
|
||||
dist = distanceFromC2;
|
||||
normalVector = float4(normalize(position - worldC2).xyz, 0.f);
|
||||
} else {
|
||||
dist = distanceFromLine;
|
||||
normalVector = float4(normalize(position - closestPoint).xyz, 0.f);
|
||||
}
|
||||
|
||||
float4 colliderLinearVelocity = shapeDescription.linearVelocity;
|
||||
float4 colliderAngularVelocity = shapeDescription.angularVelocity;
|
||||
float4 velocityOfSurfacePoint = colliderLinearVelocity + cross(colliderAngularVelocity, position - float4(worldTransform[0].w, worldTransform[1].w, worldTransform[2].w, 0.f));
|
||||
|
||||
float minDistance = capsuleRadius + capsuleMargin;
|
||||
|
||||
// In case of no collision, this is the value of velocity
|
||||
velocity = (position - previousPosition) * velocityCoefficient * isolverdt;
|
||||
|
||||
|
||||
// Check for a collision
|
||||
if( dist < minDistance )
|
||||
{
|
||||
// Project back to surface along normal
|
||||
position = position + float4(normalVector*(minDistance - dist)*0.9f);
|
||||
velocity = (position - previousPosition) * velocityCoefficient * isolverdt;
|
||||
float4 relativeVelocity = velocity - velocityOfSurfacePoint;
|
||||
|
||||
float4 p1 = normalize(cross(normalVector, segment));
|
||||
float4 p2 = normalize(cross(p1, normalVector));
|
||||
// Full friction is sum of velocities in each direction of plane
|
||||
float4 frictionVector = p1*mydot3a(relativeVelocity, p1) + p2*mydot3a(relativeVelocity, p2);
|
||||
|
||||
// Real friction is peak friction corrected by friction coefficients
|
||||
frictionVector = frictionVector * (colliderFriction*clothFriction);
|
||||
|
||||
float approachSpeed = dot(relativeVelocity, normalVector);
|
||||
|
||||
if( approachSpeed <= 0.0f )
|
||||
forceOnVertex -= frictionVector;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_vertexVelocities[nodeID] = float4(velocity.xyz, 0.f);
|
||||
|
||||
// Update external force
|
||||
g_vertexForces[nodeID] = float4(forceOnVertex.xyz, 0.f);
|
||||
|
||||
g_vertexPositions[nodeID] = float4(position.xyz, 0.f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
MINICL_REGISTER(SolveCollisionsAndUpdateVelocitiesKernel);
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
|
||||
ADD_DEFINITIONS(-DUSE_NVIDIA_OPENCL)
|
||||
ADD_DEFINITIONS(-DCL_PLATFORM_NVIDIA)
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/src
|
||||
${NVIDIA_OPENCL_INCLUDES}
|
||||
)
|
||||
|
||||
|
||||
|
||||
SET(BulletSoftBodyOpenCLSolvers_SRCS
|
||||
../btSoftBodySolver_OpenCL.cpp
|
||||
../btSoftBodySolver_OpenCLSIMDAware.cpp
|
||||
../btSoftBodySolverOutputCLtoGL.cpp
|
||||
)
|
||||
|
||||
SET(BulletSoftBodyOpenCLSolvers_HDRS
|
||||
../btSoftBodySolver_OpenCL.h
|
||||
../../Shared/btSoftBodySolverData.h
|
||||
../btSoftBodySolverVertexData_OpenCL.h
|
||||
../btSoftBodySolverTriangleData_OpenCL.h
|
||||
../btSoftBodySolverLinkData_OpenCL.h
|
||||
../btSoftBodySolverLinkData_OpenCLSIMDAware.h
|
||||
../btSoftBodySolverBuffer_OpenCL.h
|
||||
../btSoftBodySolverVertexBuffer_OpenGL.h
|
||||
../btSoftBodySolverOutputCLtoGL.h
|
||||
)
|
||||
|
||||
# OpenCL and HLSL Shaders.
|
||||
# Build rules generated to stringify these into headers
|
||||
# which are needed by some of the sources
|
||||
SET(BulletSoftBodyOpenCLSolvers_Shaders
|
||||
# OutputToVertexArray
|
||||
UpdateNormals
|
||||
Integrate
|
||||
UpdatePositions
|
||||
UpdateNodes
|
||||
SolvePositions
|
||||
UpdatePositionsFromVelocities
|
||||
ApplyForces
|
||||
PrepareLinks
|
||||
VSolveLinks
|
||||
)
|
||||
|
||||
foreach(f ${BulletSoftBodyOpenCLSolvers_Shaders})
|
||||
LIST(APPEND BulletSoftBodyOpenCLSolvers_OpenCLC "../OpenCLC10/${f}.cl")
|
||||
endforeach(f)
|
||||
|
||||
|
||||
|
||||
ADD_LIBRARY(BulletSoftBodySolvers_OpenCL_NVidia
|
||||
${BulletSoftBodyOpenCLSolvers_SRCS}
|
||||
${BulletSoftBodyOpenCLSolvers_HDRS}
|
||||
${BulletSoftBodyOpenCLSolvers_OpenCLC}
|
||||
)
|
||||
|
||||
SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_NVidia PROPERTIES VERSION ${BULLET_VERSION})
|
||||
SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_NVidia PROPERTIES SOVERSION ${BULLET_VERSION})
|
||||
IF (BUILD_SHARED_LIBS)
|
||||
TARGET_LINK_LIBRARIES(BulletSoftBodySolvers_OpenCL_NVidia BulletSoftBody BulletDynamics)
|
||||
ENDIF (BUILD_SHARED_LIBS)
|
||||
|
||||
|
||||
IF (INSTALL_LIBS)
|
||||
IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES)
|
||||
IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5)
|
||||
IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
INSTALL(TARGETS BulletSoftBodySolvers_OpenCL_NVidia DESTINATION .)
|
||||
ELSE (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
INSTALL(TARGETS BulletSoftBodySolvers_OpenCL_NVidia
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION lib${LIB_SUFFIX}
|
||||
ARCHIVE DESTINATION lib${LIB_SUFFIX})
|
||||
#headers are already installed by BulletMultiThreaded library
|
||||
ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5)
|
||||
|
||||
IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_NVidia PROPERTIES FRAMEWORK true)
|
||||
SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_NVidia PROPERTIES PUBLIC_HEADER "${BulletSoftBodyOpenCLSolvers_HDRS}")
|
||||
ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES)
|
||||
ENDIF (INSTALL_LIBS)
|
||||
@@ -0,0 +1,27 @@
|
||||
|
||||
hasCL = findOpenCL_NVIDIA()
|
||||
|
||||
if (hasCL) then
|
||||
|
||||
project "BulletSoftBodySolvers_OpenCL_NVIDIA"
|
||||
|
||||
defines { "USE_NVIDIA_OPENCL","CL_PLATFORM_NVIDIA"}
|
||||
|
||||
initOpenCL_NVIDIA()
|
||||
|
||||
kind "StaticLib"
|
||||
|
||||
targetdir "../../../../../lib"
|
||||
|
||||
includedirs {
|
||||
".",
|
||||
"../../../..",
|
||||
"../../../../../Glut"
|
||||
}
|
||||
files {
|
||||
"../btSoftBodySolver_OpenCL.cpp",
|
||||
"../btSoftBodySolver_OpenCLSIMDAware.cpp",
|
||||
"../btSoftBodySolverOutputCLtoGL.cpp"
|
||||
}
|
||||
|
||||
end
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
MSTRINGIFY(
|
||||
|
||||
|
||||
float adot3(float4 a, float4 b)
|
||||
{
|
||||
return a.x*b.x + a.y*b.y + a.z*b.z;
|
||||
}
|
||||
|
||||
float alength3(float4 a)
|
||||
{
|
||||
a.w = 0;
|
||||
return length(a);
|
||||
}
|
||||
|
||||
float4 anormalize3(float4 a)
|
||||
{
|
||||
a.w = 0;
|
||||
return normalize(a);
|
||||
}
|
||||
|
||||
float4 projectOnAxis( float4 v, float4 a )
|
||||
{
|
||||
return (a*adot3(v, a));
|
||||
}
|
||||
|
||||
__kernel void
|
||||
ApplyForcesKernel(
|
||||
const uint numNodes,
|
||||
const float solverdt,
|
||||
const float epsilon,
|
||||
__global int * g_vertexClothIdentifier,
|
||||
__global float4 * g_vertexNormal,
|
||||
__global float * g_vertexArea,
|
||||
__global float * g_vertexInverseMass,
|
||||
__global float * g_clothLiftFactor,
|
||||
__global float * g_clothDragFactor,
|
||||
__global float4 * g_clothWindVelocity,
|
||||
__global float4 * g_clothAcceleration,
|
||||
__global float * g_clothMediumDensity,
|
||||
__global float4 * g_vertexForceAccumulator,
|
||||
__global float4 * g_vertexVelocity GUID_ARG)
|
||||
{
|
||||
unsigned int nodeID = get_global_id(0);
|
||||
if( nodeID < numNodes )
|
||||
{
|
||||
int clothId = g_vertexClothIdentifier[nodeID];
|
||||
float nodeIM = g_vertexInverseMass[nodeID];
|
||||
|
||||
if( nodeIM > 0.0f )
|
||||
{
|
||||
float4 nodeV = g_vertexVelocity[nodeID];
|
||||
float4 normal = g_vertexNormal[nodeID];
|
||||
float area = g_vertexArea[nodeID];
|
||||
float4 nodeF = g_vertexForceAccumulator[nodeID];
|
||||
|
||||
// Read per-cloth values
|
||||
float4 clothAcceleration = g_clothAcceleration[clothId];
|
||||
float4 clothWindVelocity = g_clothWindVelocity[clothId];
|
||||
float liftFactor = g_clothLiftFactor[clothId];
|
||||
float dragFactor = g_clothDragFactor[clothId];
|
||||
float mediumDensity = g_clothMediumDensity[clothId];
|
||||
|
||||
// Apply the acceleration to the cloth rather than do this via a force
|
||||
nodeV += (clothAcceleration*solverdt);
|
||||
|
||||
g_vertexVelocity[nodeID] = nodeV;
|
||||
|
||||
// Aerodynamics
|
||||
float4 rel_v = nodeV - clothWindVelocity;
|
||||
float rel_v_len = alength3(rel_v);
|
||||
float rel_v2 = dot(rel_v, rel_v);
|
||||
|
||||
if( rel_v2 > epsilon )
|
||||
{
|
||||
float4 rel_v_nrm = anormalize3(rel_v);
|
||||
float4 nrm = normal;
|
||||
|
||||
nrm = nrm * (dot(nrm, rel_v) < 0 ? -1.f : 1.f);
|
||||
|
||||
float4 fDrag = (float4)(0.f, 0.f, 0.f, 0.f);
|
||||
float4 fLift = (float4)(0.f, 0.f, 0.f, 0.f);
|
||||
|
||||
float n_dot_v = dot(nrm, rel_v_nrm);
|
||||
|
||||
// drag force
|
||||
if ( dragFactor > 0.f )
|
||||
fDrag = 0.5f * dragFactor * mediumDensity * rel_v2 * area * n_dot_v * (-1.0f) * rel_v_nrm;
|
||||
|
||||
// lift force
|
||||
// Check angle of attack
|
||||
// cos(10º) = 0.98480
|
||||
if ( 0 < n_dot_v && n_dot_v < 0.98480f)
|
||||
fLift = 0.5f * liftFactor * mediumDensity * rel_v_len * area * sqrt(1.0f-n_dot_v*n_dot_v) * (cross(cross(nrm, rel_v_nrm), rel_v_nrm));
|
||||
|
||||
nodeF += fDrag + fLift;
|
||||
g_vertexForceAccumulator[nodeID] = nodeF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
MSTRINGIFY(
|
||||
#pragma OPENCL EXTENSION cl_khr_global_int32_extended_atomics : enable\n
|
||||
#pragma OPENCL EXTENSION cl_khr_local_int32_extended_atomics : enable\n
|
||||
|
||||
__kernel void
|
||||
ComputeBoundsKernel(
|
||||
const int numNodes,
|
||||
const int numSoftBodies,
|
||||
__global int * g_vertexClothIdentifier,
|
||||
__global float4 * g_vertexPositions,
|
||||
/* Unfortunately, to get the atomics below to work these arrays cannot be */
|
||||
/* uint4, though that is the layout of the data */
|
||||
/* Therefore this is little-endian-only code */
|
||||
volatile __global uint * g_clothMinBounds,
|
||||
volatile __global uint * g_clothMaxBounds,
|
||||
volatile __local uint * clothMinBounds,
|
||||
volatile __local uint * clothMaxBounds)
|
||||
{
|
||||
// Init min and max bounds arrays
|
||||
if( get_local_id(0) < numSoftBodies )
|
||||
{
|
||||
|
||||
clothMinBounds[get_local_id(0)*4] = UINT_MAX;
|
||||
clothMinBounds[get_local_id(0)*4+1] = UINT_MAX;
|
||||
clothMinBounds[get_local_id(0)*4+2] = UINT_MAX;
|
||||
clothMinBounds[get_local_id(0)*4+3] = UINT_MAX;
|
||||
clothMaxBounds[get_local_id(0)*4] = 0;
|
||||
clothMaxBounds[get_local_id(0)*4+1] = 0;
|
||||
clothMaxBounds[get_local_id(0)*4+2] = 0;
|
||||
clothMaxBounds[get_local_id(0)*4+3] = 0;
|
||||
|
||||
}
|
||||
|
||||
barrier(CLK_LOCAL_MEM_FENCE);
|
||||
|
||||
int nodeID = get_global_id(0);
|
||||
if( nodeID < numNodes )
|
||||
{
|
||||
int clothIdentifier = g_vertexClothIdentifier[nodeID];
|
||||
if( clothIdentifier >= 0 )
|
||||
{
|
||||
|
||||
float4 position = (float4)(g_vertexPositions[nodeID].xyz, 0.f);
|
||||
|
||||
/* Reinterpret position as uint */
|
||||
uint4 positionUInt = (uint4)(as_uint(position.x), as_uint(position.y), as_uint(position.z), 0);
|
||||
|
||||
/* Invert sign bit of positives and whole of negatives to allow comparison as unsigned ints */
|
||||
positionUInt.x ^= (1+~(positionUInt.x >> 31) | 0x80000000);
|
||||
positionUInt.y ^= (1+~(positionUInt.y >> 31) | 0x80000000);
|
||||
positionUInt.z ^= (1+~(positionUInt.z >> 31) | 0x80000000);
|
||||
|
||||
// Min/max with the LDS values
|
||||
atom_min(&(clothMinBounds[clothIdentifier*4]), positionUInt.x);
|
||||
atom_min(&(clothMinBounds[clothIdentifier*4+1]), positionUInt.y);
|
||||
atom_min(&(clothMinBounds[clothIdentifier*4+2]), positionUInt.z);
|
||||
|
||||
atom_max(&(clothMaxBounds[clothIdentifier*4]), positionUInt.x);
|
||||
atom_max(&(clothMaxBounds[clothIdentifier*4+1]), positionUInt.y);
|
||||
atom_max(&(clothMaxBounds[clothIdentifier*4+2]), positionUInt.z);
|
||||
}
|
||||
}
|
||||
|
||||
barrier(CLK_LOCAL_MEM_FENCE);
|
||||
|
||||
|
||||
/* Use global atomics to update the global versions of the data */
|
||||
if( get_local_id(0) < numSoftBodies )
|
||||
{
|
||||
/*atom_min(&(g_clothMinBounds[get_local_id(0)].x), clothMinBounds[get_local_id(0)].x);*/
|
||||
atom_min(&(g_clothMinBounds[get_local_id(0)*4]), clothMinBounds[get_local_id(0)*4]);
|
||||
atom_min(&(g_clothMinBounds[get_local_id(0)*4+1]), clothMinBounds[get_local_id(0)*4+1]);
|
||||
atom_min(&(g_clothMinBounds[get_local_id(0)*4+2]), clothMinBounds[get_local_id(0)*4+2]);
|
||||
|
||||
atom_max(&(g_clothMaxBounds[get_local_id(0)*4]), clothMaxBounds[get_local_id(0)*4]);
|
||||
atom_max(&(g_clothMaxBounds[get_local_id(0)*4+1]), clothMaxBounds[get_local_id(0)*4+1]);
|
||||
atom_max(&(g_clothMaxBounds[get_local_id(0)*4+2]), clothMaxBounds[get_local_id(0)*4+2]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
);
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
MSTRINGIFY(
|
||||
|
||||
// Node indices for each link
|
||||
|
||||
|
||||
|
||||
__kernel void
|
||||
IntegrateKernel(
|
||||
const int numNodes,
|
||||
const float solverdt,
|
||||
__global float * g_vertexInverseMasses,
|
||||
__global float4 * g_vertexPositions,
|
||||
__global float4 * g_vertexVelocity,
|
||||
__global float4 * g_vertexPreviousPositions,
|
||||
__global float4 * g_vertexForceAccumulator GUID_ARG)
|
||||
{
|
||||
int nodeID = get_global_id(0);
|
||||
if( nodeID < numNodes )
|
||||
{
|
||||
float4 position = g_vertexPositions[nodeID];
|
||||
float4 velocity = g_vertexVelocity[nodeID];
|
||||
float4 force = g_vertexForceAccumulator[nodeID];
|
||||
float inverseMass = g_vertexInverseMasses[nodeID];
|
||||
|
||||
g_vertexPreviousPositions[nodeID] = position;
|
||||
velocity += force * inverseMass * solverdt;
|
||||
position += velocity * solverdt;
|
||||
|
||||
g_vertexForceAccumulator[nodeID] = (float4)(0.f, 0.f, 0.f, 0.0f);
|
||||
g_vertexPositions[nodeID] = position;
|
||||
g_vertexVelocity[nodeID] = velocity;
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
MSTRINGIFY(
|
||||
|
||||
__kernel void
|
||||
OutputToVertexArrayWithNormalsKernel(
|
||||
const int startNode, const int numNodes, __global float *g_vertexBuffer,
|
||||
const int positionOffset, const int positionStride, const __global float4* g_vertexPositions,
|
||||
const int normalOffset, const int normalStride, const __global float4* g_vertexNormals )
|
||||
{
|
||||
int nodeID = get_global_id(0);
|
||||
if( nodeID < numNodes )
|
||||
{
|
||||
float4 position = g_vertexPositions[nodeID + startNode];
|
||||
float4 normal = g_vertexNormals[nodeID + startNode];
|
||||
|
||||
// Stride should account for the float->float4 conversion
|
||||
int positionDestination = nodeID * positionStride + positionOffset;
|
||||
g_vertexBuffer[positionDestination] = position.x;
|
||||
g_vertexBuffer[positionDestination+1] = position.y;
|
||||
g_vertexBuffer[positionDestination+2] = position.z;
|
||||
|
||||
int normalDestination = nodeID * normalStride + normalOffset;
|
||||
g_vertexBuffer[normalDestination] = normal.x;
|
||||
g_vertexBuffer[normalDestination+1] = normal.y;
|
||||
g_vertexBuffer[normalDestination+2] = normal.z;
|
||||
}
|
||||
}
|
||||
|
||||
__kernel void
|
||||
OutputToVertexArrayWithoutNormalsKernel(
|
||||
const int startNode, const int numNodes, __global float *g_vertexBuffer,
|
||||
const int positionOffset, const int positionStride, const __global float4* g_vertexPositions )
|
||||
{
|
||||
int nodeID = get_global_id(0);
|
||||
if( nodeID < numNodes )
|
||||
{
|
||||
float4 position = g_vertexPositions[nodeID + startNode];
|
||||
|
||||
// Stride should account for the float->float4 conversion
|
||||
int positionDestination = nodeID * positionStride + positionOffset;
|
||||
g_vertexBuffer[positionDestination] = position.x;
|
||||
g_vertexBuffer[positionDestination+1] = position.y;
|
||||
g_vertexBuffer[positionDestination+2] = position.z;
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
MSTRINGIFY(
|
||||
|
||||
|
||||
|
||||
__kernel void
|
||||
PrepareLinksKernel(
|
||||
const int numLinks,
|
||||
__global int2 * g_linksVertexIndices,
|
||||
__global float * g_linksMassLSC,
|
||||
__global float4 * g_nodesPreviousPosition,
|
||||
__global float * g_linksLengthRatio,
|
||||
__global float4 * g_linksCurrentLength GUID_ARG)
|
||||
{
|
||||
int linkID = get_global_id(0);
|
||||
if( linkID < numLinks )
|
||||
{
|
||||
|
||||
int2 nodeIndices = g_linksVertexIndices[linkID];
|
||||
int node0 = nodeIndices.x;
|
||||
int node1 = nodeIndices.y;
|
||||
|
||||
float4 nodePreviousPosition0 = g_nodesPreviousPosition[node0];
|
||||
float4 nodePreviousPosition1 = g_nodesPreviousPosition[node1];
|
||||
|
||||
float massLSC = g_linksMassLSC[linkID];
|
||||
|
||||
float4 linkCurrentLength = nodePreviousPosition1 - nodePreviousPosition0;
|
||||
linkCurrentLength.w = 0.f;
|
||||
|
||||
float linkLengthRatio = dot(linkCurrentLength, linkCurrentLength)*massLSC;
|
||||
linkLengthRatio = 1.0f/linkLengthRatio;
|
||||
|
||||
g_linksCurrentLength[linkID] = linkCurrentLength;
|
||||
g_linksLengthRatio[linkID] = linkLengthRatio;
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
+204
@@ -0,0 +1,204 @@
|
||||
MSTRINGIFY(
|
||||
|
||||
|
||||
|
||||
float mydot3a(float4 a, float4 b)
|
||||
{
|
||||
return a.x*b.x + a.y*b.y + a.z*b.z;
|
||||
}
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int firstObject;
|
||||
int endObject;
|
||||
} CollisionObjectIndices;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float4 shapeTransform[4]; // column major 4x4 matrix
|
||||
float4 linearVelocity;
|
||||
float4 angularVelocity;
|
||||
|
||||
int softBodyIdentifier;
|
||||
int collisionShapeType;
|
||||
|
||||
|
||||
// Shape information
|
||||
// Compressed from the union
|
||||
float radius;
|
||||
float halfHeight;
|
||||
int upAxis;
|
||||
|
||||
float margin;
|
||||
float friction;
|
||||
|
||||
int padding0;
|
||||
|
||||
} CollisionShapeDescription;
|
||||
|
||||
// From btBroadphaseProxy.h
|
||||
__constant int CAPSULE_SHAPE_PROXYTYPE = 10;
|
||||
|
||||
// Multiply column-major matrix against vector
|
||||
float4 matrixVectorMul( float4 matrix[4], float4 vector )
|
||||
{
|
||||
float4 returnVector;
|
||||
float4 row0 = (float4)(matrix[0].x, matrix[1].x, matrix[2].x, matrix[3].x);
|
||||
float4 row1 = (float4)(matrix[0].y, matrix[1].y, matrix[2].y, matrix[3].y);
|
||||
float4 row2 = (float4)(matrix[0].z, matrix[1].z, matrix[2].z, matrix[3].z);
|
||||
float4 row3 = (float4)(matrix[0].w, matrix[1].w, matrix[2].w, matrix[3].w);
|
||||
returnVector.x = dot(row0, vector);
|
||||
returnVector.y = dot(row1, vector);
|
||||
returnVector.z = dot(row2, vector);
|
||||
returnVector.w = dot(row3, vector);
|
||||
return returnVector;
|
||||
}
|
||||
|
||||
__kernel void
|
||||
SolveCollisionsAndUpdateVelocitiesKernel(
|
||||
const int numNodes,
|
||||
const float isolverdt,
|
||||
__global int *g_vertexClothIdentifier,
|
||||
__global float4 *g_vertexPreviousPositions,
|
||||
__global float * g_perClothFriction,
|
||||
__global float * g_clothDampingFactor,
|
||||
__global CollisionObjectIndices * g_perClothCollisionObjectIndices,
|
||||
__global CollisionShapeDescription * g_collisionObjectDetails,
|
||||
__global float4 * g_vertexForces,
|
||||
__global float4 *g_vertexVelocities,
|
||||
__global float4 *g_vertexPositions GUID_ARG)
|
||||
{
|
||||
int nodeID = get_global_id(0);
|
||||
float4 forceOnVertex = (float4)(0.f, 0.f, 0.f, 0.f);
|
||||
|
||||
if( get_global_id(0) < numNodes )
|
||||
{
|
||||
int clothIdentifier = g_vertexClothIdentifier[nodeID];
|
||||
|
||||
// Abort if this is not a valid cloth
|
||||
if( clothIdentifier < 0 )
|
||||
return;
|
||||
|
||||
|
||||
float4 position = (float4)(g_vertexPositions[nodeID].xyz, 1.f);
|
||||
float4 previousPosition = (float4)(g_vertexPreviousPositions[nodeID].xyz, 1.f);
|
||||
|
||||
float clothFriction = g_perClothFriction[clothIdentifier];
|
||||
float dampingFactor = g_clothDampingFactor[clothIdentifier];
|
||||
float velocityCoefficient = (1.f - dampingFactor);
|
||||
float4 difference = position - previousPosition;
|
||||
float4 velocity = difference*velocityCoefficient*isolverdt;
|
||||
|
||||
CollisionObjectIndices collisionObjectIndices = g_perClothCollisionObjectIndices[clothIdentifier];
|
||||
|
||||
int numObjects = collisionObjectIndices.endObject - collisionObjectIndices.firstObject;
|
||||
|
||||
if( numObjects > 0 )
|
||||
{
|
||||
// We have some possible collisions to deal with
|
||||
for( int collision = collisionObjectIndices.firstObject; collision < collisionObjectIndices.endObject; ++collision )
|
||||
{
|
||||
CollisionShapeDescription shapeDescription = g_collisionObjectDetails[collision];
|
||||
float colliderFriction = shapeDescription.friction;
|
||||
|
||||
if( shapeDescription.collisionShapeType == CAPSULE_SHAPE_PROXYTYPE )
|
||||
{
|
||||
// Colliding with a capsule
|
||||
|
||||
float capsuleHalfHeight = shapeDescription.halfHeight;
|
||||
float capsuleRadius = shapeDescription.radius;
|
||||
float capsuleMargin = shapeDescription.margin;
|
||||
int capsuleupAxis = shapeDescription.upAxis;
|
||||
|
||||
// Four columns of worldTransform matrix
|
||||
float4 worldTransform[4];
|
||||
worldTransform[0] = shapeDescription.shapeTransform[0];
|
||||
worldTransform[1] = shapeDescription.shapeTransform[1];
|
||||
worldTransform[2] = shapeDescription.shapeTransform[2];
|
||||
worldTransform[3] = shapeDescription.shapeTransform[3];
|
||||
|
||||
// Correctly define capsule centerline vector
|
||||
float4 c1 = (float4)(0.f, 0.f, 0.f, 1.f);
|
||||
float4 c2 = (float4)(0.f, 0.f, 0.f, 1.f);
|
||||
c1.x = select( 0.f, -capsuleHalfHeight, capsuleupAxis == 0 );
|
||||
c1.y = select( 0.f, -capsuleHalfHeight, capsuleupAxis == 1 );
|
||||
c1.z = select( 0.f, -capsuleHalfHeight, capsuleupAxis == 2 );
|
||||
c2.x = -c1.x;
|
||||
c2.y = -c1.y;
|
||||
c2.z = -c1.z;
|
||||
|
||||
|
||||
float4 worldC1 = matrixVectorMul(worldTransform, c1);
|
||||
float4 worldC2 = matrixVectorMul(worldTransform, c2);
|
||||
float4 segment = (worldC2 - worldC1);
|
||||
|
||||
// compute distance of tangent to vertex along line segment in capsule
|
||||
float distanceAlongSegment = -( mydot3a( (worldC1 - position), segment ) / mydot3a(segment, segment) );
|
||||
|
||||
float4 closestPoint = (worldC1 + (float4)(segment * distanceAlongSegment));
|
||||
float distanceFromLine = length(position - closestPoint);
|
||||
float distanceFromC1 = length(worldC1 - position);
|
||||
float distanceFromC2 = length(worldC2 - position);
|
||||
|
||||
// Final distance from collision, point to push from, direction to push in
|
||||
// for impulse force
|
||||
float dist;
|
||||
float4 normalVector;
|
||||
if( distanceAlongSegment < 0 )
|
||||
{
|
||||
dist = distanceFromC1;
|
||||
normalVector = (float4)(normalize(position - worldC1).xyz, 0.f);
|
||||
} else if( distanceAlongSegment > 1.f ) {
|
||||
dist = distanceFromC2;
|
||||
normalVector = (float4)(normalize(position - worldC2).xyz, 0.f);
|
||||
} else {
|
||||
dist = distanceFromLine;
|
||||
normalVector = (float4)(normalize(position - closestPoint).xyz, 0.f);
|
||||
}
|
||||
|
||||
float4 colliderLinearVelocity = shapeDescription.linearVelocity;
|
||||
float4 colliderAngularVelocity = shapeDescription.angularVelocity;
|
||||
float4 velocityOfSurfacePoint = colliderLinearVelocity + cross(colliderAngularVelocity, position - (float4)(worldTransform[0].w, worldTransform[1].w, worldTransform[2].w, 0.f));
|
||||
|
||||
float minDistance = capsuleRadius + capsuleMargin;
|
||||
|
||||
// In case of no collision, this is the value of velocity
|
||||
velocity = (position - previousPosition) * velocityCoefficient * isolverdt;
|
||||
|
||||
|
||||
// Check for a collision
|
||||
if( dist < minDistance )
|
||||
{
|
||||
// Project back to surface along normal
|
||||
position = position + (float4)((minDistance - dist)*normalVector*0.9f);
|
||||
velocity = (position - previousPosition) * velocityCoefficient * isolverdt;
|
||||
float4 relativeVelocity = velocity - velocityOfSurfacePoint;
|
||||
|
||||
float4 p1 = normalize(cross(normalVector, segment));
|
||||
float4 p2 = normalize(cross(p1, normalVector));
|
||||
// Full friction is sum of velocities in each direction of plane
|
||||
float4 frictionVector = p1*mydot3a(relativeVelocity, p1) + p2*mydot3a(relativeVelocity, p2);
|
||||
|
||||
// Real friction is peak friction corrected by friction coefficients
|
||||
frictionVector = frictionVector * (colliderFriction*clothFriction);
|
||||
|
||||
float approachSpeed = dot(relativeVelocity, normalVector);
|
||||
|
||||
if( approachSpeed <= 0.0f )
|
||||
forceOnVertex -= frictionVector;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_vertexVelocities[nodeID] = (float4)(velocity.xyz, 0.f);
|
||||
|
||||
// Update external force
|
||||
g_vertexForces[nodeID] = (float4)(forceOnVertex.xyz, 0.f);
|
||||
|
||||
g_vertexPositions[nodeID] = (float4)(position.xyz, 0.f);
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
+242
@@ -0,0 +1,242 @@
|
||||
MSTRINGIFY(
|
||||
|
||||
//#pragma OPENCL EXTENSION cl_amd_printf:enable\n
|
||||
|
||||
float mydot3a(float4 a, float4 b)
|
||||
{
|
||||
return a.x*b.x + a.y*b.y + a.z*b.z;
|
||||
}
|
||||
|
||||
float mylength3(float4 a)
|
||||
{
|
||||
a.w = 0;
|
||||
return length(a);
|
||||
}
|
||||
|
||||
float4 mynormalize3(float4 a)
|
||||
{
|
||||
a.w = 0;
|
||||
return normalize(a);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int firstObject;
|
||||
int endObject;
|
||||
} CollisionObjectIndices;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float4 shapeTransform[4]; // column major 4x4 matrix
|
||||
float4 linearVelocity;
|
||||
float4 angularVelocity;
|
||||
|
||||
int softBodyIdentifier;
|
||||
int collisionShapeType;
|
||||
|
||||
|
||||
// Shape information
|
||||
// Compressed from the union
|
||||
float radius;
|
||||
float halfHeight;
|
||||
int upAxis;
|
||||
|
||||
float margin;
|
||||
float friction;
|
||||
|
||||
int padding0;
|
||||
|
||||
} CollisionShapeDescription;
|
||||
|
||||
// From btBroadphaseProxy.h
|
||||
__constant int CAPSULE_SHAPE_PROXYTYPE = 10;
|
||||
|
||||
// Multiply column-major matrix against vector
|
||||
float4 matrixVectorMul( float4 matrix[4], float4 vector )
|
||||
{
|
||||
float4 returnVector;
|
||||
float4 row0 = (float4)(matrix[0].x, matrix[1].x, matrix[2].x, matrix[3].x);
|
||||
float4 row1 = (float4)(matrix[0].y, matrix[1].y, matrix[2].y, matrix[3].y);
|
||||
float4 row2 = (float4)(matrix[0].z, matrix[1].z, matrix[2].z, matrix[3].z);
|
||||
float4 row3 = (float4)(matrix[0].w, matrix[1].w, matrix[2].w, matrix[3].w);
|
||||
returnVector.x = dot(row0, vector);
|
||||
returnVector.y = dot(row1, vector);
|
||||
returnVector.z = dot(row2, vector);
|
||||
returnVector.w = dot(row3, vector);
|
||||
return returnVector;
|
||||
}
|
||||
|
||||
__kernel void
|
||||
SolveCollisionsAndUpdateVelocitiesKernel(
|
||||
const int numNodes,
|
||||
const float isolverdt,
|
||||
__global int *g_vertexClothIdentifier,
|
||||
__global float4 *g_vertexPreviousPositions,
|
||||
__global float * g_perClothFriction,
|
||||
__global float * g_clothDampingFactor,
|
||||
__global CollisionObjectIndices * g_perClothCollisionObjectIndices,
|
||||
__global CollisionShapeDescription * g_collisionObjectDetails,
|
||||
__global float4 * g_vertexForces,
|
||||
__global float4 *g_vertexVelocities,
|
||||
__global float4 *g_vertexPositions,
|
||||
__local CollisionShapeDescription *localCollisionShapes,
|
||||
__global float * g_vertexInverseMasses)
|
||||
{
|
||||
int nodeID = get_global_id(0);
|
||||
float4 forceOnVertex = (float4)(0.f, 0.f, 0.f, 0.f);
|
||||
|
||||
int clothIdentifier = g_vertexClothIdentifier[nodeID];
|
||||
|
||||
// Abort if this is not a valid cloth
|
||||
if( clothIdentifier < 0 )
|
||||
return;
|
||||
|
||||
|
||||
float4 position = (float4)(g_vertexPositions[nodeID].xyz, 0.f);
|
||||
float4 previousPosition = (float4)(g_vertexPreviousPositions[nodeID].xyz, 0.f);
|
||||
|
||||
float clothFriction = g_perClothFriction[clothIdentifier];
|
||||
float dampingFactor = g_clothDampingFactor[clothIdentifier];
|
||||
float velocityCoefficient = (1.f - dampingFactor);
|
||||
float4 difference = position - previousPosition;
|
||||
float4 velocity = difference*velocityCoefficient*isolverdt;
|
||||
float inverseMass = g_vertexInverseMasses[nodeID];
|
||||
|
||||
CollisionObjectIndices collisionObjectIndices = g_perClothCollisionObjectIndices[clothIdentifier];
|
||||
|
||||
int numObjects = collisionObjectIndices.endObject - collisionObjectIndices.firstObject;
|
||||
|
||||
if( numObjects > 0 )
|
||||
{
|
||||
// We have some possible collisions to deal with
|
||||
|
||||
// First load all of the collision objects into LDS
|
||||
int numObjects = collisionObjectIndices.endObject - collisionObjectIndices.firstObject;
|
||||
if( get_local_id(0) < numObjects )
|
||||
{
|
||||
localCollisionShapes[get_local_id(0)] = g_collisionObjectDetails[ collisionObjectIndices.firstObject + get_local_id(0) ];
|
||||
}
|
||||
}
|
||||
|
||||
// Safe as the vertices are padded so that not more than one soft body is in a group
|
||||
barrier(CLK_LOCAL_MEM_FENCE);
|
||||
|
||||
// Annoyingly, even though I know the flow control is not varying, the compiler will not let me skip this
|
||||
if( numObjects > 0 )
|
||||
{
|
||||
|
||||
|
||||
// We have some possible collisions to deal with
|
||||
for( int collision = 0; collision < numObjects; ++collision )
|
||||
{
|
||||
CollisionShapeDescription shapeDescription = localCollisionShapes[collision];
|
||||
float colliderFriction = localCollisionShapes[collision].friction;
|
||||
|
||||
if( localCollisionShapes[collision].collisionShapeType == CAPSULE_SHAPE_PROXYTYPE )
|
||||
{
|
||||
// Colliding with a capsule
|
||||
|
||||
float capsuleHalfHeight = localCollisionShapes[collision].halfHeight;
|
||||
float capsuleRadius = localCollisionShapes[collision].radius;
|
||||
float capsuleMargin = localCollisionShapes[collision].margin;
|
||||
int capsuleupAxis = localCollisionShapes[collision].upAxis;
|
||||
|
||||
if ( capsuleHalfHeight <= 0 )
|
||||
capsuleHalfHeight = 0.0001f;
|
||||
float4 worldTransform[4];
|
||||
worldTransform[0] = localCollisionShapes[collision].shapeTransform[0];
|
||||
worldTransform[1] = localCollisionShapes[collision].shapeTransform[1];
|
||||
worldTransform[2] = localCollisionShapes[collision].shapeTransform[2];
|
||||
worldTransform[3] = localCollisionShapes[collision].shapeTransform[3];
|
||||
|
||||
// Correctly define capsule centerline vector
|
||||
float4 c1 = (float4)(0.f, 0.f, 0.f, 1.f);
|
||||
float4 c2 = (float4)(0.f, 0.f, 0.f, 1.f);
|
||||
c1.x = select( 0.f, -capsuleHalfHeight, capsuleupAxis == 0 );
|
||||
c1.y = select( 0.f, -capsuleHalfHeight, capsuleupAxis == 1 );
|
||||
c1.z = select( 0.f, -capsuleHalfHeight, capsuleupAxis == 2 );
|
||||
c2.x = -c1.x;
|
||||
c2.y = -c1.y;
|
||||
c2.z = -c1.z;
|
||||
|
||||
float4 worldC1 = matrixVectorMul(worldTransform, c1);
|
||||
float4 worldC2 = matrixVectorMul(worldTransform, c2);
|
||||
float4 segment = (float4)((worldC2 - worldC1).xyz, 0.f);
|
||||
|
||||
float4 segmentNormalized = mynormalize3(segment);
|
||||
float distanceAlongSegment =mydot3a( (position - worldC1), segmentNormalized );
|
||||
|
||||
float4 closestPointOnSegment = (worldC1 + (float4)(segmentNormalized * distanceAlongSegment));
|
||||
float distanceFromLine = mylength3(position - closestPointOnSegment);
|
||||
float distanceFromC1 = mylength3(worldC1 - position);
|
||||
float distanceFromC2 = mylength3(worldC2 - position);
|
||||
|
||||
// Final distance from collision, point to push from, direction to push in
|
||||
// for impulse force
|
||||
float dist;
|
||||
float4 normalVector;
|
||||
|
||||
if( distanceAlongSegment < 0 )
|
||||
{
|
||||
dist = distanceFromC1;
|
||||
normalVector = (float4)(normalize(position - worldC1).xyz, 0.f);
|
||||
} else if( distanceAlongSegment > length(segment) ) {
|
||||
dist = distanceFromC2;
|
||||
normalVector = (float4)(normalize(position - worldC2).xyz, 0.f);
|
||||
} else {
|
||||
dist = distanceFromLine;
|
||||
normalVector = (float4)(normalize(position - closestPointOnSegment).xyz, 0.f);
|
||||
}
|
||||
|
||||
float minDistance = capsuleRadius + capsuleMargin;
|
||||
float4 closestPointOnSurface = (float4)((position + (minDistance - dist) * normalVector).xyz, 0.f);
|
||||
|
||||
float4 colliderLinearVelocity = shapeDescription.linearVelocity;
|
||||
float4 colliderAngularVelocity = shapeDescription.angularVelocity;
|
||||
float4 velocityOfSurfacePoint = colliderLinearVelocity + cross(colliderAngularVelocity, closestPointOnSurface - (float4)(worldTransform[0].w, worldTransform[1].w, worldTransform[2].w, 0.f));
|
||||
|
||||
|
||||
// Check for a collision
|
||||
if( dist < minDistance )
|
||||
{
|
||||
// Project back to surface along normal
|
||||
position = closestPointOnSurface;
|
||||
velocity = (position - previousPosition) * velocityCoefficient * isolverdt;
|
||||
float4 relativeVelocity = velocity - velocityOfSurfacePoint;
|
||||
|
||||
float4 p1 = mynormalize3(cross(normalVector, segment));
|
||||
float4 p2 = mynormalize3(cross(p1, normalVector));
|
||||
|
||||
float4 tangentialVel = p1*mydot3a(relativeVelocity, p1) + p2*mydot3a(relativeVelocity, p2);
|
||||
float frictionCoef = (colliderFriction * clothFriction);
|
||||
if (frictionCoef>1.f)
|
||||
frictionCoef = 1.f;
|
||||
|
||||
//only apply friction if objects are not moving apart
|
||||
float projVel = mydot3a(relativeVelocity,normalVector);
|
||||
if ( projVel >= -0.001f)
|
||||
{
|
||||
if ( inverseMass > 0 )
|
||||
{
|
||||
//float4 myforceOnVertex = -tangentialVel * frictionCoef * isolverdt * (1.0f / inverseMass);
|
||||
position += (-tangentialVel * frictionCoef) / (isolverdt);
|
||||
}
|
||||
}
|
||||
|
||||
// In case of no collision, this is the value of velocity
|
||||
velocity = (position - previousPosition) * velocityCoefficient * isolverdt;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_vertexVelocities[nodeID] = (float4)(velocity.xyz, 0.f);
|
||||
|
||||
// Update external force
|
||||
g_vertexForces[nodeID] = (float4)(forceOnVertex.xyz, 0.f);
|
||||
|
||||
g_vertexPositions[nodeID] = (float4)(position.xyz, 0.f);
|
||||
}
|
||||
|
||||
);
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
|
||||
|
||||
|
||||
MSTRINGIFY(
|
||||
|
||||
|
||||
float mydot3(float4 a, float4 b)
|
||||
{
|
||||
return a.x*b.x + a.y*b.y + a.z*b.z;
|
||||
}
|
||||
|
||||
|
||||
__kernel void
|
||||
SolvePositionsFromLinksKernel(
|
||||
const int startLink,
|
||||
const int numLinks,
|
||||
const float kst,
|
||||
const float ti,
|
||||
__global int2 * g_linksVertexIndices,
|
||||
__global float * g_linksMassLSC,
|
||||
__global float * g_linksRestLengthSquared,
|
||||
__global float * g_verticesInverseMass,
|
||||
__global float4 * g_vertexPositions GUID_ARG)
|
||||
|
||||
{
|
||||
int linkID = get_global_id(0) + startLink;
|
||||
if( get_global_id(0) < numLinks )
|
||||
{
|
||||
float massLSC = g_linksMassLSC[linkID];
|
||||
float restLengthSquared = g_linksRestLengthSquared[linkID];
|
||||
|
||||
if( massLSC > 0.0f )
|
||||
{
|
||||
int2 nodeIndices = g_linksVertexIndices[linkID];
|
||||
int node0 = nodeIndices.x;
|
||||
int node1 = nodeIndices.y;
|
||||
|
||||
float4 position0 = g_vertexPositions[node0];
|
||||
float4 position1 = g_vertexPositions[node1];
|
||||
|
||||
float inverseMass0 = g_verticesInverseMass[node0];
|
||||
float inverseMass1 = g_verticesInverseMass[node1];
|
||||
|
||||
float4 del = position1 - position0;
|
||||
float len = mydot3(del, del);
|
||||
float k = ((restLengthSquared - len)/(massLSC*(restLengthSquared+len)))*kst;
|
||||
position0 = position0 - del*(k*inverseMass0);
|
||||
position1 = position1 + del*(k*inverseMass1);
|
||||
|
||||
g_vertexPositions[node0] = position0;
|
||||
g_vertexPositions[node1] = position1;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
MSTRINGIFY(
|
||||
|
||||
float mydot3(float4 a, float4 b)
|
||||
{
|
||||
return a.x*b.x + a.y*b.y + a.z*b.z;
|
||||
}
|
||||
|
||||
__kernel __attribute__((reqd_work_group_size(WAVEFRONT_BLOCK_MULTIPLIER*WAVEFRONT_SIZE, 1, 1)))
|
||||
void
|
||||
SolvePositionsFromLinksKernel(
|
||||
const int startWaveInBatch,
|
||||
const int numWaves,
|
||||
const float kst,
|
||||
const float ti,
|
||||
__global int2 *g_wavefrontBatchCountsVertexCounts,
|
||||
__global int *g_vertexAddressesPerWavefront,
|
||||
__global int2 * g_linksVertexIndices,
|
||||
__global float * g_linksMassLSC,
|
||||
__global float * g_linksRestLengthSquared,
|
||||
__global float * g_verticesInverseMass,
|
||||
__global float4 * g_vertexPositions,
|
||||
__local int2 *wavefrontBatchCountsVertexCounts,
|
||||
__local float4 *vertexPositionSharedData,
|
||||
__local float *vertexInverseMassSharedData)
|
||||
{
|
||||
const int laneInWavefront = (get_global_id(0) & (WAVEFRONT_SIZE-1));
|
||||
const int wavefront = startWaveInBatch + (get_global_id(0) / WAVEFRONT_SIZE);
|
||||
const int firstWavefrontInBlock = startWaveInBatch + get_group_id(0) * WAVEFRONT_BLOCK_MULTIPLIER;
|
||||
const int localWavefront = wavefront - firstWavefrontInBlock;
|
||||
|
||||
// Mask out in case there's a stray "wavefront" at the end that's been forced in through the multiplier
|
||||
if( wavefront < (startWaveInBatch + numWaves) )
|
||||
{
|
||||
// Load the batch counts for the wavefronts
|
||||
|
||||
int2 batchesAndVerticesWithinWavefront = g_wavefrontBatchCountsVertexCounts[wavefront];
|
||||
int batchesWithinWavefront = batchesAndVerticesWithinWavefront.x;
|
||||
int verticesUsedByWave = batchesAndVerticesWithinWavefront.y;
|
||||
|
||||
// Load the vertices for the wavefronts
|
||||
for( int vertex = laneInWavefront; vertex < verticesUsedByWave; vertex+=WAVEFRONT_SIZE )
|
||||
{
|
||||
int vertexAddress = g_vertexAddressesPerWavefront[wavefront*MAX_NUM_VERTICES_PER_WAVE + vertex];
|
||||
|
||||
vertexPositionSharedData[localWavefront*MAX_NUM_VERTICES_PER_WAVE + vertex] = g_vertexPositions[vertexAddress];
|
||||
vertexInverseMassSharedData[localWavefront*MAX_NUM_VERTICES_PER_WAVE + vertex] = g_verticesInverseMass[vertexAddress];
|
||||
}
|
||||
|
||||
barrier(CLK_LOCAL_MEM_FENCE);
|
||||
|
||||
// Loop through the batches performing the solve on each in LDS
|
||||
int baseDataLocationForWave = WAVEFRONT_SIZE * wavefront * MAX_BATCHES_PER_WAVE;
|
||||
|
||||
//for( int batch = 0; batch < batchesWithinWavefront; ++batch )
|
||||
|
||||
int batch = 0;
|
||||
do
|
||||
{
|
||||
int baseDataLocation = baseDataLocationForWave + WAVEFRONT_SIZE * batch;
|
||||
int locationOfValue = baseDataLocation + laneInWavefront;
|
||||
|
||||
|
||||
// These loads should all be perfectly linear across the WF
|
||||
int2 localVertexIndices = g_linksVertexIndices[locationOfValue];
|
||||
float massLSC = g_linksMassLSC[locationOfValue];
|
||||
float restLengthSquared = g_linksRestLengthSquared[locationOfValue];
|
||||
|
||||
// LDS vertex addresses based on logical wavefront number in block and loaded index
|
||||
int vertexAddress0 = MAX_NUM_VERTICES_PER_WAVE * localWavefront + localVertexIndices.x;
|
||||
int vertexAddress1 = MAX_NUM_VERTICES_PER_WAVE * localWavefront + localVertexIndices.y;
|
||||
|
||||
float4 position0 = vertexPositionSharedData[vertexAddress0];
|
||||
float4 position1 = vertexPositionSharedData[vertexAddress1];
|
||||
|
||||
float inverseMass0 = vertexInverseMassSharedData[vertexAddress0];
|
||||
float inverseMass1 = vertexInverseMassSharedData[vertexAddress1];
|
||||
|
||||
float4 del = position1 - position0;
|
||||
float len = mydot3(del, del);
|
||||
|
||||
float k = 0;
|
||||
if( massLSC > 0.0f )
|
||||
{
|
||||
k = ((restLengthSquared - len)/(massLSC*(restLengthSquared+len)))*kst;
|
||||
}
|
||||
|
||||
position0 = position0 - del*(k*inverseMass0);
|
||||
position1 = position1 + del*(k*inverseMass1);
|
||||
|
||||
// Ensure compiler does not re-order memory operations
|
||||
barrier(CLK_LOCAL_MEM_FENCE);
|
||||
|
||||
vertexPositionSharedData[vertexAddress0] = position0;
|
||||
vertexPositionSharedData[vertexAddress1] = position1;
|
||||
|
||||
// Ensure compiler does not re-order memory operations
|
||||
barrier(CLK_LOCAL_MEM_FENCE);
|
||||
|
||||
|
||||
++batch;
|
||||
} while( batch < batchesWithinWavefront );
|
||||
|
||||
// Update the global memory vertices for the wavefronts
|
||||
for( int vertex = laneInWavefront; vertex < verticesUsedByWave; vertex+=WAVEFRONT_SIZE )
|
||||
{
|
||||
int vertexAddress = g_vertexAddressesPerWavefront[wavefront*MAX_NUM_VERTICES_PER_WAVE + vertex];
|
||||
|
||||
g_vertexPositions[vertexAddress] = (float4)(vertexPositionSharedData[localWavefront*MAX_NUM_VERTICES_PER_WAVE + vertex].xyz, 0.f);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
);
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
MSTRINGIFY(
|
||||
|
||||
/*#define float3 float4
|
||||
|
||||
float dot3(float3 a, float3 b)
|
||||
{
|
||||
return a.x*b.x + a.y*b.y + a.z*b.z;
|
||||
}*/
|
||||
|
||||
__kernel void
|
||||
UpdateConstantsKernel(
|
||||
const int numLinks,
|
||||
__global int2 * g_linksVertexIndices,
|
||||
__global float4 * g_vertexPositions,
|
||||
__global float * g_vertexInverseMasses,
|
||||
__global float * g_linksMaterialLSC,
|
||||
__global float * g_linksMassLSC,
|
||||
__global float * g_linksRestLengthSquared,
|
||||
__global float * g_linksRestLengths)
|
||||
{
|
||||
int linkID = get_global_id(0);
|
||||
if( linkID < numLinks )
|
||||
{
|
||||
int2 nodeIndices = g_linksVertexIndices[linkID];
|
||||
int node0 = nodeIndices.x;
|
||||
int node1 = nodeIndices.y;
|
||||
float linearStiffnessCoefficient = g_linksMaterialLSC[ linkID ];
|
||||
|
||||
float3 position0 = g_vertexPositions[node0].xyz;
|
||||
float3 position1 = g_vertexPositions[node1].xyz;
|
||||
float inverseMass0 = g_vertexInverseMasses[node0];
|
||||
float inverseMass1 = g_vertexInverseMasses[node1];
|
||||
|
||||
float3 difference = position0 - position1;
|
||||
float length2 = dot(difference, difference);
|
||||
float length = sqrt(length2);
|
||||
|
||||
g_linksRestLengths[linkID] = length;
|
||||
g_linksMassLSC[linkID] = (inverseMass0 + inverseMass1)/linearStiffnessCoefficient;
|
||||
g_linksRestLengthSquared[linkID] = length*length;
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
MSTRINGIFY(
|
||||
|
||||
__kernel void
|
||||
UpdateFixedVertexPositions(
|
||||
const uint numNodes,
|
||||
__global int * g_anchorIndex,
|
||||
__global float4 * g_vertexPositions,
|
||||
__global float4 * g_anchorPositions GUID_ARG)
|
||||
{
|
||||
unsigned int nodeID = get_global_id(0);
|
||||
|
||||
if( nodeID < numNodes )
|
||||
{
|
||||
int anchorIndex = g_anchorIndex[nodeID];
|
||||
float4 position = g_vertexPositions[nodeID];
|
||||
|
||||
if ( anchorIndex >= 0 )
|
||||
{
|
||||
float4 anchorPosition = g_anchorPositions[anchorIndex];
|
||||
g_vertexPositions[nodeID] = anchorPosition;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
MSTRINGIFY(
|
||||
|
||||
|
||||
__kernel void
|
||||
updateVelocitiesFromPositionsWithVelocitiesKernel(
|
||||
int numNodes,
|
||||
float isolverdt,
|
||||
__global float4 * g_vertexPositions,
|
||||
__global float4 * g_vertexPreviousPositions,
|
||||
__global int * g_vertexClothIndices,
|
||||
__global float *g_clothVelocityCorrectionCoefficients,
|
||||
__global float * g_clothDampingFactor,
|
||||
__global float4 * g_vertexVelocities,
|
||||
__global float4 * g_vertexForces GUID_ARG)
|
||||
{
|
||||
int nodeID = get_global_id(0);
|
||||
if( nodeID < numNodes )
|
||||
{
|
||||
float4 position = g_vertexPositions[nodeID];
|
||||
float4 previousPosition = g_vertexPreviousPositions[nodeID];
|
||||
float4 velocity = g_vertexVelocities[nodeID];
|
||||
int clothIndex = g_vertexClothIndices[nodeID];
|
||||
float velocityCorrectionCoefficient = g_clothVelocityCorrectionCoefficients[clothIndex];
|
||||
float dampingFactor = g_clothDampingFactor[clothIndex];
|
||||
float velocityCoefficient = (1.f - dampingFactor);
|
||||
|
||||
float4 difference = position - previousPosition;
|
||||
|
||||
velocity += difference*velocityCorrectionCoefficient*isolverdt;
|
||||
|
||||
// Damp the velocity
|
||||
velocity *= velocityCoefficient;
|
||||
|
||||
g_vertexVelocities[nodeID] = velocity;
|
||||
g_vertexForces[nodeID] = (float4)(0.f, 0.f, 0.f, 0.f);
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
MSTRINGIFY(
|
||||
|
||||
float length3(float4 a)
|
||||
{
|
||||
a.w = 0;
|
||||
return length(a);
|
||||
}
|
||||
|
||||
float4 normalize3(float4 a)
|
||||
{
|
||||
a.w = 0;
|
||||
return normalize(a);
|
||||
}
|
||||
|
||||
__kernel void
|
||||
ResetNormalsAndAreasKernel(
|
||||
const unsigned int numNodes,
|
||||
__global float4 * g_vertexNormals,
|
||||
__global float * g_vertexArea GUID_ARG)
|
||||
{
|
||||
if( get_global_id(0) < numNodes )
|
||||
{
|
||||
g_vertexNormals[get_global_id(0)] = (float4)(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
g_vertexArea[get_global_id(0)] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
__kernel void
|
||||
UpdateSoftBodiesKernel(
|
||||
const unsigned int startFace,
|
||||
const unsigned int numFaces,
|
||||
__global int4 * g_triangleVertexIndexSet,
|
||||
__global float4 * g_vertexPositions,
|
||||
__global float4 * g_vertexNormals,
|
||||
__global float * g_vertexArea,
|
||||
__global float4 * g_triangleNormals,
|
||||
__global float * g_triangleArea GUID_ARG)
|
||||
{
|
||||
int faceID = get_global_id(0) + startFace;
|
||||
if( get_global_id(0) < numFaces )
|
||||
{
|
||||
int4 triangleIndexSet = g_triangleVertexIndexSet[ faceID ];
|
||||
int nodeIndex0 = triangleIndexSet.x;
|
||||
int nodeIndex1 = triangleIndexSet.y;
|
||||
int nodeIndex2 = triangleIndexSet.z;
|
||||
|
||||
float4 node0 = g_vertexPositions[nodeIndex0];
|
||||
float4 node1 = g_vertexPositions[nodeIndex1];
|
||||
float4 node2 = g_vertexPositions[nodeIndex2];
|
||||
float4 nodeNormal0 = g_vertexNormals[nodeIndex0];
|
||||
float4 nodeNormal1 = g_vertexNormals[nodeIndex1];
|
||||
float4 nodeNormal2 = g_vertexNormals[nodeIndex2];
|
||||
float vertexArea0 = g_vertexArea[nodeIndex0];
|
||||
float vertexArea1 = g_vertexArea[nodeIndex1];
|
||||
float vertexArea2 = g_vertexArea[nodeIndex2];
|
||||
|
||||
float4 vector0 = node1 - node0;
|
||||
float4 vector1 = node2 - node0;
|
||||
|
||||
float4 faceNormal = cross(vector0, vector1);
|
||||
float triangleArea = length(faceNormal);
|
||||
|
||||
nodeNormal0 = nodeNormal0 + faceNormal;
|
||||
nodeNormal1 = nodeNormal1 + faceNormal;
|
||||
nodeNormal2 = nodeNormal2 + faceNormal;
|
||||
vertexArea0 = vertexArea0 + triangleArea;
|
||||
vertexArea1 = vertexArea1 + triangleArea;
|
||||
vertexArea2 = vertexArea2 + triangleArea;
|
||||
|
||||
g_triangleNormals[faceID] = normalize3(faceNormal);
|
||||
g_vertexNormals[nodeIndex0] = nodeNormal0;
|
||||
g_vertexNormals[nodeIndex1] = nodeNormal1;
|
||||
g_vertexNormals[nodeIndex2] = nodeNormal2;
|
||||
g_triangleArea[faceID] = triangleArea;
|
||||
g_vertexArea[nodeIndex0] = vertexArea0;
|
||||
g_vertexArea[nodeIndex1] = vertexArea1;
|
||||
g_vertexArea[nodeIndex2] = vertexArea2;
|
||||
}
|
||||
}
|
||||
|
||||
__kernel void
|
||||
NormalizeNormalsAndAreasKernel(
|
||||
const unsigned int numNodes,
|
||||
__global int * g_vertexTriangleCount,
|
||||
__global float4 * g_vertexNormals,
|
||||
__global float * g_vertexArea GUID_ARG)
|
||||
{
|
||||
if( get_global_id(0) < numNodes )
|
||||
{
|
||||
float4 normal = g_vertexNormals[get_global_id(0)];
|
||||
float area = g_vertexArea[get_global_id(0)];
|
||||
int numTriangles = g_vertexTriangleCount[get_global_id(0)];
|
||||
|
||||
float vectorLength = length3(normal);
|
||||
|
||||
g_vertexNormals[get_global_id(0)] = normalize3(normal);
|
||||
g_vertexArea[get_global_id(0)] = area/(float)(numTriangles);
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
MSTRINGIFY(
|
||||
|
||||
__kernel void
|
||||
updateVelocitiesFromPositionsWithoutVelocitiesKernel(
|
||||
const int numNodes,
|
||||
const float isolverdt,
|
||||
__global float4 * g_vertexPositions,
|
||||
__global float4 * g_vertexPreviousPositions,
|
||||
__global int * g_vertexClothIndices,
|
||||
__global float * g_clothDampingFactor,
|
||||
__global float4 * g_vertexVelocities,
|
||||
__global float4 * g_vertexForces GUID_ARG)
|
||||
|
||||
{
|
||||
int nodeID = get_global_id(0);
|
||||
if( nodeID < numNodes )
|
||||
{
|
||||
float4 position = g_vertexPositions[nodeID];
|
||||
float4 previousPosition = g_vertexPreviousPositions[nodeID];
|
||||
float4 velocity = g_vertexVelocities[nodeID];
|
||||
int clothIndex = g_vertexClothIndices[nodeID];
|
||||
float dampingFactor = g_clothDampingFactor[clothIndex];
|
||||
float velocityCoefficient = (1.f - dampingFactor);
|
||||
|
||||
float4 difference = position - previousPosition;
|
||||
|
||||
velocity = difference*velocityCoefficient*isolverdt;
|
||||
|
||||
g_vertexVelocities[nodeID] = velocity;
|
||||
g_vertexForces[nodeID] = (float4)(0.f, 0.f, 0.f, 0.f);
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
|
||||
MSTRINGIFY(
|
||||
|
||||
|
||||
|
||||
|
||||
__kernel void
|
||||
UpdatePositionsFromVelocitiesKernel(
|
||||
const int numNodes,
|
||||
const float solverSDT,
|
||||
__global float4 * g_vertexVelocities,
|
||||
__global float4 * g_vertexPreviousPositions,
|
||||
__global float4 * g_vertexCurrentPosition GUID_ARG)
|
||||
{
|
||||
int vertexID = get_global_id(0);
|
||||
if( vertexID < numNodes )
|
||||
{
|
||||
float4 previousPosition = g_vertexPreviousPositions[vertexID];
|
||||
float4 velocity = g_vertexVelocities[vertexID];
|
||||
|
||||
float4 newPosition = previousPosition + velocity*solverSDT;
|
||||
|
||||
g_vertexCurrentPosition[vertexID] = newPosition;
|
||||
g_vertexPreviousPositions[vertexID] = newPosition;
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
MSTRINGIFY(
|
||||
|
||||
__kernel void
|
||||
VSolveLinksKernel(
|
||||
int startLink,
|
||||
int numLinks,
|
||||
float kst,
|
||||
__global int2 * g_linksVertexIndices,
|
||||
__global float * g_linksLengthRatio,
|
||||
__global float4 * g_linksCurrentLength,
|
||||
__global float * g_vertexInverseMass,
|
||||
__global float4 * g_vertexVelocity GUID_ARG)
|
||||
{
|
||||
int linkID = get_global_id(0) + startLink;
|
||||
if( get_global_id(0) < numLinks )
|
||||
{
|
||||
int2 nodeIndices = g_linksVertexIndices[linkID];
|
||||
int node0 = nodeIndices.x;
|
||||
int node1 = nodeIndices.y;
|
||||
|
||||
float linkLengthRatio = g_linksLengthRatio[linkID];
|
||||
float3 linkCurrentLength = g_linksCurrentLength[linkID].xyz;
|
||||
|
||||
float3 vertexVelocity0 = g_vertexVelocity[node0].xyz;
|
||||
float3 vertexVelocity1 = g_vertexVelocity[node1].xyz;
|
||||
|
||||
float vertexInverseMass0 = g_vertexInverseMass[node0];
|
||||
float vertexInverseMass1 = g_vertexInverseMass[node1];
|
||||
|
||||
float3 nodeDifference = vertexVelocity0 - vertexVelocity1;
|
||||
float dotResult = dot(linkCurrentLength, nodeDifference);
|
||||
float j = -dotResult*linkLengthRatio*kst;
|
||||
|
||||
float3 velocityChange0 = linkCurrentLength*(j*vertexInverseMass0);
|
||||
float3 velocityChange1 = linkCurrentLength*(j*vertexInverseMass1);
|
||||
|
||||
vertexVelocity0 += velocityChange0;
|
||||
vertexVelocity1 -= velocityChange1;
|
||||
|
||||
g_vertexVelocity[node0] = (float4)(vertexVelocity0, 0.f);
|
||||
g_vertexVelocity[node1] = (float4)(vertexVelocity1, 0.f);
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
+209
@@ -0,0 +1,209 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef BT_SOFT_BODY_SOLVER_BUFFER_OPENCL_H
|
||||
#define BT_SOFT_BODY_SOLVER_BUFFER_OPENCL_H
|
||||
|
||||
// OpenCL support
|
||||
|
||||
#ifdef USE_MINICL
|
||||
#include "MiniCL/cl.h"
|
||||
#else //USE_MINICL
|
||||
#ifdef __APPLE__
|
||||
#include <OpenCL/OpenCL.h>
|
||||
#else
|
||||
#include <CL/cl.h>
|
||||
#endif //__APPLE__
|
||||
#endif//USE_MINICL
|
||||
|
||||
#ifndef SAFE_RELEASE
|
||||
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
|
||||
#endif
|
||||
|
||||
template <typename ElementType> class btOpenCLBuffer
|
||||
{
|
||||
public:
|
||||
|
||||
cl_command_queue m_cqCommandQue;
|
||||
cl_context m_clContext;
|
||||
cl_mem m_buffer;
|
||||
|
||||
|
||||
|
||||
btAlignedObjectArray< ElementType > * m_CPUBuffer;
|
||||
|
||||
int m_gpuSize;
|
||||
bool m_onGPU;
|
||||
bool m_readOnlyOnGPU;
|
||||
bool m_allocated;
|
||||
|
||||
|
||||
bool createBuffer( cl_mem* preexistingBuffer = 0)
|
||||
{
|
||||
|
||||
cl_int err;
|
||||
|
||||
|
||||
if( preexistingBuffer )
|
||||
{
|
||||
m_buffer = *preexistingBuffer;
|
||||
}
|
||||
else {
|
||||
|
||||
cl_mem_flags flags= m_readOnlyOnGPU ? CL_MEM_READ_ONLY : CL_MEM_READ_WRITE;
|
||||
|
||||
size_t size = m_CPUBuffer->size() * sizeof(ElementType);
|
||||
// At a minimum the buffer must exist
|
||||
if( size == 0 )
|
||||
size = sizeof(ElementType);
|
||||
m_buffer = clCreateBuffer(m_clContext, flags, size, 0, &err);
|
||||
if( err != CL_SUCCESS )
|
||||
{
|
||||
btAssert( "Buffer::Buffer(m_buffer)");
|
||||
}
|
||||
}
|
||||
|
||||
m_gpuSize = m_CPUBuffer->size();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
btOpenCLBuffer( cl_command_queue commandQue,cl_context ctx, btAlignedObjectArray< ElementType >* CPUBuffer, bool readOnly)
|
||||
:m_cqCommandQue(commandQue),
|
||||
m_clContext(ctx),
|
||||
m_buffer(0),
|
||||
m_CPUBuffer(CPUBuffer),
|
||||
m_gpuSize(0),
|
||||
m_onGPU(false),
|
||||
m_readOnlyOnGPU(readOnly),
|
||||
m_allocated(false)
|
||||
{
|
||||
}
|
||||
|
||||
~btOpenCLBuffer()
|
||||
{
|
||||
clReleaseMemObject(m_buffer);
|
||||
}
|
||||
|
||||
|
||||
bool moveToGPU()
|
||||
{
|
||||
|
||||
|
||||
cl_int err;
|
||||
|
||||
if( (m_CPUBuffer->size() != m_gpuSize) )
|
||||
{
|
||||
m_onGPU = false;
|
||||
}
|
||||
|
||||
if( !m_allocated && m_CPUBuffer->size() == 0 )
|
||||
{
|
||||
// If it isn't on the GPU and yet there is no data on the CPU side this may cause a problem with some kernels.
|
||||
// We should create *something* on the device side
|
||||
if (!createBuffer()) {
|
||||
return false;
|
||||
}
|
||||
m_allocated = true;
|
||||
}
|
||||
|
||||
if( !m_onGPU && m_CPUBuffer->size() > 0 )
|
||||
{
|
||||
if (!m_allocated || (m_CPUBuffer->size() != m_gpuSize)) {
|
||||
if (!createBuffer()) {
|
||||
return false;
|
||||
}
|
||||
m_allocated = true;
|
||||
}
|
||||
|
||||
size_t size = m_CPUBuffer->size() * sizeof(ElementType);
|
||||
err = clEnqueueWriteBuffer(m_cqCommandQue,m_buffer,
|
||||
CL_FALSE,
|
||||
0,
|
||||
size,
|
||||
&((*m_CPUBuffer)[0]),0,0,0);
|
||||
if( err != CL_SUCCESS )
|
||||
{
|
||||
btAssert( "CommandQueue::enqueueWriteBuffer(m_buffer)" );
|
||||
}
|
||||
|
||||
m_onGPU = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool moveFromGPU()
|
||||
{
|
||||
|
||||
cl_int err;
|
||||
|
||||
if (m_CPUBuffer->size() > 0) {
|
||||
if (m_onGPU && !m_readOnlyOnGPU) {
|
||||
size_t size = m_CPUBuffer->size() * sizeof(ElementType);
|
||||
err = clEnqueueReadBuffer(m_cqCommandQue,
|
||||
m_buffer,
|
||||
CL_TRUE,
|
||||
0,
|
||||
size,
|
||||
&((*m_CPUBuffer)[0]),0,0,0);
|
||||
|
||||
if( err != CL_SUCCESS )
|
||||
{
|
||||
btAssert( "CommandQueue::enqueueReadBuffer(m_buffer)" );
|
||||
}
|
||||
|
||||
m_onGPU = false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool copyFromGPU()
|
||||
{
|
||||
|
||||
cl_int err;
|
||||
size_t size = m_CPUBuffer->size() * sizeof(ElementType);
|
||||
|
||||
if (m_CPUBuffer->size() > 0) {
|
||||
if (m_onGPU && !m_readOnlyOnGPU) {
|
||||
err = clEnqueueReadBuffer(m_cqCommandQue,
|
||||
m_buffer,
|
||||
CL_TRUE,
|
||||
0,size,
|
||||
&((*m_CPUBuffer)[0]),0,0,0);
|
||||
|
||||
if( err != CL_SUCCESS )
|
||||
{
|
||||
btAssert( "CommandQueue::enqueueReadBuffer(m_buffer)");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void changedOnCPU()
|
||||
{
|
||||
m_onGPU = false;
|
||||
}
|
||||
}; // class btOpenCLBuffer
|
||||
|
||||
|
||||
#endif // #ifndef BT_SOFT_BODY_SOLVER_BUFFER_OPENCL_H
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "BulletMultiThreaded/GpuSoftBodySolvers/Shared/btSoftBodySolverData.h"
|
||||
#include "btSoftBodySolverBuffer_OpenCL.h"
|
||||
|
||||
|
||||
#ifndef BT_SOFT_BODY_SOLVER_LINK_DATA_OPENCL_H
|
||||
#define BT_SOFT_BODY_SOLVER_LINK_DATA_OPENCL_H
|
||||
|
||||
|
||||
class btSoftBodyLinkDataOpenCL : public btSoftBodyLinkData
|
||||
{
|
||||
public:
|
||||
bool m_onGPU;
|
||||
|
||||
cl_command_queue m_cqCommandQue;
|
||||
|
||||
|
||||
btOpenCLBuffer<LinkNodePair> m_clLinks;
|
||||
btOpenCLBuffer<float> m_clLinkStrength;
|
||||
btOpenCLBuffer<float> m_clLinksMassLSC;
|
||||
btOpenCLBuffer<float> m_clLinksRestLengthSquared;
|
||||
btOpenCLBuffer<Vectormath::Aos::Vector3> m_clLinksCLength;
|
||||
btOpenCLBuffer<float> m_clLinksLengthRatio;
|
||||
btOpenCLBuffer<float> m_clLinksRestLength;
|
||||
btOpenCLBuffer<float> m_clLinksMaterialLinearStiffnessCoefficient;
|
||||
|
||||
struct BatchPair
|
||||
{
|
||||
int start;
|
||||
int length;
|
||||
|
||||
BatchPair() :
|
||||
start(0),
|
||||
length(0)
|
||||
{
|
||||
}
|
||||
|
||||
BatchPair( int s, int l ) :
|
||||
start( s ),
|
||||
length( l )
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Link addressing information for each cloth.
|
||||
* Allows link locations to be computed independently of data batching.
|
||||
*/
|
||||
btAlignedObjectArray< int > m_linkAddresses;
|
||||
|
||||
/**
|
||||
* Start and length values for computation batches over link data.
|
||||
*/
|
||||
btAlignedObjectArray< BatchPair > m_batchStartLengths;
|
||||
|
||||
btSoftBodyLinkDataOpenCL(cl_command_queue queue, cl_context ctx);
|
||||
|
||||
virtual ~btSoftBodyLinkDataOpenCL();
|
||||
|
||||
/** Allocate enough space in all link-related arrays to fit numLinks links */
|
||||
virtual void createLinks( int numLinks );
|
||||
|
||||
/** Insert the link described into the correct data structures assuming space has already been allocated by a call to createLinks */
|
||||
virtual void setLinkAt(
|
||||
const LinkDescription &link,
|
||||
int linkIndex );
|
||||
|
||||
virtual bool onAccelerator();
|
||||
|
||||
virtual bool moveToAccelerator();
|
||||
|
||||
virtual bool moveFromAccelerator();
|
||||
|
||||
/**
|
||||
* Generate (and later update) the batching for the entire link set.
|
||||
* This redoes a lot of work because it batches the entire set when each cloth is inserted.
|
||||
* In theory we could delay it until just before we need the cloth.
|
||||
* It's a one-off overhead, though, so that is a later optimisation.
|
||||
*/
|
||||
void generateBatches();
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // #ifndef BT_SOFT_BODY_SOLVER_LINK_DATA_OPENCL_H
|
||||
+169
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "BulletMultiThreaded/GpuSoftBodySolvers/Shared/btSoftBodySolverData.h"
|
||||
#include "btSoftBodySolverBuffer_OpenCL.h"
|
||||
|
||||
|
||||
#ifndef BT_SOFT_BODY_SOLVER_LINK_DATA_OPENCL_SIMDAWARE_H
|
||||
#define BT_SOFT_BODY_SOLVER_LINK_DATA_OPENCL_SIMDAWARE_H
|
||||
|
||||
|
||||
class btSoftBodyLinkDataOpenCLSIMDAware : public btSoftBodyLinkData
|
||||
{
|
||||
public:
|
||||
bool m_onGPU;
|
||||
|
||||
cl_command_queue m_cqCommandQue;
|
||||
|
||||
const int m_wavefrontSize;
|
||||
const int m_linksPerWorkItem;
|
||||
const int m_maxLinksPerWavefront;
|
||||
int m_maxBatchesWithinWave;
|
||||
int m_maxVerticesWithinWave;
|
||||
int m_numWavefronts;
|
||||
|
||||
int m_maxVertex;
|
||||
|
||||
struct NumBatchesVerticesPair
|
||||
{
|
||||
int numBatches;
|
||||
int numVertices;
|
||||
};
|
||||
|
||||
btAlignedObjectArray<int> m_linksPerWavefront;
|
||||
btAlignedObjectArray<NumBatchesVerticesPair> m_numBatchesAndVerticesWithinWaves;
|
||||
btOpenCLBuffer< NumBatchesVerticesPair > m_clNumBatchesAndVerticesWithinWaves;
|
||||
|
||||
// All arrays here will contain batches of m_maxLinksPerWavefront links
|
||||
// ordered by wavefront.
|
||||
// with either global vertex pairs or local vertex pairs
|
||||
btAlignedObjectArray< int > m_wavefrontVerticesGlobalAddresses; // List of global vertices per wavefront
|
||||
btOpenCLBuffer<int> m_clWavefrontVerticesGlobalAddresses;
|
||||
btAlignedObjectArray< LinkNodePair > m_linkVerticesLocalAddresses; // Vertex pair for the link
|
||||
btOpenCLBuffer<LinkNodePair> m_clLinkVerticesLocalAddresses;
|
||||
btOpenCLBuffer<float> m_clLinkStrength;
|
||||
btOpenCLBuffer<float> m_clLinksMassLSC;
|
||||
btOpenCLBuffer<float> m_clLinksRestLengthSquared;
|
||||
btOpenCLBuffer<float> m_clLinksRestLength;
|
||||
btOpenCLBuffer<float> m_clLinksMaterialLinearStiffnessCoefficient;
|
||||
|
||||
struct BatchPair
|
||||
{
|
||||
int start;
|
||||
int length;
|
||||
|
||||
BatchPair() :
|
||||
start(0),
|
||||
length(0)
|
||||
{
|
||||
}
|
||||
|
||||
BatchPair( int s, int l ) :
|
||||
start( s ),
|
||||
length( l )
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Link addressing information for each cloth.
|
||||
* Allows link locations to be computed independently of data batching.
|
||||
*/
|
||||
btAlignedObjectArray< int > m_linkAddresses;
|
||||
|
||||
/**
|
||||
* Start and length values for computation batches over link data.
|
||||
*/
|
||||
btAlignedObjectArray< BatchPair > m_wavefrontBatchStartLengths;
|
||||
|
||||
btSoftBodyLinkDataOpenCLSIMDAware(cl_command_queue queue, cl_context ctx);
|
||||
|
||||
virtual ~btSoftBodyLinkDataOpenCLSIMDAware();
|
||||
|
||||
/** Allocate enough space in all link-related arrays to fit numLinks links */
|
||||
virtual void createLinks( int numLinks );
|
||||
|
||||
/** Insert the link described into the correct data structures assuming space has already been allocated by a call to createLinks */
|
||||
virtual void setLinkAt(
|
||||
const LinkDescription &link,
|
||||
int linkIndex );
|
||||
|
||||
virtual bool onAccelerator();
|
||||
|
||||
virtual bool moveToAccelerator();
|
||||
|
||||
virtual bool moveFromAccelerator();
|
||||
|
||||
/**
|
||||
* Generate (and later update) the batching for the entire link set.
|
||||
* This redoes a lot of work because it batches the entire set when each cloth is inserted.
|
||||
* In theory we could delay it until just before we need the cloth.
|
||||
* It's a one-off overhead, though, so that is a later optimisation.
|
||||
*/
|
||||
void generateBatches();
|
||||
|
||||
int getMaxVerticesPerWavefront()
|
||||
{
|
||||
return m_maxVerticesWithinWave;
|
||||
}
|
||||
|
||||
int getWavefrontSize()
|
||||
{
|
||||
return m_wavefrontSize;
|
||||
}
|
||||
|
||||
int getLinksPerWorkItem()
|
||||
{
|
||||
return m_linksPerWorkItem;
|
||||
}
|
||||
|
||||
int getMaxLinksPerWavefront()
|
||||
{
|
||||
return m_maxLinksPerWavefront;
|
||||
}
|
||||
|
||||
int getMaxBatchesPerWavefront()
|
||||
{
|
||||
return m_maxBatchesWithinWave;
|
||||
}
|
||||
|
||||
int getNumWavefronts()
|
||||
{
|
||||
return m_numWavefronts;
|
||||
}
|
||||
|
||||
NumBatchesVerticesPair getNumBatchesAndVerticesWithinWavefront( int wavefront )
|
||||
{
|
||||
return m_numBatchesAndVerticesWithinWaves[wavefront];
|
||||
}
|
||||
|
||||
int getVertexGlobalAddresses( int vertexIndex )
|
||||
{
|
||||
return m_wavefrontVerticesGlobalAddresses[vertexIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get post-batching local addresses of the vertex pair for a link assuming all vertices used by a wavefront are loaded locally.
|
||||
*/
|
||||
LinkNodePair getVertexPairLocalAddresses( int linkIndex )
|
||||
{
|
||||
return m_linkVerticesLocalAddresses[linkIndex];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // #ifndef BT_SOFT_BODY_SOLVER_LINK_DATA_OPENCL_SIMDAWARE_H
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
#include "btSoftBodySolverOutputCLtoGL.h"
|
||||
#include <stdio.h> //@todo: remove the debugging printf at some stage
|
||||
#include "btSoftBodySolver_OpenCL.h"
|
||||
#include "BulletSoftBody/btSoftBodySolverVertexBuffer.h"
|
||||
#include "btSoftBodySolverVertexBuffer_OpenGL.h"
|
||||
#include "BulletSoftBody/btSoftBody.h"
|
||||
|
||||
////OpenCL 1.0 kernels don't use float3
|
||||
#define MSTRINGIFY(A) #A
|
||||
static char* OutputToVertexArrayCLString =
|
||||
#include "OpenCLC10/OutputToVertexArray.cl"
|
||||
|
||||
|
||||
#define RELEASE_CL_KERNEL(kernelName) {if( kernelName ){ clReleaseKernel( kernelName ); kernelName = 0; }}
|
||||
|
||||
static const size_t workGroupSize = 128;
|
||||
|
||||
void btSoftBodySolverOutputCLtoGL::copySoftBodyToVertexBuffer( const btSoftBody * const softBody, btVertexBufferDescriptor *vertexBuffer )
|
||||
{
|
||||
|
||||
btSoftBodySolver *solver = softBody->getSoftBodySolver();
|
||||
btAssert( solver->getSolverType() == btSoftBodySolver::CL_SOLVER || solver->getSolverType() == btSoftBodySolver::CL_SIMD_SOLVER );
|
||||
btOpenCLSoftBodySolver *dxSolver = static_cast< btOpenCLSoftBodySolver * >( solver );
|
||||
checkInitialized();
|
||||
btOpenCLAcceleratedSoftBodyInterface* currentCloth = dxSolver->findSoftBodyInterface( softBody );
|
||||
btSoftBodyVertexDataOpenCL &vertexData( dxSolver->m_vertexData );
|
||||
|
||||
const int firstVertex = currentCloth->getFirstVertex();
|
||||
const int lastVertex = firstVertex + currentCloth->getNumVertices();
|
||||
|
||||
if( vertexBuffer->getBufferType() == btVertexBufferDescriptor::OPENGL_BUFFER ) {
|
||||
|
||||
const btOpenGLInteropVertexBufferDescriptor *openGLVertexBuffer = static_cast< btOpenGLInteropVertexBufferDescriptor* >(vertexBuffer);
|
||||
cl_int ciErrNum = CL_SUCCESS;
|
||||
|
||||
cl_mem clBuffer = openGLVertexBuffer->getBuffer();
|
||||
cl_kernel outputKernel = outputToVertexArrayWithNormalsKernel;
|
||||
if( !vertexBuffer->hasNormals() )
|
||||
outputKernel = outputToVertexArrayWithoutNormalsKernel;
|
||||
|
||||
ciErrNum = clEnqueueAcquireGLObjects(m_cqCommandQue, 1, &clBuffer, 0, 0, NULL);
|
||||
if( ciErrNum != CL_SUCCESS )
|
||||
{
|
||||
btAssert( 0 && "clEnqueueAcquireGLObjects(copySoftBodyToVertexBuffer)");
|
||||
}
|
||||
|
||||
int numVertices = currentCloth->getNumVertices();
|
||||
|
||||
ciErrNum = clSetKernelArg(outputKernel, 0, sizeof(int), &firstVertex );
|
||||
ciErrNum = clSetKernelArg(outputKernel, 1, sizeof(int), &numVertices );
|
||||
ciErrNum = clSetKernelArg(outputKernel, 2, sizeof(cl_mem), (void*)&clBuffer );
|
||||
if( vertexBuffer->hasVertexPositions() )
|
||||
{
|
||||
int vertexOffset = vertexBuffer->getVertexOffset();
|
||||
int vertexStride = vertexBuffer->getVertexStride();
|
||||
ciErrNum = clSetKernelArg(outputKernel, 3, sizeof(int), &vertexOffset );
|
||||
ciErrNum = clSetKernelArg(outputKernel, 4, sizeof(int), &vertexStride );
|
||||
ciErrNum = clSetKernelArg(outputKernel, 5, sizeof(cl_mem), (void*)&vertexData.m_clVertexPosition.m_buffer );
|
||||
|
||||
}
|
||||
if( vertexBuffer->hasNormals() )
|
||||
{
|
||||
int normalOffset = vertexBuffer->getNormalOffset();
|
||||
int normalStride = vertexBuffer->getNormalStride();
|
||||
ciErrNum = clSetKernelArg(outputKernel, 6, sizeof(int), &normalOffset );
|
||||
ciErrNum = clSetKernelArg(outputKernel, 7, sizeof(int), &normalStride );
|
||||
ciErrNum = clSetKernelArg(outputKernel, 8, sizeof(cl_mem), (void*)&vertexData.m_clVertexNormal.m_buffer );
|
||||
|
||||
}
|
||||
size_t numWorkItems = workGroupSize*((vertexData.getNumVertices() + (workGroupSize-1)) / workGroupSize);
|
||||
ciErrNum = clEnqueueNDRangeKernel(m_cqCommandQue, outputKernel, 1, NULL, &numWorkItems, &workGroupSize,0 ,0 ,0);
|
||||
if( ciErrNum != CL_SUCCESS )
|
||||
{
|
||||
btAssert( 0 && "enqueueNDRangeKernel(copySoftBodyToVertexBuffer)");
|
||||
}
|
||||
|
||||
ciErrNum = clEnqueueReleaseGLObjects(m_cqCommandQue, 1, &clBuffer, 0, 0, 0);
|
||||
if( ciErrNum != CL_SUCCESS )
|
||||
{
|
||||
btAssert( 0 && "clEnqueueReleaseGLObjects(copySoftBodyToVertexBuffer)");
|
||||
}
|
||||
} else {
|
||||
btAssert( "Undefined output for this solver output" == false );
|
||||
}
|
||||
|
||||
// clFinish in here may not be the best thing. It's possible that we should have a waitForFrameComplete function.
|
||||
clFinish(m_cqCommandQue);
|
||||
|
||||
} // btSoftBodySolverOutputCLtoGL::outputToVertexBuffers
|
||||
|
||||
bool btSoftBodySolverOutputCLtoGL::buildShaders()
|
||||
{
|
||||
// Ensure current kernels are released first
|
||||
releaseKernels();
|
||||
|
||||
bool returnVal = true;
|
||||
|
||||
if( m_shadersInitialized )
|
||||
return true;
|
||||
|
||||
outputToVertexArrayWithNormalsKernel = clFunctions.compileCLKernelFromString( OutputToVertexArrayCLString, "OutputToVertexArrayWithNormalsKernel" ,"","OpenCLC10/OutputToVertexArray.cl");
|
||||
outputToVertexArrayWithoutNormalsKernel = clFunctions.compileCLKernelFromString( OutputToVertexArrayCLString, "OutputToVertexArrayWithoutNormalsKernel" ,"","OpenCLC10/OutputToVertexArray.cl");
|
||||
|
||||
|
||||
if( returnVal )
|
||||
m_shadersInitialized = true;
|
||||
|
||||
return returnVal;
|
||||
} // btSoftBodySolverOutputCLtoGL::buildShaders
|
||||
|
||||
void btSoftBodySolverOutputCLtoGL::releaseKernels()
|
||||
{
|
||||
RELEASE_CL_KERNEL( outputToVertexArrayWithNormalsKernel );
|
||||
RELEASE_CL_KERNEL( outputToVertexArrayWithoutNormalsKernel );
|
||||
|
||||
m_shadersInitialized = false;
|
||||
} // btSoftBodySolverOutputCLtoGL::releaseKernels
|
||||
|
||||
bool btSoftBodySolverOutputCLtoGL::checkInitialized()
|
||||
{
|
||||
if( !m_shadersInitialized )
|
||||
if( buildShaders() )
|
||||
m_shadersInitialized = true;
|
||||
|
||||
return m_shadersInitialized;
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef BT_SOFT_BODY_SOLVER_OUTPUT_CL_TO_GL_H
|
||||
#define BT_SOFT_BODY_SOLVER_OUTPUT_CL_TO_GL_H
|
||||
|
||||
#include "btSoftBodySolver_OpenCL.h"
|
||||
|
||||
/**
|
||||
* Class to manage movement of data from a solver to a given target.
|
||||
* This version is the CL to GL interop version.
|
||||
*/
|
||||
class btSoftBodySolverOutputCLtoGL : public btSoftBodySolverOutput
|
||||
{
|
||||
protected:
|
||||
cl_command_queue m_cqCommandQue;
|
||||
cl_context m_cxMainContext;
|
||||
CLFunctions clFunctions;
|
||||
|
||||
cl_kernel outputToVertexArrayWithNormalsKernel;
|
||||
cl_kernel outputToVertexArrayWithoutNormalsKernel;
|
||||
|
||||
bool m_shadersInitialized;
|
||||
|
||||
virtual bool checkInitialized();
|
||||
virtual bool buildShaders();
|
||||
void releaseKernels();
|
||||
public:
|
||||
btSoftBodySolverOutputCLtoGL(cl_command_queue cqCommandQue, cl_context cxMainContext) :
|
||||
m_cqCommandQue( cqCommandQue ),
|
||||
m_cxMainContext( cxMainContext ),
|
||||
clFunctions(cqCommandQue, cxMainContext),
|
||||
outputToVertexArrayWithNormalsKernel( 0 ),
|
||||
outputToVertexArrayWithoutNormalsKernel( 0 ),
|
||||
m_shadersInitialized( false )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~btSoftBodySolverOutputCLtoGL()
|
||||
{
|
||||
releaseKernels();
|
||||
}
|
||||
|
||||
/** Output current computed vertex data to the vertex buffers for all cloths in the solver. */
|
||||
virtual void copySoftBodyToVertexBuffer( const btSoftBody * const softBody, btVertexBufferDescriptor *vertexBuffer );
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // #ifndef BT_SOFT_BODY_SOLVER_OUTPUT_CL_TO_GL_H
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#include "BulletMultiThreaded/GpuSoftBodySolvers/Shared/btSoftBodySolverData.h"
|
||||
#include "btSoftBodySolverBuffer_OpenCL.h"
|
||||
|
||||
|
||||
#ifndef BT_SOFT_BODY_SOLVER_TRIANGLE_DATA_OPENCL_H
|
||||
#define BT_SOFT_BODY_SOLVER_TRIANGLE_DATA_OPENCL_H
|
||||
|
||||
|
||||
class btSoftBodyTriangleDataOpenCL : public btSoftBodyTriangleData
|
||||
{
|
||||
public:
|
||||
bool m_onGPU;
|
||||
cl_command_queue m_queue;
|
||||
|
||||
btOpenCLBuffer<btSoftBodyTriangleData::TriangleNodeSet> m_clVertexIndices;
|
||||
btOpenCLBuffer<float> m_clArea;
|
||||
btOpenCLBuffer<Vectormath::Aos::Vector3> m_clNormal;
|
||||
|
||||
/**
|
||||
* Link addressing information for each cloth.
|
||||
* Allows link locations to be computed independently of data batching.
|
||||
*/
|
||||
btAlignedObjectArray< int > m_triangleAddresses;
|
||||
|
||||
/**
|
||||
* Start and length values for computation batches over link data.
|
||||
*/
|
||||
struct btSomePair
|
||||
{
|
||||
btSomePair() {}
|
||||
btSomePair(int f,int s)
|
||||
:first(f),second(s)
|
||||
{
|
||||
}
|
||||
int first;
|
||||
int second;
|
||||
};
|
||||
btAlignedObjectArray< btSomePair > m_batchStartLengths;
|
||||
|
||||
public:
|
||||
btSoftBodyTriangleDataOpenCL( cl_command_queue queue, cl_context ctx );
|
||||
|
||||
virtual ~btSoftBodyTriangleDataOpenCL();
|
||||
|
||||
/** Allocate enough space in all link-related arrays to fit numLinks links */
|
||||
virtual void createTriangles( int numTriangles );
|
||||
|
||||
/** Insert the link described into the correct data structures assuming space has already been allocated by a call to createLinks */
|
||||
virtual void setTriangleAt( const btSoftBodyTriangleData::TriangleDescription &triangle, int triangleIndex );
|
||||
|
||||
virtual bool onAccelerator();
|
||||
|
||||
virtual bool moveToAccelerator();
|
||||
|
||||
virtual bool moveFromAccelerator();
|
||||
|
||||
/**
|
||||
* Generate (and later update) the batching for the entire triangle set.
|
||||
* This redoes a lot of work because it batches the entire set when each cloth is inserted.
|
||||
* In theory we could delay it until just before we need the cloth.
|
||||
* It's a one-off overhead, though, so that is a later optimisation.
|
||||
*/
|
||||
void generateBatches();
|
||||
}; // class btSoftBodyTriangleDataOpenCL
|
||||
|
||||
|
||||
#endif // #ifndef BT_SOFT_BODY_SOLVER_TRIANGLE_DATA_OPENCL_H
|
||||
|
||||
+166
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef BT_SOFT_BODY_SOLVER_VERTEX_BUFFER_OPENGL_H
|
||||
#define BT_SOFT_BODY_SOLVER_VERTEX_BUFFER_OPENGL_H
|
||||
|
||||
|
||||
#include "BulletSoftBody/btSoftBodySolverVertexBuffer.h"
|
||||
#ifdef USE_MINICL
|
||||
#include "MiniCL/cl.h"
|
||||
#else //USE_MINICL
|
||||
#ifdef __APPLE__
|
||||
#include <OpenCL/OpenCL.h>
|
||||
#else
|
||||
#include <CL/cl.h>
|
||||
#include <CL/cl_gl.h>
|
||||
#endif //__APPLE__
|
||||
#endif//USE_MINICL
|
||||
|
||||
|
||||
#ifdef _WIN32//for glut.h
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
//think different
|
||||
#if defined(__APPLE__) && !defined (VMDMESA)
|
||||
#include <OpenGL/OpenGL.h>
|
||||
#include <OpenGL/gl.h>
|
||||
#include <OpenGL/glu.h>
|
||||
#include <GLUT/glut.h>
|
||||
#else
|
||||
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#include <windows.h>
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#else
|
||||
#include <GL/glut.h>
|
||||
#endif //_WINDOWS
|
||||
#endif //APPLE
|
||||
|
||||
|
||||
|
||||
class btOpenGLInteropVertexBufferDescriptor : public btVertexBufferDescriptor
|
||||
{
|
||||
protected:
|
||||
/** OpenCL context */
|
||||
cl_context m_context;
|
||||
|
||||
/** OpenCL command queue */
|
||||
cl_command_queue m_commandQueue;
|
||||
|
||||
/** OpenCL interop buffer */
|
||||
cl_mem m_buffer;
|
||||
|
||||
/** VBO in GL that is the basis of the interop buffer */
|
||||
GLuint m_openGLVBO;
|
||||
|
||||
|
||||
public:
|
||||
/**
|
||||
* context is the OpenCL context this interop buffer will work in.
|
||||
* queue is the command queue that kernels and data movement will be enqueued into.
|
||||
* openGLVBO is the OpenGL vertex buffer data will be copied into.
|
||||
* vertexOffset is the offset in floats to the first vertex.
|
||||
* vertexStride is the stride in floats between vertices.
|
||||
*/
|
||||
btOpenGLInteropVertexBufferDescriptor( cl_command_queue cqCommandQue, cl_context context, GLuint openGLVBO, int vertexOffset, int vertexStride )
|
||||
{
|
||||
#ifndef USE_MINICL
|
||||
cl_int ciErrNum = CL_SUCCESS;
|
||||
m_context = context;
|
||||
m_commandQueue = cqCommandQue;
|
||||
|
||||
m_vertexOffset = vertexOffset;
|
||||
m_vertexStride = vertexStride;
|
||||
|
||||
m_openGLVBO = openGLVBO;
|
||||
|
||||
m_buffer = clCreateFromGLBuffer(m_context, CL_MEM_WRITE_ONLY, openGLVBO, &ciErrNum);
|
||||
if( ciErrNum != CL_SUCCESS )
|
||||
{
|
||||
btAssert( 0 && "clEnqueueAcquireGLObjects(copySoftBodyToVertexBuffer)");
|
||||
}
|
||||
|
||||
m_hasVertexPositions = true;
|
||||
#else
|
||||
btAssert(0);//MiniCL shouldn't get here
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* context is the OpenCL context this interop buffer will work in.
|
||||
* queue is the command queue that kernels and data movement will be enqueued into.
|
||||
* openGLVBO is the OpenGL vertex buffer data will be copied into.
|
||||
* vertexOffset is the offset in floats to the first vertex.
|
||||
* vertexStride is the stride in floats between vertices.
|
||||
* normalOffset is the offset in floats to the first normal.
|
||||
* normalStride is the stride in floats between normals.
|
||||
*/
|
||||
btOpenGLInteropVertexBufferDescriptor( cl_command_queue cqCommandQue, cl_context context, GLuint openGLVBO, int vertexOffset, int vertexStride, int normalOffset, int normalStride )
|
||||
{
|
||||
#ifndef USE_MINICL
|
||||
cl_int ciErrNum = CL_SUCCESS;
|
||||
m_context = context;
|
||||
m_commandQueue = cqCommandQue;
|
||||
|
||||
m_openGLVBO = openGLVBO;
|
||||
|
||||
m_buffer = clCreateFromGLBuffer(m_context, CL_MEM_WRITE_ONLY, openGLVBO, &ciErrNum);
|
||||
if( ciErrNum != CL_SUCCESS )
|
||||
{
|
||||
btAssert( 0 && "clEnqueueAcquireGLObjects(copySoftBodyToVertexBuffer)");
|
||||
}
|
||||
|
||||
m_vertexOffset = vertexOffset;
|
||||
m_vertexStride = vertexStride;
|
||||
m_hasVertexPositions = true;
|
||||
|
||||
m_normalOffset = normalOffset;
|
||||
m_normalStride = normalStride;
|
||||
m_hasNormals = true;
|
||||
#else
|
||||
btAssert(0);
|
||||
#endif //USE_MINICL
|
||||
|
||||
}
|
||||
|
||||
virtual ~btOpenGLInteropVertexBufferDescriptor()
|
||||
{
|
||||
clReleaseMemObject( m_buffer );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the type of the vertex buffer descriptor.
|
||||
*/
|
||||
virtual BufferTypes getBufferType() const
|
||||
{
|
||||
return OPENGL_BUFFER;
|
||||
}
|
||||
|
||||
virtual cl_context getContext() const
|
||||
{
|
||||
return m_context;
|
||||
}
|
||||
|
||||
virtual cl_mem getBuffer() const
|
||||
{
|
||||
return m_buffer;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // #ifndef BT_SOFT_BODY_SOLVER_VERTEX_BUFFER_OPENGL_H
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "BulletMultiThreaded/GpuSoftBodySolvers/Shared/btSoftBodySolverData.h"
|
||||
#include "btSoftBodySolverBuffer_OpenCL.h"
|
||||
|
||||
#ifndef BT_SOFT_BODY_SOLVER_VERTEX_DATA_OPENCL_H
|
||||
#define BT_SOFT_BODY_SOLVER_VERTEX_DATA_OPENCL_H
|
||||
|
||||
|
||||
class btSoftBodyVertexDataOpenCL : public btSoftBodyVertexData
|
||||
{
|
||||
protected:
|
||||
bool m_onGPU;
|
||||
cl_command_queue m_queue;
|
||||
|
||||
public:
|
||||
btOpenCLBuffer<int> m_clClothIdentifier;
|
||||
btOpenCLBuffer<Vectormath::Aos::Point3> m_clVertexPosition;
|
||||
btOpenCLBuffer<Vectormath::Aos::Point3> m_clVertexPreviousPosition;
|
||||
btOpenCLBuffer<Vectormath::Aos::Vector3> m_clVertexVelocity;
|
||||
btOpenCLBuffer<Vectormath::Aos::Vector3> m_clVertexForceAccumulator;
|
||||
btOpenCLBuffer<Vectormath::Aos::Vector3> m_clVertexNormal;
|
||||
btOpenCLBuffer<float> m_clVertexInverseMass;
|
||||
btOpenCLBuffer<float> m_clVertexArea;
|
||||
btOpenCLBuffer<int> m_clVertexTriangleCount;
|
||||
public:
|
||||
btSoftBodyVertexDataOpenCL( cl_command_queue queue, cl_context ctx);
|
||||
|
||||
virtual ~btSoftBodyVertexDataOpenCL();
|
||||
|
||||
virtual bool onAccelerator();
|
||||
|
||||
virtual bool moveToAccelerator();
|
||||
|
||||
virtual bool moveFromAccelerator(bool bCopy = false, bool bCopyMinimum = true);
|
||||
};
|
||||
|
||||
|
||||
#endif // #ifndef BT_SOFT_BODY_SOLVER_VERTEX_DATA_OPENCL_H
|
||||
+1820
File diff suppressed because it is too large
Load Diff
+527
@@ -0,0 +1,527 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef BT_SOFT_BODY_SOLVER_OPENCL_H
|
||||
#define BT_SOFT_BODY_SOLVER_OPENCL_H
|
||||
|
||||
#include "stddef.h" //for size_t
|
||||
#include "vectormath/vmInclude.h"
|
||||
|
||||
#include "BulletSoftBody/btSoftBodySolvers.h"
|
||||
#include "BulletSoftBody/btSoftBody.h"
|
||||
#include "btSoftBodySolverBuffer_OpenCL.h"
|
||||
#include "btSoftBodySolverLinkData_OpenCL.h"
|
||||
#include "btSoftBodySolverVertexData_OpenCL.h"
|
||||
#include "btSoftBodySolverTriangleData_OpenCL.h"
|
||||
|
||||
class CLFunctions
|
||||
{
|
||||
protected:
|
||||
cl_command_queue m_cqCommandQue;
|
||||
cl_context m_cxMainContext;
|
||||
|
||||
int m_kernelCompilationFailures;
|
||||
|
||||
|
||||
public:
|
||||
CLFunctions(cl_command_queue cqCommandQue, cl_context cxMainContext) :
|
||||
m_cqCommandQue( cqCommandQue ),
|
||||
m_cxMainContext( cxMainContext ),
|
||||
m_kernelCompilationFailures(0)
|
||||
{
|
||||
}
|
||||
|
||||
int getKernelCompilationFailures() const
|
||||
{
|
||||
return m_kernelCompilationFailures;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a compute shader kernel from a string and return the appropriate cl_kernel object.
|
||||
*/
|
||||
virtual cl_kernel compileCLKernelFromString( const char* kernelSource, const char* kernelName, const char* additionalMacros, const char* srcFileNameForCaching);
|
||||
|
||||
void clearKernelCompilationFailures()
|
||||
{
|
||||
m_kernelCompilationFailures=0;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Entry in the collision shape array.
|
||||
* Specifies the shape type, the transform matrix and the necessary details of the collisionShape.
|
||||
*/
|
||||
struct CollisionShapeDescription
|
||||
{
|
||||
Vectormath::Aos::Transform3 shapeTransform;
|
||||
Vectormath::Aos::Vector3 linearVelocity;
|
||||
Vectormath::Aos::Vector3 angularVelocity;
|
||||
|
||||
int softBodyIdentifier;
|
||||
int collisionShapeType;
|
||||
|
||||
// Both needed for capsule
|
||||
float radius;
|
||||
float halfHeight;
|
||||
int upAxis;
|
||||
|
||||
float margin;
|
||||
float friction;
|
||||
|
||||
CollisionShapeDescription()
|
||||
{
|
||||
collisionShapeType = 0;
|
||||
margin = 0;
|
||||
friction = 0;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* SoftBody class to maintain information about a soft body instance
|
||||
* within a solver.
|
||||
* This data addresses the main solver arrays.
|
||||
*/
|
||||
class btOpenCLAcceleratedSoftBodyInterface
|
||||
{
|
||||
protected:
|
||||
/** Current number of vertices that are part of this cloth */
|
||||
int m_numVertices;
|
||||
/** Maximum number of vertices allocated to be part of this cloth */
|
||||
int m_maxVertices;
|
||||
/** Current number of triangles that are part of this cloth */
|
||||
int m_numTriangles;
|
||||
/** Maximum number of triangles allocated to be part of this cloth */
|
||||
int m_maxTriangles;
|
||||
/** Index of first vertex in the world allocated to this cloth */
|
||||
int m_firstVertex;
|
||||
/** Index of first triangle in the world allocated to this cloth */
|
||||
int m_firstTriangle;
|
||||
/** Index of first link in the world allocated to this cloth */
|
||||
int m_firstLink;
|
||||
/** Maximum number of links allocated to this cloth */
|
||||
int m_maxLinks;
|
||||
/** Current number of links allocated to this cloth */
|
||||
int m_numLinks;
|
||||
|
||||
/** The actual soft body this data represents */
|
||||
btSoftBody *m_softBody;
|
||||
|
||||
|
||||
public:
|
||||
btOpenCLAcceleratedSoftBodyInterface( btSoftBody *softBody ) :
|
||||
m_softBody( softBody )
|
||||
{
|
||||
m_numVertices = 0;
|
||||
m_maxVertices = 0;
|
||||
m_numTriangles = 0;
|
||||
m_maxTriangles = 0;
|
||||
m_firstVertex = 0;
|
||||
m_firstTriangle = 0;
|
||||
m_firstLink = 0;
|
||||
m_maxLinks = 0;
|
||||
m_numLinks = 0;
|
||||
}
|
||||
int getNumVertices()
|
||||
{
|
||||
return m_numVertices;
|
||||
}
|
||||
|
||||
int getNumTriangles()
|
||||
{
|
||||
return m_numTriangles;
|
||||
}
|
||||
|
||||
int getMaxVertices()
|
||||
{
|
||||
return m_maxVertices;
|
||||
}
|
||||
|
||||
int getMaxTriangles()
|
||||
{
|
||||
return m_maxTriangles;
|
||||
}
|
||||
|
||||
int getFirstVertex()
|
||||
{
|
||||
return m_firstVertex;
|
||||
}
|
||||
|
||||
int getFirstTriangle()
|
||||
{
|
||||
return m_firstTriangle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the bounds in the btSoftBody object
|
||||
*/
|
||||
void updateBounds( const btVector3 &lowerBound, const btVector3 &upperBound );
|
||||
|
||||
// TODO: All of these set functions will have to do checks and
|
||||
// update the world because restructuring of the arrays will be necessary
|
||||
// Reasonable use of "friend"?
|
||||
void setNumVertices( int numVertices )
|
||||
{
|
||||
m_numVertices = numVertices;
|
||||
}
|
||||
|
||||
void setNumTriangles( int numTriangles )
|
||||
{
|
||||
m_numTriangles = numTriangles;
|
||||
}
|
||||
|
||||
void setMaxVertices( int maxVertices )
|
||||
{
|
||||
m_maxVertices = maxVertices;
|
||||
}
|
||||
|
||||
void setMaxTriangles( int maxTriangles )
|
||||
{
|
||||
m_maxTriangles = maxTriangles;
|
||||
}
|
||||
|
||||
void setFirstVertex( int firstVertex )
|
||||
{
|
||||
m_firstVertex = firstVertex;
|
||||
}
|
||||
|
||||
void setFirstTriangle( int firstTriangle )
|
||||
{
|
||||
m_firstTriangle = firstTriangle;
|
||||
}
|
||||
|
||||
void setMaxLinks( int maxLinks )
|
||||
{
|
||||
m_maxLinks = maxLinks;
|
||||
}
|
||||
|
||||
void setNumLinks( int numLinks )
|
||||
{
|
||||
m_numLinks = numLinks;
|
||||
}
|
||||
|
||||
void setFirstLink( int firstLink )
|
||||
{
|
||||
m_firstLink = firstLink;
|
||||
}
|
||||
|
||||
int getMaxLinks()
|
||||
{
|
||||
return m_maxLinks;
|
||||
}
|
||||
|
||||
int getNumLinks()
|
||||
{
|
||||
return m_numLinks;
|
||||
}
|
||||
|
||||
int getFirstLink()
|
||||
{
|
||||
return m_firstLink;
|
||||
}
|
||||
|
||||
btSoftBody* getSoftBody()
|
||||
{
|
||||
return m_softBody;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
class btOpenCLSoftBodySolver : public btSoftBodySolver
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
struct UIntVector3
|
||||
{
|
||||
UIntVector3()
|
||||
{
|
||||
x = 0;
|
||||
y = 0;
|
||||
z = 0;
|
||||
_padding = 0;
|
||||
}
|
||||
|
||||
UIntVector3( unsigned int x_, unsigned int y_, unsigned int z_ )
|
||||
{
|
||||
x = x_;
|
||||
y = y_;
|
||||
z = z_;
|
||||
_padding = 0;
|
||||
}
|
||||
|
||||
unsigned int x;
|
||||
unsigned int y;
|
||||
unsigned int z;
|
||||
unsigned int _padding;
|
||||
};
|
||||
|
||||
struct CollisionObjectIndices
|
||||
{
|
||||
CollisionObjectIndices( int f, int e )
|
||||
{
|
||||
firstObject = f;
|
||||
endObject = e;
|
||||
}
|
||||
|
||||
int firstObject;
|
||||
int endObject;
|
||||
};
|
||||
|
||||
btSoftBodyLinkDataOpenCL m_linkData;
|
||||
btSoftBodyVertexDataOpenCL m_vertexData;
|
||||
btSoftBodyTriangleDataOpenCL m_triangleData;
|
||||
|
||||
protected:
|
||||
|
||||
CLFunctions m_defaultCLFunctions;
|
||||
CLFunctions* m_currentCLFunctions;
|
||||
|
||||
/** Variable to define whether we need to update solver constants on the next iteration */
|
||||
bool m_updateSolverConstants;
|
||||
|
||||
bool m_shadersInitialized;
|
||||
|
||||
/**
|
||||
* Cloths owned by this solver.
|
||||
* Only our cloths are in this array.
|
||||
*/
|
||||
btAlignedObjectArray< btOpenCLAcceleratedSoftBodyInterface * > m_softBodySet;
|
||||
|
||||
/** Acceleration value to be applied to all non-static vertices in the solver.
|
||||
* Index n is cloth n, array sized by number of cloths in the world not the solver.
|
||||
*/
|
||||
btAlignedObjectArray< Vectormath::Aos::Vector3 > m_perClothAcceleration;
|
||||
btOpenCLBuffer<Vectormath::Aos::Vector3> m_clPerClothAcceleration;
|
||||
|
||||
/** Wind velocity to be applied normal to all non-static vertices in the solver.
|
||||
* Index n is cloth n, array sized by number of cloths in the world not the solver.
|
||||
*/
|
||||
btAlignedObjectArray< Vectormath::Aos::Vector3 > m_perClothWindVelocity;
|
||||
btOpenCLBuffer<Vectormath::Aos::Vector3> m_clPerClothWindVelocity;
|
||||
|
||||
/** Velocity damping factor */
|
||||
btAlignedObjectArray< float > m_perClothDampingFactor;
|
||||
btOpenCLBuffer<float> m_clPerClothDampingFactor;
|
||||
|
||||
/** Velocity correction coefficient */
|
||||
btAlignedObjectArray< float > m_perClothVelocityCorrectionCoefficient;
|
||||
btOpenCLBuffer<float> m_clPerClothVelocityCorrectionCoefficient;
|
||||
|
||||
/** Lift parameter for wind effect on cloth. */
|
||||
btAlignedObjectArray< float > m_perClothLiftFactor;
|
||||
btOpenCLBuffer<float> m_clPerClothLiftFactor;
|
||||
|
||||
/** Drag parameter for wind effect on cloth. */
|
||||
btAlignedObjectArray< float > m_perClothDragFactor;
|
||||
btOpenCLBuffer<float> m_clPerClothDragFactor;
|
||||
|
||||
/** Density of the medium in which each cloth sits */
|
||||
btAlignedObjectArray< float > m_perClothMediumDensity;
|
||||
btOpenCLBuffer<float> m_clPerClothMediumDensity;
|
||||
|
||||
/**
|
||||
* Collision shape details: pair of index of first collision shape for the cloth and number of collision objects.
|
||||
*/
|
||||
btAlignedObjectArray< CollisionObjectIndices > m_perClothCollisionObjects;
|
||||
btOpenCLBuffer<CollisionObjectIndices> m_clPerClothCollisionObjects;
|
||||
|
||||
/**
|
||||
* Collision shapes being passed across to the cloths in this solver.
|
||||
*/
|
||||
btAlignedObjectArray< CollisionShapeDescription > m_collisionObjectDetails;
|
||||
btOpenCLBuffer< CollisionShapeDescription > m_clCollisionObjectDetails;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Friction coefficient for each cloth
|
||||
*/
|
||||
btAlignedObjectArray< float > m_perClothFriction;
|
||||
btOpenCLBuffer< float > m_clPerClothFriction;
|
||||
|
||||
// anchor node info
|
||||
struct AnchorNodeInfoCL
|
||||
{
|
||||
int clVertexIndex;
|
||||
btSoftBody::Node* pNode;
|
||||
};
|
||||
|
||||
btAlignedObjectArray<AnchorNodeInfoCL> m_anchorNodeInfoArray;
|
||||
btAlignedObjectArray<Vectormath::Aos::Point3> m_anchorPosition;
|
||||
btOpenCLBuffer<Vectormath::Aos::Point3> m_clAnchorPosition;
|
||||
btAlignedObjectArray<int> m_anchorIndex;
|
||||
btOpenCLBuffer<int> m_clAnchorIndex;
|
||||
|
||||
bool m_bUpdateAnchoredNodePos;
|
||||
|
||||
cl_kernel m_prepareLinksKernel;
|
||||
cl_kernel m_solvePositionsFromLinksKernel;
|
||||
cl_kernel m_updateConstantsKernel;
|
||||
cl_kernel m_integrateKernel;
|
||||
cl_kernel m_addVelocityKernel;
|
||||
cl_kernel m_updatePositionsFromVelocitiesKernel;
|
||||
cl_kernel m_updateVelocitiesFromPositionsWithoutVelocitiesKernel;
|
||||
cl_kernel m_updateVelocitiesFromPositionsWithVelocitiesKernel;
|
||||
cl_kernel m_vSolveLinksKernel;
|
||||
cl_kernel m_solveCollisionsAndUpdateVelocitiesKernel;
|
||||
cl_kernel m_resetNormalsAndAreasKernel;
|
||||
cl_kernel m_normalizeNormalsAndAreasKernel;
|
||||
cl_kernel m_updateSoftBodiesKernel;
|
||||
|
||||
cl_kernel m_outputToVertexArrayKernel;
|
||||
cl_kernel m_applyForcesKernel;
|
||||
cl_kernel m_updateFixedVertexPositionsKernel;
|
||||
|
||||
cl_command_queue m_cqCommandQue;
|
||||
cl_context m_cxMainContext;
|
||||
|
||||
size_t m_defaultWorkGroupSize;
|
||||
|
||||
|
||||
virtual bool buildShaders();
|
||||
|
||||
void resetNormalsAndAreas( int numVertices );
|
||||
|
||||
void normalizeNormalsAndAreas( int numVertices );
|
||||
|
||||
void executeUpdateSoftBodies( int firstTriangle, int numTriangles );
|
||||
|
||||
void prepareCollisionConstraints();
|
||||
|
||||
Vectormath::Aos::Vector3 ProjectOnAxis( const Vectormath::Aos::Vector3 &v, const Vectormath::Aos::Vector3 &a );
|
||||
|
||||
void ApplyClampedForce( float solverdt, const Vectormath::Aos::Vector3 &force, const Vectormath::Aos::Vector3 &vertexVelocity, float inverseMass, Vectormath::Aos::Vector3 &vertexForce );
|
||||
|
||||
|
||||
int findSoftBodyIndex( const btSoftBody* const softBody );
|
||||
|
||||
virtual void applyForces( float solverdt );
|
||||
|
||||
void updateFixedVertexPositions();
|
||||
|
||||
/**
|
||||
* Integrate motion on the solver.
|
||||
*/
|
||||
virtual void integrate( float solverdt );
|
||||
|
||||
virtual void updateConstants( float timeStep );
|
||||
|
||||
float computeTriangleArea(
|
||||
const Vectormath::Aos::Point3 &vertex0,
|
||||
const Vectormath::Aos::Point3 &vertex1,
|
||||
const Vectormath::Aos::Point3 &vertex2 );
|
||||
|
||||
|
||||
//////////////////////////////////////
|
||||
// Kernel dispatches
|
||||
void prepareLinks();
|
||||
|
||||
void solveLinksForVelocity( int startLink, int numLinks, float kst );
|
||||
|
||||
void updatePositionsFromVelocities( float solverdt );
|
||||
|
||||
virtual void solveLinksForPosition( int startLink, int numLinks, float kst, float ti );
|
||||
|
||||
void updateVelocitiesFromPositionsWithVelocities( float isolverdt );
|
||||
|
||||
void updateVelocitiesFromPositionsWithoutVelocities( float isolverdt );
|
||||
virtual void solveCollisionsAndUpdateVelocities( float isolverdt );
|
||||
|
||||
// End kernel dispatches
|
||||
/////////////////////////////////////
|
||||
|
||||
void updateBounds();
|
||||
|
||||
void releaseKernels();
|
||||
|
||||
public:
|
||||
btOpenCLSoftBodySolver(cl_command_queue queue,cl_context ctx, bool bUpdateAchchoredNodePos = false);
|
||||
|
||||
virtual ~btOpenCLSoftBodySolver();
|
||||
|
||||
|
||||
|
||||
btOpenCLAcceleratedSoftBodyInterface *findSoftBodyInterface( const btSoftBody* const softBody );
|
||||
|
||||
virtual btSoftBodyLinkData &getLinkData();
|
||||
|
||||
virtual btSoftBodyVertexData &getVertexData();
|
||||
|
||||
virtual btSoftBodyTriangleData &getTriangleData();
|
||||
|
||||
virtual SolverTypes getSolverType() const
|
||||
{
|
||||
return CL_SOLVER;
|
||||
}
|
||||
|
||||
|
||||
virtual bool checkInitialized();
|
||||
|
||||
virtual void updateSoftBodies( );
|
||||
|
||||
virtual void optimize( btAlignedObjectArray< btSoftBody * > &softBodies , bool forceUpdate=false);
|
||||
|
||||
virtual void copyBackToSoftBodies(bool bMove = true);
|
||||
|
||||
virtual void solveConstraints( float solverdt );
|
||||
|
||||
virtual void predictMotion( float solverdt );
|
||||
|
||||
virtual void processCollision( btSoftBody *, const btCollisionObjectWrapper* );
|
||||
|
||||
virtual void processCollision( btSoftBody*, btSoftBody* );
|
||||
|
||||
virtual void setDefaultWorkgroupSize(size_t workGroupSize)
|
||||
{
|
||||
m_defaultWorkGroupSize = workGroupSize;
|
||||
}
|
||||
virtual size_t getDefaultWorkGroupSize() const
|
||||
{
|
||||
return m_defaultWorkGroupSize;
|
||||
}
|
||||
|
||||
void setCLFunctions(CLFunctions* funcs)
|
||||
{
|
||||
if (funcs)
|
||||
m_currentCLFunctions = funcs;
|
||||
else
|
||||
m_currentCLFunctions = &m_defaultCLFunctions;
|
||||
}
|
||||
|
||||
}; // btOpenCLSoftBodySolver
|
||||
|
||||
|
||||
/**
|
||||
* Class to manage movement of data from a solver to a given target.
|
||||
* This version is the CL to CPU version.
|
||||
*/
|
||||
class btSoftBodySolverOutputCLtoCPU : public btSoftBodySolverOutput
|
||||
{
|
||||
protected:
|
||||
|
||||
public:
|
||||
btSoftBodySolverOutputCLtoCPU()
|
||||
{
|
||||
}
|
||||
|
||||
/** Output current computed vertex data to the vertex buffers for all cloths in the solver. */
|
||||
virtual void copySoftBodyToVertexBuffer( const btSoftBody * const softBody, btVertexBufferDescriptor *vertexBuffer );
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // #ifndef BT_SOFT_BODY_SOLVER_OPENCL_H
|
||||
+1101
File diff suppressed because it is too large
Load Diff
+81
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef BT_SOFT_BODY_SOLVER_OPENCL_SIMDAWARE_H
|
||||
#define BT_SOFT_BODY_SOLVER_OPENCL_SIMDAWARE_H
|
||||
|
||||
#include "stddef.h" //for size_t
|
||||
#include "vectormath/vmInclude.h"
|
||||
|
||||
#include "btSoftBodySolver_OpenCL.h"
|
||||
#include "btSoftBodySolverBuffer_OpenCL.h"
|
||||
#include "btSoftBodySolverLinkData_OpenCLSIMDAware.h"
|
||||
#include "btSoftBodySolverVertexData_OpenCL.h"
|
||||
#include "btSoftBodySolverTriangleData_OpenCL.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class btOpenCLSoftBodySolverSIMDAware : public btOpenCLSoftBodySolver
|
||||
{
|
||||
protected:
|
||||
|
||||
|
||||
btSoftBodyLinkDataOpenCLSIMDAware m_linkData;
|
||||
|
||||
|
||||
|
||||
|
||||
virtual bool buildShaders();
|
||||
|
||||
|
||||
void updateConstants( float timeStep );
|
||||
|
||||
float computeTriangleArea(
|
||||
const Vectormath::Aos::Point3 &vertex0,
|
||||
const Vectormath::Aos::Point3 &vertex1,
|
||||
const Vectormath::Aos::Point3 &vertex2 );
|
||||
|
||||
|
||||
//////////////////////////////////////
|
||||
// Kernel dispatches
|
||||
void solveLinksForPosition( int startLink, int numLinks, float kst, float ti );
|
||||
|
||||
void solveCollisionsAndUpdateVelocities( float isolverdt );
|
||||
// End kernel dispatches
|
||||
/////////////////////////////////////
|
||||
|
||||
public:
|
||||
btOpenCLSoftBodySolverSIMDAware(cl_command_queue queue,cl_context ctx, bool bUpdateAchchoredNodePos = false);
|
||||
|
||||
virtual ~btOpenCLSoftBodySolverSIMDAware();
|
||||
|
||||
virtual SolverTypes getSolverType() const
|
||||
{
|
||||
return CL_SIMD_SOLVER;
|
||||
}
|
||||
|
||||
|
||||
virtual btSoftBodyLinkData &getLinkData();
|
||||
|
||||
|
||||
virtual void optimize( btAlignedObjectArray< btSoftBody * > &softBodies , bool forceUpdate=false);
|
||||
|
||||
virtual void solveConstraints( float solverdt );
|
||||
|
||||
}; // btOpenCLSoftBodySolverSIMDAware
|
||||
|
||||
#endif // #ifndef BT_SOFT_BODY_SOLVER_OPENCL_SIMDAWARE_H
|
||||
Reference in New Issue
Block a user