Remove btSoftBodySolver_CPU.*
Move btSoftBodySolverData.h to src/BulletMultiThreaded/GpuSoftBodySolvers/Shared/btSoftBodySolverData.h Attempt to re-enable MiniCL version of OpenCLClothDemo (cloth-capsule collision still broken) Add optional OpenCL acceleration to SerializeDemo (just for cloth)
This commit is contained in:
@@ -31,7 +31,7 @@ class btDX11SIMDAwareSoftBodySolver;
|
||||
|
||||
#include "BulletSoftBody/btSoftBodySolvers.h"
|
||||
#include "BulletSoftBody/btDefaultSoftBodySolver.h"
|
||||
#include "BulletMultiThreaded/GpuSoftBodySolvers/CPU/btSoftBodySolver_CPU.h"
|
||||
|
||||
#include "BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolver_DX11.h"
|
||||
#include "BulletMultiThreaded/GpuSoftBodySolvers/DX11/btSoftBodySolver_DX11SIMDAware.h"
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ IF (USE_GLUT)
|
||||
LINK_LIBRARIES(
|
||||
OpenGLSupport
|
||||
BulletSoftBodySolvers_OpenCL_Mini
|
||||
BulletSoftBodySolvers_CPU
|
||||
MiniCL
|
||||
BulletMultiThreaded
|
||||
BulletSoftBody
|
||||
|
||||
@@ -18,15 +18,18 @@ subject to the following restrictions:
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifndef USE_MINICL
|
||||
#define USE_SIMDAWARE_SOLVER
|
||||
#ifndef __APPLE__
|
||||
//#define USE_SIMDAWARE_SOLVER
|
||||
#endif
|
||||
|
||||
#if !defined (__APPLE__)
|
||||
#define USE_GPU_SOLVER
|
||||
#if defined (_WIN32)
|
||||
#if defined (_WIN32) && !defined(USE_MINICL)
|
||||
#define USE_GPU_COPY //only tested on Windows
|
||||
#endif //_WIN32
|
||||
#endif //__APPLE__
|
||||
#endif //USE_MINICL
|
||||
#endif //_WIN32 && !USE_MINICL
|
||||
#endif //!__APPLE__
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -43,13 +46,7 @@ const int numFlags = 5;
|
||||
const int clothWidth = 40;
|
||||
const int clothHeight = 60;//60;
|
||||
float _windAngle = 1.0;//0.4;
|
||||
float _windStrength = 10.;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
float _windStrength = 0.;
|
||||
|
||||
|
||||
|
||||
@@ -57,7 +54,6 @@ float _windStrength = 10.;
|
||||
#include "LinearMath/btHashMap.h"
|
||||
#include "BulletSoftBody/btSoftRigidDynamicsWorld.h"
|
||||
#include "vectormath/vmInclude.h"
|
||||
#include "BulletMultiThreaded/GpuSoftBodySolvers/CPU/btSoftBodySolver_CPU.h"
|
||||
#include "BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolver_OpenCL.h"
|
||||
#include "BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolver_OpenCLSIMDAware.h"
|
||||
#include "BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolverVertexBuffer_OpenGL.h"
|
||||
@@ -95,7 +91,6 @@ btCollisionDispatcher* m_dispatcher;
|
||||
btConstraintSolver* m_solver;
|
||||
btDefaultCollisionConfiguration* m_collisionConfiguration;
|
||||
|
||||
btCPUSoftBodySolver *g_cpuSolver = NULL;
|
||||
btOpenCLSoftBodySolver *g_openCLSolver = NULL;
|
||||
btOpenCLSoftBodySolverSIMDAware *g_openCLSIMDSolver = NULL;
|
||||
|
||||
@@ -368,9 +363,8 @@ void initBullet(void)
|
||||
#endif // #ifdef USE_GPU_COPY
|
||||
#endif
|
||||
#else
|
||||
g_cpuSolver = new btCPUSoftBodySolver;
|
||||
g_solver = g_cpuSolver;
|
||||
g_softBodyOutput = new btSoftBodySolverOutputCPUtoCPU;
|
||||
g_openCLSolver = new btOpenCLSoftBodySolver( g_cqCommandQue, g_cxMainContext );
|
||||
g_solver = g_openCLSolver;
|
||||
#endif
|
||||
|
||||
//m_collisionConfiguration = new btDefaultCollisionConfiguration();
|
||||
@@ -471,11 +465,11 @@ void initBullet(void)
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef USE_GPU_SOLVER
|
||||
//#ifdef USE_GPU_SOLVER
|
||||
createFlag( *g_openCLSolver, clothWidth, clothHeight, m_flags );
|
||||
#else
|
||||
createFlag( *g_cpuSolver, clothWidth, clothHeight, m_flags );
|
||||
#endif
|
||||
//#else
|
||||
|
||||
//#endif
|
||||
|
||||
// Create output buffer descriptions for ecah flag
|
||||
// These describe where the simulation should send output data to
|
||||
@@ -544,7 +538,7 @@ void doFlags()
|
||||
//debugDraw.setDebugMode(btIDebugDraw::DBG_DrawWireframe);
|
||||
//g_solver->copyBackToSoftBodies();
|
||||
|
||||
//m_dynamicsWorld->debugDrawWorld();
|
||||
m_dynamicsWorld->debugDrawWorld();
|
||||
|
||||
}
|
||||
|
||||
@@ -607,8 +601,6 @@ int main(int argc, char *argv[])
|
||||
|
||||
goGL();
|
||||
|
||||
if( g_cpuSolver )
|
||||
delete g_cpuSolver;
|
||||
if( g_openCLSolver )
|
||||
delete g_openCLSolver;
|
||||
if( g_openCLSIMDSolver )
|
||||
|
||||
131
Demos/SerializeDemo/AMD/CMakeLists.txt
Normal file
131
Demos/SerializeDemo/AMD/CMakeLists.txt
Normal file
@@ -0,0 +1,131 @@
|
||||
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/src
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/Extras/Serialize/BulletFileLoader
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/Extras/Serialize/BulletWorldImporter
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL
|
||||
${AMD_OPENCL_INCLUDES}
|
||||
)
|
||||
|
||||
ADD_DEFINITIONS(-DDESERIALIZE_SOFT_BODIES)
|
||||
ADD_DEFINITIONS(-DUSE_AMD_OPENCL)
|
||||
ADD_DEFINITIONS(-DCL_PLATFORM_AMD)
|
||||
IF (CMAKE_CL_64)
|
||||
SET(CMAK_GLEW_LIBRARY
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/Glut/glew64.lib )
|
||||
ELSE(CMAKE_CL_64)
|
||||
SET(CMAK_GLEW_LIBRARY ${BULLET_PHYSICS_SOURCE_DIR}/Glut/glew32.lib )
|
||||
ENDIF(CMAKE_CL_64)
|
||||
|
||||
|
||||
IF (USE_GLUT)
|
||||
LINK_LIBRARIES(
|
||||
OpenGLSupport
|
||||
BulletWorldImporter
|
||||
BulletSoftBody
|
||||
BulletDynamics
|
||||
BulletCollision
|
||||
BulletFileLoader
|
||||
LinearMath
|
||||
BulletSoftBodySolvers_OpenCL_AMD
|
||||
BulletMultiThreaded
|
||||
${GLUT_glut_LIBRARY}
|
||||
${OPENGL_gl_LIBRARY}
|
||||
${OPENGL_glu_LIBRARY}
|
||||
${CMAK_GLEW_LIBRARY}
|
||||
${CMAKE_ATISTREAMSDK_LIBPATH}/OpenCL.lib
|
||||
)
|
||||
|
||||
IF (WIN32)
|
||||
ADD_EXECUTABLE(AppSerializeDemo_AMD
|
||||
../main.cpp
|
||||
../SerializeDemo.cpp
|
||||
../SerializeDemo.h
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/msvc/bullet.rc
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOclUtils.h
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOclCommon.h
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOclUtils.cpp
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOclCommon.cpp
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/clew.c
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/clew.h
|
||||
|
||||
)
|
||||
ELSE()
|
||||
ADD_EXECUTABLE(AppSerializeDemo_AMD
|
||||
../main.cpp
|
||||
../SerializeDemo.cpp
|
||||
../SerializeDemo.h
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOclUtils.h
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOclCommon.h
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOclUtils.cpp
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOclCommon.cpp
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/clew.c
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/clew.h
|
||||
)
|
||||
ENDIF()
|
||||
IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES)
|
||||
IF (WIN32)
|
||||
IF (CMAKE_CL_64)
|
||||
ADD_CUSTOM_COMMAND(
|
||||
TARGET AppSerializeDemo_AMD
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/glut64.dll ${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
ELSE(CMAKE_CL_64)
|
||||
ADD_CUSTOM_COMMAND(
|
||||
TARGET AppSerializeDemo_AMD
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/GLUT32.DLL ${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
ENDIF(CMAKE_CL_64)
|
||||
ENDIF(WIN32)
|
||||
ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES)
|
||||
|
||||
ELSE (USE_GLUT)
|
||||
|
||||
LINK_LIBRARIES(
|
||||
OpenGLSupport
|
||||
BulletWorldImporter
|
||||
BulletSoftBody
|
||||
BulletDynamics
|
||||
BulletCollision
|
||||
BulletFileLoader
|
||||
LinearMath
|
||||
BulletSoftBodySolvers_OpenCL_AMD
|
||||
BulletMultiThreaded
|
||||
${OPENGL_gl_LIBRARY}
|
||||
${OPENGL_glu_LIBRARY}
|
||||
${CMAK_GLEW_LIBRARY}
|
||||
${CMAKE_ATISTREAMSDK_LIBPATH}/OpenCL.lib
|
||||
)
|
||||
|
||||
ADD_EXECUTABLE(AppSerializeDemo_AMD
|
||||
WIN32
|
||||
../../OpenGL/Win32AppMain.cpp
|
||||
../Win32SerializeDemo.cpp
|
||||
../SerializeDemo.cpp
|
||||
../SerializeDemo.h
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/msvc/bullet.rc
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOclUtils.h
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOclCommon.h
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOclUtils.cpp
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/Demos/SharedOpenCL/btOclCommon.cpp
|
||||
)
|
||||
ENDIF (USE_GLUT)
|
||||
|
||||
IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES AND NOT INTERNAL_UPDATE_SERIALIZATION_STRUCTURES)
|
||||
ADD_CUSTOM_COMMAND(
|
||||
TARGET AppSerializeDemo_AMD
|
||||
POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${BULLET_PHYSICS_SOURCE_DIR}/Demos/SerializeDemo/testFile.bullet ${CMAKE_CURRENT_BINARY_DIR}/testFile.bullet
|
||||
)
|
||||
ENDIF ()
|
||||
|
||||
|
||||
IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES)
|
||||
SET_TARGET_PROPERTIES(AppSerializeDemo_AMD PROPERTIES DEBUG_POSTFIX "_Debug")
|
||||
SET_TARGET_PROPERTIES(AppSerializeDemo_AMD PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel")
|
||||
SET_TARGET_PROPERTIES(AppSerializeDemo_AMD PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo")
|
||||
ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES)
|
||||
65
Demos/SerializeDemo/AMD/premake4.lua
Normal file
65
Demos/SerializeDemo/AMD/premake4.lua
Normal file
@@ -0,0 +1,65 @@
|
||||
|
||||
hasCL = findOpenCL_AMD()
|
||||
|
||||
if (hasCL) then
|
||||
|
||||
project "AppOpenCLClothDemo_AMD"
|
||||
|
||||
defines { "USE_AMD_OPENCL","CL_PLATFORM_AMD"}
|
||||
|
||||
initOpenCL_AMD()
|
||||
|
||||
language "C++"
|
||||
|
||||
kind "ConsoleApp"
|
||||
targetdir "../../.."
|
||||
|
||||
libdirs {"../../../Glut"}
|
||||
|
||||
links {
|
||||
"LinearMath",
|
||||
"BulletCollision",
|
||||
"BulletDynamics",
|
||||
"BulletSoftBody",
|
||||
"BulletSoftBodySolvers_OpenCL_AMD",
|
||||
"opengl32"
|
||||
}
|
||||
|
||||
configuration "x64"
|
||||
links {
|
||||
"glut64",
|
||||
"glew64"
|
||||
}
|
||||
configuration "x32"
|
||||
links {
|
||||
"glut32",
|
||||
"glew32"
|
||||
}
|
||||
|
||||
configuration{}
|
||||
|
||||
|
||||
includedirs {
|
||||
"../../../src",
|
||||
"../../../Glut",
|
||||
"../../SharedOpenCL",
|
||||
"../../OpenGL"
|
||||
}
|
||||
|
||||
files {
|
||||
"../cl_cloth_demo.cpp",
|
||||
"../../SharedOpenCL/btOclUtils.h",
|
||||
"../../SharedOpenCL/btOclCommon.h",
|
||||
"../../SharedOpenCL/btOclUtils.cpp",
|
||||
"../../SharedOpenCL/btOclCommon.cpp",
|
||||
"../../OpenGL/GLDebugDrawer.cpp",
|
||||
"../../OpenGL/stb_image.cpp",
|
||||
"../../OpenGL/stb_image.h",
|
||||
"../gl_win.cpp",
|
||||
"../clstuff.cpp",
|
||||
"../clstuff.h",
|
||||
"../gl_win.h",
|
||||
"../cloth.h"
|
||||
}
|
||||
|
||||
end
|
||||
@@ -11,6 +11,10 @@ SET(GLUT_ROOT ${BULLET_PHYSICS_SOURCE_DIR}/Glut)
|
||||
# You shouldn't have to modify anything below this line
|
||||
########################################################
|
||||
|
||||
IF(BUILD_AMD_OPENCL_DEMOS)
|
||||
SUBDIRS(AMD)
|
||||
ENDIF()
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/src
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/Demos/OpenGL
|
||||
@@ -86,4 +90,6 @@ IF (INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES)
|
||||
SET_TARGET_PROPERTIES(AppSerializeDemo PROPERTIES DEBUG_POSTFIX "_Debug")
|
||||
SET_TARGET_PROPERTIES(AppSerializeDemo PROPERTIES MINSIZEREL_POSTFIX "_MinsizeRel")
|
||||
SET_TARGET_PROPERTIES(AppSerializeDemo PROPERTIES RELWITHDEBINFO_POSTFIX "_RelWithDebugInfo")
|
||||
ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES)
|
||||
ENDIF(INTERNAL_ADD_POSTFIX_EXECUTABLE_NAMES)
|
||||
|
||||
|
||||
|
||||
@@ -51,12 +51,26 @@ subject to the following restrictions:
|
||||
|
||||
|
||||
#ifdef DESERIALIZE_SOFT_BODIES
|
||||
#include "BulletSoftBody/btSoftBodySolvers.h"
|
||||
|
||||
|
||||
#ifdef USE_AMD_OPENCL
|
||||
#include <BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolver_OpenCL.h>
|
||||
#include <BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/btSoftBodySolver_OpenCLSIMDAware.h>
|
||||
extern cl_context g_cxMainContext;
|
||||
extern cl_device_id g_cdDevice;
|
||||
extern cl_command_queue g_cqCommandQue;
|
||||
#endif
|
||||
|
||||
btSoftBodySolver* fSoftBodySolver=0;
|
||||
|
||||
#include "BulletSoftBody/btSoftBodyHelpers.h"
|
||||
#include "BulletSoftBody/btSoftRigidDynamicsWorld.h"
|
||||
#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
void SerializeDemo::clientMoveAndDisplay()
|
||||
{
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
@@ -69,8 +83,27 @@ void SerializeDemo::clientMoveAndDisplay()
|
||||
{
|
||||
|
||||
m_dynamicsWorld->stepSimulation(ms / 1000000.f);
|
||||
//optional but useful: debug drawing
|
||||
|
||||
if (fSoftBodySolver)
|
||||
fSoftBodySolver->copyBackToSoftBodies();
|
||||
|
||||
m_dynamicsWorld->debugDrawWorld();
|
||||
|
||||
if (m_dynamicsWorld->getWorldType()==BT_SOFT_RIGID_DYNAMICS_WORLD)
|
||||
{
|
||||
//optional but useful: debug drawing
|
||||
btSoftRigidDynamicsWorld* softWorld = (btSoftRigidDynamicsWorld*)m_dynamicsWorld;
|
||||
|
||||
for ( int i=0;i<softWorld->getSoftBodyArray().size();i++)
|
||||
{
|
||||
btSoftBody* psb=(btSoftBody*)softWorld->getSoftBodyArray()[i];
|
||||
if (softWorld->getDebugDrawer() && !(softWorld->getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe)))
|
||||
{
|
||||
btSoftBodyHelpers::DrawFrame(psb,softWorld->getDebugDrawer());
|
||||
btSoftBodyHelpers::Draw(psb,softWorld->getDebugDrawer(),softWorld->getDrawFlags());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
renderme();
|
||||
@@ -87,6 +120,22 @@ void SerializeDemo::displayCallback(void) {
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
if (m_dynamicsWorld->getWorldType()==BT_SOFT_RIGID_DYNAMICS_WORLD)
|
||||
{
|
||||
//optional but useful: debug drawing
|
||||
btSoftRigidDynamicsWorld* softWorld = (btSoftRigidDynamicsWorld*)m_dynamicsWorld;
|
||||
|
||||
for ( int i=0;i<softWorld->getSoftBodyArray().size();i++)
|
||||
{
|
||||
btSoftBody* psb=(btSoftBody*)softWorld->getSoftBodyArray()[i];
|
||||
if (softWorld->getDebugDrawer() && !(softWorld->getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe)))
|
||||
{
|
||||
btSoftBodyHelpers::DrawFrame(psb,softWorld->getDebugDrawer());
|
||||
btSoftBodyHelpers::Draw(psb,softWorld->getDebugDrawer(),softWorld->getDrawFlags());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
renderme();
|
||||
|
||||
//optional but useful: debug drawing to detect problems
|
||||
@@ -97,7 +146,12 @@ void SerializeDemo::displayCallback(void) {
|
||||
swapBuffers();
|
||||
}
|
||||
|
||||
|
||||
enum SolverType
|
||||
{
|
||||
kSolverAccelerationOpenCL_CPU = 1,
|
||||
kSolverAccelerationOpenCL_GPU = 2,
|
||||
kSolverAccelerationNone = 3
|
||||
};
|
||||
|
||||
|
||||
void SerializeDemo::setupEmptyDynamicsWorld()
|
||||
@@ -123,7 +177,62 @@ void SerializeDemo::setupEmptyDynamicsWorld()
|
||||
m_solver = sol;
|
||||
|
||||
#ifdef DESERIALIZE_SOFT_BODIES
|
||||
btSoftRigidDynamicsWorld* world = new btSoftRigidDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration);
|
||||
|
||||
|
||||
|
||||
#ifdef USE_AMD_OPENCL
|
||||
|
||||
int solverAccel = kSolverAccelerationOpenCL_GPU;
|
||||
|
||||
if ( 1 ) {
|
||||
switch (solverAccel)
|
||||
{
|
||||
case kSolverAccelerationOpenCL_GPU:
|
||||
{
|
||||
fSoftBodySolver
|
||||
= new btOpenCLSoftBodySolverSIMDAware( g_cqCommandQue,
|
||||
g_cxMainContext );
|
||||
// fSoftBodySolver = new btOpenCLSoftBodySolver( g_cqCommandQue, g_cxMainContext);
|
||||
|
||||
/*if (!fSoftBodySolver->checkInitialized())
|
||||
{
|
||||
btAssert(0);
|
||||
delete fSoftBodySolver;
|
||||
fSoftBodySolver = NULL;
|
||||
}
|
||||
*/
|
||||
|
||||
break;
|
||||
}
|
||||
case kSolverAccelerationOpenCL_CPU:
|
||||
{
|
||||
//fSoftBodySolver = new btCPUSoftBodySolver();
|
||||
break;
|
||||
};
|
||||
case kSolverAccelerationNone:
|
||||
default:
|
||||
{
|
||||
fSoftBodySolver = NULL;
|
||||
}
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( solverAccel != kSolverAccelerationNone )
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
fSoftBodySolver = NULL;
|
||||
}
|
||||
#else
|
||||
|
||||
fSoftBodySolver = NULL;
|
||||
#endif
|
||||
|
||||
btSoftRigidDynamicsWorld* world = new btSoftRigidDynamicsWorld(m_dispatcher, m_broadphase, m_solver,
|
||||
m_collisionConfiguration, fSoftBodySolver);
|
||||
m_dynamicsWorld = world;
|
||||
//world->setDrawFlags(world->getDrawFlags()^fDrawFlags::Clusters);
|
||||
#else
|
||||
@@ -510,6 +619,7 @@ SerializeDemo::~SerializeDemo()
|
||||
|
||||
void SerializeDemo::initPhysics()
|
||||
{
|
||||
m_idle = true;
|
||||
setTexturing(true);
|
||||
setShadows(true);
|
||||
|
||||
|
||||
@@ -19,69 +19,93 @@ subject to the following restrictions:
|
||||
#include "btBulletDynamicsCommon.h"
|
||||
#include "LinearMath/btHashMap.h"
|
||||
|
||||
class OurValue
|
||||
{
|
||||
int m_uid;
|
||||
|
||||
public:
|
||||
OurValue(const btVector3& initialPos)
|
||||
:m_position(initialPos)
|
||||
{
|
||||
static int gUid=0;
|
||||
m_uid=gUid;
|
||||
gUid++;
|
||||
}
|
||||
|
||||
btVector3 m_position;
|
||||
int getUid() const
|
||||
{
|
||||
return m_uid;
|
||||
}
|
||||
};
|
||||
#ifdef USE_AMD_OPENCL
|
||||
|
||||
#ifdef _DEBUG
|
||||
bool bDebug = true;
|
||||
#else
|
||||
bool bDebug = false;
|
||||
#endif
|
||||
|
||||
|
||||
#include "btOclCommon.h"
|
||||
#include "btOclUtils.h"
|
||||
#include <LinearMath/btScalar.h>
|
||||
|
||||
cl_context g_cxMainContext;
|
||||
cl_device_id g_cdDevice;
|
||||
cl_command_queue g_cqCommandQue;
|
||||
|
||||
|
||||
// Returns true if OpenCL is initialized properly, false otherwise.
|
||||
bool initCL( void* glCtx, void* glDC )
|
||||
{
|
||||
int ciErrNum = 0;
|
||||
|
||||
#ifdef BT_USE_CLEW
|
||||
ciErrNum = clewInit( "OpenCL.dll" );
|
||||
if ( ciErrNum != CLEW_SUCCESS ) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CL_PLATFORM_MINI_CL)
|
||||
cl_device_type deviceType = CL_DEVICE_TYPE_CPU;
|
||||
#elif defined(CL_PLATFORM_AMD)
|
||||
cl_device_type deviceType = CL_DEVICE_TYPE_GPU;
|
||||
#elif defined(CL_PLATFORM_NVIDIA)
|
||||
cl_device_type deviceType = CL_DEVICE_TYPE_GPU;
|
||||
#else
|
||||
cl_device_type deviceType = CL_DEVICE_TYPE_CPU;
|
||||
#endif
|
||||
|
||||
//g_cxMainContext = btOclCommon::createContextFromType(CL_DEVICE_TYPE_ALL, &ciErrNum);
|
||||
//g_cxMainContext = btOclCommon::createContextFromType(CL_DEVICE_TYPE_GPU, &ciErrNum);
|
||||
//g_cxMainContext = btOclCommon::createContextFromType(CL_DEVICE_TYPE_CPU, &ciErrNum);
|
||||
//try CL_DEVICE_TYPE_DEBUG for sequential, non-threaded execution, when using MiniCL on CPU, it gives a full callstack at the crash in the kernel
|
||||
//#ifdef USE_MINICL
|
||||
// g_cxMainContext = btOclCommon::createContextFromType(CL_DEVICE_TYPE_DEBUG, &ciErrNum);
|
||||
//#else
|
||||
g_cxMainContext = btOclCommon::createContextFromType(deviceType, &ciErrNum, glCtx, glDC);
|
||||
//#endif
|
||||
|
||||
oclCHECKERROR(ciErrNum, CL_SUCCESS);
|
||||
g_cdDevice = btOclGetMaxFlopsDev(g_cxMainContext);
|
||||
|
||||
if ( bDebug ) {
|
||||
btOclPrintDevInfo(g_cdDevice);
|
||||
}
|
||||
|
||||
// create a command-queue
|
||||
g_cqCommandQue = clCreateCommandQueue(g_cxMainContext, g_cdDevice, 0, &ciErrNum);
|
||||
oclCHECKERROR(ciErrNum, CL_SUCCESS);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif //#ifdef USE_AMD_OPENCL
|
||||
|
||||
|
||||
int main(int argc,char** argv)
|
||||
{
|
||||
GLDebugDrawer gDebugDrawer;
|
||||
#ifdef USE_AMD_OPENCL
|
||||
bool initialized = initCL(0,0);
|
||||
btAssert(initialized);
|
||||
#endif //USE_AMD_OPENCL
|
||||
|
||||
///testing the btHashMap
|
||||
btHashMap<btHashKey<OurValue>,OurValue> map;
|
||||
|
||||
OurValue value1(btVector3(2,3,4));
|
||||
btHashKey<OurValue> key1(value1.getUid());
|
||||
map.insert(key1,value1);
|
||||
|
||||
|
||||
OurValue value2(btVector3(5,6,7));
|
||||
btHashKey<OurValue> key2(value2.getUid());
|
||||
map.insert(key2,value2);
|
||||
|
||||
|
||||
{
|
||||
OurValue value3(btVector3(7,8,9));
|
||||
btHashKey<OurValue> key3(value3.getUid());
|
||||
map.insert(key3,value3);
|
||||
}
|
||||
|
||||
|
||||
map.remove(key2);
|
||||
|
||||
// const OurValue* ourPtr = map.find(key1);
|
||||
// for (int i=0;i<map.size();i++)
|
||||
// {
|
||||
// OurValue* tmp = map.getAtIndex(i);
|
||||
// //printf("tmp value=%f,%f,%f\n",tmp->m_position.getX(),tmp->m_position.getY(),tmp->m_position.getZ());
|
||||
// }
|
||||
|
||||
SerializeDemo ccdDemo;
|
||||
ccdDemo.initPhysics();
|
||||
ccdDemo.getDynamicsWorld()->setDebugDrawer(&gDebugDrawer);
|
||||
SerializeDemo serializeDemo;
|
||||
serializeDemo.initPhysics();
|
||||
serializeDemo.getDynamicsWorld()->setDebugDrawer(&gDebugDrawer);
|
||||
|
||||
|
||||
#ifdef CHECK_MEMORY_LEAKS
|
||||
ccdDemo.exitPhysics();
|
||||
serializeDemo.exitPhysics();
|
||||
#else
|
||||
return glutmain(argc, argv,640,480,"Bullet Physics Demo. http://bulletphysics.org",&ccdDemo);
|
||||
return glutmain(argc, argv,640,480,"Bullet Physics Demo. http://bulletphysics.org",&serializeDemo);
|
||||
#endif
|
||||
|
||||
//default glut doesn't return from mainloop
|
||||
|
||||
Binary file not shown.
@@ -18,7 +18,7 @@ subject to the following restrictions:
|
||||
#include "btOclCommon.h"
|
||||
|
||||
|
||||
static const char* spPlatformVendor =
|
||||
static char* spPlatformVendor =
|
||||
#if defined(CL_PLATFORM_MINI_CL)
|
||||
"MiniCL, SCEA";
|
||||
#elif defined(CL_PLATFORM_INTEL)
|
||||
@@ -37,6 +37,7 @@ static const char* spPlatformVendor =
|
||||
#endif //_WIN32
|
||||
#endif
|
||||
|
||||
|
||||
cl_context btOclCommon::createContextFromType(cl_device_type deviceType, cl_int* pErrNum, void* pGLContext, void* pGLDC )
|
||||
{
|
||||
cl_uint numPlatforms;
|
||||
@@ -91,8 +92,9 @@ cl_context btOclCommon::createContextFromType(cl_device_type deviceType, cl_int*
|
||||
0,
|
||||
0
|
||||
};
|
||||
#ifndef CL_PLATFORM_MINI_CL
|
||||
#ifndef CL_PLATFORM_MINI_CL
|
||||
#ifdef _WIN32
|
||||
#ifndef BT_USE_CLEW
|
||||
// If we have a gl context then enable interop
|
||||
if( pGLContext )
|
||||
{
|
||||
@@ -101,7 +103,8 @@ cl_context btOclCommon::createContextFromType(cl_device_type deviceType, cl_int*
|
||||
cps[4] = CL_WGL_HDC_KHR;
|
||||
cps[5] = (cl_context_properties)pGLDC;
|
||||
}
|
||||
#endif
|
||||
#endif // DONT_USE_CLEW
|
||||
#endif //_WIN32
|
||||
#endif //CL_PLATFORM_MINI_CL
|
||||
|
||||
/* Use NULL for backward compatibility */
|
||||
@@ -115,3 +118,4 @@ cl_context btOclCommon::createContextFromType(cl_device_type deviceType, cl_int*
|
||||
return retContext;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -16,20 +16,7 @@ subject to the following restrictions:
|
||||
#ifndef BTOCLCOMMON_H
|
||||
#define BTOCLCOMMON_H
|
||||
|
||||
#ifdef __APPLE__
|
||||
#ifdef USE_MINICL
|
||||
#include <MiniCL/cl.h>
|
||||
#else
|
||||
#include <OpenCL/cl.h>
|
||||
#endif
|
||||
#else
|
||||
#ifdef USE_MINICL
|
||||
#include <MiniCL/cl.h>
|
||||
#else
|
||||
#include <CL/cl.h>
|
||||
#endif
|
||||
#endif //__APPLE__
|
||||
|
||||
#include "btOclUtils.h"
|
||||
|
||||
class btOclCommon
|
||||
{
|
||||
@@ -38,8 +25,9 @@ public:
|
||||
// to have to understand GL types.
|
||||
// It is a HGLRC in _WIN32 or a GLXContext otherwise.
|
||||
static cl_context createContextFromType(cl_device_type deviceType, cl_int* pErrNum, void* pGLCtx = 0, void* pGLDC = 0);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // BTOCLCOMMON_H
|
||||
#endif // BTOCLCOMMON_H
|
||||
|
||||
@@ -13,11 +13,14 @@ subject to the following restrictions:
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#define myprintf printf
|
||||
|
||||
|
||||
|
||||
#include "btOclUtils.h"
|
||||
@@ -56,92 +59,6 @@ cl_device_id btOclGetDev(cl_context cxMainContext, unsigned int nr)
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//! Gets the id of device with maximal FLOPS from the context
|
||||
//!
|
||||
//! @return the id
|
||||
//! @param cxMainContext OpenCL context
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
cl_device_id btOclGetMaxFlopsDev(cl_context cxMainContext)
|
||||
{
|
||||
size_t szParmDataBytes;
|
||||
cl_device_id* cdDevices;
|
||||
|
||||
// get the list of GPU devices associated with context
|
||||
clGetContextInfo(cxMainContext, CL_CONTEXT_DEVICES, 0, NULL, &szParmDataBytes);
|
||||
cdDevices = (cl_device_id*) malloc(szParmDataBytes);
|
||||
size_t device_count = szParmDataBytes / sizeof(cl_device_id);
|
||||
|
||||
clGetContextInfo(cxMainContext, CL_CONTEXT_DEVICES, szParmDataBytes, cdDevices, NULL);
|
||||
|
||||
cl_device_id max_flops_device = cdDevices[0];
|
||||
int max_flops = 0;
|
||||
|
||||
size_t current_device = 0;
|
||||
|
||||
// CL_DEVICE_MAX_COMPUTE_UNITS
|
||||
cl_uint compute_units;
|
||||
clGetDeviceInfo(cdDevices[current_device], CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(compute_units), &compute_units, NULL);
|
||||
|
||||
// CL_DEVICE_MAX_CLOCK_FREQUENCY
|
||||
cl_uint clock_frequency;
|
||||
clGetDeviceInfo(cdDevices[current_device], CL_DEVICE_MAX_CLOCK_FREQUENCY, sizeof(clock_frequency), &clock_frequency, NULL);
|
||||
|
||||
cl_device_type device_type;
|
||||
clGetDeviceInfo(cdDevices[current_device], CL_DEVICE_TYPE, sizeof(device_type), &device_type, NULL);
|
||||
|
||||
int SIMDmultiplier = 1;
|
||||
|
||||
if( device_type == CL_DEVICE_TYPE_CPU )
|
||||
{
|
||||
// For simplicity assume that the CPU is running single SSE instructions
|
||||
// This will of course depend on the kernel
|
||||
SIMDmultiplier = 4;
|
||||
} else if( device_type == CL_DEVICE_TYPE_GPU ) {
|
||||
// Approximation to GPU compute power
|
||||
// As long as this beats the CPU number that's the important thing, really
|
||||
#if defined(CL_PLATFORM_INTEL)
|
||||
// SSE - 4, AVX1,2 - 8 : TODO: detect AVX?
|
||||
SIMDmultiplier = 4;
|
||||
#elif defined(CL_PLATFORM_AMD)
|
||||
// 16 processing elements, 5 ALUs each
|
||||
SIMDmultiplier = 80;
|
||||
#elif defined(CL_PLATFORM_NVIDIA)
|
||||
// 8 processing elements, dual issue - pre-Fermi at least
|
||||
SIMDmultiplier = 16;
|
||||
#else
|
||||
SIMDmultiplier = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
max_flops = compute_units * clock_frequency * SIMDmultiplier;
|
||||
++current_device;
|
||||
|
||||
while( current_device < device_count )
|
||||
{
|
||||
// CL_DEVICE_MAX_COMPUTE_UNITS
|
||||
cl_uint compute_units;
|
||||
clGetDeviceInfo(cdDevices[current_device], CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(compute_units), &compute_units, NULL);
|
||||
|
||||
// CL_DEVICE_MAX_CLOCK_FREQUENCY
|
||||
cl_uint clock_frequency;
|
||||
clGetDeviceInfo(cdDevices[current_device], CL_DEVICE_MAX_CLOCK_FREQUENCY, sizeof(clock_frequency), &clock_frequency, NULL);
|
||||
|
||||
int flops = compute_units * clock_frequency;
|
||||
if( flops > max_flops )
|
||||
{
|
||||
max_flops = flops;
|
||||
max_flops_device = cdDevices[current_device];
|
||||
}
|
||||
++current_device;
|
||||
}
|
||||
|
||||
free(cdDevices);
|
||||
|
||||
return max_flops_device;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//! Loads a Program file and prepends the cPreamble to the code.
|
||||
@@ -221,140 +138,139 @@ cl_device_id btOclGetFirstDev(cl_context cxMainContext)
|
||||
void btOclPrintDevInfo(cl_device_id device)
|
||||
{
|
||||
char device_string[1024];
|
||||
bool nv_device_attibute_query = false;
|
||||
|
||||
// CL_DEVICE_NAME
|
||||
clGetDeviceInfo(device, CL_DEVICE_NAME, sizeof(device_string), &device_string, NULL);
|
||||
printf(" CL_DEVICE_NAME: \t\t\t%s\n", device_string);
|
||||
myprintf(" CL_DEVICE_NAME: \t\t\t%s\n", device_string);
|
||||
|
||||
// CL_DEVICE_VENDOR
|
||||
clGetDeviceInfo(device, CL_DEVICE_VENDOR, sizeof(device_string), &device_string, NULL);
|
||||
printf(" CL_DEVICE_VENDOR: \t\t\t%s\n", device_string);
|
||||
myprintf(" CL_DEVICE_VENDOR: \t\t\t%s\n", device_string);
|
||||
|
||||
// CL_DRIVER_VERSION
|
||||
clGetDeviceInfo(device, CL_DRIVER_VERSION, sizeof(device_string), &device_string, NULL);
|
||||
printf(" CL_DRIVER_VERSION: \t\t\t%s\n", device_string);
|
||||
myprintf(" CL_DRIVER_VERSION: \t\t\t%s\n", device_string);
|
||||
|
||||
// CL_DEVICE_INFO
|
||||
cl_device_type type;
|
||||
clGetDeviceInfo(device, CL_DEVICE_TYPE, sizeof(type), &type, NULL);
|
||||
if( type & CL_DEVICE_TYPE_CPU )
|
||||
printf(" CL_DEVICE_TYPE:\t\t\t%s\n", "CL_DEVICE_TYPE_CPU");
|
||||
myprintf(" CL_DEVICE_TYPE:\t\t\t%s\n", "CL_DEVICE_TYPE_CPU");
|
||||
if( type & CL_DEVICE_TYPE_GPU )
|
||||
printf(" CL_DEVICE_TYPE:\t\t\t%s\n", "CL_DEVICE_TYPE_GPU");
|
||||
myprintf(" CL_DEVICE_TYPE:\t\t\t%s\n", "CL_DEVICE_TYPE_GPU");
|
||||
if( type & CL_DEVICE_TYPE_ACCELERATOR )
|
||||
printf(" CL_DEVICE_TYPE:\t\t\t%s\n", "CL_DEVICE_TYPE_ACCELERATOR");
|
||||
myprintf(" CL_DEVICE_TYPE:\t\t\t%s\n", "CL_DEVICE_TYPE_ACCELERATOR");
|
||||
if( type & CL_DEVICE_TYPE_DEFAULT )
|
||||
printf(" CL_DEVICE_TYPE:\t\t\t%s\n", "CL_DEVICE_TYPE_DEFAULT");
|
||||
myprintf(" CL_DEVICE_TYPE:\t\t\t%s\n", "CL_DEVICE_TYPE_DEFAULT");
|
||||
|
||||
// CL_DEVICE_MAX_COMPUTE_UNITS
|
||||
cl_uint compute_units;
|
||||
clGetDeviceInfo(device, CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(compute_units), &compute_units, NULL);
|
||||
printf(" CL_DEVICE_MAX_COMPUTE_UNITS:\t\t%u\n", compute_units);
|
||||
myprintf(" CL_DEVICE_MAX_COMPUTE_UNITS:\t\t%u\n", compute_units);
|
||||
|
||||
// CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS
|
||||
size_t workitem_dims;
|
||||
clGetDeviceInfo(device, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, sizeof(workitem_dims), &workitem_dims, NULL);
|
||||
printf(" CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS:\t%d\n", workitem_dims);
|
||||
myprintf(" CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS:\t%u\n", workitem_dims);
|
||||
|
||||
// CL_DEVICE_MAX_WORK_ITEM_SIZES
|
||||
size_t workitem_size[3];
|
||||
clGetDeviceInfo(device, CL_DEVICE_MAX_WORK_ITEM_SIZES, sizeof(workitem_size), &workitem_size, NULL);
|
||||
printf(" CL_DEVICE_MAX_WORK_ITEM_SIZES:\t%d / %d / %d \n", workitem_size[0], workitem_size[1], workitem_size[2]);
|
||||
myprintf(" CL_DEVICE_MAX_WORK_ITEM_SIZES:\t%u / %u / %u \n", workitem_size[0], workitem_size[1], workitem_size[2]);
|
||||
|
||||
// CL_DEVICE_MAX_WORK_GROUP_SIZE
|
||||
size_t workgroup_size;
|
||||
clGetDeviceInfo(device, CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof(workgroup_size), &workgroup_size, NULL);
|
||||
printf(" CL_DEVICE_MAX_WORK_GROUP_SIZE:\t%d\n", workgroup_size);
|
||||
myprintf(" CL_DEVICE_MAX_WORK_GROUP_SIZE:\t%u\n", workgroup_size);
|
||||
|
||||
// CL_DEVICE_MAX_CLOCK_FREQUENCY
|
||||
cl_uint clock_frequency;
|
||||
clGetDeviceInfo(device, CL_DEVICE_MAX_CLOCK_FREQUENCY, sizeof(clock_frequency), &clock_frequency, NULL);
|
||||
printf(" CL_DEVICE_MAX_CLOCK_FREQUENCY:\t%u MHz\n", clock_frequency);
|
||||
myprintf(" CL_DEVICE_MAX_CLOCK_FREQUENCY:\t%u MHz\n", clock_frequency);
|
||||
|
||||
// CL_DEVICE_ADDRESS_BITS
|
||||
cl_uint addr_bits;
|
||||
clGetDeviceInfo(device, CL_DEVICE_ADDRESS_BITS, sizeof(addr_bits), &addr_bits, NULL);
|
||||
printf(" CL_DEVICE_ADDRESS_BITS:\t\t%u\n", addr_bits);
|
||||
myprintf(" CL_DEVICE_ADDRESS_BITS:\t\t%u\n", addr_bits);
|
||||
|
||||
// CL_DEVICE_MAX_MEM_ALLOC_SIZE
|
||||
cl_ulong max_mem_alloc_size;
|
||||
clGetDeviceInfo(device, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof(max_mem_alloc_size), &max_mem_alloc_size, NULL);
|
||||
printf(" CL_DEVICE_MAX_MEM_ALLOC_SIZE:\t\t%u MByte\n", (unsigned int)(max_mem_alloc_size / (1024 * 1024)));
|
||||
myprintf(" CL_DEVICE_MAX_MEM_ALLOC_SIZE:\t\t%u MByte\n", (unsigned int)(max_mem_alloc_size / (1024 * 1024)));
|
||||
|
||||
// CL_DEVICE_GLOBAL_MEM_SIZE
|
||||
cl_ulong mem_size;
|
||||
clGetDeviceInfo(device, CL_DEVICE_GLOBAL_MEM_SIZE, sizeof(mem_size), &mem_size, NULL);
|
||||
printf(" CL_DEVICE_GLOBAL_MEM_SIZE:\t\t%u MByte\n", (unsigned int)(mem_size / (1024 * 1024)));
|
||||
myprintf(" CL_DEVICE_GLOBAL_MEM_SIZE:\t\t%u MByte\n", (unsigned int)(mem_size / (1024 * 1024)));
|
||||
|
||||
// CL_DEVICE_ERROR_CORRECTION_SUPPORT
|
||||
cl_bool error_correction_support;
|
||||
clGetDeviceInfo(device, CL_DEVICE_ERROR_CORRECTION_SUPPORT, sizeof(error_correction_support), &error_correction_support, NULL);
|
||||
printf(" CL_DEVICE_ERROR_CORRECTION_SUPPORT:\t%s\n", error_correction_support == CL_TRUE ? "yes" : "no");
|
||||
myprintf(" CL_DEVICE_ERROR_CORRECTION_SUPPORT:\t%s\n", error_correction_support == CL_TRUE ? "yes" : "no");
|
||||
|
||||
// CL_DEVICE_LOCAL_MEM_TYPE
|
||||
cl_device_local_mem_type local_mem_type;
|
||||
clGetDeviceInfo(device, CL_DEVICE_LOCAL_MEM_TYPE, sizeof(local_mem_type), &local_mem_type, NULL);
|
||||
printf(" CL_DEVICE_LOCAL_MEM_TYPE:\t\t%s\n", local_mem_type == 1 ? "local" : "global");
|
||||
myprintf(" CL_DEVICE_LOCAL_MEM_TYPE:\t\t%s\n", local_mem_type == 1 ? "local" : "global");
|
||||
|
||||
// CL_DEVICE_LOCAL_MEM_SIZE
|
||||
clGetDeviceInfo(device, CL_DEVICE_LOCAL_MEM_SIZE, sizeof(mem_size), &mem_size, NULL);
|
||||
printf(" CL_DEVICE_LOCAL_MEM_SIZE:\t\t%u KByte\n", (unsigned int)(mem_size / 1024));
|
||||
myprintf(" CL_DEVICE_LOCAL_MEM_SIZE:\t\t%u KByte\n", (unsigned int)(mem_size / 1024));
|
||||
|
||||
// CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE
|
||||
clGetDeviceInfo(device, CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE, sizeof(mem_size), &mem_size, NULL);
|
||||
printf(" CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE:\t%u KByte\n", (unsigned int)(mem_size / 1024));
|
||||
myprintf(" CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE:\t%u KByte\n", (unsigned int)(mem_size / 1024));
|
||||
|
||||
// CL_DEVICE_QUEUE_PROPERTIES
|
||||
cl_command_queue_properties queue_properties;
|
||||
clGetDeviceInfo(device, CL_DEVICE_QUEUE_PROPERTIES, sizeof(queue_properties), &queue_properties, NULL);
|
||||
if( queue_properties & CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE )
|
||||
printf(" CL_DEVICE_QUEUE_PROPERTIES:\t\t%s\n", "CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE");
|
||||
myprintf(" CL_DEVICE_QUEUE_PROPERTIES:\t\t%s\n", "CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE");
|
||||
if( queue_properties & CL_QUEUE_PROFILING_ENABLE )
|
||||
printf(" CL_DEVICE_QUEUE_PROPERTIES:\t\t%s\n", "CL_QUEUE_PROFILING_ENABLE");
|
||||
myprintf(" CL_DEVICE_QUEUE_PROPERTIES:\t\t%s\n", "CL_QUEUE_PROFILING_ENABLE");
|
||||
|
||||
// CL_DEVICE_IMAGE_SUPPORT
|
||||
cl_bool image_support;
|
||||
clGetDeviceInfo(device, CL_DEVICE_IMAGE_SUPPORT, sizeof(image_support), &image_support, NULL);
|
||||
printf(" CL_DEVICE_IMAGE_SUPPORT:\t\t%u\n", image_support);
|
||||
myprintf(" CL_DEVICE_IMAGE_SUPPORT:\t\t%u\n", image_support);
|
||||
|
||||
// CL_DEVICE_MAX_READ_IMAGE_ARGS
|
||||
cl_uint max_read_image_args;
|
||||
clGetDeviceInfo(device, CL_DEVICE_MAX_READ_IMAGE_ARGS, sizeof(max_read_image_args), &max_read_image_args, NULL);
|
||||
printf(" CL_DEVICE_MAX_READ_IMAGE_ARGS:\t%u\n", max_read_image_args);
|
||||
myprintf(" CL_DEVICE_MAX_READ_IMAGE_ARGS:\t%u\n", max_read_image_args);
|
||||
|
||||
// CL_DEVICE_MAX_WRITE_IMAGE_ARGS
|
||||
cl_uint max_write_image_args;
|
||||
clGetDeviceInfo(device, CL_DEVICE_MAX_WRITE_IMAGE_ARGS, sizeof(max_write_image_args), &max_write_image_args, NULL);
|
||||
printf(" CL_DEVICE_MAX_WRITE_IMAGE_ARGS:\t%u\n", max_write_image_args);
|
||||
myprintf(" CL_DEVICE_MAX_WRITE_IMAGE_ARGS:\t%u\n", max_write_image_args);
|
||||
|
||||
// CL_DEVICE_IMAGE2D_MAX_WIDTH, CL_DEVICE_IMAGE2D_MAX_HEIGHT, CL_DEVICE_IMAGE3D_MAX_WIDTH, CL_DEVICE_IMAGE3D_MAX_HEIGHT, CL_DEVICE_IMAGE3D_MAX_DEPTH
|
||||
size_t szMaxDims[5];
|
||||
printf("\n CL_DEVICE_IMAGE <dim>");
|
||||
myprintf("\n CL_DEVICE_IMAGE <dim>\n");
|
||||
clGetDeviceInfo(device, CL_DEVICE_IMAGE2D_MAX_WIDTH, sizeof(size_t), &szMaxDims[0], NULL);
|
||||
printf("\t\t\t2D_MAX_WIDTH\t %d\n", szMaxDims[0]);
|
||||
myprintf("\t\t\t2D_MAX_WIDTH\t %u\n", szMaxDims[0]);
|
||||
clGetDeviceInfo(device, CL_DEVICE_IMAGE2D_MAX_HEIGHT, sizeof(size_t), &szMaxDims[1], NULL);
|
||||
printf("\t\t\t\t\t2D_MAX_HEIGHT\t %d\n", szMaxDims[1]);
|
||||
myprintf("\t\t\t\t\t2D_MAX_HEIGHT\t %u\n", szMaxDims[1]);
|
||||
clGetDeviceInfo(device, CL_DEVICE_IMAGE3D_MAX_WIDTH, sizeof(size_t), &szMaxDims[2], NULL);
|
||||
printf("\t\t\t\t\t3D_MAX_WIDTH\t %d\n", szMaxDims[2]);
|
||||
myprintf("\t\t\t\t\t3D_MAX_WIDTH\t %u\n", szMaxDims[2]);
|
||||
clGetDeviceInfo(device, CL_DEVICE_IMAGE3D_MAX_HEIGHT, sizeof(size_t), &szMaxDims[3], NULL);
|
||||
printf("\t\t\t\t\t3D_MAX_HEIGHT\t %d\n", szMaxDims[3]);
|
||||
myprintf("\t\t\t\t\t3D_MAX_HEIGHT\t %u\n", szMaxDims[3]);
|
||||
clGetDeviceInfo(device, CL_DEVICE_IMAGE3D_MAX_DEPTH, sizeof(size_t), &szMaxDims[4], NULL);
|
||||
printf("\t\t\t\t\t3D_MAX_DEPTH\t %d\n", szMaxDims[4]);
|
||||
myprintf("\t\t\t\t\t3D_MAX_DEPTH\t %u\n", szMaxDims[4]);
|
||||
|
||||
// CL_DEVICE_EXTENSIONS: get device extensions, and if any then parse & log the string onto separate lines
|
||||
clGetDeviceInfo(device, CL_DEVICE_EXTENSIONS, sizeof(device_string), &device_string, NULL);
|
||||
if (device_string != 0)
|
||||
{
|
||||
printf("\n CL_DEVICE_EXTENSIONS:%s\n",device_string);
|
||||
myprintf("\n CL_DEVICE_EXTENSIONS:%s\n",device_string);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf(" CL_DEVICE_EXTENSIONS: None\n");
|
||||
myprintf(" CL_DEVICE_EXTENSIONS: None\n");
|
||||
}
|
||||
|
||||
// CL_DEVICE_PREFERRED_VECTOR_WIDTH_<type>
|
||||
printf(" CL_DEVICE_PREFERRED_VECTOR_WIDTH_<t>\t");
|
||||
myprintf(" CL_DEVICE_PREFERRED_VECTOR_WIDTH_<t>\t\n");
|
||||
cl_uint vec_width [6];
|
||||
clGetDeviceInfo(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR, sizeof(cl_uint), &vec_width[0], NULL);
|
||||
clGetDeviceInfo(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT, sizeof(cl_uint), &vec_width[1], NULL);
|
||||
@@ -362,6 +278,7 @@ void btOclPrintDevInfo(cl_device_id device)
|
||||
clGetDeviceInfo(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG, sizeof(cl_uint), &vec_width[3], NULL);
|
||||
clGetDeviceInfo(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT, sizeof(cl_uint), &vec_width[4], NULL);
|
||||
clGetDeviceInfo(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE, sizeof(cl_uint), &vec_width[5], NULL);
|
||||
printf("CHAR %u, SHORT %u, INT %u, FLOAT %u, DOUBLE %u\n\n\n",
|
||||
myprintf("CHAR %u, SHORT %u, INT %u, FLOAT %u, DOUBLE %u\n\n",
|
||||
vec_width[0], vec_width[1], vec_width[2], vec_width[3], vec_width[4]);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,15 +18,17 @@ subject to the following restrictions:
|
||||
|
||||
#ifdef USE_MINICL
|
||||
#include <MiniCL/cl.h>
|
||||
#else //USE_MINICL
|
||||
#ifdef BT_USE_CLEW
|
||||
#include "clew.h"
|
||||
#else
|
||||
#ifdef __APPLE__
|
||||
#include <OpenCL/cl.h>
|
||||
#else
|
||||
#include <CL/cl.h>
|
||||
#endif __APPLE__
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#ifdef __APPLE__
|
||||
#include <OpenCL/cl.h>
|
||||
#else
|
||||
#include <CL/cl.h>
|
||||
#endif //__APPLE__
|
||||
#endif //BT_USE_CLEW
|
||||
#endif //USE_MINICL
|
||||
|
||||
|
||||
//#define oclCHECKERROR(a, b) btAssert((a) == (b))
|
||||
@@ -35,7 +37,6 @@ subject to the following restrictions:
|
||||
|
||||
void btOclPrintDevInfo(cl_device_id device);
|
||||
cl_device_id btOclGetDev(cl_context cxMainContext, unsigned int nr);
|
||||
cl_device_id btOclGetMaxFlopsDev(cl_context cxMainContext);
|
||||
char* btOclLoadProgSource(const char* cFilename, const char* cPreamble, size_t* szFinalLength);
|
||||
cl_device_id btOclGetFirstDev(cl_context cxMainContext);
|
||||
#endif //BT_OCL_UTILS_H
|
||||
|
||||
313
Demos/SharedOpenCL/clew.c
Normal file
313
Demos/SharedOpenCL/clew.c
Normal file
@@ -0,0 +1,313 @@
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (c) 2009 Organic Vectory B.V.
|
||||
// Written by George van Venrooij
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file license.txt)
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
#ifndef USE_MINICL
|
||||
#include "clew.h"
|
||||
|
||||
//! \file clew.c
|
||||
//! \brief OpenCL run-time loader source
|
||||
|
||||
#ifndef CLCC_GENERATE_DOCUMENTATION
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define VC_EXTRALEAN
|
||||
#define NOMINMAX
|
||||
#include <windows.h>
|
||||
|
||||
typedef HMODULE CLCC_DYNLIB_HANDLE;
|
||||
|
||||
#define CLCC_DYNLIB_OPEN LoadLibrary
|
||||
#define CLCC_DYNLIB_CLOSE FreeLibrary
|
||||
#define CLCC_DYNLIB_IMPORT GetProcAddress
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
|
||||
typedef void* CLCC_DYNLIB_HANDLE;
|
||||
|
||||
#define CLCC_DYNLIB_OPEN(path) dlopen(path, RTLD_NOW | RTLD_GLOBAL)
|
||||
#define CLCC_DYNLIB_CLOSE dlclose
|
||||
#define CLCC_DYNLIB_IMPORT dlsym
|
||||
#endif
|
||||
#else
|
||||
//typedef implementation_defined CLCC_DYNLIB_HANDLE;
|
||||
//#define CLCC_DYNLIB_OPEN(path) implementation_defined
|
||||
//#define CLCC_DYNLIB_CLOSE implementation_defined
|
||||
//#define CLCC_DYNLIB_IMPORT implementation_defined
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
//! \brief module handle
|
||||
static CLCC_DYNLIB_HANDLE module = NULL;
|
||||
|
||||
// Variables holding function entry points
|
||||
#ifndef CLCC_GENERATE_DOCUMENTATION
|
||||
PFNCLGETPLATFORMIDS __clewGetPlatformIDs = NULL;
|
||||
PFNCLGETPLATFORMINFO __clewGetPlatformInfo = NULL;
|
||||
PFNCLGETDEVICEIDS __clewGetDeviceIDs = NULL;
|
||||
PFNCLGETDEVICEINFO __clewGetDeviceInfo = NULL;
|
||||
PFNCLCREATECONTEXT __clewCreateContext = NULL;
|
||||
PFNCLCREATECONTEXTFROMTYPE __clewCreateContextFromType = NULL;
|
||||
PFNCLRETAINCONTEXT __clewRetainContext = NULL;
|
||||
PFNCLRELEASECONTEXT __clewReleaseContext = NULL;
|
||||
PFNCLGETCONTEXTINFO __clewGetContextInfo = NULL;
|
||||
PFNCLCREATECOMMANDQUEUE __clewCreateCommandQueue = NULL;
|
||||
PFNCLRETAINCOMMANDQUEUE __clewRetainCommandQueue = NULL;
|
||||
PFNCLRELEASECOMMANDQUEUE __clewReleaseCommandQueue = NULL;
|
||||
PFNCLGETCOMMANDQUEUEINFO __clewGetCommandQueueInfo = NULL;
|
||||
PFNCLSETCOMMANDQUEUEPROPERTY __clewSetCommandQueueProperty = NULL;
|
||||
PFNCLCREATEBUFFER __clewCreateBuffer = NULL;
|
||||
PFNCLCREATEIMAGE2D __clewCreateImage2D = NULL;
|
||||
PFNCLCREATEIMAGE3D __clewCreateImage3D = NULL;
|
||||
PFNCLRETAINMEMOBJECT __clewRetainMemObject = NULL;
|
||||
PFNCLRELEASEMEMOBJECT __clewReleaseMemObject = NULL;
|
||||
PFNCLGETSUPPORTEDIMAGEFORMATS __clewGetSupportedImageFormats = NULL;
|
||||
PFNCLGETMEMOBJECTINFO __clewGetMemObjectInfo = NULL;
|
||||
PFNCLGETIMAGEINFO __clewGetImageInfo = NULL;
|
||||
PFNCLCREATESAMPLER __clewCreateSampler = NULL;
|
||||
PFNCLRETAINSAMPLER __clewRetainSampler = NULL;
|
||||
PFNCLRELEASESAMPLER __clewReleaseSampler = NULL;
|
||||
PFNCLGETSAMPLERINFO __clewGetSamplerInfo = NULL;
|
||||
PFNCLCREATEPROGRAMWITHSOURCE __clewCreateProgramWithSource = NULL;
|
||||
PFNCLCREATEPROGRAMWITHBINARY __clewCreateProgramWithBinary = NULL;
|
||||
PFNCLRETAINPROGRAM __clewRetainProgram = NULL;
|
||||
PFNCLRELEASEPROGRAM __clewReleaseProgram = NULL;
|
||||
PFNCLBUILDPROGRAM __clewBuildProgram = NULL;
|
||||
PFNCLUNLOADCOMPILER __clewUnloadCompiler = NULL;
|
||||
PFNCLGETPROGRAMINFO __clewGetProgramInfo = NULL;
|
||||
PFNCLGETPROGRAMBUILDINFO __clewGetProgramBuildInfo = NULL;
|
||||
PFNCLCREATEKERNEL __clewCreateKernel = NULL;
|
||||
PFNCLCREATEKERNELSINPROGRAM __clewCreateKernelsInProgram = NULL;
|
||||
PFNCLRETAINKERNEL __clewRetainKernel = NULL;
|
||||
PFNCLRELEASEKERNEL __clewReleaseKernel = NULL;
|
||||
PFNCLSETKERNELARG __clewSetKernelArg = NULL;
|
||||
PFNCLGETKERNELINFO __clewGetKernelInfo = NULL;
|
||||
PFNCLGETKERNELWORKGROUPINFO __clewGetKernelWorkGroupInfo = NULL;
|
||||
PFNCLWAITFOREVENTS __clewWaitForEvents = NULL;
|
||||
PFNCLGETEVENTINFO __clewGetEventInfo = NULL;
|
||||
PFNCLRETAINEVENT __clewRetainEvent = NULL;
|
||||
PFNCLRELEASEEVENT __clewReleaseEvent = NULL;
|
||||
PFNCLGETEVENTPROFILINGINFO __clewGetEventProfilingInfo = NULL;
|
||||
PFNCLFLUSH __clewFlush = NULL;
|
||||
PFNCLFINISH __clewFinish = NULL;
|
||||
PFNCLENQUEUEREADBUFFER __clewEnqueueReadBuffer = NULL;
|
||||
PFNCLENQUEUEWRITEBUFFER __clewEnqueueWriteBuffer = NULL;
|
||||
PFNCLENQUEUECOPYBUFFER __clewEnqueueCopyBuffer = NULL;
|
||||
PFNCLENQUEUEREADIMAGE __clewEnqueueReadImage = NULL;
|
||||
PFNCLENQUEUEWRITEIMAGE __clewEnqueueWriteImage = NULL;
|
||||
PFNCLENQUEUECOPYIMAGE __clewEnqueueCopyImage = NULL;
|
||||
PFNCLENQUEUECOPYIMAGETOBUFFER __clewEnqueueCopyImageToBuffer = NULL;
|
||||
PFNCLENQUEUECOPYBUFFERTOIMAGE __clewEnqueueCopyBufferToImage = NULL;
|
||||
PFNCLENQUEUEMAPBUFFER __clewEnqueueMapBuffer = NULL;
|
||||
PFNCLENQUEUEMAPIMAGE __clewEnqueueMapImage = NULL;
|
||||
PFNCLENQUEUEUNMAPMEMOBJECT __clewEnqueueUnmapMemObject = NULL;
|
||||
PFNCLENQUEUENDRANGEKERNEL __clewEnqueueNDRangeKernel = NULL;
|
||||
PFNCLENQUEUETASK __clewEnqueueTask = NULL;
|
||||
PFNCLENQUEUENATIVEKERNEL __clewEnqueueNativeKernel = NULL;
|
||||
PFNCLENQUEUEMARKER __clewEnqueueMarker = NULL;
|
||||
PFNCLENQUEUEWAITFOREVENTS __clewEnqueueWaitForEvents = NULL;
|
||||
PFNCLENQUEUEBARRIER __clewEnqueueBarrier = NULL;
|
||||
PFNCLGETEXTENSIONFUNCTIONADDRESS __clewGetExtensionFunctionAddress = NULL;
|
||||
#endif // CLCC_GENERATE_DOCUMENTATION
|
||||
|
||||
|
||||
//! \brief Unloads OpenCL dynamic library, should not be called directly
|
||||
static void clewExit(void)
|
||||
{
|
||||
if (module != NULL)
|
||||
{
|
||||
// Ignore errors
|
||||
CLCC_DYNLIB_CLOSE(module);
|
||||
module = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//! \param path path to dynamic library to load
|
||||
//! \return CLEW_ERROR_OPEN_FAILED if the library could not be opened
|
||||
//! CLEW_ERROR_ATEXIT_FAILED if atexit(clewExit) failed
|
||||
//! CLEW_SUCCESS when the library was succesfully loaded
|
||||
int clewInit(const char* path)
|
||||
{
|
||||
int error = 0;
|
||||
|
||||
// Check if already initialized
|
||||
if (module != NULL)
|
||||
{
|
||||
return CLEW_SUCCESS;
|
||||
}
|
||||
|
||||
// Load library
|
||||
module = CLCC_DYNLIB_OPEN(path);
|
||||
|
||||
// Check for errors
|
||||
if (module == NULL)
|
||||
{
|
||||
return CLEW_ERROR_OPEN_FAILED;
|
||||
}
|
||||
|
||||
// Set unloading
|
||||
error = atexit(clewExit);
|
||||
|
||||
if (error)
|
||||
{
|
||||
// Failure queing atexit, shutdown with error
|
||||
CLCC_DYNLIB_CLOSE(module);
|
||||
module = NULL;
|
||||
|
||||
return CLEW_ERROR_ATEXIT_FAILED;
|
||||
}
|
||||
|
||||
// Determine function entry-points
|
||||
__clewGetPlatformIDs = (PFNCLGETPLATFORMIDS )CLCC_DYNLIB_IMPORT(module, "clGetPlatformIDs");
|
||||
__clewGetPlatformInfo = (PFNCLGETPLATFORMINFO )CLCC_DYNLIB_IMPORT(module, "clGetPlatformInfo");
|
||||
__clewGetDeviceIDs = (PFNCLGETDEVICEIDS )CLCC_DYNLIB_IMPORT(module, "clGetDeviceIDs");
|
||||
__clewGetDeviceInfo = (PFNCLGETDEVICEINFO )CLCC_DYNLIB_IMPORT(module, "clGetDeviceInfo");
|
||||
__clewCreateContext = (PFNCLCREATECONTEXT )CLCC_DYNLIB_IMPORT(module, "clCreateContext");
|
||||
__clewCreateContextFromType = (PFNCLCREATECONTEXTFROMTYPE )CLCC_DYNLIB_IMPORT(module, "clCreateContextFromType");
|
||||
__clewRetainContext = (PFNCLRETAINCONTEXT )CLCC_DYNLIB_IMPORT(module, "clRetainContext");
|
||||
__clewReleaseContext = (PFNCLRELEASECONTEXT )CLCC_DYNLIB_IMPORT(module, "clReleaseContext");
|
||||
__clewGetContextInfo = (PFNCLGETCONTEXTINFO )CLCC_DYNLIB_IMPORT(module, "clGetContextInfo");
|
||||
__clewCreateCommandQueue = (PFNCLCREATECOMMANDQUEUE )CLCC_DYNLIB_IMPORT(module, "clCreateCommandQueue");
|
||||
__clewRetainCommandQueue = (PFNCLRETAINCOMMANDQUEUE )CLCC_DYNLIB_IMPORT(module, "clRetainCommandQueue");
|
||||
__clewReleaseCommandQueue = (PFNCLRELEASECOMMANDQUEUE )CLCC_DYNLIB_IMPORT(module, "clReleaseCommandQueue");
|
||||
__clewGetCommandQueueInfo = (PFNCLGETCOMMANDQUEUEINFO )CLCC_DYNLIB_IMPORT(module, "clGetCommandQueueInfo");
|
||||
__clewSetCommandQueueProperty = (PFNCLSETCOMMANDQUEUEPROPERTY )CLCC_DYNLIB_IMPORT(module, "clSetCommandQueueProperty");
|
||||
__clewCreateBuffer = (PFNCLCREATEBUFFER )CLCC_DYNLIB_IMPORT(module, "clCreateBuffer");
|
||||
__clewCreateImage2D = (PFNCLCREATEIMAGE2D )CLCC_DYNLIB_IMPORT(module, "clCreateImage2D");
|
||||
__clewCreateImage3D = (PFNCLCREATEIMAGE3D )CLCC_DYNLIB_IMPORT(module, "clCreateImage3D");
|
||||
__clewRetainMemObject = (PFNCLRETAINMEMOBJECT )CLCC_DYNLIB_IMPORT(module, "clRetainMemObject");
|
||||
__clewReleaseMemObject = (PFNCLRELEASEMEMOBJECT )CLCC_DYNLIB_IMPORT(module, "clReleaseMemObject");
|
||||
__clewGetSupportedImageFormats = (PFNCLGETSUPPORTEDIMAGEFORMATS )CLCC_DYNLIB_IMPORT(module, "clGetSupportedImageFormats");
|
||||
__clewGetMemObjectInfo = (PFNCLGETMEMOBJECTINFO )CLCC_DYNLIB_IMPORT(module, "clGetMemObjectInfo");
|
||||
__clewGetImageInfo = (PFNCLGETIMAGEINFO )CLCC_DYNLIB_IMPORT(module, "clGetImageInfo");
|
||||
__clewCreateSampler = (PFNCLCREATESAMPLER )CLCC_DYNLIB_IMPORT(module, "clCreateSampler");
|
||||
__clewRetainSampler = (PFNCLRETAINSAMPLER )CLCC_DYNLIB_IMPORT(module, "clRetainSampler");
|
||||
__clewReleaseSampler = (PFNCLRELEASESAMPLER )CLCC_DYNLIB_IMPORT(module, "clReleaseSampler");
|
||||
__clewGetSamplerInfo = (PFNCLGETSAMPLERINFO )CLCC_DYNLIB_IMPORT(module, "clGetSamplerInfo");
|
||||
__clewCreateProgramWithSource = (PFNCLCREATEPROGRAMWITHSOURCE )CLCC_DYNLIB_IMPORT(module, "clCreateProgramWithSource");
|
||||
__clewCreateProgramWithBinary = (PFNCLCREATEPROGRAMWITHBINARY )CLCC_DYNLIB_IMPORT(module, "clCreateProgramWithBinary");
|
||||
__clewRetainProgram = (PFNCLRETAINPROGRAM )CLCC_DYNLIB_IMPORT(module, "clRetainProgram");
|
||||
__clewReleaseProgram = (PFNCLRELEASEPROGRAM )CLCC_DYNLIB_IMPORT(module, "clReleaseProgram");
|
||||
__clewBuildProgram = (PFNCLBUILDPROGRAM )CLCC_DYNLIB_IMPORT(module, "clBuildProgram");
|
||||
__clewUnloadCompiler = (PFNCLUNLOADCOMPILER )CLCC_DYNLIB_IMPORT(module, "clUnloadCompiler");
|
||||
__clewGetProgramInfo = (PFNCLGETPROGRAMINFO )CLCC_DYNLIB_IMPORT(module, "clGetProgramInfo");
|
||||
__clewGetProgramBuildInfo = (PFNCLGETPROGRAMBUILDINFO )CLCC_DYNLIB_IMPORT(module, "clGetProgramBuildInfo");
|
||||
__clewCreateKernel = (PFNCLCREATEKERNEL )CLCC_DYNLIB_IMPORT(module, "clCreateKernel");
|
||||
__clewCreateKernelsInProgram = (PFNCLCREATEKERNELSINPROGRAM )CLCC_DYNLIB_IMPORT(module, "clCreateKernelsInProgram");
|
||||
__clewRetainKernel = (PFNCLRETAINKERNEL )CLCC_DYNLIB_IMPORT(module, "clRetainKernel");
|
||||
__clewReleaseKernel = (PFNCLRELEASEKERNEL )CLCC_DYNLIB_IMPORT(module, "clReleaseKernel");
|
||||
__clewSetKernelArg = (PFNCLSETKERNELARG )CLCC_DYNLIB_IMPORT(module, "clSetKernelArg");
|
||||
__clewGetKernelInfo = (PFNCLGETKERNELINFO )CLCC_DYNLIB_IMPORT(module, "clGetKernelInfo");
|
||||
__clewGetKernelWorkGroupInfo = (PFNCLGETKERNELWORKGROUPINFO )CLCC_DYNLIB_IMPORT(module, "clGetKernelWorkGroupInfo");
|
||||
__clewWaitForEvents = (PFNCLWAITFOREVENTS )CLCC_DYNLIB_IMPORT(module, "clWaitForEvents");
|
||||
__clewGetEventInfo = (PFNCLGETEVENTINFO )CLCC_DYNLIB_IMPORT(module, "clGetEventInfo");
|
||||
__clewRetainEvent = (PFNCLRETAINEVENT )CLCC_DYNLIB_IMPORT(module, "clRetainEvent");
|
||||
__clewReleaseEvent = (PFNCLRELEASEEVENT )CLCC_DYNLIB_IMPORT(module, "clReleaseEvent");
|
||||
__clewGetEventProfilingInfo = (PFNCLGETEVENTPROFILINGINFO )CLCC_DYNLIB_IMPORT(module, "clGetEventProfilingInfo");
|
||||
__clewFlush = (PFNCLFLUSH )CLCC_DYNLIB_IMPORT(module, "clFlush");
|
||||
__clewFinish = (PFNCLFINISH )CLCC_DYNLIB_IMPORT(module, "clFinish");
|
||||
__clewEnqueueReadBuffer = (PFNCLENQUEUEREADBUFFER )CLCC_DYNLIB_IMPORT(module, "clEnqueueReadBuffer");
|
||||
__clewEnqueueWriteBuffer = (PFNCLENQUEUEWRITEBUFFER )CLCC_DYNLIB_IMPORT(module, "clEnqueueWriteBuffer");
|
||||
__clewEnqueueCopyBuffer = (PFNCLENQUEUECOPYBUFFER )CLCC_DYNLIB_IMPORT(module, "clEnqueueCopyBuffer");
|
||||
__clewEnqueueReadImage = (PFNCLENQUEUEREADIMAGE )CLCC_DYNLIB_IMPORT(module, "clEnqueueReadImage");
|
||||
__clewEnqueueWriteImage = (PFNCLENQUEUEWRITEIMAGE )CLCC_DYNLIB_IMPORT(module, "clEnqueueWriteImage");
|
||||
__clewEnqueueCopyImage = (PFNCLENQUEUECOPYIMAGE )CLCC_DYNLIB_IMPORT(module, "clEnqueueCopyImage");
|
||||
__clewEnqueueCopyImageToBuffer = (PFNCLENQUEUECOPYIMAGETOBUFFER )CLCC_DYNLIB_IMPORT(module, "clEnqueueCopyImageToBuffer");
|
||||
__clewEnqueueCopyBufferToImage = (PFNCLENQUEUECOPYBUFFERTOIMAGE )CLCC_DYNLIB_IMPORT(module, "clEnqueueCopyBufferToImage");
|
||||
__clewEnqueueMapBuffer = (PFNCLENQUEUEMAPBUFFER )CLCC_DYNLIB_IMPORT(module, "clEnqueueMapBuffer");
|
||||
__clewEnqueueMapImage = (PFNCLENQUEUEMAPIMAGE )CLCC_DYNLIB_IMPORT(module, "clEnqueueMapImage");
|
||||
__clewEnqueueUnmapMemObject = (PFNCLENQUEUEUNMAPMEMOBJECT )CLCC_DYNLIB_IMPORT(module, "clEnqueueUnmapMemObject");
|
||||
__clewEnqueueNDRangeKernel = (PFNCLENQUEUENDRANGEKERNEL )CLCC_DYNLIB_IMPORT(module, "clEnqueueNDRangeKernel");
|
||||
__clewEnqueueTask = (PFNCLENQUEUETASK )CLCC_DYNLIB_IMPORT(module, "clEnqueueTask");
|
||||
__clewEnqueueNativeKernel = (PFNCLENQUEUENATIVEKERNEL )CLCC_DYNLIB_IMPORT(module, "clEnqueueNativeKernel");
|
||||
__clewEnqueueMarker = (PFNCLENQUEUEMARKER )CLCC_DYNLIB_IMPORT(module, "clEnqueueMarker");
|
||||
__clewEnqueueWaitForEvents = (PFNCLENQUEUEWAITFOREVENTS )CLCC_DYNLIB_IMPORT(module, "clEnqueueWaitForEvents");
|
||||
__clewEnqueueBarrier = (PFNCLENQUEUEBARRIER )CLCC_DYNLIB_IMPORT(module, "clEnqueueBarrier");
|
||||
__clewGetExtensionFunctionAddress = (PFNCLGETEXTENSIONFUNCTIONADDRESS )CLCC_DYNLIB_IMPORT(module, "clGetExtensionFunctionAddress");
|
||||
|
||||
return CLEW_SUCCESS;
|
||||
}
|
||||
|
||||
//! \param error CL error code
|
||||
//! \return a string representation of the error code
|
||||
const char* clewErrorString(cl_int error)
|
||||
{
|
||||
static const char* strings[] =
|
||||
{
|
||||
// Error Codes
|
||||
"CL_SUCCESS" // 0
|
||||
, "CL_DEVICE_NOT_FOUND" // -1
|
||||
, "CL_DEVICE_NOT_AVAILABLE" // -2
|
||||
, "CL_COMPILER_NOT_AVAILABLE" // -3
|
||||
, "CL_MEM_OBJECT_ALLOCATION_FAILURE" // -4
|
||||
, "CL_OUT_OF_RESOURCES" // -5
|
||||
, "CL_OUT_OF_HOST_MEMORY" // -6
|
||||
, "CL_PROFILING_INFO_NOT_AVAILABLE" // -7
|
||||
, "CL_MEM_COPY_OVERLAP" // -8
|
||||
, "CL_IMAGE_FORMAT_MISMATCH" // -9
|
||||
, "CL_IMAGE_FORMAT_NOT_SUPPORTED" // -10
|
||||
, "CL_BUILD_PROGRAM_FAILURE" // -11
|
||||
, "CL_MAP_FAILURE" // -12
|
||||
|
||||
, "" // -13
|
||||
, "" // -14
|
||||
, "" // -15
|
||||
, "" // -16
|
||||
, "" // -17
|
||||
, "" // -18
|
||||
, "" // -19
|
||||
|
||||
, "" // -20
|
||||
, "" // -21
|
||||
, "" // -22
|
||||
, "" // -23
|
||||
, "" // -24
|
||||
, "" // -25
|
||||
, "" // -26
|
||||
, "" // -27
|
||||
, "" // -28
|
||||
, "" // -29
|
||||
|
||||
, "CL_INVALID_VALUE" // -30
|
||||
, "CL_INVALID_DEVICE_TYPE" // -31
|
||||
, "CL_INVALID_PLATFORM" // -32
|
||||
, "CL_INVALID_DEVICE" // -33
|
||||
, "CL_INVALID_CONTEXT" // -34
|
||||
, "CL_INVALID_QUEUE_PROPERTIES" // -35
|
||||
, "CL_INVALID_COMMAND_QUEUE" // -36
|
||||
, "CL_INVALID_HOST_PTR" // -37
|
||||
, "CL_INVALID_MEM_OBJECT" // -38
|
||||
, "CL_INVALID_IMAGE_FORMAT_DESCRIPTOR" // -39
|
||||
, "CL_INVALID_IMAGE_SIZE" // -40
|
||||
, "CL_INVALID_SAMPLER" // -41
|
||||
, "CL_INVALID_BINARY" // -42
|
||||
, "CL_INVALID_BUILD_OPTIONS" // -43
|
||||
, "CL_INVALID_PROGRAM" // -44
|
||||
, "CL_INVALID_PROGRAM_EXECUTABLE" // -45
|
||||
, "CL_INVALID_KERNEL_NAME" // -46
|
||||
, "CL_INVALID_KERNEL_DEFINITION" // -47
|
||||
, "CL_INVALID_KERNEL" // -48
|
||||
, "CL_INVALID_ARG_INDEX" // -49
|
||||
, "CL_INVALID_ARG_VALUE" // -50
|
||||
, "CL_INVALID_ARG_SIZE" // -51
|
||||
, "CL_INVALID_KERNEL_ARGS" // -52
|
||||
, "CL_INVALID_WORK_DIMENSION" // -53
|
||||
, "CL_INVALID_WORK_GROUP_SIZE" // -54
|
||||
, "CL_INVALID_WORK_ITEM_SIZE" // -55
|
||||
, "CL_INVALID_GLOBAL_OFFSET" // -56
|
||||
, "CL_INVALID_EVENT_WAIT_LIST" // -57
|
||||
, "CL_INVALID_EVENT" // -58
|
||||
, "CL_INVALID_OPERATION" // -59
|
||||
, "CL_INVALID_GL_OBJECT" // -60
|
||||
, "CL_INVALID_BUFFER_SIZE" // -61
|
||||
, "CL_INVALID_MIP_LEVEL" // -62
|
||||
, "CL_INVALID_GLOBAL_WORK_SIZE" // -63
|
||||
};
|
||||
|
||||
return strings[-error];
|
||||
}
|
||||
#endif
|
||||
1316
Demos/SharedOpenCL/clew.h
Normal file
1316
Demos/SharedOpenCL/clew.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,6 @@ ${BULLET_PHYSICS_SOURCE_DIR}/src
|
||||
|
||||
SUBDIRS (
|
||||
OpenCL
|
||||
CPU
|
||||
)
|
||||
|
||||
IF( USE_DX11 )
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/src
|
||||
${VECTOR_MATH_INCLUDE}
|
||||
)
|
||||
|
||||
|
||||
|
||||
SET(BulletSoftBodyCPUSolvers_SRCS
|
||||
btSoftBodySolver_CPU.cpp
|
||||
)
|
||||
|
||||
SET(BulletSoftBodyCPUSolvers_HDRS
|
||||
btSoftBodySolver_CPU.h
|
||||
btSoftBodySolverData.h
|
||||
)
|
||||
|
||||
|
||||
ADD_LIBRARY(BulletSoftBodySolvers_CPU ${BulletSoftBodyCPUSolvers_SRCS} ${BulletSoftBodyCPUSolvers_HDRS} )
|
||||
SET_TARGET_PROPERTIES(BulletSoftBodySolvers_CPU PROPERTIES VERSION ${BULLET_VERSION})
|
||||
SET_TARGET_PROPERTIES(BulletSoftBodySolvers_CPU PROPERTIES SOVERSION ${BULLET_VERSION})
|
||||
IF (BUILD_SHARED_LIBS)
|
||||
TARGET_LINK_LIBRARIES(BulletSoftBodySolvers_CPU 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_CPU DESTINATION .)
|
||||
ELSE (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
INSTALL(TARGETS BulletSoftBodySolvers_CPU 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_CPU PROPERTIES FRAMEWORK true)
|
||||
SET_TARGET_PROPERTIES(BulletSoftBodySolvers_CPU PROPERTIES PUBLIC_HEADER "${BulletSoftBodyCPUSolvers_HDRS}")
|
||||
ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES)
|
||||
ENDIF (INSTALL_LIBS)
|
||||
@@ -1,979 +0,0 @@
|
||||
/*
|
||||
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 "BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
|
||||
#include "BulletCollision/CollisionShapes/btCollisionShape.h"
|
||||
#include "vectormath/vmInclude.h"
|
||||
|
||||
#include "BulletMultiThreaded/GpuSoftBodySolvers/CPU/btSoftBodySolver_CPU.h"
|
||||
#include "BulletSoftBody/btSoftBody.h"
|
||||
#include "BulletCollision/CollisionShapes/btCapsuleShape.h"
|
||||
|
||||
|
||||
btCPUSoftBodySolver::btCPUSoftBodySolver()
|
||||
{
|
||||
// Initial we will clearly need to update solver constants
|
||||
// For now this is global for the cloths linked with this solver - we should probably make this body specific
|
||||
// for performance in future once we understand more clearly when constants need to be updated
|
||||
m_updateSolverConstants = true;
|
||||
}
|
||||
|
||||
btCPUSoftBodySolver::~btCPUSoftBodySolver()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
btSoftBodyLinkData &btCPUSoftBodySolver::getLinkData()
|
||||
{
|
||||
return m_linkData;
|
||||
}
|
||||
|
||||
btSoftBodyVertexData &btCPUSoftBodySolver::getVertexData()
|
||||
{
|
||||
return m_vertexData;
|
||||
}
|
||||
|
||||
btSoftBodyTriangleData &btCPUSoftBodySolver::getTriangleData()
|
||||
{
|
||||
return m_triangleData;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static Vectormath::Aos::Vector3 toVector3( const btVector3 &vec )
|
||||
{
|
||||
Vectormath::Aos::Vector3 outVec( vec.getX(), vec.getY(), vec.getZ() );
|
||||
return outVec;
|
||||
}
|
||||
|
||||
static Vectormath::Aos::Transform3 toTransform3( const btTransform &transform )
|
||||
{
|
||||
Vectormath::Aos::Transform3 outTransform;
|
||||
outTransform.setCol(0, toVector3(transform.getBasis().getColumn(0)));
|
||||
outTransform.setCol(1, toVector3(transform.getBasis().getColumn(1)));
|
||||
outTransform.setCol(2, toVector3(transform.getBasis().getColumn(2)));
|
||||
outTransform.setCol(3, toVector3(transform.getOrigin()));
|
||||
return outTransform;
|
||||
}
|
||||
|
||||
void btCPUSoftBodySolver::btAcceleratedSoftBodyInterface::updateBounds( const btVector3 &lowerBound, const btVector3 &upperBound )
|
||||
{
|
||||
float scalarMargin = this->getSoftBody()->getCollisionShape()->getMargin();
|
||||
btVector3 vectorMargin( scalarMargin, scalarMargin, scalarMargin );
|
||||
m_softBody->m_bounds[0] = lowerBound - vectorMargin;
|
||||
m_softBody->m_bounds[1] = upperBound + vectorMargin;
|
||||
}
|
||||
|
||||
|
||||
void btCPUSoftBodySolver::copyBackToSoftBodies()
|
||||
{
|
||||
// Loop over soft bodies, copying all the vertex positions back for each body in turn
|
||||
for( int softBodyIndex = 0; softBodyIndex < m_softBodySet.size(); ++softBodyIndex )
|
||||
{
|
||||
btAcceleratedSoftBodyInterface *softBodyInterface = m_softBodySet[ softBodyIndex ];
|
||||
btSoftBody *softBody = softBodyInterface->getSoftBody();
|
||||
|
||||
int firstVertex = softBodyInterface->getFirstVertex();
|
||||
int numVertices = softBodyInterface->getNumVertices();
|
||||
|
||||
// Copy vertices from solver back into the softbody
|
||||
for( int vertex = 0; vertex < numVertices; ++vertex )
|
||||
{
|
||||
using Vectormath::Aos::Point3;
|
||||
Point3 vertexPosition( getVertexData().getVertexPositions()[firstVertex + vertex] );
|
||||
|
||||
softBody->m_nodes[vertex].m_x.setX( vertexPosition.getX() );
|
||||
softBody->m_nodes[vertex].m_x.setY( vertexPosition.getY() );
|
||||
softBody->m_nodes[vertex].m_x.setZ( vertexPosition.getZ() );
|
||||
|
||||
softBody->m_nodes[vertex].m_n.setX( vertexPosition.getX() );
|
||||
softBody->m_nodes[vertex].m_n.setY( vertexPosition.getY() );
|
||||
softBody->m_nodes[vertex].m_n.setZ( vertexPosition.getZ() );
|
||||
}
|
||||
}
|
||||
} // btCPUSoftBodySolver::copyBackToSoftBodies
|
||||
|
||||
void btCPUSoftBodySolver::optimize( btAlignedObjectArray< btSoftBody * > &softBodies , bool forceUpdate )
|
||||
{
|
||||
if( forceUpdate || m_softBodySet.size() != softBodies.size() )
|
||||
{
|
||||
// Have a change in the soft body set so update, reloading all the data
|
||||
getVertexData().clear();
|
||||
getTriangleData().clear();
|
||||
getLinkData().clear();
|
||||
m_softBodySet.resize(0);
|
||||
|
||||
|
||||
for( int softBodyIndex = 0; softBodyIndex < softBodies.size(); ++softBodyIndex )
|
||||
{
|
||||
btSoftBody *softBody = softBodies[ softBodyIndex ];
|
||||
using Vectormath::Aos::Matrix3;
|
||||
using Vectormath::Aos::Point3;
|
||||
|
||||
// Create SoftBody that will store the information within the solver
|
||||
btAcceleratedSoftBodyInterface *newSoftBody = new btAcceleratedSoftBodyInterface( softBody );
|
||||
m_softBodySet.push_back( newSoftBody );
|
||||
|
||||
m_perClothAcceleration.push_back( toVector3(softBody->getWorldInfo()->m_gravity) );
|
||||
m_perClothDampingFactor.push_back(softBody->m_cfg.kDP);
|
||||
m_perClothVelocityCorrectionCoefficient.push_back( softBody->m_cfg.kVCF );
|
||||
m_perClothLiftFactor.push_back( softBody->m_cfg.kLF );
|
||||
m_perClothDragFactor.push_back( softBody->m_cfg.kDG );
|
||||
m_perClothMediumDensity.push_back(softBody->getWorldInfo()->air_density);
|
||||
m_perClothCollisionObjects.push_back( CollisionObjectIndices(-1, -1) );
|
||||
|
||||
// Add space for new vertices and triangles in the default solver for now
|
||||
// TODO: Include space here for tearing too later
|
||||
int firstVertex = getVertexData().getNumVertices();
|
||||
int numVertices = softBody->m_nodes.size();
|
||||
int maxVertices = numVertices;
|
||||
// Allocate space for new vertices in all the vertex arrays
|
||||
getVertexData().createVertices( maxVertices, softBodyIndex );
|
||||
|
||||
int firstTriangle = getTriangleData().getNumTriangles();
|
||||
int numTriangles = softBody->m_faces.size();
|
||||
int maxTriangles = numTriangles;
|
||||
getTriangleData().createTriangles( maxTriangles );
|
||||
|
||||
// Copy vertices from softbody into the solver
|
||||
for( int vertex = 0; vertex < numVertices; ++vertex )
|
||||
{
|
||||
Point3 multPoint(softBody->m_nodes[vertex].m_x.getX(), softBody->m_nodes[vertex].m_x.getY(), softBody->m_nodes[vertex].m_x.getZ());
|
||||
btSoftBodyVertexData::VertexDescription desc;
|
||||
|
||||
// TODO: Position in the softbody might be pre-transformed
|
||||
// or we may need to adapt for the pose.
|
||||
//desc.setPosition( cloth.getMeshTransform()*multPoint );
|
||||
desc.setPosition( multPoint );
|
||||
|
||||
float vertexInverseMass = softBody->m_nodes[vertex].m_im;
|
||||
desc.setInverseMass(vertexInverseMass);
|
||||
getVertexData().setVertexAt( desc, firstVertex + vertex );
|
||||
}
|
||||
|
||||
// Copy triangles similarly
|
||||
// We're assuming here that vertex indices are based on the firstVertex rather than the entire scene
|
||||
for( int triangle = 0; triangle < numTriangles; ++triangle )
|
||||
{
|
||||
// Note that large array storage is relative to the array not to the cloth
|
||||
// So we need to add firstVertex to each value
|
||||
int vertexIndex0 = (softBody->m_faces[triangle].m_n[0] - &(softBody->m_nodes[0]));
|
||||
int vertexIndex1 = (softBody->m_faces[triangle].m_n[1] - &(softBody->m_nodes[0]));
|
||||
int vertexIndex2 = (softBody->m_faces[triangle].m_n[2] - &(softBody->m_nodes[0]));
|
||||
btSoftBodyTriangleData::TriangleDescription newTriangle(vertexIndex0 + firstVertex, vertexIndex1 + firstVertex, vertexIndex2 + firstVertex);
|
||||
getTriangleData().setTriangleAt( newTriangle, firstTriangle + triangle );
|
||||
|
||||
// Increase vertex triangle counts for this triangle
|
||||
getVertexData().getTriangleCount(newTriangle.getVertexSet().vertex0)++;
|
||||
getVertexData().getTriangleCount(newTriangle.getVertexSet().vertex1)++;
|
||||
getVertexData().getTriangleCount(newTriangle.getVertexSet().vertex2)++;
|
||||
}
|
||||
|
||||
int firstLink = getLinkData().getNumLinks();
|
||||
int numLinks = softBody->m_links.size();
|
||||
int maxLinks = numLinks;
|
||||
|
||||
// Allocate space for the links
|
||||
getLinkData().createLinks( numLinks );
|
||||
|
||||
// Add the links
|
||||
for( int link = 0; link < numLinks; ++link )
|
||||
{
|
||||
int vertexIndex0 = softBody->m_links[link].m_n[0] - &(softBody->m_nodes[0]);
|
||||
int vertexIndex1 = softBody->m_links[link].m_n[1] - &(softBody->m_nodes[0]);
|
||||
|
||||
btSoftBodyLinkData::LinkDescription newLink(vertexIndex0 + firstVertex, vertexIndex1 + firstVertex, softBody->m_links[link].m_material->m_kLST);
|
||||
newLink.setLinkStrength(1.f);
|
||||
getLinkData().setLinkAt(newLink, firstLink + link);
|
||||
}
|
||||
|
||||
newSoftBody->setFirstVertex( firstVertex );
|
||||
newSoftBody->setFirstTriangle( firstTriangle );
|
||||
newSoftBody->setNumVertices( numVertices );
|
||||
newSoftBody->setMaxVertices( maxVertices );
|
||||
newSoftBody->setNumTriangles( numTriangles );
|
||||
newSoftBody->setMaxTriangles( maxTriangles );
|
||||
newSoftBody->setFirstLink( firstLink );
|
||||
newSoftBody->setNumLinks( numLinks );
|
||||
}
|
||||
|
||||
|
||||
|
||||
updateConstants(0.f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void btCPUSoftBodySolver::updateSoftBodies()
|
||||
{
|
||||
using namespace Vectormath::Aos;
|
||||
|
||||
int numVertices = m_vertexData.getNumVertices();
|
||||
int numTriangles = m_triangleData.getNumTriangles();
|
||||
|
||||
// Initialise normal and vertex counts
|
||||
for( int vertexIndex = 0; vertexIndex < numVertices; ++vertexIndex )
|
||||
{
|
||||
m_vertexData.getArea(vertexIndex) = 0.f;
|
||||
m_vertexData.getNormal(vertexIndex) = Vector3(0.f, 0.f, 0.f);
|
||||
}
|
||||
|
||||
// Update the areas for the triangles and vertices.
|
||||
for( int triangleIndex = 0; triangleIndex < numTriangles; ++triangleIndex )
|
||||
{
|
||||
float &triangleArea( m_triangleData.getTriangleArea( triangleIndex ) );
|
||||
const btSoftBodyTriangleData::TriangleNodeSet &vertices( m_triangleData.getVertexSet(triangleIndex) );
|
||||
|
||||
Point3 &vertexPosition0( m_vertexData.getPosition( vertices.vertex0 ) );
|
||||
Point3 &vertexPosition1( m_vertexData.getPosition( vertices.vertex1 ) );
|
||||
Point3 &vertexPosition2( m_vertexData.getPosition( vertices.vertex2 ) );
|
||||
|
||||
triangleArea = computeTriangleArea( vertexPosition0, vertexPosition1, vertexPosition2 );
|
||||
|
||||
// Add to areas for vertices and increase the count of the number of triangles affecting the vertex
|
||||
m_vertexData.getArea(vertices.vertex0) += triangleArea;
|
||||
m_vertexData.getArea(vertices.vertex1) += triangleArea;
|
||||
m_vertexData.getArea(vertices.vertex2) += triangleArea;
|
||||
|
||||
Point3 &vertex0( m_vertexData.getPosition(vertices.vertex0) );
|
||||
Point3 &vertex1( m_vertexData.getPosition(vertices.vertex1) );
|
||||
Point3 &vertex2( m_vertexData.getPosition(vertices.vertex2) );
|
||||
|
||||
Vector3 triangleNormal = cross( vertex1-vertex0, vertex2 - vertex0 );
|
||||
|
||||
m_triangleData.getNormal(triangleIndex) = normalize(triangleNormal);
|
||||
|
||||
m_vertexData.getNormal(vertices.vertex0) += triangleNormal;
|
||||
m_vertexData.getNormal(vertices.vertex1) += triangleNormal;
|
||||
m_vertexData.getNormal(vertices.vertex2) += triangleNormal;
|
||||
|
||||
}
|
||||
|
||||
// Normalise the area and normals
|
||||
for( int vertexIndex = 0; vertexIndex < numVertices; ++vertexIndex )
|
||||
{
|
||||
m_vertexData.getArea(vertexIndex) /= m_vertexData.getTriangleCount(vertexIndex);
|
||||
m_vertexData.getNormal(vertexIndex) = normalize( m_vertexData.getNormal(vertexIndex) );
|
||||
}
|
||||
|
||||
|
||||
// Clear the collision shape array for the next frame
|
||||
m_collisionObjectDetails.clear();
|
||||
|
||||
} // updateSoftBodies
|
||||
|
||||
|
||||
Vectormath::Aos::Vector3 btCPUSoftBodySolver::ProjectOnAxis( const Vectormath::Aos::Vector3 &v, const Vectormath::Aos::Vector3 &a )
|
||||
{
|
||||
return a*Vectormath::Aos::dot(v, a);
|
||||
}
|
||||
|
||||
void btCPUSoftBodySolver::ApplyClampedForce( float solverdt, const Vectormath::Aos::Vector3 &force, const Vectormath::Aos::Vector3 &vertexVelocity, float inverseMass, Vectormath::Aos::Vector3 &vertexForce )
|
||||
{
|
||||
float dtInverseMass = solverdt*inverseMass;
|
||||
if( Vectormath::Aos::lengthSqr(force * dtInverseMass) > Vectormath::Aos::lengthSqr(vertexVelocity) )
|
||||
{
|
||||
vertexForce -= ProjectOnAxis( vertexVelocity, normalize( force ) )/dtInverseMass;
|
||||
} else {
|
||||
vertexForce += force;
|
||||
}
|
||||
}
|
||||
|
||||
bool btCPUSoftBodySolver::checkInitialized()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void btCPUSoftBodySolver::applyForces( float solverdt )
|
||||
{
|
||||
using namespace Vectormath::Aos;
|
||||
|
||||
int numVertices = m_vertexData.getNumVertices();
|
||||
for( int clothIndex = 0; clothIndex < m_softBodySet.size(); ++clothIndex )
|
||||
{
|
||||
btAcceleratedSoftBodyInterface *currentCloth = m_softBodySet[clothIndex];
|
||||
const int startVertex = currentCloth->getFirstVertex();
|
||||
const int numVertices = currentCloth->getNumVertices();
|
||||
|
||||
Vector3 velocityChange = m_perClothAcceleration[clothIndex]*solverdt;
|
||||
for( int vertexIndex = startVertex; vertexIndex < (startVertex + numVertices); ++vertexIndex )
|
||||
{
|
||||
float inverseMass = m_vertexData.getInverseMass( vertexIndex );
|
||||
Vector3 &vertexVelocity( m_vertexData.getVelocity( vertexIndex ) );
|
||||
|
||||
// First apply the global acceleration to all vertices
|
||||
if( inverseMass > 0 )
|
||||
vertexVelocity += velocityChange;
|
||||
|
||||
// If it's a non-static vertex
|
||||
if( m_vertexData.getInverseMass(vertexIndex) > 0 )
|
||||
{
|
||||
// Wind effects on a wind-per-cloth basis
|
||||
float liftFactor = m_perClothLiftFactor[clothIndex];
|
||||
float dragFactor = m_perClothDragFactor[clothIndex];
|
||||
if( (liftFactor > 0.f) || (dragFactor > 0.f) )
|
||||
{
|
||||
Vector3 normal = m_vertexData.getNormal(vertexIndex);
|
||||
Vector3 relativeWindVelocity = m_vertexData.getVelocity(vertexIndex) - m_perClothWindVelocity[clothIndex];
|
||||
float relativeSpeedSquared = lengthSqr(relativeWindVelocity);
|
||||
if( relativeSpeedSquared > FLT_EPSILON )
|
||||
{
|
||||
normal = normal * (dot(normal, relativeWindVelocity) < 0 ? -1.f : +1.f);
|
||||
float dvNormal = dot(normal, relativeWindVelocity);
|
||||
if( dvNormal > 0 )
|
||||
{
|
||||
Vector3 force( 0.f, 0.f, 0.f );
|
||||
float c0 = m_vertexData.getArea(vertexIndex) * dvNormal * relativeSpeedSquared / 2;
|
||||
float c1 = c0 * m_perClothMediumDensity[clothIndex];
|
||||
force += normal * (-c1 * liftFactor);
|
||||
force += normalize(relativeWindVelocity)*(-c1 * dragFactor);
|
||||
|
||||
Vectormath::Aos::Vector3 &vertexForce( m_vertexData.getForceAccumulator(vertexIndex) );
|
||||
ApplyClampedForce( solverdt, force, vertexVelocity, inverseMass, vertexForce );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // btCPUSoftBodySolver::applyForces
|
||||
|
||||
/**
|
||||
* Integrate motion on the solver.
|
||||
*/
|
||||
void btCPUSoftBodySolver::integrate( float solverdt )
|
||||
{
|
||||
using namespace Vectormath::Aos;
|
||||
int numVertices = m_vertexData.getNumVertices();
|
||||
for( int vertexIndex = 0; vertexIndex < numVertices; ++vertexIndex )
|
||||
{
|
||||
Point3 &position( m_vertexData.getPosition(vertexIndex) );
|
||||
Point3 &previousPosition( m_vertexData.getPreviousPosition(vertexIndex) );
|
||||
Vector3 &forceAccumulator( m_vertexData.getForceAccumulator(vertexIndex) );
|
||||
Vector3 &velocity( m_vertexData.getVelocity(vertexIndex) );
|
||||
float inverseMass = m_vertexData.getInverseMass(vertexIndex);
|
||||
|
||||
previousPosition = position;
|
||||
velocity += forceAccumulator * inverseMass * solverdt;
|
||||
position += velocity * solverdt;
|
||||
forceAccumulator = Vector3(0.f, 0.f, 0.f);
|
||||
}
|
||||
} // btCPUSoftBodySolver::integrate
|
||||
|
||||
float btCPUSoftBodySolver::computeTriangleArea(
|
||||
const Vectormath::Aos::Point3 &vertex0,
|
||||
const Vectormath::Aos::Point3 &vertex1,
|
||||
const Vectormath::Aos::Point3 &vertex2 )
|
||||
{
|
||||
Vectormath::Aos::Vector3 a = vertex1 - vertex0;
|
||||
Vectormath::Aos::Vector3 b = vertex2 - vertex0;
|
||||
Vectormath::Aos::Vector3 crossProduct = cross(a, b);
|
||||
float area = length( crossProduct );
|
||||
return area;
|
||||
}
|
||||
|
||||
void btCPUSoftBodySolver::updateConstants( float timeStep )
|
||||
{
|
||||
using namespace Vectormath::Aos;
|
||||
|
||||
if( m_updateSolverConstants )
|
||||
{
|
||||
m_updateSolverConstants = false;
|
||||
|
||||
// Will have to redo this if we change the structure (tear, maybe) or various other possible changes
|
||||
|
||||
// Initialise link constants
|
||||
const int numLinks = m_linkData.getNumLinks();
|
||||
for( int linkIndex = 0; linkIndex < numLinks; ++linkIndex )
|
||||
{
|
||||
btSoftBodyLinkData::LinkNodePair &vertices( m_linkData.getVertexPair(linkIndex) );
|
||||
m_linkData.getRestLength(linkIndex) = length((m_vertexData.getPosition( vertices.vertex0 ) - m_vertexData.getPosition( vertices.vertex1 )));
|
||||
float invMass0 = m_vertexData.getInverseMass(vertices.vertex0);
|
||||
float invMass1 = m_vertexData.getInverseMass(vertices.vertex1);
|
||||
float linearStiffness = m_linkData.getLinearStiffnessCoefficient(linkIndex);
|
||||
float massLSC = (invMass0 + invMass1)/linearStiffness;
|
||||
m_linkData.getMassLSC(linkIndex) = massLSC;
|
||||
float restLength = m_linkData.getRestLength(linkIndex);
|
||||
float restLengthSquared = restLength*restLength;
|
||||
m_linkData.getRestLengthSquared(linkIndex) = restLengthSquared;
|
||||
}
|
||||
}
|
||||
} // btCPUSoftBodySolver::updateConstants
|
||||
|
||||
|
||||
|
||||
|
||||
void btCPUSoftBodySolver::updateBounds()
|
||||
{
|
||||
using Vectormath::Aos::Point3;
|
||||
|
||||
for( int clothIndex = 0; clothIndex < m_softBodySet.size(); ++clothIndex )
|
||||
{
|
||||
btAcceleratedSoftBodyInterface *currentCloth = m_softBodySet[clothIndex];
|
||||
btVector3 startBound(FLT_MAX, FLT_MAX, FLT_MAX);
|
||||
btVector3 endBound(FLT_MIN, FLT_MIN, FLT_MIN);
|
||||
|
||||
const int startVertex = currentCloth->getFirstVertex();
|
||||
const int numVertices = currentCloth->getNumVertices();
|
||||
|
||||
int endVertex = startVertex + numVertices;
|
||||
for(int vertexIndex = startVertex; vertexIndex < endVertex; ++vertexIndex)
|
||||
{
|
||||
btVector3 vertexPosition( m_vertexData.getVertexPositions()[vertexIndex].getX(), m_vertexData.getVertexPositions()[vertexIndex].getY(), m_vertexData.getVertexPositions()[vertexIndex].getZ() );
|
||||
startBound.setX( btMin( startBound.getX(), vertexPosition.getX() ) );
|
||||
startBound.setY( btMin( startBound.getY(), vertexPosition.getY() ) );
|
||||
startBound.setZ( btMin( startBound.getZ(), vertexPosition.getZ() ) );
|
||||
|
||||
endBound.setX( btMax( endBound.getX(), vertexPosition.getX() ) );
|
||||
endBound.setY( btMax( endBound.getY(), vertexPosition.getY() ) );
|
||||
endBound.setZ( btMax( endBound.getZ(), vertexPosition.getZ() ) );
|
||||
}
|
||||
|
||||
m_softBodySet[clothIndex]->updateBounds( startBound, endBound );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class btCPUSB_QuickSortCompare
|
||||
{
|
||||
public:
|
||||
|
||||
bool operator() ( const btCPUCollisionShapeDescription& a, const btCPUCollisionShapeDescription& b )
|
||||
{
|
||||
return ( a.softBodyIdentifier < b.softBodyIdentifier );
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Sort the collision object details array and generate indexing into it for the per-cloth collision object array.
|
||||
*/
|
||||
void btCPUSoftBodySolver::prepareCollisionConstraints()
|
||||
{
|
||||
// First do a simple sort on the collision objects
|
||||
btAlignedObjectArray<int> numObjectsPerClothPrefixSum;
|
||||
btAlignedObjectArray<int> numObjectsPerCloth;
|
||||
numObjectsPerCloth.resize( m_softBodySet.size(), 0 );
|
||||
numObjectsPerClothPrefixSum.resize( m_softBodySet.size(), 0 );
|
||||
|
||||
if (!m_perClothCollisionObjects.size())
|
||||
return;
|
||||
|
||||
m_collisionObjectDetails.quickSort( btCPUSB_QuickSortCompare() );
|
||||
|
||||
// Generating indexing for perClothCollisionObjects
|
||||
// First clear the previous values with the "no collision object for cloth" constant
|
||||
for( int clothIndex = 0; clothIndex < m_perClothCollisionObjects.size(); ++clothIndex )
|
||||
{
|
||||
m_perClothCollisionObjects[clothIndex].firstObject = -1;
|
||||
m_perClothCollisionObjects[clothIndex].endObject = -1;
|
||||
}
|
||||
int currentCloth = 0;
|
||||
int startIndex = 0;
|
||||
for( int collisionObject = 0; collisionObject < m_collisionObjectDetails.size(); ++collisionObject )
|
||||
{
|
||||
int nextCloth = m_collisionObjectDetails[collisionObject].softBodyIdentifier;
|
||||
if( nextCloth != currentCloth )
|
||||
{
|
||||
// Changed cloth in the array
|
||||
// Set the end index and the range is what we need for currentCloth
|
||||
m_perClothCollisionObjects[currentCloth].firstObject = startIndex;
|
||||
m_perClothCollisionObjects[currentCloth].endObject = collisionObject;
|
||||
currentCloth = nextCloth;
|
||||
startIndex = collisionObject;
|
||||
}
|
||||
}
|
||||
|
||||
// And update last cloth
|
||||
m_perClothCollisionObjects[currentCloth].firstObject = startIndex;
|
||||
m_perClothCollisionObjects[currentCloth].endObject = m_collisionObjectDetails.size();
|
||||
|
||||
} // prepareCollisionConstraints
|
||||
|
||||
|
||||
void btCPUSoftBodySolver::solveConstraints( float solverdt )
|
||||
{
|
||||
using Vectormath::Aos::Vector3;
|
||||
using Vectormath::Aos::Point3;
|
||||
using Vectormath::Aos::lengthSqr;
|
||||
using Vectormath::Aos::dot;
|
||||
|
||||
// Prepare links
|
||||
int numLinks = m_linkData.getNumLinks();
|
||||
int numVertices = m_vertexData.getNumVertices();
|
||||
|
||||
float kst = 1.f;
|
||||
|
||||
for( int linkIndex = 0; linkIndex < numLinks; ++linkIndex )
|
||||
{
|
||||
btSoftBodyLinkData::LinkNodePair &nodePair( m_linkData.getVertexPair(linkIndex) );
|
||||
Vector3 currentLength = m_vertexData.getPreviousPosition( nodePair.vertex1 ) - m_vertexData.getPreviousPosition( nodePair.vertex0 );
|
||||
m_linkData.getCurrentLength(linkIndex) = currentLength;
|
||||
|
||||
// If mass at both ends of links is 0 (both static points) then we don't want this information.
|
||||
// In reality this would be a fairly pointless link, but it could have been inserted
|
||||
float linkLengthRatio = 0;
|
||||
if( m_linkData.getMassLSC(linkIndex) > 0 )
|
||||
linkLengthRatio = 1.f/(lengthSqr(currentLength) * m_linkData.getMassLSC(linkIndex));
|
||||
m_linkData.getLinkLengthRatio(linkIndex) = linkLengthRatio;
|
||||
|
||||
}
|
||||
|
||||
|
||||
prepareCollisionConstraints();
|
||||
|
||||
|
||||
for( int iteration = 0; iteration < m_numberOfVelocityIterations ; ++iteration )
|
||||
{
|
||||
// Solve velocity
|
||||
for(int linkIndex = 0; linkIndex < numLinks; ++linkIndex)
|
||||
{
|
||||
|
||||
int vertexIndex0 = m_linkData.getVertexPair(linkIndex).vertex0;
|
||||
int vertexIndex1 = m_linkData.getVertexPair(linkIndex).vertex1;
|
||||
|
||||
float j = -dot(m_linkData.getCurrentLength(linkIndex), m_vertexData.getVelocity(vertexIndex0) - m_vertexData.getVelocity(vertexIndex1)) * m_linkData.getLinkLengthRatio(linkIndex)*kst;
|
||||
|
||||
// If both ends of the link have no mass then this will be zero. Catch that case.
|
||||
// TODO: Should really catch the /0 in the link setup, too
|
||||
//if(psb->m_linksc0[i]>0)
|
||||
{
|
||||
m_vertexData.getVelocity(vertexIndex0) = m_vertexData.getVelocity(vertexIndex0) + m_linkData.getCurrentLength(linkIndex)*j*m_vertexData.getInverseMass(vertexIndex0);
|
||||
m_vertexData.getVelocity(vertexIndex1) = m_vertexData.getVelocity(vertexIndex1) - m_linkData.getCurrentLength(linkIndex)*j*m_vertexData.getInverseMass(vertexIndex1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Compute new positions from velocity
|
||||
// Also update the previous position so that our position computation is now based on the new position from the velocity solution
|
||||
// rather than based directly on the original positions
|
||||
if( m_numberOfVelocityIterations > 0 )
|
||||
{
|
||||
for(int vertexIndex = 0; vertexIndex < numVertices; ++vertexIndex)
|
||||
{
|
||||
m_vertexData.getPosition(vertexIndex) = m_vertexData.getPreviousPosition(vertexIndex) + m_vertexData.getVelocity(vertexIndex) * solverdt;
|
||||
m_vertexData.getPreviousPosition(vertexIndex) = m_vertexData.getPosition(vertexIndex);
|
||||
}
|
||||
}
|
||||
|
||||
// Solve drift
|
||||
for( int iteration = 0; iteration < m_numberOfPositionIterations ; ++iteration )
|
||||
{
|
||||
for( int clothIndex = 0; clothIndex < m_softBodySet.size(); ++clothIndex )
|
||||
{
|
||||
btAcceleratedSoftBodyInterface *currentCloth = m_softBodySet[clothIndex];
|
||||
|
||||
const int startLink = currentCloth->getFirstLink();
|
||||
const int numLinks = currentCloth->getNumLinks();
|
||||
|
||||
int endLink = startLink + numLinks;
|
||||
for(int linkIndex = startLink; linkIndex < endLink; ++linkIndex)
|
||||
{
|
||||
int vertexIndex0 = m_linkData.getVertexPair(linkIndex).vertex0;
|
||||
int vertexIndex1 = m_linkData.getVertexPair(linkIndex).vertex1;
|
||||
|
||||
float massLSC = m_linkData.getMassLSC(linkIndex);
|
||||
if( massLSC > 0.f )
|
||||
{
|
||||
Point3 &vertexPosition0( m_vertexData.getPosition( vertexIndex0 ) );
|
||||
Point3 &vertexPosition1( m_vertexData.getPosition( vertexIndex1 ) );
|
||||
|
||||
Vector3 del = vertexPosition1 - vertexPosition0;
|
||||
float len = lengthSqr(del);
|
||||
float restLength2 = m_linkData.getRestLengthSquared(linkIndex);
|
||||
float k = ((restLength2 - len) / (massLSC * (restLength2 + len) ) )*kst;
|
||||
|
||||
vertexPosition0 -= del*(k*m_vertexData.getInverseMass(vertexIndex0));
|
||||
vertexPosition1 += del*(k*m_vertexData.getInverseMass(vertexIndex1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clear forces so that friction is applied correctly
|
||||
for( int clothIndex = 0; clothIndex < m_softBodySet.size(); ++clothIndex )
|
||||
{
|
||||
btAcceleratedSoftBodyInterface *currentCloth = m_softBodySet[clothIndex];
|
||||
|
||||
const int startLink = currentCloth->getFirstLink();
|
||||
const int numLinks = currentCloth->getNumLinks();
|
||||
const int startVertex = currentCloth->getFirstVertex();
|
||||
const int numVertices = currentCloth->getNumVertices();
|
||||
const int lastVertex = startVertex + numVertices;
|
||||
// Update the velocities based on the change in position
|
||||
// TODO: Damping should only be applied to the action of link constraints so the cloth still falls but then moves stiffly once it hits something
|
||||
float velocityCoefficient = (1.f - m_perClothDampingFactor[clothIndex]);
|
||||
float velocityCorrectionCoefficient = m_perClothVelocityCorrectionCoefficient[clothIndex];
|
||||
float isolverDt = 1.f/solverdt;
|
||||
|
||||
for(int vertexIndex = startVertex; vertexIndex < lastVertex; ++vertexIndex)
|
||||
{
|
||||
m_vertexData.getForceAccumulator( vertexIndex ) = Vector3(0.f, 0.f, 0.f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Solve collision constraints
|
||||
// Very simple solver that pushes the vertex out of collision imposters for now
|
||||
// to test integration with the broad phase code.
|
||||
// May also want to put this into position solver loop every n iterations depending on
|
||||
// how it behaves
|
||||
for( int clothIndex = 0; clothIndex < m_softBodySet.size(); ++clothIndex )
|
||||
{
|
||||
btAcceleratedSoftBodyInterface *currentCloth = m_softBodySet[clothIndex];
|
||||
|
||||
float clothFriction = currentCloth->getSoftBody()->getFriction();
|
||||
|
||||
const int startVertex = currentCloth->getFirstVertex();
|
||||
const int numVertices = currentCloth->getNumVertices();
|
||||
int endVertex = startVertex + numVertices;
|
||||
|
||||
float velocityCoefficient = (1.f - m_perClothDampingFactor[clothIndex]);
|
||||
float velocityCorrectionCoefficient = m_perClothVelocityCorrectionCoefficient[clothIndex];
|
||||
float isolverDt = 1.f/solverdt;
|
||||
|
||||
int startObject = m_perClothCollisionObjects[clothIndex].firstObject;
|
||||
int endObject = m_perClothCollisionObjects[clothIndex].endObject;
|
||||
|
||||
if( endObject == startObject )
|
||||
{
|
||||
// No collisions so just do the force update
|
||||
for(int vertexIndex = startVertex; vertexIndex < endVertex; ++vertexIndex)
|
||||
{
|
||||
m_vertexData.getForceAccumulator( vertexIndex ) = Vector3(0.f, 0.f, 0.f);
|
||||
}
|
||||
|
||||
// Recompute velocity based on updated position inclusive of drift
|
||||
for(int vertexIndex = startVertex; vertexIndex < endVertex; ++vertexIndex)
|
||||
{
|
||||
m_vertexData.getVelocity(vertexIndex) = (m_vertexData.getPosition(vertexIndex) - m_vertexData.getPreviousPosition(vertexIndex)) * velocityCoefficient * isolverDt;
|
||||
}
|
||||
} else {
|
||||
|
||||
for( int collisionObject = startObject; collisionObject < endObject; ++collisionObject )
|
||||
{
|
||||
btCPUCollisionShapeDescription &shapeDescription( m_collisionObjectDetails[collisionObject] );
|
||||
|
||||
float colliderFriction = shapeDescription.friction;
|
||||
|
||||
if( shapeDescription.collisionShapeType == CAPSULE_SHAPE_PROXYTYPE )
|
||||
{
|
||||
using namespace Vectormath::Aos;
|
||||
|
||||
float capsuleHalfHeight = shapeDescription.shapeInformation.capsule.halfHeight;
|
||||
float capsuleRadius = shapeDescription.shapeInformation.capsule.radius;
|
||||
int capsuleUpAxis = shapeDescription.shapeInformation.capsule.upAxis;
|
||||
float capsuleMargin = shapeDescription.margin;
|
||||
|
||||
Transform3 worldTransform = shapeDescription.shapeTransform;
|
||||
|
||||
// As this is a GPU comparison solver just iterate over the vertices
|
||||
for( int vertexIndex = startVertex; vertexIndex < endVertex; ++vertexIndex )
|
||||
{
|
||||
// Clear force for vertex first
|
||||
m_vertexData.getForceAccumulator( vertexIndex ) = Vector3(0.f, 0.f, 0.f);
|
||||
|
||||
Point3 vertex( m_vertexData.getPosition( vertexIndex ) );
|
||||
|
||||
// Correctly define the centerline depending on the upAxis
|
||||
Point3 c1(0.f, 0.f, 0.f);
|
||||
Point3 c2(0.f, 0.f, 0.f);
|
||||
if( capsuleUpAxis == 0 ) {
|
||||
c1.setX(-capsuleHalfHeight);
|
||||
c2.setX(capsuleHalfHeight);
|
||||
} else if( capsuleUpAxis == 1 ) {
|
||||
c1.setY(-capsuleHalfHeight);
|
||||
c2.setY(capsuleHalfHeight);
|
||||
} else {
|
||||
c1.setZ(-capsuleHalfHeight);
|
||||
c2.setZ(capsuleHalfHeight);
|
||||
}
|
||||
|
||||
Point3 worldC1 = worldTransform * c1;
|
||||
Point3 worldC2 = worldTransform * c2;
|
||||
Vector3 segment = worldC2 - worldC1;
|
||||
|
||||
// compute distance of tangent to vertex along line segment in capsule
|
||||
float distanceAlongSegment = -( dot( worldC1 - vertex, segment ) / lengthSqr(segment) );
|
||||
|
||||
Point3 closestPoint = (worldC1 + segment * distanceAlongSegment);
|
||||
float distanceFromLine = length(vertex - closestPoint);
|
||||
float distanceFromC1 = length(worldC1 - vertex);
|
||||
float distanceFromC2 = length(worldC2 - vertex);
|
||||
|
||||
// Final distance from collision, point to push from, direction to push in
|
||||
// for impulse force
|
||||
float distance;
|
||||
Point3 sourcePoint;
|
||||
Vector3 normalVector;
|
||||
if( distanceAlongSegment < 0 )
|
||||
{
|
||||
distance = distanceFromC1;
|
||||
sourcePoint = worldC1;
|
||||
normalVector = normalize(vertex - worldC1);
|
||||
} else if( distanceAlongSegment > 1.f ) {
|
||||
distance = distanceFromC2;
|
||||
sourcePoint = worldC2;
|
||||
normalVector = normalize(vertex - worldC2);
|
||||
} else {
|
||||
distance = distanceFromLine;
|
||||
sourcePoint = closestPoint;
|
||||
normalVector = normalize(vertex - closestPoint);
|
||||
}
|
||||
|
||||
Vector3 colliderLinearVelocity( shapeDescription.linearVelocity );
|
||||
Vector3 colliderAngularVelocity( shapeDescription.angularVelocity );
|
||||
Vector3 velocityOfSurfacePoint = colliderLinearVelocity + cross(colliderAngularVelocity, Vector3(vertex) - worldTransform.getTranslation());
|
||||
|
||||
float minDistance = capsuleRadius + capsuleMargin;
|
||||
bool collided = false;
|
||||
|
||||
if( distance < minDistance )
|
||||
{
|
||||
// Project back to surface along normal
|
||||
Vectormath::Aos::Point3 sourcePos = m_vertexData.getPosition( vertexIndex );
|
||||
Vectormath::Aos::Vector3 posChange = (minDistance - distance)*normalVector*0.9;
|
||||
//if( length(posChange) > 1 )
|
||||
// std::cerr << "Poschange: " << length(posChange) << "\n";
|
||||
|
||||
Vectormath::Aos::Point3 newPos = sourcePos + posChange;
|
||||
m_vertexData.getPosition( vertexIndex ) = newPos;
|
||||
//m_vertexData.getPosition( vertexIndex ) = m_vertexData.getPosition( vertexIndex ) + (minDistance - distance)*normalVector*0.9;
|
||||
|
||||
// Experiment with moving back along source vector.
|
||||
// Removes all ability to slide because it projects back along the vector length so it would undo lateral movement.
|
||||
// TODO: This isn't quite right because we should take the movement of the collider into account as well
|
||||
/*Vector3 incomingMoveVector( normalize(m_vertexData.getPreviousPosition(vertexIndex) - m_vertexData.getPosition(vertexIndex)) );
|
||||
Vector3 normalDirectionMoveOut( (minDistance - distance)*normalVector*0.9 );
|
||||
float distanceOnIncomingVector = dot(normalDirectionMoveOut, incomingMoveVector);
|
||||
Vector3 vectorCorrection( distanceOnIncomingVector*incomingMoveVector );
|
||||
m_vertexData.getPosition( vertexIndex ) = m_vertexData.getPosition( vertexIndex ) + vectorCorrection;*/
|
||||
|
||||
|
||||
collided = true;
|
||||
}
|
||||
|
||||
// Update velocity of vertex based on position
|
||||
m_vertexData.getVelocity(vertexIndex) = (m_vertexData.getPosition(vertexIndex) - m_vertexData.getPreviousPosition(vertexIndex)) * velocityCoefficient * isolverDt;
|
||||
|
||||
// If we collided before we are on the surface so have friction
|
||||
if( collided )
|
||||
{
|
||||
// Compute friction
|
||||
|
||||
// TODO: Just vertex velocity not enough, really we need the velocity
|
||||
// relative to closest point on the surface of the collider
|
||||
Vector3 vertexVelocity( m_vertexData.getVelocity(vertexIndex) );
|
||||
Vector3 relativeVelocity( vertexVelocity - velocityOfSurfacePoint );
|
||||
|
||||
|
||||
// First compute vectors for plane perpendicular to normal vector
|
||||
// Cross any vector with normal vector first then cross the normal with it again
|
||||
Vector3 p1(normalize(cross(normalVector, segment)));
|
||||
Vector3 p2(normalize(cross(p1, normalVector)));
|
||||
// Full friction is sum of velocities in each direction of plane.
|
||||
Vector3 frictionVector(p1*dot(relativeVelocity, p1) + p2*dot(relativeVelocity, p2));
|
||||
|
||||
// Real friction is peak friction corrected by friction coefficients.
|
||||
frictionVector = frictionVector*(colliderFriction*clothFriction);
|
||||
|
||||
float approachSpeed = dot( relativeVelocity, normalVector );
|
||||
|
||||
// For now just update vertex position by moving to radius distance along the push vector
|
||||
// Could use this as the basis for simple vector distance constraint for the point later, possibly?
|
||||
// That way in the main solver loop all shape types could be the same... though when
|
||||
// we need to apply bi-directionally it becomes more complicated
|
||||
|
||||
// Add friction vector to the force accumulator
|
||||
Vector3 ¤tForce( m_vertexData.getForceAccumulator( vertexIndex ) );
|
||||
|
||||
// Only apply if the vertex is moving towards the object to reduce jitter error
|
||||
if( approachSpeed <= 0.0 )
|
||||
currentForce -= frictionVector;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // for( int collisionObject = startObject; collisionObject < endObject; ++collisionObject )
|
||||
} // if( endObject == startObject )
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
} // btCPUSoftBodySolver::solveConstraints
|
||||
|
||||
|
||||
btCPUSoftBodySolver::btAcceleratedSoftBodyInterface *btCPUSoftBodySolver::findSoftBodyInterface( const btSoftBody* const softBody )
|
||||
{
|
||||
for( int softBodyIndex = 0; softBodyIndex < m_softBodySet.size(); ++softBodyIndex )
|
||||
{
|
||||
btAcceleratedSoftBodyInterface *softBodyInterface = m_softBodySet[softBodyIndex];
|
||||
if( softBodyInterface->getSoftBody() == softBody )
|
||||
return softBodyInterface;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const btCPUSoftBodySolver::btAcceleratedSoftBodyInterface * const btCPUSoftBodySolver::findSoftBodyInterface( const btSoftBody* const softBody ) const
|
||||
{
|
||||
for( int softBodyIndex = 0; softBodyIndex < m_softBodySet.size(); ++softBodyIndex )
|
||||
{
|
||||
const btAcceleratedSoftBodyInterface *const softBodyInterface = m_softBodySet[softBodyIndex];
|
||||
if( softBodyInterface->getSoftBody() == softBody )
|
||||
return softBodyInterface;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int btCPUSoftBodySolver::findSoftBodyIndex( const btSoftBody* const softBody )
|
||||
{
|
||||
for( int softBodyIndex = 0; softBodyIndex < m_softBodySet.size(); ++softBodyIndex )
|
||||
{
|
||||
btAcceleratedSoftBodyInterface *softBodyInterface = m_softBodySet[softBodyIndex];
|
||||
if( softBodyInterface->getSoftBody() == softBody )
|
||||
return softBodyIndex;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void btSoftBodySolverOutputCPUtoCPU::copySoftBodyToVertexBuffer( const btSoftBody * const softBody, btVertexBufferDescriptor *vertexBuffer )
|
||||
{
|
||||
// Currently only support CPU output buffers
|
||||
|
||||
const btSoftBodySolver *solver = softBody->getSoftBodySolver();
|
||||
btAssert( solver->getSolverType() == btSoftBodySolver::CPU_SOLVER );
|
||||
const btCPUSoftBodySolver *cpuSolver = static_cast< const btCPUSoftBodySolver * >( solver );
|
||||
const btCPUSoftBodySolver::btAcceleratedSoftBodyInterface * const currentCloth = cpuSolver->findSoftBodyInterface( softBody );
|
||||
const btSoftBodyVertexData &vertexData( cpuSolver->m_vertexData );
|
||||
|
||||
if( vertexBuffer->getBufferType() == btVertexBufferDescriptor::CPU_BUFFER )
|
||||
{
|
||||
const int firstVertex = currentCloth->getFirstVertex();
|
||||
const int lastVertex = firstVertex + currentCloth->getNumVertices();
|
||||
const btCPUVertexBufferDescriptor *cpuVertexBuffer = static_cast< btCPUVertexBufferDescriptor* >(vertexBuffer);
|
||||
float *basePointer = cpuVertexBuffer->getBasePointer();
|
||||
|
||||
if( vertexBuffer->hasVertexPositions() )
|
||||
{
|
||||
const int vertexOffset = cpuVertexBuffer->getVertexOffset();
|
||||
const int vertexStride = cpuVertexBuffer->getVertexStride();
|
||||
float *vertexPointer = basePointer + vertexOffset;
|
||||
|
||||
for( int vertexIndex = firstVertex; vertexIndex < lastVertex; ++vertexIndex )
|
||||
{
|
||||
Vectormath::Aos::Point3 position = vertexData.getPosition(vertexIndex);
|
||||
*(vertexPointer + 0) = position.getX();
|
||||
*(vertexPointer + 1) = position.getY();
|
||||
*(vertexPointer + 2) = position.getZ();
|
||||
vertexPointer += vertexStride;
|
||||
}
|
||||
}
|
||||
if( vertexBuffer->hasNormals() )
|
||||
{
|
||||
const int normalOffset = cpuVertexBuffer->getNormalOffset();
|
||||
const int normalStride = cpuVertexBuffer->getNormalStride();
|
||||
float *normalPointer = basePointer + normalOffset;
|
||||
|
||||
for( int vertexIndex = firstVertex; vertexIndex < lastVertex; ++vertexIndex )
|
||||
{
|
||||
Vectormath::Aos::Vector3 normal = vertexData.getNormal(vertexIndex);
|
||||
*(normalPointer + 0) = normal.getX();
|
||||
*(normalPointer + 1) = normal.getY();
|
||||
*(normalPointer + 2) = normal.getZ();
|
||||
normalPointer += normalStride;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
btAssert( 0=="Invalid vertex buffer descriptor used in CPU output." );
|
||||
}
|
||||
} // btCPUSoftBodySolver::outputToVertexBuffers
|
||||
|
||||
void btCPUSoftBodySolver::processCollision( btSoftBody*, btSoftBody *)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Add the collision object to the set to deal with for a particular soft body
|
||||
void btCPUSoftBodySolver::processCollision( btSoftBody *softBody, btCollisionObject* collisionObject )
|
||||
{
|
||||
int softBodyIndex = findSoftBodyIndex( softBody );
|
||||
|
||||
if( softBodyIndex >= 0 )
|
||||
{
|
||||
btCollisionShape *collisionShape = collisionObject->getCollisionShape();
|
||||
float friction = collisionObject->getFriction();
|
||||
int shapeType = collisionShape->getShapeType();
|
||||
if( shapeType == CAPSULE_SHAPE_PROXYTYPE )
|
||||
{
|
||||
// Add to the list of expected collision objects
|
||||
btCPUCollisionShapeDescription newCollisionShapeDescription;
|
||||
newCollisionShapeDescription.softBodyIdentifier = softBodyIndex;
|
||||
newCollisionShapeDescription.collisionShapeType = shapeType;
|
||||
newCollisionShapeDescription.shapeTransform = toTransform3(collisionObject->getWorldTransform());
|
||||
btCapsuleShape *capsule = static_cast<btCapsuleShape*>( collisionShape );
|
||||
newCollisionShapeDescription.shapeInformation.capsule.radius = capsule->getRadius();
|
||||
newCollisionShapeDescription.shapeInformation.capsule.halfHeight = capsule->getHalfHeight();
|
||||
newCollisionShapeDescription.shapeInformation.capsule.upAxis = capsule->getUpAxis();
|
||||
newCollisionShapeDescription.margin = capsule->getMargin();
|
||||
newCollisionShapeDescription.friction = friction;
|
||||
btRigidBody* body = static_cast< btRigidBody* >( collisionObject );
|
||||
newCollisionShapeDescription.linearVelocity = toVector3(body->getLinearVelocity());
|
||||
newCollisionShapeDescription.angularVelocity = toVector3(body->getAngularVelocity());
|
||||
m_collisionObjectDetails.push_back( newCollisionShapeDescription );
|
||||
} else {
|
||||
btAssert("Unsupported collision shape type\n");
|
||||
}
|
||||
} else {
|
||||
btAssert("Unknown soft body");
|
||||
}
|
||||
} // btCPUSoftBodySolver::processCollision
|
||||
|
||||
|
||||
void btCPUSoftBodySolver::predictMotion( float timeStep )
|
||||
{
|
||||
// Fill the force arrays with current acceleration data etc
|
||||
m_perClothWindVelocity.resize( m_softBodySet.size() );
|
||||
for( int softBodyIndex = 0; softBodyIndex < m_softBodySet.size(); ++softBodyIndex )
|
||||
{
|
||||
btSoftBody *softBody = m_softBodySet[softBodyIndex]->getSoftBody();
|
||||
|
||||
m_perClothWindVelocity[softBodyIndex] = toVector3(softBody->getWindVelocity());
|
||||
}
|
||||
|
||||
|
||||
// Apply forces that we know about to the cloths
|
||||
applyForces( timeStep * getTimeScale() );
|
||||
|
||||
// Itegrate motion for all soft bodies dealt with by the solver
|
||||
integrate( timeStep * getTimeScale() );
|
||||
|
||||
// Update bounds
|
||||
// Will update the bounds for all softBodies being dealt with by the solver and
|
||||
// set the values in the btSoftBody object
|
||||
updateBounds();
|
||||
|
||||
// End prediction work for solvers
|
||||
}
|
||||
|
||||
|
||||
@@ -1,370 +0,0 @@
|
||||
/*
|
||||
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_ACCELERATED_SOFT_BODY_CPU_SOLVER_H
|
||||
#define BT_ACCELERATED_SOFT_BODY_CPU_SOLVER_H
|
||||
|
||||
#include "vectormath/vmInclude.h"
|
||||
#include "BulletSoftBody/btSoftBodySolvers.h"
|
||||
#include "BulletSoftBody/btSoftBodySolverVertexBuffer.h"
|
||||
#include "BulletMultiThreaded/GpuSoftBodySolvers/CPU/btSoftBodySolverData.h"
|
||||
|
||||
struct btCPUCollisionShapeDescription
|
||||
{
|
||||
int softBodyIdentifier;
|
||||
int collisionShapeType;
|
||||
Vectormath::Aos::Transform3 shapeTransform;
|
||||
union
|
||||
{
|
||||
struct Sphere
|
||||
{
|
||||
float radius;
|
||||
} sphere;
|
||||
struct Capsule
|
||||
{
|
||||
float radius;
|
||||
float halfHeight;
|
||||
int upAxis;
|
||||
} capsule;
|
||||
} shapeInformation;
|
||||
|
||||
float margin;
|
||||
float friction;
|
||||
Vectormath::Aos::Vector3 linearVelocity;
|
||||
Vectormath::Aos::Vector3 angularVelocity;
|
||||
|
||||
btCPUCollisionShapeDescription()
|
||||
{
|
||||
collisionShapeType = 0;
|
||||
margin = 0;
|
||||
friction = 0;
|
||||
}
|
||||
};
|
||||
|
||||
class btCPUSoftBodySolver : public btSoftBodySolver
|
||||
{
|
||||
protected:
|
||||
/**
|
||||
* Entry in the collision shape array.
|
||||
* Specifies the shape type, the transform matrix and the necessary details of the collisionShape.
|
||||
*/
|
||||
|
||||
|
||||
// Public because output classes need it. This is a better encapsulation to break in the short term
|
||||
// Than having the solvers themselves need dependencies on DX, CL etc unnecessarily
|
||||
public:
|
||||
|
||||
struct CollisionObjectIndices
|
||||
{
|
||||
CollisionObjectIndices( int f, int e )
|
||||
{
|
||||
firstObject = f;
|
||||
endObject = e;
|
||||
}
|
||||
|
||||
int firstObject;
|
||||
int endObject;
|
||||
};
|
||||
|
||||
/**
|
||||
* SoftBody class to maintain information about a soft body instance
|
||||
* within a solver.
|
||||
* This data addresses the main solver arrays.
|
||||
*/
|
||||
class btAcceleratedSoftBodyInterface
|
||||
{
|
||||
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:
|
||||
btAcceleratedSoftBodyInterface( 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() const
|
||||
{
|
||||
return m_numVertices;
|
||||
}
|
||||
|
||||
int getNumTriangles() const
|
||||
{
|
||||
return m_numTriangles;
|
||||
}
|
||||
|
||||
int getMaxVertices() const
|
||||
{
|
||||
return m_maxVertices;
|
||||
}
|
||||
|
||||
int getMaxTriangles() const
|
||||
{
|
||||
return m_maxTriangles;
|
||||
}
|
||||
|
||||
int getFirstVertex() const
|
||||
{
|
||||
return m_firstVertex;
|
||||
}
|
||||
|
||||
int getFirstTriangle() const
|
||||
{
|
||||
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() const
|
||||
{
|
||||
return m_maxLinks;
|
||||
}
|
||||
|
||||
int getNumLinks() const
|
||||
{
|
||||
return m_numLinks;
|
||||
}
|
||||
|
||||
int getFirstLink() const
|
||||
{
|
||||
return m_firstLink;
|
||||
}
|
||||
|
||||
btSoftBody* getSoftBody()
|
||||
{
|
||||
return m_softBody;
|
||||
}
|
||||
|
||||
const btSoftBody* const getSoftBody() const
|
||||
{
|
||||
return m_softBody;
|
||||
}
|
||||
};
|
||||
|
||||
btSoftBodyLinkData m_linkData;
|
||||
btSoftBodyVertexData m_vertexData;
|
||||
btSoftBodyTriangleData m_triangleData;
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
|
||||
/** Variable to define whether we need to update solver constants on the next iteration */
|
||||
bool m_updateSolverConstants;
|
||||
|
||||
/**
|
||||
* Cloths owned by this solver.
|
||||
* Only our cloths are in this array.
|
||||
*/
|
||||
btAlignedObjectArray< btAcceleratedSoftBodyInterface * > 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;
|
||||
|
||||
/** 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;
|
||||
|
||||
/** Velocity damping factor */
|
||||
btAlignedObjectArray< float > m_perClothDampingFactor;
|
||||
|
||||
/** Velocity correction coefficient */
|
||||
btAlignedObjectArray< float > m_perClothVelocityCorrectionCoefficient;
|
||||
|
||||
/** Lift parameter for wind effect on cloth. */
|
||||
btAlignedObjectArray< float > m_perClothLiftFactor;
|
||||
|
||||
/** Drag parameter for wind effect on cloth. */
|
||||
btAlignedObjectArray< float > m_perClothDragFactor;
|
||||
|
||||
/** Density of the medium in which each cloth sits */
|
||||
btAlignedObjectArray< float > m_perClothMediumDensity;
|
||||
|
||||
/**
|
||||
* Collision shape details: pair of index of first collision shape for the cloth and number of collision objects.
|
||||
*/
|
||||
btAlignedObjectArray< CollisionObjectIndices > m_perClothCollisionObjects;
|
||||
|
||||
/**
|
||||
* Collision shapes being passed across to the cloths in this solver.
|
||||
*/
|
||||
btAlignedObjectArray< btCPUCollisionShapeDescription > m_collisionObjectDetails;
|
||||
|
||||
|
||||
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 );
|
||||
|
||||
float computeTriangleArea(
|
||||
const Vectormath::Aos::Point3 &vertex0,
|
||||
const Vectormath::Aos::Point3 &vertex1,
|
||||
const Vectormath::Aos::Point3 &vertex2 );
|
||||
|
||||
void applyForces( float solverdt );
|
||||
void integrate( float solverdt );
|
||||
void updateConstants( float timeStep );
|
||||
int findSoftBodyIndex( const btSoftBody* const softBody );
|
||||
|
||||
/** Update the bounds of the soft body objects in the solver */
|
||||
void updateBounds();
|
||||
|
||||
|
||||
public:
|
||||
btCPUSoftBodySolver();
|
||||
|
||||
virtual ~btCPUSoftBodySolver();
|
||||
|
||||
|
||||
virtual SolverTypes getSolverType() const
|
||||
{
|
||||
return CPU_SOLVER;
|
||||
}
|
||||
|
||||
|
||||
virtual btSoftBodyLinkData &getLinkData();
|
||||
|
||||
virtual btSoftBodyVertexData &getVertexData();
|
||||
|
||||
virtual btSoftBodyTriangleData &getTriangleData();
|
||||
|
||||
|
||||
|
||||
btAcceleratedSoftBodyInterface *findSoftBodyInterface( const btSoftBody* const softBody );
|
||||
const btAcceleratedSoftBodyInterface * const findSoftBodyInterface( const btSoftBody* const softBody ) const;
|
||||
|
||||
|
||||
|
||||
virtual bool checkInitialized();
|
||||
|
||||
virtual void updateSoftBodies( );
|
||||
|
||||
virtual void optimize( btAlignedObjectArray< btSoftBody * > &softBodies , bool forceUpdate=false);
|
||||
|
||||
virtual void copyBackToSoftBodies();
|
||||
|
||||
virtual void solveConstraints( float solverdt );
|
||||
|
||||
virtual void predictMotion( float solverdt );
|
||||
|
||||
virtual void processCollision( btSoftBody *, btCollisionObject* );
|
||||
|
||||
virtual void processCollision( btSoftBody*, btSoftBody *);
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Class to manage movement of data from a solver to a given target.
|
||||
* This version is the CPU to CPU generic version.
|
||||
*/
|
||||
class btSoftBodySolverOutputCPUtoCPU : public btSoftBodySolverOutput
|
||||
{
|
||||
protected:
|
||||
|
||||
public:
|
||||
btSoftBodySolverOutputCPUtoCPU()
|
||||
{
|
||||
}
|
||||
|
||||
/** 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_ACCELERATED_SOFT_BODY_CPU_SOLVER_H
|
||||
@@ -8,7 +8,7 @@ SET(DX11_INCLUDE_PATH "${DIRECTX_SDK_BASE_DIR}/Include" CACHE DOCSTRING "Micros
|
||||
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
${DX11_INCLUDE_PATH} "../cpu/"
|
||||
${DX11_INCLUDE_PATH} "../Shared/"
|
||||
${VECTOR_MATH_INCLUDE}
|
||||
)
|
||||
|
||||
@@ -20,7 +20,7 @@ SET(BulletSoftBodyDX11Solvers_SRCS
|
||||
SET(BulletSoftBodyDX11Solvers_HDRS
|
||||
btSoftBodySolver_DX11.h
|
||||
btSoftBodySolver_DX11SIMDAware.h
|
||||
../cpu/btSoftBodySolverData.h
|
||||
../Shared/btSoftBodySolverData.h
|
||||
btSoftBodySolverVertexData_DX11.h
|
||||
btSoftBodySolverTriangleData_DX11.h
|
||||
btSoftBodySolverLinkData_DX11.h
|
||||
|
||||
@@ -14,7 +14,7 @@ subject to the following restrictions:
|
||||
*/
|
||||
|
||||
|
||||
#include "BulletMultiThreaded/GpuSoftBodySolvers/CPU/btSoftBodySolverData.h"
|
||||
#include "BulletMultiThreaded/GpuSoftBodySolvers/Shared/btSoftBodySolverData.h"
|
||||
#include "btSoftBodySolverBuffer_DX11.h"
|
||||
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ subject to the following restrictions:
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "BulletMultiThreaded/GpuSoftBodySolvers/CPU/btSoftBodySolverData.h"
|
||||
#include "BulletMultiThreaded/GpuSoftBodySolvers/Shared/btSoftBodySolverData.h"
|
||||
#include "btSoftBodySolverBuffer_DX11.h"
|
||||
|
||||
#ifndef BT_ACCELERATED_SOFT_BODY_LINK_DATA_DX11_SIMDAWARE_H
|
||||
|
||||
@@ -13,7 +13,7 @@ subject to the following restrictions:
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "BulletMultiThreaded/GpuSoftBodySolvers/CPU/btSoftBodySolverData.h"
|
||||
#include "BulletMultiThreaded/GpuSoftBodySolvers/Shared/btSoftBodySolverData.h"
|
||||
#include "btSoftBodySolverBuffer_DX11.h"
|
||||
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ subject to the following restrictions:
|
||||
*/
|
||||
|
||||
|
||||
#include "BulletMultiThreaded/GpuSoftBodySolvers/CPU/btSoftBodySolverData.h"
|
||||
#include "BulletMultiThreaded/GpuSoftBodySolvers/Shared/btSoftBodySolverData.h"
|
||||
#include "btSoftBodySolverBuffer_DX11.h"
|
||||
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ SET(BulletSoftBodyOpenCLSolvers_SRCS
|
||||
SET(BulletSoftBodyOpenCLSolvers_HDRS
|
||||
../btSoftBodySolver_OpenCL.h
|
||||
../btSoftBodySolver_OpenCLSIMDAware.h
|
||||
../../CPU/btSoftBodySolverData.h
|
||||
../../Shared/btSoftBodySolverData.h
|
||||
../btSoftBodySolverVertexData_OpenCL.h
|
||||
../btSoftBodySolverTriangleData_OpenCL.h
|
||||
../btSoftBodySolverLinkData_OpenCL.h
|
||||
|
||||
@@ -13,7 +13,7 @@ SET(BulletSoftBodyOpenCLSolvers_SRCS
|
||||
|
||||
SET(BulletSoftBodyOpenCLSolvers_HDRS
|
||||
../btSoftBodySolver_OpenCL.h
|
||||
../../CPU/btSoftBodySolverData.h
|
||||
../../Shared/btSoftBodySolverData.h
|
||||
../btSoftBodySolverVertexData_OpenCL.h
|
||||
../btSoftBodySolverTriangleData_OpenCL.h
|
||||
../btSoftBodySolverLinkData_OpenCL.h
|
||||
|
||||
@@ -18,7 +18,7 @@ SET(BulletSoftBodyOpenCLSolvers_SRCS
|
||||
SET(BulletSoftBodyOpenCLSolvers_HDRS
|
||||
../btSoftBodySolver_OpenCL.h
|
||||
../btSoftBodySolver_OpenCLSIMDAware.h
|
||||
../../CPU/btSoftBodySolverData.h
|
||||
../../Shared/btSoftBodySolverData.h
|
||||
../btSoftBodySolverVertexData_OpenCL.h
|
||||
../btSoftBodySolverTriangleData_OpenCL.h
|
||||
../btSoftBodySolverLinkData_OpenCL.h
|
||||
|
||||
@@ -14,7 +14,7 @@ SET(BulletSoftBodyOpenCLSolvers_SRCS
|
||||
|
||||
SET(BulletSoftBodyOpenCLSolvers_HDRS
|
||||
../btSoftBodySolver_OpenCL.h
|
||||
../../CPU/btSoftBodySolverData.h
|
||||
../../Shared/btSoftBodySolverData.h
|
||||
../btSoftBodySolverVertexData_OpenCL.h
|
||||
../btSoftBodySolverTriangleData_OpenCL.h
|
||||
../btSoftBodySolverLinkData_OpenCL.h
|
||||
|
||||
@@ -24,9 +24,12 @@ subject to the following restrictions:
|
||||
#include "../OpenCLC10/UpdateNormals.cl"
|
||||
#include "../OpenCLC10/UpdatePositions.cl"
|
||||
#include "../OpenCLC10/UpdatePositionsFromVelocities.cl"
|
||||
//#include "../OpenCLC10/VSolveLinks.cl"
|
||||
#include "../OpenCLC10/VSolveLinks.cl"
|
||||
//#include "../OpenCLC10/SolveCollisionsAndUpdateVelocities.cl"
|
||||
|
||||
|
||||
MINICL_REGISTER(PrepareLinksKernel)
|
||||
MINICL_REGISTER(VSolveLinksKernel)
|
||||
MINICL_REGISTER(UpdatePositionsFromVelocitiesKernel)
|
||||
MINICL_REGISTER(SolvePositionsFromLinksKernel)
|
||||
MINICL_REGISTER(updateVelocitiesFromPositionsWithVelocitiesKernel)
|
||||
@@ -38,3 +41,208 @@ MINICL_REGISTER(NormalizeNormalsAndAreasKernel)
|
||||
MINICL_REGISTER(UpdateSoftBodiesKernel)
|
||||
|
||||
|
||||
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);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ SET(BulletSoftBodyOpenCLSolvers_SRCS
|
||||
|
||||
SET(BulletSoftBodyOpenCLSolvers_HDRS
|
||||
../btSoftBodySolver_OpenCL.h
|
||||
../../CPU/btSoftBodySolverData.h
|
||||
../../Shared/btSoftBodySolverData.h
|
||||
../btSoftBodySolverVertexData_OpenCL.h
|
||||
../btSoftBodySolverTriangleData_OpenCL.h
|
||||
../btSoftBodySolverLinkData_OpenCL.h
|
||||
|
||||
@@ -78,8 +78,8 @@ ApplyForcesKernel(
|
||||
float4 nodeFMinus = nodeF - (projectOnAxis(nodeV, normalize(force))/dtim);
|
||||
|
||||
nodeF = nodeFPlusForce;
|
||||
if( dot(forceDTIM, forceDTIM) > dot(nodeV, nodeV) )
|
||||
nodeF = nodeFMinus;
|
||||
//if( dot(forceDTIM, forceDTIM) > dot(nodeV, nodeV) )
|
||||
// nodeF = nodeFMinus;
|
||||
|
||||
g_vertexForceAccumulator[nodeID] = nodeF;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
MSTRINGIFY(
|
||||
|
||||
#pragma OPENCL EXTENSION cl_amd_printf : enable\n
|
||||
|
||||
float mydot3(float4 a, float4 b)
|
||||
|
||||
float mydot3a(float4 a, float4 b)
|
||||
{
|
||||
return a.x*b.x + a.y*b.y + a.z*b.z;
|
||||
}
|
||||
@@ -67,7 +67,7 @@ SolveCollisionsAndUpdateVelocitiesKernel(
|
||||
__global CollisionShapeDescription * g_collisionObjectDetails,
|
||||
__global float4 * g_vertexForces,
|
||||
__global float4 *g_vertexVelocities,
|
||||
__global float4 *g_vertexPositions)
|
||||
__global float4 *g_vertexPositions GUID_ARG)
|
||||
{
|
||||
int nodeID = get_global_id(0);
|
||||
float4 forceOnVertex = (float4)(0.f, 0.f, 0.f, 0.f);
|
||||
@@ -134,7 +134,7 @@ SolveCollisionsAndUpdateVelocitiesKernel(
|
||||
float4 segment = (worldC2 - worldC1);
|
||||
|
||||
// compute distance of tangent to vertex along line segment in capsule
|
||||
float distanceAlongSegment = -( mydot3( (worldC1 - position), segment ) / mydot3(segment, segment) );
|
||||
float distanceAlongSegment = -( mydot3a( (worldC1 - position), segment ) / mydot3a(segment, segment) );
|
||||
|
||||
float4 closestPoint = (worldC1 + (float4)(segment * distanceAlongSegment));
|
||||
float distanceFromLine = length(position - closestPoint);
|
||||
@@ -178,7 +178,7 @@ SolveCollisionsAndUpdateVelocitiesKernel(
|
||||
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*mydot3(relativeVelocity, p1) + p2*mydot3(relativeVelocity, p2);
|
||||
float4 frictionVector = p1*mydot3a(relativeVelocity, p1) + p2*mydot3a(relativeVelocity, p2);
|
||||
|
||||
// Real friction is peak friction corrected by friction coefficients
|
||||
frictionVector = frictionVector * (colliderFriction*clothFriction);
|
||||
|
||||
@@ -13,7 +13,7 @@ subject to the following restrictions:
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "BulletMultiThreaded/GpuSoftBodySolvers/CPU/btSoftBodySolverData.h"
|
||||
#include "BulletMultiThreaded/GpuSoftBodySolvers/Shared/btSoftBodySolverData.h"
|
||||
#include "btSoftBodySolverBuffer_OpenCL.h"
|
||||
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ subject to the following restrictions:
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "BulletMultiThreaded/GpuSoftBodySolvers/CPU/btSoftBodySolverData.h"
|
||||
#include "BulletMultiThreaded/GpuSoftBodySolvers/Shared/btSoftBodySolverData.h"
|
||||
#include "btSoftBodySolverBuffer_OpenCL.h"
|
||||
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ subject to the following restrictions:
|
||||
*/
|
||||
|
||||
|
||||
#include "BulletMultiThreaded/GpuSoftBodySolvers/CPU/btSoftBodySolverData.h"
|
||||
#include "BulletMultiThreaded/GpuSoftBodySolvers/Shared/btSoftBodySolverData.h"
|
||||
#include "btSoftBodySolverBuffer_OpenCL.h"
|
||||
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ subject to the following restrictions:
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "BulletMultiThreaded/GpuSoftBodySolvers/CPU/btSoftBodySolverData.h"
|
||||
#include "BulletMultiThreaded/GpuSoftBodySolvers/Shared/btSoftBodySolverData.h"
|
||||
#include "btSoftBodySolverBuffer_OpenCL.h"
|
||||
|
||||
#ifndef BT_SOFT_BODY_SOLVER_VERTEX_DATA_OPENCL_H
|
||||
|
||||
@@ -1642,10 +1642,11 @@ void btOpenCLSoftBodySolver::processCollision( btSoftBody *softBody, btCollision
|
||||
m_collisionObjectDetails.push_back( newCollisionShapeDescription );
|
||||
|
||||
} else {
|
||||
btAssert(0 && "Unsupported collision shape type\n");
|
||||
printf("Unsupported collision shape type\n");
|
||||
//btAssert(0 && "Unsupported collision shape type\n");
|
||||
}
|
||||
} else {
|
||||
btAssert("Unknown soft body");
|
||||
btAssert(0,"Unknown soft body");
|
||||
}
|
||||
} // btOpenCLSoftBodySolver::processCollision
|
||||
|
||||
|
||||
@@ -1822,7 +1822,7 @@ btScalar btSoftBody::RayFromToCaster::rayFromToTriangle( const btVector3& rayF
|
||||
void btSoftBody::pointersToIndices()
|
||||
{
|
||||
#define PTR2IDX(_p_,_b_) reinterpret_cast<btSoftBody::Node*>((_p_)-(_b_))
|
||||
btSoftBody::Node* base=&m_nodes[0];
|
||||
btSoftBody::Node* base=m_nodes.size() ? &m_nodes[0] : 0;
|
||||
int i,ni;
|
||||
|
||||
for(i=0,ni=m_nodes.size();i<ni;++i)
|
||||
@@ -1866,7 +1866,7 @@ void btSoftBody::indicesToPointers(const int* map)
|
||||
{
|
||||
#define IDX2PTR(_p_,_b_) map?(&(_b_)[map[(((char*)_p_)-(char*)0)]]): \
|
||||
(&(_b_)[(((char*)_p_)-(char*)0)])
|
||||
btSoftBody::Node* base=&m_nodes[0];
|
||||
btSoftBody::Node* base=m_nodes.size() ? &m_nodes[0]:0;
|
||||
int i,ni;
|
||||
|
||||
for(i=0,ni=m_nodes.size();i<ni;++i)
|
||||
|
||||
@@ -57,11 +57,118 @@ struct float8
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
float select( float arg0, float arg1, bool select)
|
||||
{
|
||||
if (select)
|
||||
return arg0;
|
||||
return arg1;
|
||||
}
|
||||
|
||||
#define __constant
|
||||
|
||||
|
||||
struct float3
|
||||
{
|
||||
float x,y,z;
|
||||
|
||||
float3& operator+=(const float3& other)
|
||||
{
|
||||
x += other.x;
|
||||
y += other.y;
|
||||
z += other.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
float3& operator-=(const float3& other)
|
||||
{
|
||||
x -= other.x;
|
||||
y -= other.y;
|
||||
z -= other.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
static float dot(const float3&a ,const float3& b)
|
||||
{
|
||||
float3 tmp;
|
||||
tmp.x = a.x*b.x;
|
||||
tmp.y = a.y*b.y;
|
||||
tmp.z = a.z*b.z;
|
||||
return tmp.x+tmp.y+tmp.z;
|
||||
}
|
||||
|
||||
static float3 operator-(const float3& a,const float3& b)
|
||||
{
|
||||
float3 tmp;
|
||||
tmp.x = a.x - b.x;
|
||||
tmp.y = a.y - b.y;
|
||||
tmp.z = a.z - b.z;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static float3 operator*(const float& scalar,const float3& b)
|
||||
{
|
||||
float3 tmp;
|
||||
tmp.x = scalar * b.x;
|
||||
tmp.y = scalar * b.y;
|
||||
tmp.z = scalar * b.z;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static float3 operator*(const float3& a,const float& scalar)
|
||||
{
|
||||
float3 tmp;
|
||||
tmp.x = a.x * scalar;
|
||||
tmp.y = a.y * scalar;
|
||||
tmp.z = a.z * scalar;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
static float3 operator*(const float3& a,const float3& b)
|
||||
{
|
||||
float3 tmp;
|
||||
tmp.x = a.x * b.x;
|
||||
tmp.y = a.y * b.y;
|
||||
tmp.z = a.z * b.z;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
//ATTRIBUTE_ALIGNED16(struct) float4
|
||||
struct float4
|
||||
{
|
||||
float x,y,z,w;
|
||||
union
|
||||
{
|
||||
struct {
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
};
|
||||
float3 xyz;
|
||||
};
|
||||
float w;
|
||||
|
||||
float4() {}
|
||||
|
||||
float4(float v0, float v1, float v2, float v3)
|
||||
{
|
||||
x=v0;
|
||||
y=v1;
|
||||
z=v2;
|
||||
w=v3;
|
||||
|
||||
}
|
||||
float4(float3 xyz, float scalarW)
|
||||
{
|
||||
x = xyz.x;
|
||||
y = xyz.y;
|
||||
z = xyz.z;
|
||||
w = scalarW;
|
||||
}
|
||||
|
||||
float4(float v)
|
||||
{
|
||||
x = y = z = w = v;
|
||||
@@ -76,6 +183,8 @@ struct float4
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
float4 operator*(const float& other)
|
||||
{
|
||||
float4 tmp;
|
||||
@@ -203,6 +312,7 @@ static float4 operator/(const float4& b,float a)
|
||||
|
||||
|
||||
|
||||
|
||||
static float dot(const float4&a ,const float4& b)
|
||||
{
|
||||
float4 tmp;
|
||||
|
||||
Reference in New Issue
Block a user